cjson
.github
workflows CI.yml ci-fuzz.yml
CONTRIBUTING.md
fuzzing
inputs test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9
.gitignore CMakeLists.txt afl-prepare-linux.sh afl.c afl.sh cjson_read_fuzzer.c fuzz_main.c json.dict ossfuzz.sh
library_config cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmake
tests
inputs test1 test1.expected test10 test10.expected test11 test11.expected test2 test2.expected test3 test3.expected test4 test4.expected test5 test5.expected test6 test7 test7.expected test8 test8.expected test9 test9.expected
json-patch-tests .editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.json
unity
auto colour_prompt.rb colour_reporter.rb generate_config.yml generate_module.rb generate_test_runner.rb parse_output.rb stylize_as_junit.rb test_file_filter.rb type_sanitizer.rb unity_test_summary.py unity_test_summary.rb unity_to_junit.py
docs ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txt
examples
example_1
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_2
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_3
helper UnityHelper.c UnityHelper.h
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
rakefile.rb rakefile_helper.rb readme.txt target_gcc_32.yml
unity_config.h
extras
eclipse error_parsers.txt
fixture
src unity_fixture.c unity_fixture.h unity_fixture_internals.h unity_fixture_malloc_overrides.h
rakefile.rb rakefile_helper.rb readme.txt
release build.info version.info
src unity.c unity.h unity_internals.h
.gitattributes .gitignore .travis.yml README.md
CMakeLists.txt cjson_add.c common.h compare_tests.c json_patch_tests.c minify_tests.c misc_tests.c misc_utils_tests.c old_utils_tests.c parse_array.c parse_examples.c parse_hex4.c parse_number.c parse_object.c parse_string.c parse_value.c parse_with_opts.c print_array.c print_number.c print_object.c print_string.c print_value.c readme_examples.c unity_setup.c
.editorconfig .gitattributes .gitignore .travis.yml CHANGELOG.md CMakeLists.txt CONTRIBUTORS.md LICENSE Makefile README.md SECURITY.md appveyor.yml cJSON.c cJSON.h cJSON_Utils.c cJSON_Utils.h test.c valgrind.supp
curl
.circleci config.yml
.github
ISSUE_TEMPLATE bug_report.yml config.yml docs.yml
scripts cleancmd.pl cmp-config.pl cmp-pkg-config.sh codespell-ignore.words codespell.sh distfiles.sh pyspelling.words pyspelling.yaml randcurl.pl requirements-docs.txt requirements-proselint.txt requirements.txt shellcheck-ci.sh shellcheck.sh spellcheck.curl trimmarkdownheader.pl typos.sh typos.toml verify-examples.pl verify-synopsis.pl yamlcheck.sh yamlcheck.yaml
workflows appveyor-status.yml checkdocs.yml checksrc.yml checkurls.yml codeql.yml configure-vs-cmake.yml curl-for-win.yml distcheck.yml fuzz.yml http3-linux.yml label.yml linux-old.yml linux.yml macos.yml non-native.yml windows.yml
CODEOWNERS CONTRIBUTING.md FUNDING.yml dependabot.yml labeler.yml lock.yml stale.yml
CMake CurlSymbolHiding.cmake CurlTests.c FindBrotli.cmake FindCares.cmake FindGSS.cmake FindGnuTLS.cmake FindLDAP.cmake FindLibbacktrace.cmake FindLibgsasl.cmake FindLibidn2.cmake FindLibpsl.cmake FindLibssh.cmake FindLibssh2.cmake FindLibuv.cmake FindMbedTLS.cmake FindNGHTTP2.cmake FindNGHTTP3.cmake FindNGTCP2.cmake FindNettle.cmake FindQuiche.cmake FindRustls.cmake FindWolfSSL.cmake FindZstd.cmake Macros.cmake OtherTests.cmake PickyWarnings.cmake Utilities.cmake cmake_uninstall.in.cmake curl-config.in.cmake unix-cache.cmake win32-cache.cmake
LICENSES BSD-4-Clause-UC.txt ISC.txt curl.txt
docs
cmdline-opts .gitignore CMakeLists.txt MANPAGE.md Makefile.am Makefile.inc _AUTHORS.md _BUGS.md _DESCRIPTION.md _ENVIRONMENT.md _EXITCODES.md _FILES.md _GLOBBING.md _NAME.md _OPTIONS.md _OUTPUT.md _PROGRESS.md _PROTOCOLS.md _PROXYPREFIX.md _SEEALSO.md _SYNOPSIS.md _URL.md _VARIABLES.md _VERSION.md _WWW.md abstract-unix-socket.md alt-svc.md anyauth.md append.md aws-sigv4.md basic.md ca-native.md cacert.md capath.md cert-status.md cert-type.md cert.md ciphers.md compressed-ssh.md compressed.md config.md connect-timeout.md connect-to.md continue-at.md cookie-jar.md cookie.md create-dirs.md create-file-mode.md crlf.md crlfile.md curves.md data-ascii.md data-binary.md data-raw.md data-urlencode.md data.md delegation.md digest.md disable-eprt.md disable-epsv.md disable.md disallow-username-in-url.md dns-interface.md dns-ipv4-addr.md dns-ipv6-addr.md dns-servers.md doh-cert-status.md doh-insecure.md doh-url.md dump-ca-embed.md dump-header.md ech.md egd-file.md engine.md etag-compare.md etag-save.md expect100-timeout.md fail-early.md fail-with-body.md fail.md false-start.md follow.md form-escape.md form-string.md form.md ftp-account.md ftp-alternative-to-user.md ftp-create-dirs.md ftp-method.md ftp-pasv.md ftp-port.md ftp-pret.md ftp-skip-pasv-ip.md ftp-ssl-ccc-mode.md ftp-ssl-ccc.md ftp-ssl-control.md get.md globoff.md happy-eyeballs-timeout-ms.md haproxy-clientip.md haproxy-protocol.md head.md header.md help.md hostpubmd5.md hostpubsha256.md hsts.md http0.9.md http1.0.md http1.1.md http2-prior-knowledge.md http2.md http3-only.md http3.md ignore-content-length.md insecure.md interface.md ip-tos.md ipfs-gateway.md ipv4.md ipv6.md json.md junk-session-cookies.md keepalive-cnt.md keepalive-time.md key-type.md key.md knownhosts.md krb.md libcurl.md limit-rate.md list-only.md local-port.md location-trusted.md location.md login-options.md mail-auth.md mail-from.md mail-rcpt-allowfails.md mail-rcpt.md mainpage.idx manual.md max-filesize.md max-redirs.md max-time.md metalink.md mptcp.md negotiate.md netrc-file.md netrc-optional.md netrc.md next.md no-alpn.md no-buffer.md no-clobber.md no-keepalive.md no-npn.md no-progress-meter.md no-sessionid.md noproxy.md ntlm-wb.md ntlm.md oauth2-bearer.md out-null.md output-dir.md output.md parallel-immediate.md parallel-max-host.md parallel-max.md parallel.md pass.md path-as-is.md pinnedpubkey.md post301.md post302.md post303.md preproxy.md progress-bar.md proto-default.md proto-redir.md proto.md proxy-anyauth.md proxy-basic.md proxy-ca-native.md proxy-cacert.md proxy-capath.md proxy-cert-type.md proxy-cert.md proxy-ciphers.md proxy-crlfile.md proxy-digest.md proxy-header.md proxy-http2.md proxy-insecure.md proxy-key-type.md proxy-key.md proxy-negotiate.md proxy-ntlm.md proxy-pass.md proxy-pinnedpubkey.md proxy-service-name.md proxy-ssl-allow-beast.md proxy-ssl-auto-client-cert.md proxy-tls13-ciphers.md proxy-tlsauthtype.md proxy-tlspassword.md proxy-tlsuser.md proxy-tlsv1.md proxy-user.md proxy.md proxy1.0.md proxytunnel.md pubkey.md quote.md random-file.md range.md rate.md raw.md referer.md remote-header-name.md remote-name-all.md remote-name.md remote-time.md remove-on-error.md request-target.md request.md resolve.md retry-all-errors.md retry-connrefused.md retry-delay.md retry-max-time.md retry.md sasl-authzid.md sasl-ir.md service-name.md show-error.md show-headers.md sigalgs.md silent.md skip-existing.md socks4.md socks4a.md socks5-basic.md socks5-gssapi-nec.md socks5-gssapi-service.md socks5-gssapi.md socks5-hostname.md socks5.md speed-limit.md speed-time.md ssl-allow-beast.md ssl-auto-client-cert.md ssl-no-revoke.md ssl-reqd.md ssl-revoke-best-effort.md ssl-sessions.md ssl.md sslv2.md sslv3.md stderr.md styled-output.md suppress-connect-headers.md tcp-fastopen.md tcp-nodelay.md telnet-option.md tftp-blksize.md tftp-no-options.md time-cond.md tls-earlydata.md tls-max.md tls13-ciphers.md tlsauthtype.md tlspassword.md tlsuser.md tlsv1.0.md tlsv1.1.md tlsv1.2.md tlsv1.3.md tlsv1.md tr-encoding.md trace-ascii.md trace-config.md trace-ids.md trace-time.md trace.md unix-socket.md upload-file.md upload-flags.md url-query.md url.md use-ascii.md user-agent.md user.md variable.md verbose.md version.md vlan-priority.md write-out.md xattr.md
examples .checksrc .gitignore 10-at-a-time.c CMakeLists.txt Makefile.am Makefile.example Makefile.inc README.md adddocsref.pl address-scope.c altsvc.c anyauthput.c block_ip.c cacertinmem.c certinfo.c chkspeed.c connect-to.c cookie_interface.c crawler.c debug.c default-scheme.c ephiperfifo.c evhiperfifo.c externalsocket.c fileupload.c ftp-delete.c ftp-wildcard.c ftpget.c ftpgetinfo.c ftpgetresp.c ftpsget.c ftpupload.c ftpuploadfrommem.c ftpuploadresume.c getinfo.c getinmemory.c getredirect.c getreferrer.c ghiper.c headerapi.c hiperfifo.c hsts-preload.c htmltidy.c htmltitle.cpp http-options.c http-post.c http2-download.c http2-pushinmemory.c http2-serverpush.c http2-upload.c http3-present.c http3.c httpcustomheader.c httpput-postfields.c httpput.c https.c imap-append.c imap-authzid.c imap-copy.c imap-create.c imap-delete.c imap-examine.c imap-fetch.c imap-list.c imap-lsub.c imap-multi.c imap-noop.c imap-search.c imap-ssl.c imap-store.c imap-tls.c interface.c ipv6.c keepalive.c localport.c log_failed_transfers.c maxconnects.c multi-app.c multi-debugcallback.c multi-double.c multi-event.c multi-formadd.c multi-legacy.c multi-post.c multi-single.c multi-uv.c netrc.c parseurl.c persistent.c pop3-authzid.c pop3-dele.c pop3-list.c pop3-multi.c pop3-noop.c pop3-retr.c pop3-ssl.c pop3-stat.c pop3-tls.c pop3-top.c pop3-uidl.c post-callback.c postinmemory.c postit2-formadd.c postit2.c progressfunc.c protofeats.c range.c resolve.c rtsp-options.c sendrecv.c sepheaders.c sessioninfo.c sftpget.c sftpuploadresume.c shared-connection-cache.c simple.c simplepost.c simplessl.c smooth-gtk-thread.c smtp-authzid.c smtp-expn.c smtp-mail.c smtp-mime.c smtp-multi.c smtp-ssl.c smtp-tls.c smtp-vrfy.c sslbackend.c synctime.c threaded.c unixsocket.c url2file.c urlapi.c usercertinmem.c version-check.pl websocket-cb.c websocket-updown.c websocket.c xmlstream.c
internals BUFQ.md BUFREF.md CHECKSRC.md CLIENT-READERS.md CLIENT-WRITERS.md CODE_STYLE.md CONNECTION-FILTERS.md CREDENTIALS.md CURLX.md DYNBUF.md HASH.md LLIST.md MID.md MQTT.md MULTI-EV.md NEW-PROTOCOL.md PEERS.md PORTING.md RATELIMITS.md README.md SCORECARD.md SPLAY.md STRPARSE.md THRDPOOL-AND-QUEUE.md TIME-KEEPING.md TLS-SESSIONS.md UINT_SETS.md WEBSOCKET.md
libcurl
opts CMakeLists.txt CURLINFO_ACTIVESOCKET.md CURLINFO_APPCONNECT_TIME.md CURLINFO_APPCONNECT_TIME_T.md CURLINFO_CAINFO.md CURLINFO_CAPATH.md CURLINFO_CERTINFO.md CURLINFO_CONDITION_UNMET.md CURLINFO_CONNECT_TIME.md CURLINFO_CONNECT_TIME_T.md CURLINFO_CONN_ID.md CURLINFO_CONTENT_LENGTH_DOWNLOAD.md CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md CURLINFO_CONTENT_LENGTH_UPLOAD.md CURLINFO_CONTENT_LENGTH_UPLOAD_T.md CURLINFO_CONTENT_TYPE.md CURLINFO_COOKIELIST.md CURLINFO_EARLYDATA_SENT_T.md CURLINFO_EFFECTIVE_METHOD.md CURLINFO_EFFECTIVE_URL.md CURLINFO_FILETIME.md CURLINFO_FILETIME_T.md CURLINFO_FTP_ENTRY_PATH.md CURLINFO_HEADER_SIZE.md CURLINFO_HTTPAUTH_AVAIL.md CURLINFO_HTTPAUTH_USED.md CURLINFO_HTTP_CONNECTCODE.md CURLINFO_HTTP_VERSION.md CURLINFO_LASTSOCKET.md CURLINFO_LOCAL_IP.md CURLINFO_LOCAL_PORT.md CURLINFO_NAMELOOKUP_TIME.md CURLINFO_NAMELOOKUP_TIME_T.md CURLINFO_NUM_CONNECTS.md CURLINFO_OS_ERRNO.md CURLINFO_POSTTRANSFER_TIME_T.md CURLINFO_PRETRANSFER_TIME.md CURLINFO_PRETRANSFER_TIME_T.md CURLINFO_PRIMARY_IP.md CURLINFO_PRIMARY_PORT.md CURLINFO_PRIVATE.md CURLINFO_PROTOCOL.md CURLINFO_PROXYAUTH_AVAIL.md CURLINFO_PROXYAUTH_USED.md CURLINFO_PROXY_ERROR.md CURLINFO_PROXY_SSL_VERIFYRESULT.md CURLINFO_QUEUE_TIME_T.md CURLINFO_REDIRECT_COUNT.md CURLINFO_REDIRECT_TIME.md CURLINFO_REDIRECT_TIME_T.md CURLINFO_REDIRECT_URL.md CURLINFO_REFERER.md CURLINFO_REQUEST_SIZE.md CURLINFO_RESPONSE_CODE.md CURLINFO_RETRY_AFTER.md CURLINFO_RTSP_CLIENT_CSEQ.md CURLINFO_RTSP_CSEQ_RECV.md CURLINFO_RTSP_SERVER_CSEQ.md CURLINFO_RTSP_SESSION_ID.md CURLINFO_SCHEME.md CURLINFO_SIZE_DELIVERED.md CURLINFO_SIZE_DOWNLOAD.md CURLINFO_SIZE_DOWNLOAD_T.md CURLINFO_SIZE_UPLOAD.md CURLINFO_SIZE_UPLOAD_T.md CURLINFO_SPEED_DOWNLOAD.md CURLINFO_SPEED_DOWNLOAD_T.md CURLINFO_SPEED_UPLOAD.md CURLINFO_SPEED_UPLOAD_T.md CURLINFO_SSL_ENGINES.md CURLINFO_SSL_VERIFYRESULT.md CURLINFO_STARTTRANSFER_TIME.md CURLINFO_STARTTRANSFER_TIME_T.md CURLINFO_TLS_SESSION.md CURLINFO_TLS_SSL_PTR.md CURLINFO_TOTAL_TIME.md CURLINFO_TOTAL_TIME_T.md CURLINFO_USED_PROXY.md CURLINFO_XFER_ID.md CURLMINFO_XFERS_ADDED.md CURLMINFO_XFERS_CURRENT.md CURLMINFO_XFERS_DONE.md CURLMINFO_XFERS_PENDING.md CURLMINFO_XFERS_RUNNING.md CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.md CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.md CURLMOPT_MAXCONNECTS.md CURLMOPT_MAX_CONCURRENT_STREAMS.md CURLMOPT_MAX_HOST_CONNECTIONS.md CURLMOPT_MAX_PIPELINE_LENGTH.md CURLMOPT_MAX_TOTAL_CONNECTIONS.md CURLMOPT_NETWORK_CHANGED.md CURLMOPT_NOTIFYDATA.md CURLMOPT_NOTIFYFUNCTION.md CURLMOPT_PIPELINING.md CURLMOPT_PIPELINING_SERVER_BL.md CURLMOPT_PIPELINING_SITE_BL.md CURLMOPT_PUSHDATA.md CURLMOPT_PUSHFUNCTION.md CURLMOPT_QUICK_EXIT.md CURLMOPT_RESOLVE_THREADS_MAX.md CURLMOPT_SOCKETDATA.md CURLMOPT_SOCKETFUNCTION.md CURLMOPT_TIMERDATA.md CURLMOPT_TIMERFUNCTION.md CURLOPT_ABSTRACT_UNIX_SOCKET.md CURLOPT_ACCEPTTIMEOUT_MS.md CURLOPT_ACCEPT_ENCODING.md CURLOPT_ADDRESS_SCOPE.md CURLOPT_ALTSVC.md CURLOPT_ALTSVC_CTRL.md CURLOPT_APPEND.md CURLOPT_AUTOREFERER.md CURLOPT_AWS_SIGV4.md CURLOPT_BUFFERSIZE.md CURLOPT_CAINFO.md CURLOPT_CAINFO_BLOB.md CURLOPT_CAPATH.md CURLOPT_CA_CACHE_TIMEOUT.md CURLOPT_CERTINFO.md CURLOPT_CHUNK_BGN_FUNCTION.md CURLOPT_CHUNK_DATA.md CURLOPT_CHUNK_END_FUNCTION.md CURLOPT_CLOSESOCKETDATA.md CURLOPT_CLOSESOCKETFUNCTION.md CURLOPT_CONNECTTIMEOUT.md CURLOPT_CONNECTTIMEOUT_MS.md CURLOPT_CONNECT_ONLY.md CURLOPT_CONNECT_TO.md CURLOPT_CONV_FROM_NETWORK_FUNCTION.md CURLOPT_CONV_FROM_UTF8_FUNCTION.md CURLOPT_CONV_TO_NETWORK_FUNCTION.md CURLOPT_COOKIE.md CURLOPT_COOKIEFILE.md CURLOPT_COOKIEJAR.md CURLOPT_COOKIELIST.md CURLOPT_COOKIESESSION.md CURLOPT_COPYPOSTFIELDS.md CURLOPT_CRLF.md CURLOPT_CRLFILE.md CURLOPT_CURLU.md CURLOPT_CUSTOMREQUEST.md CURLOPT_DEBUGDATA.md CURLOPT_DEBUGFUNCTION.md CURLOPT_DEFAULT_PROTOCOL.md CURLOPT_DIRLISTONLY.md CURLOPT_DISALLOW_USERNAME_IN_URL.md CURLOPT_DNS_CACHE_TIMEOUT.md CURLOPT_DNS_INTERFACE.md CURLOPT_DNS_LOCAL_IP4.md CURLOPT_DNS_LOCAL_IP6.md CURLOPT_DNS_SERVERS.md CURLOPT_DNS_SHUFFLE_ADDRESSES.md CURLOPT_DNS_USE_GLOBAL_CACHE.md CURLOPT_DOH_SSL_VERIFYHOST.md CURLOPT_DOH_SSL_VERIFYPEER.md CURLOPT_DOH_SSL_VERIFYSTATUS.md CURLOPT_DOH_URL.md CURLOPT_ECH.md CURLOPT_EGDSOCKET.md CURLOPT_ERRORBUFFER.md CURLOPT_EXPECT_100_TIMEOUT_MS.md CURLOPT_FAILONERROR.md CURLOPT_FILETIME.md CURLOPT_FNMATCH_DATA.md CURLOPT_FNMATCH_FUNCTION.md CURLOPT_FOLLOWLOCATION.md CURLOPT_FORBID_REUSE.md CURLOPT_FRESH_CONNECT.md CURLOPT_FTPPORT.md CURLOPT_FTPSSLAUTH.md CURLOPT_FTP_ACCOUNT.md CURLOPT_FTP_ALTERNATIVE_TO_USER.md CURLOPT_FTP_CREATE_MISSING_DIRS.md CURLOPT_FTP_FILEMETHOD.md CURLOPT_FTP_SKIP_PASV_IP.md CURLOPT_FTP_SSL_CCC.md CURLOPT_FTP_USE_EPRT.md CURLOPT_FTP_USE_EPSV.md CURLOPT_FTP_USE_PRET.md CURLOPT_GSSAPI_DELEGATION.md CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.md CURLOPT_HAPROXYPROTOCOL.md CURLOPT_HAPROXY_CLIENT_IP.md CURLOPT_HEADER.md CURLOPT_HEADERDATA.md CURLOPT_HEADERFUNCTION.md CURLOPT_HEADEROPT.md CURLOPT_HSTS.md CURLOPT_HSTSREADDATA.md CURLOPT_HSTSREADFUNCTION.md CURLOPT_HSTSWRITEDATA.md CURLOPT_HSTSWRITEFUNCTION.md CURLOPT_HSTS_CTRL.md CURLOPT_HTTP09_ALLOWED.md CURLOPT_HTTP200ALIASES.md CURLOPT_HTTPAUTH.md CURLOPT_HTTPGET.md CURLOPT_HTTPHEADER.md CURLOPT_HTTPPOST.md CURLOPT_HTTPPROXYTUNNEL.md CURLOPT_HTTP_CONTENT_DECODING.md CURLOPT_HTTP_TRANSFER_DECODING.md CURLOPT_HTTP_VERSION.md CURLOPT_IGNORE_CONTENT_LENGTH.md CURLOPT_INFILESIZE.md CURLOPT_INFILESIZE_LARGE.md CURLOPT_INTERFACE.md CURLOPT_INTERLEAVEDATA.md CURLOPT_INTERLEAVEFUNCTION.md CURLOPT_IOCTLDATA.md CURLOPT_IOCTLFUNCTION.md CURLOPT_IPRESOLVE.md CURLOPT_ISSUERCERT.md CURLOPT_ISSUERCERT_BLOB.md CURLOPT_KEEP_SENDING_ON_ERROR.md CURLOPT_KEYPASSWD.md CURLOPT_KRBLEVEL.md CURLOPT_LOCALPORT.md CURLOPT_LOCALPORTRANGE.md CURLOPT_LOGIN_OPTIONS.md CURLOPT_LOW_SPEED_LIMIT.md CURLOPT_LOW_SPEED_TIME.md CURLOPT_MAIL_AUTH.md CURLOPT_MAIL_FROM.md CURLOPT_MAIL_RCPT.md CURLOPT_MAIL_RCPT_ALLOWFAILS.md CURLOPT_MAXAGE_CONN.md CURLOPT_MAXCONNECTS.md CURLOPT_MAXFILESIZE.md CURLOPT_MAXFILESIZE_LARGE.md CURLOPT_MAXLIFETIME_CONN.md CURLOPT_MAXREDIRS.md CURLOPT_MAX_RECV_SPEED_LARGE.md CURLOPT_MAX_SEND_SPEED_LARGE.md CURLOPT_MIMEPOST.md CURLOPT_MIME_OPTIONS.md CURLOPT_NETRC.md CURLOPT_NETRC_FILE.md CURLOPT_NEW_DIRECTORY_PERMS.md CURLOPT_NEW_FILE_PERMS.md CURLOPT_NOBODY.md CURLOPT_NOPROGRESS.md CURLOPT_NOPROXY.md CURLOPT_NOSIGNAL.md CURLOPT_OPENSOCKETDATA.md CURLOPT_OPENSOCKETFUNCTION.md CURLOPT_PASSWORD.md CURLOPT_PATH_AS_IS.md CURLOPT_PINNEDPUBLICKEY.md CURLOPT_PIPEWAIT.md CURLOPT_PORT.md CURLOPT_POST.md CURLOPT_POSTFIELDS.md CURLOPT_POSTFIELDSIZE.md CURLOPT_POSTFIELDSIZE_LARGE.md CURLOPT_POSTQUOTE.md CURLOPT_POSTREDIR.md CURLOPT_PREQUOTE.md CURLOPT_PREREQDATA.md CURLOPT_PREREQFUNCTION.md CURLOPT_PRE_PROXY.md CURLOPT_PRIVATE.md CURLOPT_PROGRESSDATA.md CURLOPT_PROGRESSFUNCTION.md CURLOPT_PROTOCOLS.md CURLOPT_PROTOCOLS_STR.md CURLOPT_PROXY.md CURLOPT_PROXYAUTH.md CURLOPT_PROXYHEADER.md CURLOPT_PROXYPASSWORD.md CURLOPT_PROXYPORT.md CURLOPT_PROXYTYPE.md CURLOPT_PROXYUSERNAME.md CURLOPT_PROXYUSERPWD.md CURLOPT_PROXY_CAINFO.md CURLOPT_PROXY_CAINFO_BLOB.md CURLOPT_PROXY_CAPATH.md CURLOPT_PROXY_CRLFILE.md CURLOPT_PROXY_ISSUERCERT.md CURLOPT_PROXY_ISSUERCERT_BLOB.md CURLOPT_PROXY_KEYPASSWD.md CURLOPT_PROXY_PINNEDPUBLICKEY.md CURLOPT_PROXY_SERVICE_NAME.md CURLOPT_PROXY_SSLCERT.md CURLOPT_PROXY_SSLCERTTYPE.md CURLOPT_PROXY_SSLCERT_BLOB.md CURLOPT_PROXY_SSLKEY.md CURLOPT_PROXY_SSLKEYTYPE.md CURLOPT_PROXY_SSLKEY_BLOB.md CURLOPT_PROXY_SSLVERSION.md CURLOPT_PROXY_SSL_CIPHER_LIST.md CURLOPT_PROXY_SSL_OPTIONS.md CURLOPT_PROXY_SSL_VERIFYHOST.md CURLOPT_PROXY_SSL_VERIFYPEER.md CURLOPT_PROXY_TLS13_CIPHERS.md CURLOPT_PROXY_TLSAUTH_PASSWORD.md CURLOPT_PROXY_TLSAUTH_TYPE.md CURLOPT_PROXY_TLSAUTH_USERNAME.md CURLOPT_PROXY_TRANSFER_MODE.md CURLOPT_PUT.md CURLOPT_QUICK_EXIT.md CURLOPT_QUOTE.md CURLOPT_RANDOM_FILE.md CURLOPT_RANGE.md CURLOPT_READDATA.md CURLOPT_READFUNCTION.md CURLOPT_REDIR_PROTOCOLS.md CURLOPT_REDIR_PROTOCOLS_STR.md CURLOPT_REFERER.md CURLOPT_REQUEST_TARGET.md CURLOPT_RESOLVE.md CURLOPT_RESOLVER_START_DATA.md CURLOPT_RESOLVER_START_FUNCTION.md CURLOPT_RESUME_FROM.md CURLOPT_RESUME_FROM_LARGE.md CURLOPT_RTSP_CLIENT_CSEQ.md CURLOPT_RTSP_REQUEST.md CURLOPT_RTSP_SERVER_CSEQ.md CURLOPT_RTSP_SESSION_ID.md CURLOPT_RTSP_STREAM_URI.md CURLOPT_RTSP_TRANSPORT.md CURLOPT_SASL_AUTHZID.md CURLOPT_SASL_IR.md CURLOPT_SEEKDATA.md CURLOPT_SEEKFUNCTION.md CURLOPT_SERVER_RESPONSE_TIMEOUT.md CURLOPT_SERVER_RESPONSE_TIMEOUT_MS.md CURLOPT_SERVICE_NAME.md CURLOPT_SHARE.md CURLOPT_SOCKOPTDATA.md CURLOPT_SOCKOPTFUNCTION.md CURLOPT_SOCKS5_AUTH.md CURLOPT_SOCKS5_GSSAPI_NEC.md CURLOPT_SOCKS5_GSSAPI_SERVICE.md CURLOPT_SSH_AUTH_TYPES.md CURLOPT_SSH_COMPRESSION.md CURLOPT_SSH_HOSTKEYDATA.md CURLOPT_SSH_HOSTKEYFUNCTION.md CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md CURLOPT_SSH_KEYDATA.md CURLOPT_SSH_KEYFUNCTION.md CURLOPT_SSH_KNOWNHOSTS.md CURLOPT_SSH_PRIVATE_KEYFILE.md CURLOPT_SSH_PUBLIC_KEYFILE.md CURLOPT_SSLCERT.md CURLOPT_SSLCERTTYPE.md CURLOPT_SSLCERT_BLOB.md CURLOPT_SSLENGINE.md CURLOPT_SSLENGINE_DEFAULT.md CURLOPT_SSLKEY.md CURLOPT_SSLKEYTYPE.md CURLOPT_SSLKEY_BLOB.md CURLOPT_SSLVERSION.md CURLOPT_SSL_CIPHER_LIST.md CURLOPT_SSL_CTX_DATA.md CURLOPT_SSL_CTX_FUNCTION.md CURLOPT_SSL_EC_CURVES.md CURLOPT_SSL_ENABLE_ALPN.md CURLOPT_SSL_ENABLE_NPN.md CURLOPT_SSL_FALSESTART.md CURLOPT_SSL_OPTIONS.md CURLOPT_SSL_SESSIONID_CACHE.md CURLOPT_SSL_SIGNATURE_ALGORITHMS.md CURLOPT_SSL_VERIFYHOST.md CURLOPT_SSL_VERIFYPEER.md CURLOPT_SSL_VERIFYSTATUS.md CURLOPT_STDERR.md CURLOPT_STREAM_DEPENDS.md CURLOPT_STREAM_DEPENDS_E.md CURLOPT_STREAM_WEIGHT.md CURLOPT_SUPPRESS_CONNECT_HEADERS.md CURLOPT_TCP_FASTOPEN.md CURLOPT_TCP_KEEPALIVE.md CURLOPT_TCP_KEEPCNT.md CURLOPT_TCP_KEEPIDLE.md CURLOPT_TCP_KEEPINTVL.md CURLOPT_TCP_NODELAY.md CURLOPT_TELNETOPTIONS.md CURLOPT_TFTP_BLKSIZE.md CURLOPT_TFTP_NO_OPTIONS.md CURLOPT_TIMECONDITION.md CURLOPT_TIMEOUT.md CURLOPT_TIMEOUT_MS.md CURLOPT_TIMEVALUE.md CURLOPT_TIMEVALUE_LARGE.md CURLOPT_TLS13_CIPHERS.md CURLOPT_TLSAUTH_PASSWORD.md CURLOPT_TLSAUTH_TYPE.md CURLOPT_TLSAUTH_USERNAME.md CURLOPT_TRAILERDATA.md CURLOPT_TRAILERFUNCTION.md CURLOPT_TRANSFERTEXT.md CURLOPT_TRANSFER_ENCODING.md CURLOPT_UNIX_SOCKET_PATH.md CURLOPT_UNRESTRICTED_AUTH.md CURLOPT_UPKEEP_INTERVAL_MS.md CURLOPT_UPLOAD.md CURLOPT_UPLOAD_BUFFERSIZE.md CURLOPT_UPLOAD_FLAGS.md CURLOPT_URL.md CURLOPT_USERAGENT.md CURLOPT_USERNAME.md CURLOPT_USERPWD.md CURLOPT_USE_SSL.md CURLOPT_VERBOSE.md CURLOPT_WILDCARDMATCH.md CURLOPT_WRITEDATA.md CURLOPT_WRITEFUNCTION.md CURLOPT_WS_OPTIONS.md CURLOPT_XFERINFODATA.md CURLOPT_XFERINFOFUNCTION.md CURLOPT_XOAUTH2_BEARER.md CURLSHOPT_LOCKFUNC.md CURLSHOPT_SHARE.md CURLSHOPT_UNLOCKFUNC.md CURLSHOPT_UNSHARE.md CURLSHOPT_USERDATA.md Makefile.am Makefile.inc
.gitignore ABI.md CMakeLists.txt Makefile.am Makefile.inc curl_easy_cleanup.md curl_easy_duphandle.md curl_easy_escape.md curl_easy_getinfo.md curl_easy_header.md curl_easy_init.md curl_easy_nextheader.md curl_easy_option_by_id.md curl_easy_option_by_name.md curl_easy_option_next.md curl_easy_pause.md curl_easy_perform.md curl_easy_recv.md curl_easy_reset.md curl_easy_send.md curl_easy_setopt.md curl_easy_ssls_export.md curl_easy_ssls_import.md curl_easy_strerror.md curl_easy_unescape.md curl_easy_upkeep.md curl_escape.md curl_formadd.md curl_formfree.md curl_formget.md curl_free.md curl_getdate.md curl_getenv.md curl_global_cleanup.md curl_global_init.md curl_global_init_mem.md curl_global_sslset.md curl_global_trace.md curl_mime_addpart.md curl_mime_data.md curl_mime_data_cb.md curl_mime_encoder.md curl_mime_filedata.md curl_mime_filename.md curl_mime_free.md curl_mime_headers.md curl_mime_init.md curl_mime_name.md curl_mime_subparts.md curl_mime_type.md curl_mprintf.md curl_multi_add_handle.md curl_multi_assign.md curl_multi_cleanup.md curl_multi_fdset.md curl_multi_get_handles.md curl_multi_get_offt.md curl_multi_info_read.md curl_multi_init.md curl_multi_notify_disable.md curl_multi_notify_enable.md curl_multi_perform.md curl_multi_poll.md curl_multi_remove_handle.md curl_multi_setopt.md curl_multi_socket.md curl_multi_socket_action.md curl_multi_socket_all.md curl_multi_strerror.md curl_multi_timeout.md curl_multi_wait.md curl_multi_waitfds.md curl_multi_wakeup.md curl_pushheader_byname.md curl_pushheader_bynum.md curl_share_cleanup.md curl_share_init.md curl_share_setopt.md curl_share_strerror.md curl_slist_append.md curl_slist_free_all.md curl_strequal.md curl_strnequal.md curl_unescape.md curl_url.md curl_url_cleanup.md curl_url_dup.md curl_url_get.md curl_url_set.md curl_url_strerror.md curl_version.md curl_version_info.md curl_ws_meta.md curl_ws_recv.md curl_ws_send.md curl_ws_start_frame.md libcurl-easy.md libcurl-env-dbg.md libcurl-env.md libcurl-errors.md libcurl-multi.md libcurl-security.md libcurl-share.md libcurl-thread.md libcurl-tutorial.md libcurl-url.md libcurl-ws.md libcurl.m4 libcurl.md mksymbolsmanpage.pl symbols-in-versions symbols.pl
tests CI.md FILEFORMAT.md HTTP.md TEST-SUITE.md
.gitignore ALTSVC.md BINDINGS.md BUG-BOUNTY.md BUGS.md CIPHERS-TLS12.md CIPHERS.md CMakeLists.txt CODE_OF_CONDUCT.md CODE_REVIEW.md CONTRIBUTE.md CURL-DISABLE.md CURLDOWN.md DEPRECATE.md DISTROS.md EARLY-RELEASE.md ECH.md EXPERIMENTAL.md FAQ.md FEATURES.md GOVERNANCE.md HELP-US.md HISTORY.md HSTS.md HTTP-COOKIES.md HTTP3.md HTTPSRR.md INFRASTRUCTURE.md INSTALL-CMAKE.md INSTALL.md INTERNALS.md IPFS.md KNOWN_BUGS.md KNOWN_RISKS.md MAIL-ETIQUETTE.md MANUAL.md Makefile.am README.md RELEASE-PROCEDURE.md ROADMAP.md RUSTLS.md SECURITY-ADVISORY.md SPONSORS.md SSL-PROBLEMS.md SSLCERTS.md THANKS THANKS-filter TODO.md TheArtOfHttpScripting.md URL-SYNTAX.md VERIFY.md VERSIONS.md VULN-DISCLOSURE-POLICY.md curl-config.md mk-ca-bundle.md options-in-versions runtests.md testcurl.md wcurl.md
include
curl Makefile.am curl.h curlver.h easy.h header.h mprintf.h multi.h options.h stdcheaders.h system.h typecheck-gcc.h urlapi.h websockets.h
Makefile.am README.md
lib
curlx base64.c base64.h basename.c basename.h dynbuf.c dynbuf.h fopen.c fopen.h inet_ntop.c inet_ntop.h inet_pton.c inet_pton.h multibyte.c multibyte.h nonblock.c nonblock.h snprintf.c snprintf.h strcopy.c strcopy.h strdup.c strdup.h strerr.c strerr.h strparse.c strparse.h timediff.c timediff.h timeval.c timeval.h version_win32.c version_win32.h wait.c wait.h warnless.c warnless.h winapi.c winapi.h
vauth cleartext.c cram.c digest.c digest.h digest_sspi.c gsasl.c krb5_gssapi.c krb5_sspi.c ntlm.c ntlm_sspi.c oauth2.c spnego_gssapi.c spnego_sspi.c vauth.c vauth.h
vquic curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.h
vssh libssh.c libssh2.c ssh.h vssh.c vssh.h
vtls apple.c apple.h cipher_suite.c cipher_suite.h gtls.c gtls.h hostcheck.c hostcheck.h keylog.c keylog.h mbedtls.c mbedtls.h openssl.c openssl.h rustls.c rustls.h schannel.c schannel.h schannel_int.h schannel_verify.c vtls.c vtls.h vtls_int.h vtls_scache.c vtls_scache.h vtls_spack.c vtls_spack.h wolfssl.c wolfssl.h x509asn1.c x509asn1.h
.gitignore CMakeLists.txt Makefile.am Makefile.inc Makefile.soname altsvc.c altsvc.h amigaos.c amigaos.h arpa_telnet.h asyn-ares.c asyn-base.c asyn-thrdd.c asyn.h bufq.c bufq.h bufref.c bufref.h cf-dns.c cf-dns.h cf-h1-proxy.c cf-h1-proxy.h cf-h2-proxy.c cf-h2-proxy.h cf-haproxy.c cf-haproxy.h cf-https-connect.c cf-https-connect.h cf-ip-happy.c cf-ip-happy.h cf-socket.c cf-socket.h cfilters.c cfilters.h config-mac.h config-os400.h config-riscos.h config-win32.h conncache.c conncache.h connect.c connect.h content_encoding.c content_encoding.h cookie.c cookie.h creds.c creds.h cshutdn.c cshutdn.h curl_addrinfo.c curl_addrinfo.h curl_config-cmake.h.in curl_ctype.h curl_endian.c curl_endian.h curl_fnmatch.c curl_fnmatch.h curl_fopen.c curl_fopen.h curl_get_line.c curl_get_line.h curl_gethostname.c curl_gethostname.h curl_gssapi.c curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memrchr.c curl_memrchr.h curl_ntlm_core.c curl_ntlm_core.h curl_printf.h curl_range.c curl_range.h curl_sasl.c curl_sasl.h curl_setup.h curl_sha256.h curl_sha512_256.c curl_sha512_256.h curl_share.c curl_share.h curl_sspi.c curl_sspi.h curl_threads.c curl_threads.h curl_trc.c curl_trc.h cw-out.c cw-out.h cw-pause.c cw-pause.h dict.c dict.h dllmain.c dnscache.c dnscache.h doh.c doh.h dynhds.c dynhds.h easy.c easy_lock.h easygetopt.c easyif.h easyoptions.c easyoptions.h escape.c escape.h fake_addrinfo.c fake_addrinfo.h file.c file.h fileinfo.c fileinfo.h formdata.c formdata.h ftp-int.h ftp.c ftp.h ftplistparser.c ftplistparser.h functypes.h getenv.c getinfo.c getinfo.h gopher.c gopher.h hash.c hash.h headers.c headers.h hmac.c hostip.c hostip.h hostip4.c hostip6.c hsts.c hsts.h http.c http.h http1.c http1.h http2.c http2.h http_aws_sigv4.c http_aws_sigv4.h http_chunks.c http_chunks.h http_digest.c http_digest.h http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h http_proxy.c http_proxy.h httpsrr.c httpsrr.h idn.c idn.h if2ip.c if2ip.h imap.c imap.h ldap.c libcurl.def libcurl.rc libcurl.vers.in llist.c llist.h macos.c macos.h md4.c md5.c memdebug.c mime.c mime.h mprintf.c mqtt.c mqtt.h multi.c multi_ev.c multi_ev.h multi_ntfy.c multi_ntfy.h multihandle.h multiif.h netrc.c netrc.h noproxy.c noproxy.h openldap.c optiontable.pl parsedate.c parsedate.h peer.c peer.h pingpong.c pingpong.h pop3.c pop3.h progress.c progress.h protocol.c protocol.h psl.c psl.h rand.c rand.h ratelimit.c ratelimit.h request.c request.h rtsp.c rtsp.h select.c select.h sendf.c sendf.h setopt.c setopt.h setup-os400.h setup-vms.h setup-win32.h sha256.c sigpipe.h slist.c slist.h smb.c smb.h smtp.c smtp.h sockaddr.h socketpair.c socketpair.h socks.c socks.h socks_gssapi.c socks_sspi.c splay.c splay.h strcase.c strcase.h strequal.c strerror.c strerror.h system_win32.c system_win32.h telnet.c telnet.h tftp.c tftp.h thrdpool.c thrdpool.h thrdqueue.c thrdqueue.h transfer.c transfer.h uint-bset.c uint-bset.h uint-hash.c uint-hash.h uint-spbset.c uint-spbset.h uint-table.c uint-table.h url.c url.h urlapi-int.h urlapi.c urldata.h version.c ws.c ws.h
m4 .gitignore curl-amissl.m4 curl-apple-sectrust.m4 curl-compilers.m4 curl-confopts.m4 curl-functions.m4 curl-gnutls.m4 curl-mbedtls.m4 curl-openssl.m4 curl-override.m4 curl-reentrant.m4 curl-rustls.m4 curl-schannel.m4 curl-sysconfig.m4 curl-wolfssl.m4 xc-am-iface.m4 xc-cc-check.m4 xc-lt-iface.m4 xc-val-flgs.m4 zz40-xc-ovr.m4 zz50-xc-ovr.m4
projects
OS400
rpg-examples HEADERAPI HTTPPOST INMEMORY SIMPLE1 SIMPLE2 SMTPSRCMBR
.checksrc README.OS400 ccsidcurl.c ccsidcurl.h config400.default curl.cmd curl.inc.in curlcl.c curlmain.c initscript.sh make-docs.sh make-include.sh make-lib.sh make-src.sh make-tests.sh makefile.sh os400sys.c os400sys.h
Windows
tmpl .gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filters
.gitignore README.md generate.bat
vms Makefile.am backup_gnv_curl_src.com build_curl-config_script.com build_gnv_curl.com build_gnv_curl_pcsi_desc.com build_gnv_curl_pcsi_text.com build_gnv_curl_release_notes.com build_libcurl_pc.com build_vms.com clean_gnv_curl.com compare_curl_source.com config_h.com curl_crtl_init.c curl_gnv_build_steps.txt curl_release_note_start.txt curl_startup.com curlmsg.h curlmsg.msg curlmsg.sdl curlmsg_vms.h generate_config_vms_h_curl.com generate_vax_transfer.com gnv_conftest.c_first gnv_curl_configure.sh gnv_libcurl_symbols.opt gnv_link_curl.com macro32_exactcase.patch make_gnv_curl_install.sh make_pcsi_curl_kit_name.com pcsi_gnv_curl_file_list.txt pcsi_product_gnv_curl.com readme report_openssl_version.c setup_gnv_curl_build.com stage_curl_install.com vms_eco_level.h
Makefile.am README.md
scripts .checksrc CMakeLists.txt Makefile.am badwords badwords-all badwords.txt cd2cd cd2nroff cdall checksrc-all.pl checksrc.pl cmakelint.sh completion.pl contributors.sh contrithanks.sh coverage.sh delta dmaketgz extract-unit-protos firefox-db2pem.sh installcheck.sh maketgz managen mdlinkcheck mk-ca-bundle.pl mk-unity.pl nroff2cd perlcheck.sh pythonlint.sh randdisable release-notes.pl release-tools.sh schemetable.c singleuse.pl spacecheck.pl top-complexity top-length verify-release wcurl
src
toolx tool_time.c tool_time.h
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc config2setopts.c config2setopts.h curl.rc curlinfo.c mk-file-embed.pl mkhelp.pl slist_wc.c slist_wc.h terminal.c terminal.h tool_cb_dbg.c tool_cb_dbg.h tool_cb_hdr.c tool_cb_hdr.h tool_cb_prg.c tool_cb_prg.h tool_cb_rea.c tool_cb_rea.h tool_cb_see.c tool_cb_see.h tool_cb_soc.c tool_cb_soc.h tool_cb_wrt.c tool_cb_wrt.h tool_cfgable.c tool_cfgable.h tool_dirhie.c tool_dirhie.h tool_doswin.c tool_doswin.h tool_easysrc.c tool_easysrc.h tool_filetime.c tool_filetime.h tool_findfile.c tool_findfile.h tool_formparse.c tool_formparse.h tool_getparam.c tool_getparam.h tool_getpass.c tool_getpass.h tool_help.c tool_help.h tool_helpers.c tool_helpers.h tool_hugehelp.h tool_ipfs.c tool_ipfs.h tool_libinfo.c tool_libinfo.h tool_listhelp.c tool_main.c tool_main.h tool_msgs.c tool_msgs.h tool_operate.c tool_operate.h tool_operhlp.c tool_operhlp.h tool_paramhlp.c tool_paramhlp.h tool_parsecfg.c tool_parsecfg.h tool_progress.c tool_progress.h tool_sdecls.h tool_setopt.c tool_setopt.h tool_setup.h tool_ssls.c tool_ssls.h tool_stderr.c tool_stderr.h tool_urlglob.c tool_urlglob.h tool_util.c tool_util.h tool_version.h tool_vms.c tool_vms.h tool_writeout.c tool_writeout.h tool_writeout_json.c tool_writeout_json.h tool_xattr.c tool_xattr.h var.c var.h
tests
certs .gitignore CMakeLists.txt Makefile.am Makefile.inc genserv.pl srp-verifier-conf srp-verifier-db test-ca.cnf test-ca.prm test-client-cert.prm test-client-eku-only.prm test-localhost-san-first.prm test-localhost-san-last.prm test-localhost.nn.prm test-localhost.prm test-localhost0h.prm
cmake CMakeLists.txt test.c test.cpp test.sh
data .gitignore DISABLED Makefile.am data-xml1 data1400.c data1401.c data1402.c data1403.c data1404.c data1405.c data1406.c data1407.c data1420.c data1461.txt data1463.txt data1465.c data1481.c data1705-1.md data1705-2.md data1705-3.md data1705-4.md data1705-stdout.1 data1706-1.md data1706-2.md data1706-3.md data1706-4.md data1706-stdout.txt data320.html test1 test10 test100 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 test1008 test1009 test101 test1010 test1011 test1012 test1013 test1014 test1015 test1016 test1017 test1018 test1019 test102 test1020 test1021 test1022 test1023 test1024 test1025 test1026 test1027 test1028 test1029 test103 test1030 test1031 test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 test104 test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 test1048 test1049 test105 test1050 test1051 test1052 test1053 test1054 test1055 test1056 test1057 test1058 test1059 test106 test1060 test1061 test1062 test1063 test1064 test1065 test1066 test1067 test1068 test1069 test107 test1070 test1071 test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 test108 test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 test1088 test1089 test109 test1090 test1091 test1092 test1093 test1094 test1095 test1096 test1097 test1098 test1099 test11 test110 test1100 test1101 test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 test111 test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 test112 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 test1128 test1129 test113 test1130 test1131 test1132 test1133 test1134 test1135 test1136 test1137 test1138 test1139 test114 test1140 test1141 test1142 test1143 test1144 test1145 test1146 test1147 test1148 test1149 test115 test1150 test1151 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 test116 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 test1168 test1169 test117 test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 test1178 test1179 test118 test1180 test1181 test1182 test1183 test1184 test1185 test1186 test1187 test1188 test1189 test119 test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 test1199 test12 test120 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 test1208 test1209 test121 test1210 test1211 test1212 test1213 test1214 test1215 test1216 test1217 test1218 test1219 test122 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 test1228 test1229 test123 test1230 test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 test124 test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 test1248 test1249 test125 test1250 test1251 test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 test126 test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 test1268 test1269 test127 test1270 test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 test1279 test128 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 test1288 test1289 test129 test1290 test1291 test1292 test1293 test1294 test1295 test1296 test1297 test1298 test1299 test13 test130 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 test1309 test131 test1310 test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 test132 test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 test133 test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 test134 test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 test1348 test1349 test135 test1350 test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 test136 test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 test137 test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 test138 test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 test1388 test1389 test139 test1390 test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 test14 test140 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 test141 test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 test1418 test1419 test142 test1420 test1421 test1422 test1423 test1424 test1425 test1426 test1427 test1428 test1429 test143 test1430 test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 test144 test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 test145 test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 test146 test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 test1468 test1469 test147 test1470 test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 test1479 test148 test1480 test1481 test1482 test1483 test1484 test1485 test1486 test1487 test1488 test1489 test149 test1490 test1491 test1492 test1493 test1494 test1495 test1496 test1497 test1498 test1499 test15 test150 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 test1508 test1509 test151 test1510 test1511 test1512 test1513 test1514 test1515 test1516 test1517 test1518 test1519 test152 test1520 test1521 test1522 test1523 test1524 test1525 test1526 test1527 test1528 test1529 test153 test1530 test1531 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 test154 test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 test1548 test1549 test155 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 test1558 test1559 test156 test1560 test1561 test1562 test1563 test1564 test1565 test1566 test1567 test1568 test1569 test157 test1570 test1571 test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 test158 test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 test1589 test159 test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 test1598 test1599 test16 test160 test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 test1608 test1609 test161 test1610 test1611 test1612 test1613 test1614 test1615 test1616 test1617 test1618 test1619 test162 test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 test163 test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 test1638 test1639 test164 test1640 test1641 test1642 test1643 test1644 test1645 test165 test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 test1658 test1659 test166 test1660 test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 test1669 test167 test1670 test1671 test1672 test1673 test1674 test1675 test1676 test168 test1680 test1681 test1682 test1683 test1684 test1685 test169 test17 test170 test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 test1708 test1709 test171 test1710 test1711 test1712 test1713 test1714 test1715 test172 test1720 test1721 test173 test174 test175 test176 test177 test178 test179 test18 test180 test1800 test1801 test1802 test181 test182 test183 test184 test1847 test1848 test1849 test185 test1850 test1851 test186 test187 test188 test189 test19 test190 test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 test1908 test1909 test191 test1910 test1911 test1912 test1913 test1914 test1915 test1916 test1917 test1918 test1919 test192 test1920 test1921 test193 test1933 test1934 test1935 test1936 test1937 test1938 test1939 test194 test1940 test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 test195 test1955 test1956 test1957 test1958 test1959 test196 test1960 test1964 test1965 test1966 test197 test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 test1978 test1979 test198 test1980 test1981 test1982 test1983 test1984 test199 test2 test20 test200 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 test2008 test2009 test201 test2010 test2011 test2012 test2013 test2014 test202 test2023 test2024 test2025 test2026 test2027 test2028 test2029 test203 test2030 test2031 test2032 test2033 test2034 test2035 test2037 test2038 test2039 test204 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 test2048 test2049 test205 test2050 test2051 test2052 test2053 test2054 test2055 test2056 test2057 test2058 test2059 test206 test2060 test2061 test2062 test2063 test2064 test2065 test2066 test2067 test2068 test2069 test207 test2070 test2071 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 test208 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 test2088 test2089 test209 test2090 test2091 test2092 test21 test210 test2100 test2101 test2102 test2103 test2104 test211 test212 test213 test214 test215 test216 test217 test218 test219 test22 test220 test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 test221 test222 test223 test224 test225 test226 test227 test228 test229 test23 test230 test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 test2309 test231 test232 test233 test234 test235 test236 test237 test238 test239 test24 test240 test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 test2408 test2409 test241 test2410 test2411 test242 test243 test244 test245 test246 test247 test248 test249 test25 test250 test2500 test2501 test2502 test2503 test2504 test2505 test2506 test251 test252 test253 test254 test255 test256 test257 test258 test259 test26 test260 test2600 test2601 test2602 test2603 test2604 test2605 test261 test262 test263 test264 test265 test266 test267 test268 test269 test27 test270 test2700 test2701 test2702 test2703 test2704 test2705 test2706 test2707 test2708 test2709 test271 test2710 test2711 test2712 test2713 test2714 test2715 test2716 test2717 test2718 test2719 test272 test2720 test2721 test2722 test2723 test273 test274 test275 test276 test277 test278 test279 test28 test280 test281 test282 test283 test284 test285 test286 test287 test288 test289 test29 test290 test291 test292 test293 test294 test295 test296 test297 test298 test299 test3 test30 test300 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 test3008 test3009 test301 test3010 test3011 test3012 test3013 test3014 test3015 test3016 test3017 test3018 test3019 test302 test3020 test3021 test3022 test3023 test3024 test3025 test3026 test3027 test3028 test3029 test303 test3030 test3031 test3032 test3033 test3034 test3035 test3036 test304 test305 test306 test307 test308 test309 test31 test310 test3100 test3101 test3102 test3103 test3104 test3105 test3106 test311 test312 test313 test314 test315 test316 test317 test318 test319 test32 test320 test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 test3209 test321 test3210 test3211 test3212 test3213 test3214 test3215 test3216 test3217 test3218 test3219 test322 test3220 test323 test324 test325 test326 test327 test328 test329 test33 test330 test3300 test3301 test3302 test331 test332 test333 test334 test335 test336 test337 test338 test339 test34 test340 test341 test342 test343 test344 test345 test346 test347 test348 test349 test35 test350 test351 test352 test353 test354 test355 test356 test357 test358 test359 test36 test360 test361 test362 test363 test364 test365 test366 test367 test368 test369 test37 test370 test371 test372 test373 test374 test375 test376 test378 test379 test38 test380 test381 test383 test384 test385 test386 test387 test388 test389 test39 test390 test391 test392 test393 test394 test395 test396 test397 test398 test399 test4 test40 test400 test4000 test4001 test401 test402 test403 test404 test405 test406 test407 test408 test409 test41 test410 test411 test412 test413 test414 test415 test416 test417 test418 test419 test42 test420 test421 test422 test423 test424 test425 test426 test427 test428 test429 test43 test430 test431 test432 test433 test434 test435 test436 test437 test438 test439 test44 test440 test441 test442 test443 test444 test445 test446 test447 test448 test449 test45 test450 test451 test452 test453 test454 test455 test456 test457 test458 test459 test46 test460 test461 test462 test463 test467 test468 test469 test47 test470 test471 test472 test473 test474 test475 test476 test477 test478 test479 test48 test480 test481 test482 test483 test484 test485 test486 test487 test488 test489 test49 test490 test491 test492 test493 test494 test495 test496 test497 test498 test499 test5 test50 test500 test501 test502 test503 test504 test505 test506 test507 test508 test509 test51 test510 test511 test512 test513 test514 test515 test516 test517 test518 test519 test52 test520 test521 test522 test523 test524 test525 test526 test527 test528 test529 test53 test530 test531 test532 test533 test534 test535 test536 test537 test538 test539 test54 test540 test541 test542 test543 test544 test545 test546 test547 test548 test549 test55 test550 test551 test552 test553 test554 test555 test556 test557 test558 test559 test56 test560 test561 test562 test563 test564 test565 test566 test567 test568 test569 test57 test570 test571 test572 test573 test574 test575 test576 test577 test578 test579 test58 test580 test581 test582 test583 test584 test585 test586 test587 test588 test589 test59 test590 test591 test592 test593 test594 test595 test596 test597 test598 test599 test6 test60 test600 test601 test602 test603 test604 test605 test606 test607 test608 test609 test61 test610 test611 test612 test613 test614 test615 test616 test617 test618 test619 test62 test620 test621 test622 test623 test624 test625 test626 test627 test628 test629 test63 test630 test631 test632 test633 test634 test635 test636 test637 test638 test639 test64 test640 test641 test642 test643 test644 test645 test646 test647 test648 test649 test65 test650 test651 test652 test653 test654 test655 test656 test658 test659 test66 test660 test661 test662 test663 test664 test665 test666 test667 test668 test669 test67 test670 test671 test672 test673 test674 test675 test676 test677 test678 test679 test68 test680 test681 test682 test683 test684 test685 test686 test687 test688 test689 test69 test690 test691 test692 test693 test694 test695 test696 test697 test698 test699 test7 test70 test700 test701 test702 test703 test704 test705 test706 test707 test708 test709 test71 test710 test711 test712 test713 test714 test715 test716 test717 test718 test719 test72 test720 test721 test722 test723 test724 test725 test726 test727 test728 test729 test73 test730 test731 test732 test733 test734 test735 test736 test737 test738 test739 test74 test740 test741 test742 test743 test744 test745 test746 test747 test748 test749 test75 test750 test751 test752 test753 test754 test755 test756 test757 test758 test759 test76 test760 test761 test762 test763 test764 test765 test766 test767 test768 test769 test77 test770 test771 test772 test773 test774 test775 test776 test777 test778 test779 test78 test780 test781 test782 test783 test784 test785 test786 test787 test788 test789 test79 test790 test791 test792 test793 test794 test795 test796 test797 test798 test799 test8 test80 test800 test801 test802 test803 test804 test805 test806 test807 test808 test809 test81 test810 test811 test812 test813 test814 test815 test816 test817 test818 test819 test82 test820 test821 test822 test823 test824 test825 test826 test827 test828 test829 test83 test830 test831 test832 test833 test834 test835 test836 test837 test838 test839 test84 test840 test841 test842 test843 test844 test845 test846 test847 test848 test849 test85 test850 test851 test852 test853 test854 test855 test856 test857 test858 test859 test86 test860 test861 test862 test863 test864 test865 test866 test867 test868 test869 test87 test870 test871 test872 test873 test874 test875 test876 test877 test878 test879 test88 test880 test881 test882 test883 test884 test885 test886 test887 test888 test889 test89 test890 test891 test892 test893 test894 test895 test896 test897 test898 test899 test9 test90 test900 test901 test902 test903 test904 test905 test906 test907 test908 test909 test91 test910 test911 test912 test913 test914 test915 test916 test917 test918 test919 test92 test920 test921 test922 test923 test924 test925 test926 test927 test928 test929 test93 test930 test931 test932 test933 test934 test935 test936 test937 test938 test939 test94 test940 test941 test942 test943 test944 test945 test946 test947 test948 test949 test95 test950 test951 test952 test953 test954 test955 test956 test957 test958 test959 test96 test960 test961 test962 test963 test964 test965 test966 test967 test968 test969 test97 test970 test971 test972 test973 test974 test975 test976 test977 test978 test979 test98 test980 test981 test982 test983 test984 test985 test986 test987 test988 test989 test99 test990 test991 test992 test993 test994 test995 test996 test997 test998 test999
http
testenv
mod_curltest .gitignore mod_curltest.c
__init__.py caddy.py certs.py client.py curl.py dante.py dnsd.py env.py httpd.py nghttpx.py ports.py sshd.py vsftpd.py ws_echo_server.py
.gitignore CMakeLists.txt Makefile.am config.ini.in conftest.py requirements.txt scorecard.py test_01_basic.py test_02_download.py test_03_goaway.py test_04_stuttered.py test_05_errors.py test_06_eyeballs.py test_07_upload.py test_08_caddy.py test_09_push.py test_10_proxy.py test_11_unix.py test_12_reuse.py test_13_proxy_auth.py test_14_auth.py test_15_tracing.py test_16_info.py test_17_ssl_use.py test_18_methods.py test_19_shutdown.py test_20_websockets.py test_21_resolve.py test_22_httpsrr.py test_30_vsftpd.py test_31_vsftpds.py test_32_ftps_vsftpd.py test_40_socks.py test_50_scp.py test_51_sftp.py
libtest .gitignore CMakeLists.txt Makefile.am Makefile.inc cli_ftp_upload.c cli_h2_pausing.c cli_h2_serverpush.c cli_h2_upgrade_extreme.c cli_hx_download.c cli_hx_upload.c cli_tls_session_reuse.c cli_upload_pausing.c cli_ws_data.c cli_ws_pingpong.c first.c first.h lib1156.c lib1301.c lib1308.c lib1485.c lib1500.c lib1501.c lib1502.c lib1506.c lib1507.c lib1508.c lib1509.c lib1510.c lib1511.c lib1512.c lib1513.c lib1514.c lib1515.c lib1517.c lib1518.c lib1520.c lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c lib1545.c lib1549.c lib1550.c lib1551.c lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c lib1559.c lib1560.c lib1564.c lib1565.c lib1567.c lib1568.c lib1569.c lib1571.c lib1576.c lib1582.c lib1587.c lib1588.c lib1589.c lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c lib1598.c lib1599.c lib1662.c lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c lib1933.c lib1934.c lib1935.c lib1936.c lib1937.c lib1938.c lib1939.c lib1940.c lib1945.c lib1947.c lib1948.c lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c lib1964.c lib1965.c lib1970.c lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c lib2023.c lib2032.c lib2082.c lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c lib2402.c lib2404.c lib2405.c lib2502.c lib2504.c lib2505.c lib2506.c lib2700.c lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c lib3207.c lib3208.c lib500.c lib501.c lib502.c lib503.c lib504.c lib505.c lib506.c lib507.c lib508.c lib509.c lib510.c lib511.c lib512.c lib513.c lib514.c lib515.c lib516.c lib517.c lib518.c lib519.c lib520.c lib521.c lib523.c lib524.c lib525.c lib526.c lib530.c lib533.c lib536.c lib537.c lib539.c lib540.c lib541.c lib542.c lib543.c lib544.c lib547.c lib549.c lib552.c lib553.c lib554.c lib555.c lib556.c lib557.c lib558.c lib559.c lib560.c lib562.c lib564.c lib566.c lib567.c lib568.c lib569.c lib570.c lib571.c lib572.c lib573.c lib574.c lib575.c lib576.c lib578.c lib579.c lib582.c lib583.c lib586.c lib589.c lib590.c lib591.c lib597.c lib598.c lib599.c lib643.c lib650.c lib651.c lib652.c lib653.c lib654.c lib655.c lib658.c lib659.c lib661.c lib666.c lib667.c lib668.c lib670.c lib674.c lib676.c lib677.c lib678.c lib694.c lib695.c lib751.c lib753.c lib757.c lib758.c lib766.c memptr.c mk-lib1521.pl test1013.pl test1022.pl test307.pl test610.pl test613.pl testtrace.c testtrace.h testutil.c testutil.h unitcheck.h
server .checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc dnsd.c first.c first.h getpart.c mqttd.c resolve.c rtspd.c sockfilt.c socksd.c sws.c tftpd.c util.c
tunit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.c
unit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md unit1300.c unit1302.c unit1303.c unit1304.c unit1305.c unit1307.c unit1309.c unit1323.c unit1330.c unit1395.c unit1396.c unit1397.c unit1398.c unit1399.c unit1600.c unit1601.c unit1602.c unit1603.c unit1605.c unit1606.c unit1607.c unit1608.c unit1609.c unit1610.c unit1611.c unit1612.c unit1614.c unit1615.c unit1616.c unit1620.c unit1625.c unit1626.c unit1627.c unit1636.c unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c unit1666.c unit1667.c unit1668.c unit1669.c unit1674.c unit1675.c unit1676.c unit1979.c unit1980.c unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c unit3200.c unit3205.c unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c unit3219.c unit3300.c unit3301.c unit3302.c
.gitignore CMakeLists.txt Makefile.am allversions.pm appveyor.pm azure.pm config.in configurehelp.pm.in devtest.pl dictserver.py directories.pm ech_combos.py ech_tests.sh ftpserver.pl getpart.pm globalconfig.pm http-server.pl http2-server.pl http3-server.pl memanalyze.pl memanalyzer.pm negtelnetserver.py nghttpx.conf pathhelp.pm processhelp.pm requirements.txt rtspserver.pl runner.pm runtests.pl secureserver.pl serverhelp.pm servers.pm smbserver.py sshhelp.pm sshserver.pl test1119.pl test1135.pl test1139.pl test1140.pl test1165.pl test1167.pl test1173.pl test1175.pl test1177.pl test1222.pl test1275.pl test1276.pl test1477.pl test1486.pl test1488.pl test1544.pl test1707.pl test745.pl test971.pl testcurl.pl testutil.pm tftpserver.pl util.py valgrind.pm valgrind.supp
.clang-tidy.yml .dir-locals.el .editorconfig .git-blame-ignore-revs .gitattributes .gitignore .mailmap CHANGES.md CMakeLists.txt COPYING Dockerfile GIT-INFO.md Makefile.am README README.md RELEASE-NOTES REUSE.toml SECURITY.md acinclude.m4 appveyor.sh appveyor.yml configure.ac curl-config.in libcurl.pc.in renovate.json
examples .env config.ini crypto_test.lua env_test.lua fs_example.lua http_server.lua https_test.lua ini_example.lua json.lua log.lua path_fs_example.lua process_example.lua request_download.lua request_test.lua run_all.lua sqlite_example.lua sqlite_http_template.lua stash_test.lua template_test.lua timer.lua websocket.lua
iniparser
.github
ISSUE_TEMPLATE config.yml
workflows disable-pull-requests.yml trigger-gitlab-ci.yml
cmake JoinPaths.cmake config.cmake.in pc.in
example iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.ini
src dictionary.c dictionary.h iniparser.c iniparser.h
test
ressources
bad_ini ends_well.ini twisted-errors.ini twisted-ofkey.ini twisted-ofval.ini
good_ini empty.ini spaced.ini spaced2.ini twisted.ini
gruezi.ini old.ini quotes.ini utf8.ini
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.h
.cmake-format.py .gitignore .gitlab-ci.yml .gitmessage .travis.yml AUTHORS CMakeLists.txt FAQ-en.md FAQ-zhcn.md INSTALL LICENSE README.md compile_commands.json
jinjac
example CMakeLists.txt example.c
jinjac_test_app CMakeLists.txt jinjac_test_app.c
libjinjac
include jinjac.h
src CMakeLists.txt ast.c ast.h block_statement.c block_statement.h buffer.c buffer.h buildin.c buildin.h common.h convert.c convert.h flex_decl.h jfunction.c jfunction.h jinja_expression.l jinja_expression.y jinjac_parse.c jinjac_parse.h jinjac_stream.c jinjac_stream.h jlist.c jlist.h jobject.c jobject.h parameter.c parameter.h str_obj.c str_obj.h trace.c trace.h
CMakeLists.txt
test .gitignore CMakeLists.txt autotest.rb test_01.expected test_01.jinja test_01b.expected test_01b.jinja test_01c.expected test_01c.jinja test_01d.expected test_01d.jinja test_02.expected test_02.jinja test_03.expected test_03.jinja test_04.expected test_04.jinja test_05.expected test_05.jinja test_06.expected test_06.jinja test_07.expected test_07.jinja test_08.expected test_08.jinja test_08b.expected test_08b.jinja test_09.expected test_09.jinja test_10.expected test_10.jinja test_11.expected test_11.jinja test_12.expected test_12.jinja test_13.expected test_13.jinja test_14.expected test_14.jinja test_15.expected test_15.jinja test_16.expected test_16.jinja test_17.expected test_17.jinja test_18.expected test_18.jinja test_18b.expected test_18b.jinja test_18c.expected test_18c.jinja test_19.expected test_19.jinja test_19b.expected test_19b.jinja test_19c.expected test_19c.jinja test_19d.expected test_19d.jinja test_19e.expected test_19e.jinja test_19f.expected test_19f.jinja test_20.expected test_20.jinja test_21.expected test_21.jinja test_22.expected test_22.jinja test_22a.expected test_22a.jinja test_22b.expected test_22b.jinja test_23.expected test_23.jinja test_24.expected test_24.jinja
.gitignore CMakeLists.txt LICENSE.txt README.md build_coverage.sh build_debug.sh build_release.sh cppcheck_analysis.sh
libev Changes LICENSE Makefile Makefile.am Makefile.in README Symbols.ev Symbols.event aclocal.m4 autogen.sh compile config.guess config.h config.h.in config.status config.sub configure configure.ac depcomp ev++.h ev.3 ev.c ev.h ev.pod ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_vars.h ev_win32.c ev_wrap.h event.c event.h install-sh libev.m4 libtool ltmain.sh missing mkinstalldirs stamp-h1
luajit
doc
img contact.png
bluequad-print.css bluequad.css contact.html ext_buffer.html ext_c_api.html ext_ffi.html ext_ffi_api.html ext_ffi_semantics.html ext_ffi_tutorial.html ext_jit.html ext_profiler.html extensions.html install.html luajit.html running.html
dynasm dasm_arm.h dasm_arm.lua dasm_arm64.h dasm_arm64.lua dasm_mips.h dasm_mips.lua dasm_mips64.lua dasm_ppc.h dasm_ppc.lua dasm_proto.h dasm_x64.lua dasm_x86.h dasm_x86.lua dynasm.lua
etc luajit.1 luajit.pc
src
host .gitignore README buildvm.c buildvm.h buildvm_asm.c buildvm_fold.c buildvm_lib.c buildvm_libbc.h buildvm_peobj.c genlibbc.lua genminilua.lua genversion.lua minilua.c
jit .gitignore bc.lua bcsave.lua dis_arm.lua dis_arm64.lua dis_arm64be.lua dis_mips.lua dis_mips64.lua dis_mips64el.lua dis_mips64r6.lua dis_mips64r6el.lua dis_mipsel.lua dis_ppc.lua dis_x64.lua dis_x86.lua dump.lua p.lua v.lua zone.lua
.gitignore Makefile Makefile.dep lauxlib.h lib_aux.c lib_base.c lib_bit.c lib_buffer.c lib_debug.c lib_ffi.c lib_init.c lib_io.c lib_jit.c lib_math.c lib_os.c lib_package.c lib_string.c lib_table.c lj_alloc.c lj_alloc.h lj_api.c lj_arch.h lj_asm.c lj_asm.h lj_asm_arm.h lj_asm_arm64.h lj_asm_mips.h lj_asm_ppc.h lj_asm_x86.h lj_assert.c lj_bc.c lj_bc.h lj_bcdump.h lj_bcread.c lj_bcwrite.c lj_buf.c lj_buf.h lj_carith.c lj_carith.h lj_ccall.c lj_ccall.h lj_ccallback.c lj_ccallback.h lj_cconv.c lj_cconv.h lj_cdata.c lj_cdata.h lj_char.c lj_char.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_crecord.c lj_crecord.h lj_ctype.c lj_ctype.h lj_debug.c lj_debug.h lj_def.h lj_dispatch.c lj_dispatch.h lj_emit_arm.h lj_emit_arm64.h lj_emit_mips.h lj_emit_ppc.h lj_emit_x86.h lj_err.c lj_err.h lj_errmsg.h lj_ff.h lj_ffrecord.c lj_ffrecord.h lj_frame.h lj_func.c lj_func.h lj_gc.c lj_gc.h lj_gdbjit.c lj_gdbjit.h lj_ir.c lj_ir.h lj_ircall.h lj_iropt.h lj_jit.h lj_lex.c lj_lex.h lj_lib.c lj_lib.h lj_load.c lj_mcode.c lj_mcode.h lj_meta.c lj_meta.h lj_obj.c lj_obj.h lj_opt_dce.c lj_opt_fold.c lj_opt_loop.c lj_opt_mem.c lj_opt_narrow.c lj_opt_sink.c lj_opt_split.c lj_parse.c lj_parse.h lj_prng.c lj_prng.h lj_profile.c lj_profile.h lj_record.c lj_record.h lj_serialize.c lj_serialize.h lj_snap.c lj_snap.h lj_state.c lj_state.h lj_str.c lj_str.h lj_strfmt.c lj_strfmt.h lj_strfmt_num.c lj_strscan.c lj_strscan.h lj_tab.c lj_tab.h lj_target.h lj_target_arm.h lj_target_arm64.h lj_target_mips.h lj_target_ppc.h lj_target_x86.h lj_trace.c lj_trace.h lj_traceerr.h lj_udata.c lj_udata.h lj_vm.h lj_vmevent.c lj_vmevent.h lj_vmmath.c ljamalg.c lua.h lua.hpp luaconf.h luajit.c luajit_rolling.h lualib.h msvcbuild.bat nxbuild.bat ps4build.bat ps5build.bat psvitabuild.bat vm_arm.dasc vm_arm64.dasc vm_mips.dasc vm_mips64.dasc vm_ppc.dasc vm_x64.dasc vm_x86.dasc xb1build.bat xedkbuild.bat
.gitattributes .gitignore .relver COPYRIGHT Makefile README
sqlite shell.c sqlite3.c sqlite3.h sqlite3ext.h
wolfssl
.github
ISSUE_TEMPLATE bug_report.yaml other.yaml
actions
install-apt-deps action.yml
scripts
zephyr-4.x external_libc.conf zephyr-test.sh
openssl-ech.sh tls-anvil-test.sh
workflows
disabled haproxy.yml hitch.yml hostap.yml
hostap-files
configs
07c9f183ea744ac04585fb6dd10220c75a5e2e74 hostapd.config tests wpa_supplicant.config
b607d2723e927a3446d89aed813f1aa6068186bb hostapd.config tests wpa_supplicant.config
hostap_2_10 extra.patch hostapd.config tests wpa_supplicant.config
Makefile README dbus-wpa_supplicant.conf
ada.yml arduino.yml async-examples.yml async.yml atecc608-sim.yml bind.yml cmake-autoconf.yml cmake.yml codespell.yml coverity-scan-fixes.yml cryptocb-only.yml curl.yml cyrus-sasl.yml disable-pk-algs.yml docker-Espressif.yml docker-OpenWrt.yml emnet-nonblock.yml fil-c.yml freertos-mem-track.yml gencertbuf.yml grpc.yml haproxy.yml hostap-vm.yml intelasm-c-fallback.yml ipmitool.yml jwt-cpp.yml krb5.yml libspdm.yml libssh2.yml libvncserver.yml linuxkm.yml macos-apple-native-cert-validation.yml mbedtls.sh mbedtls.yml membrowse-comment.yml membrowse-onboard.yml membrowse-report.yml memcached.sh memcached.yml mono.yml mosquitto.yml msmtp.yml msys2.yml multi-arch.yml multi-compiler.yml net-snmp.yml nginx.yml no-malloc.yml no-tls.yml nss.sh nss.yml ntp.yml ocsp.yml openldap.yml openssh.yml openssl-ech.yml opensslcoexist.yml openvpn.yml os-check.yml packaging.yml pam-ipmi.yml pq-all.yml pr-commit-check.yml psk.yml puf.yml python.yml rng-tools.yml rust-wrapper.yml se050-sim.yml smallStackSize.yml socat.yml softhsm.yml sssd.yml stm32-sim.yml stsafe-a120-sim.yml stunnel.yml symbol-prefixes.yml threadx.yml tls-anvil.yml trackmemory.yml watcomc.yml win-csharp-test.yml wolfCrypt-Wconversion.yml wolfboot-integration.yml wolfsm.yml xcode.yml zephyr-4.x.yml zephyr.yml
PULL_REQUEST_TEMPLATE.md SECURITY.md membrowse-targets.json
Docker
OpenWrt Dockerfile README.md runTests.sh
packaging
debian Dockerfile
fedora Dockerfile
wolfCLU Dockerfile README.md
yocto Dockerfile buildAndPush.sh
Dockerfile Dockerfile.cross-compiler README.md buildAndPush.sh include.am run.sh
IDE
ARDUINO
sketches
wolfssl_client README.md
wolfssl_server README.md
wolfssl_version README.md
README.md
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.h
AURIX Cpu0_Main.c README.md include.am user_settings.h wolf_main.c
Android Android.bp README.md include.am user_settings.h
CRYPTOCELL README.md include.am main.c user_settings.h
CSBENCH include.am user_settings.h
ECLIPSE
DEOS
deos_wolfssl .options
README.md deos_malloc.c include.am tls_wolfssl.c tls_wolfssl.h user_settings.h
MICRIUM README.md client_wolfssl.c client_wolfssl.h include.am server_wolfssl.c server_wolfssl.h user_settings.h wolfsslRunTests.c
RTTHREAD README.md include.am user_settings.h wolfssl_test.c
SIFIVE README.md include.am
Espressif
ESP-IDF
examples
template
VisualGDB wolfssl_template_IDF_v5.1_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_benchmark
VisualGDB wolfssl_benchmark_IDF_v4.4_ESP32.sln wolfssl_benchmark_IDF_v4.4_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32.sln wolfssl_benchmark_IDF_v5_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32C3.sln wolfssl_benchmark_IDF_v5_ESP32C3.vgdbproj wolfssl_benchmark_IDF_v5_ESP32S3.sln wolfssl_benchmark_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_client
VisualGDB README.md wolfssl_client_IDF_v5_ESP32.sln wolfssl_client_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include client-tls.h main.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild client-tls.c component.mk main.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbproj
wolfssl_server
VisualGDB README.md wolfssl_server_IDF_v5_ESP32.sln wolfssl_server_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h server-tls.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild component.mk main.c server-tls.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbproj
wolfssl_test
VisualGDB wolfssl_test-IDF_v5_ESP32.sln wolfssl_test-IDF_v5_ESP32.vgdbproj wolfssl_test-IDF_v5_ESP32C3.sln wolfssl_test-IDF_v5_ESP32C3.vgdbproj wolfssl_test-IDF_v5_ESP32C6.sln wolfssl_test-IDF_v5_ESP32C6.vgdbproj wolfssl_test_IDF_v5_ESP32S3.sln wolfssl_test_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32 sdkconfig.defaults.esp32c3 sdkconfig.defaults.esp32c6 sdkconfig.defaults.esp32h2 sdkconfig.defaults.esp32s2 sdkconfig.defaults.esp32s3 sdkconfig.defaults.esp8266 testAll.sh testMonitor.sh wolfssl_test_ESP8266.sln wolfssl_test_ESP8266.vgdbproj
wolfssl_test_idf
VisualGDB VisualGDB_wolfssl_test_idf.sln VisualGDB_wolfssl_test_idf.vgdbproj
main CMakeLists.txt Kconfig.projbuild component.mk main.c main_wip.c.ex time_helper.c time_helper.h
CMakeLists.txt Kconfig.projbuild README.md component.mk sdkconfig.defaults
README.md
libs CMakeLists.txt README.md component.mk tigard.cfg
test CMakeLists.txt README.md component.mk test_wolfssl.c
README.md README_32se.md UPDATE.md compileAllExamples.sh dummy_config_h dummy_test_paths.h setup.sh setup_win.bat user_settings.h
README.md include.am
GCC-ARM
Header user_settings.h
Source armtarget.c benchmark_main.c test_main.c tls_client.c tls_server.c wolf_main.c
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ld
Gaisler-BCC README.md include.am
HEXAGON
DSP Makefile wolfssl_dsp.idl
Makefile README.md build.sh ecc-verify-benchmark.c ecc-verify.c include.am user_settings.h
HEXIWEAR
wolfSSL_HW .cwGeneratedFileSetLog user_settings.h
IAR-EWARM
Projects
benchmark benchmark-main.c current_time.c wolfCrypt-benchmark.ewd wolfCrypt-benchmark.ewp
common minimum-startup.c wolfssl.icf
lib wolfSSL-Lib.ewd wolfSSL-Lib.ewp
test test-main.c wolfCrypt-test.ewd wolfCrypt-test.ewp
user_settings.h wolfssl.eww
embOS
SAMV71_XULT
embOS_SAMV71_XULT_Linker_Script samv71q21_wolfssl.icf
embOS_SAMV71_XULT_user_settings user_settings.h user_settings_simple_example.h user_settings_verbose_example.h
embOS_wolfcrypt_benchmark_SAMV71_XULT
Application runBenchmarks.c
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewp
embOS_wolfcrypt_lib_SAMV71_XULT README_wolfcrypt_lib wolfcrypt_lib.ewd wolfcrypt_lib.ewp
embOS_wolfcrypt_test_SAMV71_XULT
Application runWolfcryptTests.c
README_wolfcrypt_test wolfcrypt_test.ewd wolfcrypt_test.ewp
README_SAMV71
custom_port
custom_port_Linker_Script samv71q21_wolfssl.icf
custom_port_user_settings user_settings.h
wolfcrypt_benchmark_custom_port
Application runBenchmarks.c
wolfcrypt_test_custom_port
Application runWolfcryptTests.c
README_custom_port
extract_trial_here README_extract_trial_here
README
.gitignore README
IAR-MSP430 Makefile README.md include.am main.c user_settings.h
INTIME-RTOS Makefile README.md include.am libwolfssl.c libwolfssl.vcxproj user_settings.h wolfExamples.c wolfExamples.h wolfExamples.sln wolfExamples.vcxproj wolfssl-lib.sln wolfssl-lib.vcxproj
Infineon README.md include.am user_settings.h
KDS
config user_settings.h
include.am
LINUX-SGX README.md build.sh clean.sh include.am sgx_t_static.mk
LPCXPRESSO
lib_wolfssl lpc_18xx_port.c user_settings.h
wolf_example
src lpc_18xx_startup.c wolfssl_example.c
readme.txt
README.md
M68K
benchmark Makefile main.cpp
testwolfcrypt Makefile main.cpp
Makefile README.md include.am user_settings.h
MCUEXPRESSO
RT1170 fsl_caam_c.patch fsl_caam_h.patch user_settings.h
benchmark
source run_benchmark.c
wolfssl liblinks.xml
README.md include.am user_settings.h wolfcrypt_test.c
MDK-ARM
LPC43xx time-LCP43xx.c
MDK-ARM
wolfSSL Retarget.c cert_data.c cert_data.h config-BARE-METAL.h config-FS.h config-RTX-TCP-FS.h config-WOLFLIB.h main.c shell.c time-CortexM3-4.c time-dummy.c wolfssl_MDK_ARM.c wolfssl_MDK_ARM.h
STM32F2xx_StdPeriph_Lib time-STM32F2xx.c
MDK5-ARM
Conf user_settings.h
Inc wolfssl_MDK_ARM.h
Projects
CryptBenchmark Abstract.txt CryptBenchmark.sct CryptBenchmark.uvoptx CryptBenchmark.uvprojx main.c
CryptTest Abstract.txt CryptTest.sct CryptTest.uvoptx CryptTest.uvprojx main.c
EchoClient Abstract.txt EchoClient.uvoptx EchoClient.uvprojx main.c wolfssl-link.sct
EchoServer Abstract.txt EchoServer.uvoptx EchoServer.uvprojx main.c wolfssl-link.sct
SimpleClient Abstract.txt SimpleClient.uvoptx SimpleClient.uvprojx main.c wolfssl-link.sct
SimpleServer Abstract.txt SimpleServer.uvoptx SimpleServer.uvprojx main.c wolfssl-link.sct
wolfSSL-Full Abstract.txt main.c shell.c time-CortexM3-4.c wolfsslFull.uvoptx wolfsslFull.uvprojx
wolfSSL-Lib Abstract.txt wolfSSL-Lib.uvoptx wolfSSL-Lib.uvprojx
Src ssl-dummy.c
README.md include.am
MPLABX16
wolfcrypt_test.X
nbproject
private configurations.xml private.xml
configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
README.md include.am main.c user_settings.h
MQX Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.h
MSVS-2019-AZSPHERE
client client.c client.h
server server.c server.h
shared util.h
wolfssl_new_azsphere
HardwareDefinitions
avnet_mt3620_sk
inc
hw template_appliance.h
template_appliance.json
mt3620_rdb
inc
hw template_appliance.h
template_appliance.json
seeed_mt3620_mdb
inc
hw template_appliance.h
template_appliance.json
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.c
README.md include.am user_settings.h
MYSQL CMakeLists_wolfCrypt.txt CMakeLists_wolfSSL.txt do.sh
NDS README.md
NETOS Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.c
OPENSTM32 README.md
PlatformIO
examples
wolfssl_benchmark
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspace
wolfssl_test
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_test.code-workspace
README.md wolfssl_platformio.code-workspace
README.md include.am
QNX
CAAM-DRIVER Makefile
example-client Makefile client-tls.c
example-cmac Makefile cmac-test.c
example-server Makefile server-tls.c
testwolfcrypt Makefile
wolfssl Makefile user_settings.h
README.md include.am
RISCV
SIFIVE-HIFIVE1 Makefile README.md include.am main.c user_settings.h
SIFIVE-UNLEASHED README.md include.am
include.am
ROWLEY-CROSSWORKS-ARM Kinetis_FlashPlacement.xml README.md arm_startup.c benchmark_main.c hw.h include.am kinetis_hw.c retarget.c test_main.c user_settings.h wolfssl.hzp wolfssl_ltc.hzp
Renesas
cs+
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
t4_demo README_en.txt README_jp.txt t4_demo.mtpj wolf_client.c wolf_demo.h wolf_main.c wolf_server.c
test test.mtpj test_main.c
wolfssl_lib wolfssl_lib.mtpj
README include.am
e2studio
DK-S7G2
benchmark-template
src app_entry.c
example_server-template
src app_entry.c
wolfcrypttest-template
src app_entry.c
wolfssl-template-project configuration.xml
README.md include.am user_settings.h
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
tools generate_rsa_keypair.sh genhexbuf.pl rsa_pss_sign.sh
wolfssl
src .gitkeep
wolfcrypt
src .gitkeep
README include.am
RA6M3
benchmark-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
client-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
common
ra6m3g README.md
src freertos_tcp_port.c
user_settings.h util.h
server-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
test-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl
src .gitkeep
wolfcrypt .gitkeep
README.md README_APRA6M_en.md README_APRA6M_jp.md include.am
RA6M3G README.md
RA6M4
common user_settings.h wolfssl_demo.h
test
key_data key_data.h key_data_sce.c
src
SEGGER_RTT myprint.c
common .gitignore
test_main.c wolf_client.c wolfssl_sce_unit_test.c
test_RA6M4Debug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
README.md include.am
RX65N
GR-ROSE
common strings.h unistd.h user_settings.h wolfssl_dummy.c
smc smc.scfg
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
test.rcpc test_HardwareDebug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
README_EN.md README_JP.md include.am
RSK
resource section.esi
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h
InstructionManualForExample_RSK+RX65N-2MB_EN.pdf InstructionManualForExample_RSK+RX65N-2MB_JP.pdf README_EN.md README_JP.md include.am
RX72N
EnvisionKit
Simple
common sectioninfo.esi wolfssl_dummy.c
test
src
client simple_tcp_client.c simple_tls_tsip_client.c
server simple_tcp_server.c simple_tls_server.c
test_main.c wolfssl_simple_demo.h
test.rcpc test.scfg test_HardwareDebug.launch
wolfssl wolfssl.rcpc
README_EN.md README_JP.md
resource section.esi
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.c
InstructionManualForExample_RX72N_EnvisonKit_EN.pdf InstructionManualForExample_RX72N_EnvisonKit_JP.pdf README_EN.md README_JP.md include.am
RZN2L
common user_settings.h wolfssl_demo.h
test
src
serial_io app_print.c
test wolf_client.c wolf_server.c wolfssl_rsip_unit_test.c
wolfCrypt .gitignore
wolfSSL .gitignore
local_system_init.c rzn2l_tst_thread_entry.c wolfssl_dummy.c
README.md include.am
SK-S7G2
common user_settings.h
wolfssl_lib configuration.xml
.gitignore README.md include.am
STARCORE README.txt include.am starcore_test.c user_settings.h
STM32Cube README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.h
SimplicityStudio README.md include.am test_wolf.c user_settings.h
TRUESTUDIO
wolfssl user_settings.h
README include.am
VS-ARM README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VS-AZURE-SPHERE
client app_manifest.json client.c client.h client.vcxproj
server app_manifest.json server.c server.h server.vcxproj
shared util.h
wolfcrypt_test app_manifest.json wolfcrypt_test.vcxproj
README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VisualDSP include.am user_settings.h wolf_tasks.c
WICED-STUDIO README include.am user_settings.h
WIN README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxproj
WIN-SGX ReadMe.txt include.am wolfSSL_SGX.edl wolfSSL_SGX.sln wolfSSL_SGX.vcxproj
WIN-SRTP-KDF-140-3 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WIN10 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WINCE README.md include.am user_settings.h user_settings.h.140-2-deprecated
WORKBENCH README.md include.am
XCODE
Benchmark
wolfBench
Assets.xcassets
AppIcon.appiconset Contents.json
Base.lproj LaunchScreen.storyboard Main.storyboard
AppDelegate.h AppDelegate.m Info.plist ViewController.h ViewController.m main.m
wolfBench.xcodeproj project.pbxproj
include.am
wolfssl-FIPS.xcodeproj project.pbxproj
wolfssl.xcodeproj project.pbxproj
wolfssl_testsuite.xcodeproj project.pbxproj
README.md build-for-i386.sh include.am user_settings.h
XCODE-FIPSv2
macOS-C++
Intel user_settings.h
M1 user_settings.h
include.am user_settings.h
XCODE-FIPSv5 README include.am user_settings.h
XCODE-FIPSv6 README include.am user_settings.h
XilinxSDK
2018_2 lscript.ld
2019_2
wolfCrypt_example
src lscript.ld
wolfCrypt_example_system wolfCrypt_example_system.sprj
2022_1
wolfCrypt_FreeRTOS_example wolfCrypt_FreeRTOS_example.prj
wolfCrypt_FreeRTOS_example_system wolfCrypt_FreeRTOS_example_system.sprj
wolfCrypt_example wolfCrypt_example.prj
wolfCrypt_example_system wolfCrypt_example_system.sprj
.gitignore
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.c
apple-universal
wolfssl-multiplatform
wolfssl-multiplatform
Assets.xcassets
AccentColor.colorset Contents.json
AppIcon.appiconset Contents.json
Contents.json
ContentView.swift simple_client_example.c simple_client_example.h wolfssl-multiplatform-Bridging-Header.h wolfssl_multiplatform.entitlements wolfssl_multiplatformApp.swift wolfssl_test_driver.c wolfssl_test_driver.h
wolfssl-multiplatform.xcodeproj project.pbxproj
.gitignore README.md build-wolfssl-framework.sh include.am
iotsafe Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.h
iotsafe-raspberrypi Makefile README.md client-tls13.c include.am main.c
mynewt README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.sh
zephyr README.md include.am
include.am
RTOS
nuttx
wolfssl .gitignore Kconfig Make.defs Makefile README.md setup-wolfssl.sh user_settings.h
include.am
bsdkm Makefile README.md bsdkm_wc_port.h include.am wolfkmod.c wolfkmod_aes.c x86_vecreg.c
certs
1024 ca-cert.der ca-cert.pem ca-key.der ca-key.pem client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der dh1024.der dh1024.pem dsa-pub-1024.pem dsa1024.der dsa1024.pem include.am rsa1024.der server-cert.der server-cert.pem server-key.der server-key.pem
3072 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
4096 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
acert
rsa_pss acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem
acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem include.am
aia ca-issuers-cert.pem multi-aia-cert.pem overflow-aia-cert.pem
crl
extra-crls ca-int-cert-revoked.pem claim-root.pem crl_critical_entry.pem crlnum_57oct.pem crlnum_64oct.pem general-server-crl.pem large_crlnum.pem large_crlnum2.pem
hash_der 0fdb2da4.r0
hash_pem 0fdb2da4.r0
bad_time_fmt.pem ca-int-ecc.pem ca-int.pem ca-int2-ecc.pem ca-int2.pem caEcc384Crl.pem caEccCrl.der caEccCrl.pem cliCrl.pem client-int-ecc.pem client-int.pem crl.der crl.pem crl.revoked crl2.der crl2.pem crl_reason.pem crl_rsapss.pem eccCliCRL.pem eccSrvCRL.pem gencrls.sh include.am server-goodaltCrl.pem server-goodaltwildCrl.pem server-goodcnCrl.pem server-goodcnwildCrl.pem server-int-ecc.pem server-int.pem wolfssl.cnf
dilithium bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.am
ecc bp256r1-key.der bp256r1-key.pem ca-secp256k1-cert.pem ca-secp256k1-key.pem client-bp256r1-cert.der client-bp256r1-cert.pem client-secp256k1-cert.der client-secp256k1-cert.pem genecc.sh include.am secp256k1-key.der secp256k1-key.pem secp256k1-param.pem secp256k1-privkey.der secp256k1-privkey.pem server-bp256r1-cert.der server-bp256r1-cert.pem server-secp256k1-cert.der server-secp256k1-cert.pem server2-secp256k1-cert.der server2-secp256k1-cert.pem wolfssl.cnf wolfssl_384.cnf
ed25519 ca-ed25519-key.der ca-ed25519-key.pem ca-ed25519-priv.der ca-ed25519-priv.pem ca-ed25519.der ca-ed25519.pem client-ed25519-key.der client-ed25519-key.pem client-ed25519-priv.der client-ed25519-priv.pem client-ed25519.der client-ed25519.pem eddsa-ed25519.der eddsa-ed25519.pem gen-ed25519-certs.sh gen-ed25519-keys.sh gen-ed25519.sh include.am root-ed25519-key.der root-ed25519-key.pem root-ed25519-priv.der root-ed25519-priv.pem root-ed25519.der root-ed25519.pem server-ed25519-cert.pem server-ed25519-key.der server-ed25519-key.pem server-ed25519-priv.der server-ed25519-priv.pem server-ed25519.der server-ed25519.pem
ed448 ca-ed448-key.der ca-ed448-key.pem ca-ed448-priv.der ca-ed448-priv.pem ca-ed448.der ca-ed448.pem client-ed448-key.der client-ed448-key.pem client-ed448-priv.der client-ed448-priv.pem client-ed448.der client-ed448.pem gen-ed448-certs.sh gen-ed448-keys.sh include.am root-ed448-key.der root-ed448-key.pem root-ed448-priv.der root-ed448-priv.pem root-ed448.der root-ed448.pem server-ed448-cert.pem server-ed448-key.der server-ed448-key.pem server-ed448-priv.der server-ed448-priv.pem server-ed448.der server-ed448.pem
external DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.am
falcon bench_falcon_level1_key.der bench_falcon_level5_key.der include.am
intermediate
ca_false_intermediate gentestcert.sh int_ca.key server.key test_ca.key test_ca.pem test_int_not_cacert.pem test_sign_bynoca_srv.pem wolfssl_base.conf wolfssl_srv.conf
ca-ecc-bad-aki.der ca-ecc-bad-aki.pem ca-int-cert.der ca-int-cert.pem ca-int-ecc-cert.der ca-int-ecc-cert.pem ca-int-ecc-key.der ca-int-ecc-key.pem ca-int-key.der ca-int-key.pem ca-int2-cert.der ca-int2-cert.pem ca-int2-ecc-cert.der ca-int2-ecc-cert.pem ca-int2-ecc-key.der ca-int2-ecc-key.pem ca-int2-key.der ca-int2-key.pem client-chain-alt-ecc.pem client-chain-alt.pem client-chain-ecc.der client-chain-ecc.pem client-chain.der client-chain.pem client-int-cert.der client-int-cert.pem client-int-ecc-cert.der client-int-ecc-cert.pem genintcerts.sh include.am server-chain-alt-ecc.pem server-chain-alt.pem server-chain-ecc.der server-chain-ecc.pem server-chain-short.pem server-chain.der server-chain.pem server-int-cert.der server-int-cert.pem server-int-ecc-cert.der server-int-ecc-cert.pem
lms bc_hss_L2_H5_W8_root.der bc_hss_L3_H5_W4_root.der bc_lms_chain_ca.der bc_lms_chain_leaf.der bc_lms_native_bc_root.der bc_lms_sha256_h10_w8_root.der bc_lms_sha256_h5_w4_root.der include.am
mldsa README.txt include.am mldsa44-cert.der mldsa44-cert.pem mldsa44-key.pem mldsa44_bare-priv.der mldsa44_bare-seed.der mldsa44_oqskeypair.der mldsa44_priv-only.der mldsa44_pub-spki.der mldsa44_seed-only.der mldsa44_seed-priv.der mldsa65-cert.der mldsa65-cert.pem mldsa65-key.pem mldsa65_bare-priv.der mldsa65_bare-seed.der mldsa65_oqskeypair.der mldsa65_priv-only.der mldsa65_pub-spki.der mldsa65_seed-only.der mldsa65_seed-priv.der mldsa87-cert.der mldsa87-cert.pem mldsa87-key.pem mldsa87_bare-priv.der mldsa87_bare-seed.der mldsa87_oqskeypair.der mldsa87_priv-only.der mldsa87_pub-spki.der mldsa87_seed-only.der mldsa87_seed-priv.der
ocsp imposter-root-ca-cert.der imposter-root-ca-cert.pem imposter-root-ca-key.der imposter-root-ca-key.pem include.am index-ca-and-intermediate-cas.txt index-ca-and-intermediate-cas.txt.attr index-intermediate1-ca-issued-certs.txt index-intermediate1-ca-issued-certs.txt.attr index-intermediate2-ca-issued-certs.txt index-intermediate2-ca-issued-certs.txt.attr index-intermediate3-ca-issued-certs.txt index-intermediate3-ca-issued-certs.txt.attr intermediate1-ca-cert.der intermediate1-ca-cert.pem intermediate1-ca-key.der intermediate1-ca-key.pem intermediate2-ca-cert.der intermediate2-ca-cert.pem intermediate2-ca-key.der intermediate2-ca-key.pem intermediate3-ca-cert.der intermediate3-ca-cert.pem intermediate3-ca-key.der intermediate3-ca-key.pem ocsp-responder-cert.der ocsp-responder-cert.pem ocsp-responder-key.der ocsp-responder-key.pem openssl.cnf renewcerts-for-test.sh renewcerts.sh root-ca-cert.der root-ca-cert.pem root-ca-crl.pem root-ca-key.der root-ca-key.pem server1-cert.der server1-cert.pem server1-chain-noroot.pem server1-key.der server1-key.pem server2-cert.der server2-cert.pem server2-key.der server2-key.pem server3-cert.der server3-cert.pem server3-key.der server3-key.pem server4-cert.der server4-cert.pem server4-key.der server4-key.pem server5-cert.der server5-cert.pem server5-key.der server5-key.pem test-leaf-response.der test-multi-response.der test-response-nointern.der test-response-rsapss.der test-response.der
p521 ca-p521-key.der ca-p521-key.pem ca-p521-priv.der ca-p521-priv.pem ca-p521.der ca-p521.pem client-p521-key.der client-p521-key.pem client-p521-priv.der client-p521-priv.pem client-p521.der client-p521.pem gen-p521-certs.sh gen-p521-keys.sh include.am root-p521-key.der root-p521-key.pem root-p521-priv.der root-p521-priv.pem root-p521.der root-p521.pem server-p521-cert.pem server-p521-key.der server-p521-key.pem server-p521-priv.der server-p521-priv.pem server-p521.der server-p521.pem
renewcerts wolfssl.cnf
rpk client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.der
rsapss ca-3072-rsapss-key.der ca-3072-rsapss-key.pem ca-3072-rsapss-priv.der ca-3072-rsapss-priv.pem ca-3072-rsapss.der ca-3072-rsapss.pem ca-rsapss-key.der ca-rsapss-key.pem ca-rsapss-priv.der ca-rsapss-priv.pem ca-rsapss.der ca-rsapss.pem client-3072-rsapss-key.der client-3072-rsapss-key.pem client-3072-rsapss-priv.der client-3072-rsapss-priv.pem client-3072-rsapss.der client-3072-rsapss.pem client-rsapss-key.der client-rsapss-key.pem client-rsapss-priv.der client-rsapss-priv.pem client-rsapss.der client-rsapss.pem gen-rsapss-keys.sh include.am renew-rsapss-certs.sh root-3072-rsapss-key.der root-3072-rsapss-key.pem root-3072-rsapss-priv.der root-3072-rsapss-priv.pem root-3072-rsapss.der root-3072-rsapss.pem root-rsapss-key.der root-rsapss-key.pem root-rsapss-priv.der root-rsapss-priv.pem root-rsapss.der root-rsapss.pem server-3072-rsapss-cert.pem server-3072-rsapss-key.der server-3072-rsapss-key.pem server-3072-rsapss-priv.der server-3072-rsapss-priv.pem server-3072-rsapss.der server-3072-rsapss.pem server-mix-rsapss-cert.pem server-rsapss-cert.pem server-rsapss-key.der server-rsapss-key.pem server-rsapss-priv.der server-rsapss-priv.pem server-rsapss.der server-rsapss.pem
sia timestamping-sia-cert.pem
slhdsa bench_slhdsa_sha2_128f_key.der bench_slhdsa_sha2_128s_key.der bench_slhdsa_sha2_192f_key.der bench_slhdsa_sha2_192s_key.der bench_slhdsa_sha2_256f_key.der bench_slhdsa_sha2_256s_key.der bench_slhdsa_shake128f_key.der bench_slhdsa_shake128s_key.der bench_slhdsa_shake192f_key.der bench_slhdsa_shake192s_key.der bench_slhdsa_shake256f_key.der bench_slhdsa_shake256s_key.der client-mldsa44-priv.pem client-mldsa44-sha2.der client-mldsa44-sha2.pem client-mldsa44-shake.der client-mldsa44-shake.pem gen-slhdsa-mldsa-certs.sh include.am root-slhdsa-sha2-128s-priv.der root-slhdsa-sha2-128s-priv.pem root-slhdsa-sha2-128s.der root-slhdsa-sha2-128s.pem root-slhdsa-shake-128s-priv.der root-slhdsa-shake-128s-priv.pem root-slhdsa-shake-128s.der root-slhdsa-shake-128s.pem server-mldsa44-priv.pem server-mldsa44-sha2.der server-mldsa44-sha2.pem server-mldsa44-shake.der server-mldsa44-shake.pem
sm2 ca-sm2-key.der ca-sm2-key.pem ca-sm2-priv.der ca-sm2-priv.pem ca-sm2.der ca-sm2.pem client-sm2-key.der client-sm2-key.pem client-sm2-priv.der client-sm2-priv.pem client-sm2.der client-sm2.pem fix_sm2_spki.py gen-sm2-certs.sh gen-sm2-keys.sh include.am root-sm2-key.der root-sm2-key.pem root-sm2-priv.der root-sm2-priv.pem root-sm2.der root-sm2.pem self-sm2-cert.pem self-sm2-key.pem self-sm2-priv.pem server-sm2-cert.der server-sm2-cert.pem server-sm2-key.der server-sm2-key.pem server-sm2-priv.der server-sm2-priv.pem server-sm2.der server-sm2.pem
statickeys dh-ffdhe2048-params.pem dh-ffdhe2048-pub.der dh-ffdhe2048-pub.pem dh-ffdhe2048.der dh-ffdhe2048.pem ecc-secp256r1.der ecc-secp256r1.pem gen-static.sh include.am x25519-pub.der x25519-pub.pem x25519.der x25519.pem
test
expired expired-ca.der expired-ca.pem expired-cert.der expired-cert.pem
catalog.txt cert-bad-neg-int.der cert-bad-oid.der cert-bad-utf8.der cert-ext-ia.cfg cert-ext-ia.der cert-ext-ia.pem cert-ext-joi.cfg cert-ext-joi.der cert-ext-joi.pem cert-ext-mnc.der cert-ext-multiple.cfg cert-ext-multiple.der cert-ext-multiple.pem cert-ext-nc-combined.der cert-ext-nc-combined.pem cert-ext-nc.cfg cert-ext-nc.der cert-ext-nc.pem cert-ext-ncdns.der cert-ext-ncdns.pem cert-ext-ncip.der cert-ext-ncip.pem cert-ext-ncmixed.der cert-ext-ncmulti.der cert-ext-ncmulti.pem cert-ext-ncrid.der cert-ext-ncrid.pem cert-ext-nct.cfg cert-ext-nct.der cert-ext-nct.pem cert-ext-ndir-exc.cfg cert-ext-ndir-exc.der cert-ext-ndir-exc.pem cert-ext-ndir.cfg cert-ext-ndir.der cert-ext-ndir.pem cert-ext-ns.der cert-over-max-altnames.cfg cert-over-max-altnames.der cert-over-max-altnames.pem cert-over-max-nc.cfg cert-over-max-nc.der cert-over-max-nc.pem client-ecc-cert-ski.hex cn-ip-literal.der cn-ip-wildcard.der crit-cert.pem crit-key.pem dh1024.der dh1024.pem dh512.der dh512.pem digsigku.pem encrypteddata.msg gen-badsig.sh gen-ext-certs.sh gen-testcerts.sh include.am kari-keyid-cms.msg ktri-keyid-cms.msg ossl-trusted-cert.pem server-badaltname.der server-badaltname.pem server-badaltnull.der server-badaltnull.pem server-badcn.der server-badcn.pem server-badcnnull.der server-badcnnull.pem server-cert-ecc-badsig.der server-cert-ecc-badsig.pem server-cert-rsa-badsig.der server-cert-rsa-badsig.pem server-duplicate-policy.pem server-garbage.der server-garbage.pem server-goodalt.der server-goodalt.pem server-goodaltwild.der server-goodaltwild.pem server-goodcn.der server-goodcn.pem server-goodcnwild.der server-goodcnwild.pem server-localhost.der server-localhost.pem smime-test-canon.p7s smime-test-multipart-badsig.p7s smime-test-multipart.p7s smime-test.p7s
test-pathlen assemble-chains.sh chainA-ICA1-key.pem chainA-ICA1-pathlen0.pem chainA-assembled.pem chainA-entity-key.pem chainA-entity.pem chainB-ICA1-key.pem chainB-ICA1-pathlen0.pem chainB-ICA2-key.pem chainB-ICA2-pathlen1.pem chainB-assembled.pem chainB-entity-key.pem chainB-entity.pem chainC-ICA1-key.pem chainC-ICA1-pathlen1.pem chainC-assembled.pem chainC-entity-key.pem chainC-entity.pem chainD-ICA1-key.pem chainD-ICA1-pathlen127.pem chainD-assembled.pem chainD-entity-key.pem chainD-entity.pem chainE-ICA1-key.pem chainE-ICA1-pathlen128.pem chainE-assembled.pem chainE-entity-key.pem chainE-entity.pem chainF-ICA1-key.pem chainF-ICA1-pathlen1.pem chainF-ICA2-key.pem chainF-ICA2-pathlen0.pem chainF-assembled.pem chainF-entity-key.pem chainF-entity.pem chainG-ICA1-key.pem chainG-ICA1-pathlen0.pem chainG-ICA2-key.pem chainG-ICA2-pathlen1.pem chainG-ICA3-key.pem chainG-ICA3-pathlen99.pem chainG-ICA4-key.pem chainG-ICA4-pathlen5.pem chainG-ICA5-key.pem chainG-ICA5-pathlen20.pem chainG-ICA6-key.pem chainG-ICA6-pathlen10.pem chainG-ICA7-key.pem chainG-ICA7-pathlen100.pem chainG-assembled.pem chainG-entity-key.pem chainG-entity.pem chainH-ICA1-key.pem chainH-ICA1-pathlen0.pem chainH-ICA2-key.pem chainH-ICA2-pathlen2.pem chainH-ICA3-key.pem chainH-ICA3-pathlen2.pem chainH-ICA4-key.pem chainH-ICA4-pathlen2.pem chainH-assembled.pem chainH-entity-key.pem chainH-entity.pem chainI-ICA1-key.pem chainI-ICA1-no_pathlen.pem chainI-ICA2-key.pem chainI-ICA2-no_pathlen.pem chainI-ICA3-key.pem chainI-ICA3-pathlen2.pem chainI-assembled.pem chainI-entity-key.pem chainI-entity.pem chainJ-ICA1-key.pem chainJ-ICA1-no_pathlen.pem chainJ-ICA2-key.pem chainJ-ICA2-no_pathlen.pem chainJ-ICA3-key.pem chainJ-ICA3-no_pathlen.pem chainJ-ICA4-key.pem chainJ-ICA4-pathlen2.pem chainJ-assembled.pem chainJ-entity-key.pem chainJ-entity.pem include.am refreshkeys.sh
test-serial0 ee_normal.pem ee_serial0.pem generate_certs.sh include.am intermediate_serial0.pem root_serial0.pem root_serial0_key.pem selfsigned_nonca_serial0.pem
xmss bc_xmss_chain_ca.der bc_xmss_chain_leaf.der bc_xmss_sha2_10_256_root.der bc_xmss_sha2_16_256_root.der bc_xmssmt_sha2_20_2_256_root.der bc_xmssmt_sha2_20_4_256_root.der bc_xmssmt_sha2_40_8_256_root.der include.am
ca-cert-chain.der ca-cert.der ca-cert.pem ca-ecc-cert.der ca-ecc-cert.pem ca-ecc-key.der ca-ecc-key.pem ca-ecc384-cert.der ca-ecc384-cert.pem ca-ecc384-key.der ca-ecc384-key.pem ca-key-pkcs8-attribute.der ca-key.der ca-key.pem check_dates.sh client-absolute-urn.pem client-ca-cert.der client-ca-cert.pem client-ca.pem client-cert-ext.der client-cert-ext.pem client-cert.der client-cert.pem client-crl-dist.der client-crl-dist.pem client-ecc-ca-cert.der client-ecc-ca-cert.pem client-ecc-cert.der client-ecc-cert.pem client-ecc384-cert.der client-ecc384-cert.pem client-ecc384-key.der client-ecc384-key.pem client-key.der client-key.pem client-keyEnc.pem client-keyPub.der client-keyPub.pem client-relative-uri.pem client-uri-cert.pem csr.attr.der csr.dsa.der csr.dsa.pem csr.ext.der csr.signed.der dh-priv-2048.der dh-priv-2048.pem dh-pub-2048.der dh-pub-2048.pem dh-pubkey-2048.der dh2048.der dh2048.pem dh3072.der dh3072.pem dh4096.der dh4096.pem dsa-pubkey-2048.der dsa2048.der dsa2048.pem dsa3072.der dsaparams.der dsaparams.pem ecc-client-key.der ecc-client-key.pem ecc-client-keyPub.der ecc-client-keyPub.pem ecc-key-comp.pem ecc-keyPkcs8.der ecc-keyPkcs8.pem ecc-keyPkcs8Enc.der ecc-keyPkcs8Enc.pem ecc-keyPub.der ecc-keyPub.pem ecc-params.der ecc-params.pem ecc-privOnlyCert.pem ecc-privOnlyKey.pem ecc-privkey.der ecc-privkey.pem ecc-privkeyPkcs8.der ecc-privkeyPkcs8.pem ecc-rsa-server.p12 empty-issuer-cert.pem entity-no-ca-bool-cert.pem entity-no-ca-bool-key.pem fpki-cert.der fpki-certpol-cert.der gen_revoked.sh include.am renewcerts.sh rid-cert.der rsa-pub-2048.pem rsa2048.der rsa3072.der server-cert-chain.der server-cert.der server-cert.pem server-ecc-comp.der server-ecc-comp.pem server-ecc-rsa.der server-ecc-rsa.pem server-ecc-self.der server-ecc-self.pem server-ecc.der server-ecc.pem server-ecc384-cert.der server-ecc384-cert.pem server-ecc384-key.der server-ecc384-key.pem server-key.der server-key.pem server-keyEnc.pem server-keyPkcs8.der server-keyPkcs8.pem server-keyPkcs8Enc.der server-keyPkcs8Enc.pem server-keyPkcs8Enc12.pem server-keyPkcs8Enc2.pem server-keyPub.der server-keyPub.pem server-revoked-cert.pem server-revoked-key.pem taoCert.txt test-ber-exp02-05-2022.p7b test-degenerate.p7b test-multiple-recipients.p7b test-servercert-rc2.p12 test-servercert.p12 test-stream-dec.p7b test-stream-sign.p7b wolfssl-website-ca.pem x942dh2048.der x942dh2048.pem
cmake
consumer CMakeLists.txt README.md main.c
modules FindARIA.cmake FindOQS.cmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.in
debian
source format
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.in
doc
dox_comments
header_files aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h puf.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wc_she.h wc_slhdsa.h wolfio.h
header_files-ja aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wolfio.h
formats
html
html_changes
search search.css search.js
customdoxygen.css doxygen.css menu.js menudata.js tabs.css
Doxyfile footer.html header.html mainpage.dox
pdf Doxyfile header.tex
images wolfssl_logo.png
QUIC.md README.txt README_DOXYGEN check_api.sh generate_documentation.sh include.am
examples
asn1 asn1.c dumpasn1.cfg gen_oid_names.rb include.am oid_names.h
async Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.h
benchmark include.am tls_bench.c tls_bench.h
client client.c client.h client.sln client.vcproj client.vcxproj include.am
configs README.md include.am user_settings_EBSnet.h user_settings_all.h user_settings_arduino.h user_settings_baremetal.h user_settings_ca.h user_settings_curve25519nonblock.h user_settings_dtls13.h user_settings_eccnonblock.h user_settings_espressif.h user_settings_fipsv2.h user_settings_fipsv5.h user_settings_min_ecc.h user_settings_openssl_compat.h user_settings_pkcs7.h user_settings_platformio.h user_settings_pq.h user_settings_rsa_only.h user_settings_stm32.h user_settings_template.h user_settings_tls12.h user_settings_tls13.h user_settings_wolfboot_keytools.h user_settings_wolfssh.h user_settings_wolftpm.h
crypto_policies
default wolfssl.txt
future wolfssl.txt
legacy wolfssl.txt
echoclient echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quit
echoserver echoserver.c echoserver.h echoserver.sln echoserver.vcproj echoserver.vcxproj include.am
ocsp_responder include.am ocsp_responder.c ocsp_responder.h
pem include.am pem.c
sctp include.am sctp-client-dtls.c sctp-client.c sctp-server-dtls.c sctp-server.c
server include.am server.c server.h server.sln server.vcproj server.vcxproj
README.md include.am
linuxkm
patches
5.10.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch
5.10.236 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch
5.14.0-570.58.1.el9_6 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v14-570v58v1-el9_6.patch
5.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch
5.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch
5.17-ubuntu-jammy-tegra WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17-ubuntu-jammy-tegra.patch
6.1.73 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch
6.12 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch
6.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch
7.0 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-7v0.patch
regen-patches.sh
Kbuild Makefile README.md get_thread_size.c include.am linuxkm-fips-hash-wrapper.sh linuxkm-fips-hash.c linuxkm_memory.c linuxkm_memory.h linuxkm_wc_port.h lkcapi_aes_glue.c lkcapi_dh_glue.c lkcapi_ecdh_glue.c lkcapi_ecdsa_glue.c lkcapi_glue.c lkcapi_rsa_glue.c lkcapi_sha_glue.c module_exports.c.template module_hooks.c pie_redirect_table.c wolfcrypt.lds x86_vector_register_glue.c
m4 ax_add_am_macro.m4 ax_am_jobserver.m4 ax_am_macros.m4 ax_append_compile_flags.m4 ax_append_flag.m4 ax_append_link_flags.m4 ax_append_to_file.m4 ax_atomic.m4 ax_bsdkm.m4 ax_check_compile_flag.m4 ax_check_link_flag.m4 ax_compiler_version.m4 ax_count_cpus.m4 ax_create_generic_config.m4 ax_debug.m4 ax_file_escapes.m4 ax_harden_compiler_flags.m4 ax_linuxkm.m4 ax_print_to_file.m4 ax_pthread.m4 ax_require_defined.m4 ax_tls.m4 ax_vcs_checkout.m4 hexversion.m4 lib_socket_nsl.m4 visibility.m4
mcapi
wolfcrypt_mcapi.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
zlib.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README crypto.c crypto.h include.am mcapi_test.c user_settings.h
mplabx
wolfcrypt_benchmark.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README benchmark_main.c include.am test_main.c user_settings.h
mqx
util_lib
Sources include.am util.c util.h
wolfcrypt_benchmark
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfcrypt_test
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfssl include.am
wolfssl_client
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfssl_client_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
README
rpm include.am spec.in
scripts
bench bench_functions.sh
aria-cmake-build-test.sh asn1_oid_sum.pl benchmark.test benchmark_compare.sh cleanup_testfiles.sh crl-gen-openssl.test crl-revoked.test dertoc.pl dtls.test dtlscid.test external.test google.test include.am makedistsmall.sh memtest.sh ocsp-responder-openssl-interop.test ocsp-stapling-with-ca-as-responder.test ocsp-stapling-with-wolfssl-responder.test ocsp-stapling.test ocsp-stapling2.test ocsp-stapling_tls13multi.test ocsp.test openssl.test openssl_srtp.test pem.test ping.test pkcallbacks.test psk.test resume.test rsapss.test sniffer-gen.sh sniffer-ipv6.pcap sniffer-static-rsa.pcap sniffer-testsuite.test sniffer-tls12-keylog.out sniffer-tls12-keylog.pcap sniffer-tls12-keylog.sslkeylog sniffer-tls13-dh-resume.pcap sniffer-tls13-dh.pcap sniffer-tls13-ecc-resume.pcap sniffer-tls13-ecc.pcap sniffer-tls13-hrr.pcap sniffer-tls13-keylog.out sniffer-tls13-keylog.pcap sniffer-tls13-keylog.sslkeylog sniffer-tls13-x25519-resume.pcap sniffer-tls13-x25519.pcap stm32l4-v4_0_1_build.sh tls13.test trusted_peer.test unit.test.in user_settings_asm.sh
src bio.c conf.c crl.c dtls.c dtls13.c include.am internal.c keys.c ocsp.c pk.c pk_ec.c pk_rsa.c quic.c sniffer.c ssl.c ssl_api_cert.c ssl_api_crl_ocsp.c ssl_api_pk.c ssl_asn1.c ssl_bn.c ssl_certman.c ssl_crypto.c ssl_ech.c ssl_load.c ssl_misc.c ssl_p7p12.c ssl_sess.c ssl_sk.c tls.c tls13.c wolfio.c x509.c x509_str.c
sslSniffer
sslSnifferTest README_WIN.md include.am snifftest.c sslSniffTest.vcproj sslSniffTest.vcxproj
README.md sslSniffer.vcproj sslSniffer.vcxproj
support gen-debug-trace-error-codes.sh include.am wolfssl.pc.in
tests
api api.h api_decl.h create_ocsp_test_blobs.py include.am test_aes.c test_aes.h test_arc4.c test_arc4.h test_ascon.c test_ascon.h test_ascon_kats.h test_asn.c test_asn.h test_blake2.c test_blake2.h test_camellia.c test_camellia.h test_certman.c test_certman.h test_chacha.c test_chacha.h test_chacha20_poly1305.c test_chacha20_poly1305.h test_cmac.c test_cmac.h test_curve25519.c test_curve25519.h test_curve448.c test_curve448.h test_des3.c test_des3.h test_dh.c test_dh.h test_digest.h test_dsa.c test_dsa.h test_dtls.c test_dtls.h test_ecc.c test_ecc.h test_ed25519.c test_ed25519.h test_ed448.c test_ed448.h test_evp.c test_evp.h test_evp_cipher.c test_evp_cipher.h test_evp_digest.c test_evp_digest.h test_evp_pkey.c test_evp_pkey.h test_hash.c test_hash.h test_hmac.c test_hmac.h test_md2.c test_md2.h test_md4.c test_md4.h test_md5.c test_md5.h test_mldsa.c test_mldsa.h test_mlkem.c test_mlkem.h test_ocsp.c test_ocsp.h test_ocsp_test_blobs.h test_ossl_asn1.c test_ossl_asn1.h test_ossl_bio.c test_ossl_bio.h test_ossl_bn.c test_ossl_bn.h test_ossl_cipher.c test_ossl_cipher.h test_ossl_dgst.c test_ossl_dgst.h test_ossl_dh.c test_ossl_dh.h test_ossl_dsa.c test_ossl_dsa.h test_ossl_ec.c test_ossl_ec.h test_ossl_ecx.c test_ossl_ecx.h test_ossl_mac.c test_ossl_mac.h test_ossl_obj.c test_ossl_obj.h test_ossl_p7p12.c test_ossl_p7p12.h test_ossl_pem.c test_ossl_pem.h test_ossl_rand.c test_ossl_rand.h test_ossl_rsa.c test_ossl_rsa.h test_ossl_sk.c test_ossl_sk.h test_ossl_x509.c test_ossl_x509.h test_ossl_x509_acert.c test_ossl_x509_acert.h test_ossl_x509_crypto.c test_ossl_x509_crypto.h test_ossl_x509_ext.c test_ossl_x509_ext.h test_ossl_x509_info.c test_ossl_x509_info.h test_ossl_x509_io.c test_ossl_x509_io.h test_ossl_x509_lu.c test_ossl_x509_lu.h test_ossl_x509_name.c test_ossl_x509_name.h test_ossl_x509_pk.c test_ossl_x509_pk.h test_ossl_x509_str.c test_ossl_x509_str.h test_ossl_x509_vp.c test_ossl_x509_vp.h test_pkcs12.c test_pkcs12.h test_pkcs7.c test_pkcs7.h test_poly1305.c test_poly1305.h test_random.c test_random.h test_rc2.c test_rc2.h test_ripemd.c test_ripemd.h test_rsa.c test_rsa.h test_sha.c test_sha.h test_sha256.c test_sha256.h test_sha3.c test_sha3.h test_sha512.c test_sha512.h test_she.c test_she.h test_signature.c test_signature.h test_slhdsa.c test_slhdsa.h test_sm2.c test_sm2.h test_sm3.c test_sm3.h test_sm4.c test_sm4.h test_tls.c test_tls.h test_tls13.c test_tls13.h test_tls_ext.c test_tls_ext.h test_wc_encrypt.c test_wc_encrypt.h test_wolfmath.c test_wolfmath.h test_x509.c test_x509.h
emnet
IP IP.h
Makefile emnet_nonblock_test.c emnet_shim.c
freertos-mem-track-repro FreeRTOS.h repro.c run.sh semphr.h task.h user_settings.h
swdev .gitignore Makefile README.md swdev.c swdev.h swdev_loader.c swdev_loader.h user_settings.h
CONF_FILES_README.md NCONF_test.cnf README TXT_DB.txt api.c include.am quic.c srp.c suites.c test-altchains.conf test-chains.conf test-dhprime.conf test-dtls-downgrade.conf test-dtls-fails-cipher.conf test-dtls-fails.conf test-dtls-group.conf test-dtls-mtu.conf test-dtls-reneg-client.conf test-dtls-reneg-server.conf test-dtls-resume.conf test-dtls-sha2.conf test-dtls-srtp-fails.conf test-dtls-srtp.conf test-dtls.conf test-dtls13-cid.conf test-dtls13-downgrade-fails.conf test-dtls13-downgrade.conf test-dtls13-pq-hybrid-extra-frag.conf test-dtls13-pq-hybrid-extra.conf test-dtls13-pq-hybrid-frag.conf test-dtls13-pq-standalone-frag.conf test-dtls13-pq-standalone.conf test-dtls13-psk.conf test-dtls13.conf test-ecc-cust-curves.conf test-ed25519.conf test-ed448.conf test-enckeys.conf test-fails.conf test-maxfrag-dtls.conf test-maxfrag.conf test-p521.conf test-psk-no-id-sha2.conf test-psk-no-id.conf test-psk.conf test-rsapss.conf test-sctp-sha2.conf test-sctp.conf test-sha2.conf test-sig.conf test-sm2.conf test-tls-downgrade.conf test-tls13-down.conf test-tls13-ecc.conf test-tls13-pq-hybrid-extra.conf test-tls13-pq-hybrid.conf test-tls13-pq-standalone.conf test-tls13-psk-certs.conf test-tls13-psk.conf test-tls13-slhdsa-fail.conf test-tls13-slhdsa-sha2.conf test-tls13-slhdsa-shake.conf test-tls13.conf test-trustpeer.conf test.conf unit.c unit.h utils.c utils.h w64wrapper.c
testsuite include.am testsuite.c testsuite.sln testsuite.vcproj testsuite.vcxproj utils.c utils.h
tirtos
packages
ti
net
wolfssl
tests
EK_TM4C1294XL
wolfcrypt
benchmark TM4C1294NC.icf benchmark.cfg main.c package.bld.hide package.xdc
test TM4C1294NC.icf main.c package.bld.hide package.xdc test.cfg
package.bld package.xdc package.xs
.gitignore README include.am products.mak wolfssl.bld wolfssl.mak
wolfcrypt
benchmark README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.am
src
port
Espressif
esp_crt_bundle README.md cacrt_all.pem cacrt_deprecated.pem cacrt_local.pem esp_crt_bundle.c gen_crt_bundle.py pio_install_cryptography.py
README.md esp32_aes.c esp32_mp.c esp32_sha.c esp32_util.c esp_sdk_mem_lib.c esp_sdk_time_lib.c esp_sdk_wifi_lib.c
Renesas README.md renesas_common.c renesas_fspsm_aes.c renesas_fspsm_rsa.c renesas_fspsm_sha.c renesas_fspsm_util.c renesas_rx64_hw_sha.c renesas_rx64_hw_util.c renesas_tsip_aes.c renesas_tsip_rsa.c renesas_tsip_sha.c renesas_tsip_util.c
af_alg afalg_aes.c afalg_hash.c wc_afalg.c
aria aria-crypt.c aria-cryptocb.c
arm armv8-32-aes-asm.S armv8-32-aes-asm_c.c armv8-32-chacha-asm.S armv8-32-chacha-asm_c.c armv8-32-curve25519.S armv8-32-curve25519_c.c armv8-32-mlkem-asm.S armv8-32-mlkem-asm_c.c armv8-32-poly1305-asm.S armv8-32-poly1305-asm_c.c armv8-32-sha256-asm.S armv8-32-sha256-asm_c.c armv8-32-sha3-asm.S armv8-32-sha3-asm_c.c armv8-32-sha512-asm.S armv8-32-sha512-asm_c.c armv8-aes-asm.S armv8-aes-asm_c.c armv8-aes.c armv8-chacha-asm.S armv8-chacha-asm_c.c armv8-curve25519.S armv8-curve25519_c.c armv8-mlkem-asm.S armv8-mlkem-asm_c.c armv8-poly1305-asm.S armv8-poly1305-asm_c.c armv8-sha256-asm.S armv8-sha256-asm_c.c armv8-sha256.c armv8-sha3-asm.S armv8-sha3-asm_c.c armv8-sha512-asm.S armv8-sha512-asm_c.c armv8-sha512.c cryptoCell.c cryptoCellHash.c thumb2-aes-asm.S thumb2-aes-asm_c.c thumb2-chacha-asm.S thumb2-chacha-asm_c.c thumb2-curve25519.S thumb2-curve25519_c.c thumb2-mlkem-asm.S thumb2-mlkem-asm_c.c thumb2-poly1305-asm.S thumb2-poly1305-asm_c.c thumb2-sha256-asm.S thumb2-sha256-asm_c.c thumb2-sha3-asm.S thumb2-sha3-asm_c.c thumb2-sha512-asm.S thumb2-sha512-asm_c.c
atmel README.md atmel.c
autosar README.md cryif.c crypto.c csm.c include.am test.c
caam README.md caam_aes.c caam_doc.pdf caam_driver.c caam_error.c caam_integrity.c caam_qnx.c caam_sha.c wolfcaam_aes.c wolfcaam_cmac.c wolfcaam_ecdsa.c wolfcaam_fsl_nxp.c wolfcaam_hash.c wolfcaam_hmac.c wolfcaam_init.c wolfcaam_qnx.c wolfcaam_rsa.c wolfcaam_seco.c wolfcaam_x25519.c
cavium README.md README_Octeon.md cavium_nitrox.c cavium_octeon_sync.c
cuda README.md aes-cuda.cu
cypress README.md psoc6_crypto.c
devcrypto README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.c
intel README.md quickassist.c quickassist_mem.c quickassist_sync.c
iotsafe iotsafe.c
kcapi README.md kcapi_aes.c kcapi_dh.c kcapi_ecc.c kcapi_hash.c kcapi_hmac.c kcapi_rsa.c
liboqs liboqs.c
maxim README.md max3266x.c maxq10xx.c
mynewt mynewt_port.c
nxp README.md README_SE050.md casper_port.c dcp_port.c hashcrypt_port.c ksdk_port.c se050_port.c
pic32 pic32mz-crypt.c
ppc32 ppc32-sha256-asm.S ppc32-sha256-asm_c.c ppc32-sha256-asm_cr.c
psa README.md psa.c psa_aes.c psa_hash.c psa_pkcbs.c
riscv riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.c
rpi_pico README.md pico.c
silabs README.md silabs_aes.c silabs_ecc.c silabs_hash.c silabs_random.c
st README.md STM32MP13.md STM32MP25.md stm32.c stsafe.c
ti ti-aes.c ti-ccm.c ti-des3.c ti-hash.c
tropicsquare README.md tropic01.c
xilinx xil-aesgcm.c xil-sha3.c xil-versal-glue.c xil-versal-trng.c
nrf51.c
ASN_TEMPLATE.md aes.c aes_asm.S aes_asm.asm aes_gcm_asm.S aes_gcm_asm.asm aes_gcm_x86_asm.S aes_xts_asm.S aes_xts_asm.asm arc4.c ascon.c asm.c asn.c asn_orig.c async.c blake2b.c blake2s.c camellia.c chacha.c chacha20_poly1305.c chacha_asm.S chacha_asm.asm cmac.c coding.c compress.c cpuid.c cryptocb.c curve25519.c curve448.c des3.c dh.c dilithium.c dsa.c ecc.c ecc_fp.c eccsi.c ed25519.c ed448.c error.c evp.c evp_pk.c falcon.c fe_448.c fe_low_mem.c fe_operations.c fe_x25519_128.h fe_x25519_asm.S fp_mont_small.i fp_mul_comba_12.i fp_mul_comba_17.i fp_mul_comba_20.i fp_mul_comba_24.i fp_mul_comba_28.i fp_mul_comba_3.i fp_mul_comba_32.i fp_mul_comba_4.i fp_mul_comba_48.i fp_mul_comba_6.i fp_mul_comba_64.i fp_mul_comba_7.i fp_mul_comba_8.i fp_mul_comba_9.i fp_mul_comba_small_set.i fp_sqr_comba_12.i fp_sqr_comba_17.i fp_sqr_comba_20.i fp_sqr_comba_24.i fp_sqr_comba_28.i fp_sqr_comba_3.i fp_sqr_comba_32.i fp_sqr_comba_4.i fp_sqr_comba_48.i fp_sqr_comba_6.i fp_sqr_comba_64.i fp_sqr_comba_7.i fp_sqr_comba_8.i fp_sqr_comba_9.i fp_sqr_comba_small_set.i ge_448.c ge_low_mem.c ge_operations.c hash.c hmac.c hpke.c include.am integer.c kdf.c logging.c md2.c md4.c md5.c memory.c misc.c pkcs12.c pkcs7.c poly1305.c poly1305_asm.S poly1305_asm.asm puf.c pwdbased.c random.c rc2.c ripemd.c rng_bank.c rsa.c sakke.c sha.c sha256.c sha256_asm.S sha3.c sha3_asm.S sha512.c sha512_asm.S signature.c siphash.c sm2.c sm3.c sm3_asm.S sm4.c sp_arm32.c sp_arm64.c sp_armthumb.c sp_c32.c sp_c64.c sp_cortexm.c sp_dsp32.c sp_int.c sp_sm2_arm32.c sp_sm2_arm64.c sp_sm2_armthumb.c sp_sm2_c32.c sp_sm2_c64.c sp_sm2_cortexm.c sp_sm2_x86_64.c sp_sm2_x86_64_asm.S sp_x86_64.c sp_x86_64_asm.S sp_x86_64_asm.asm srp.c tfm.c wc_dsp.c wc_encrypt.c wc_lms.c wc_lms_impl.c wc_mldsa_asm.S wc_mlkem.c wc_mlkem_asm.S wc_mlkem_poly.c wc_pkcs11.c wc_port.c wc_she.c wc_slhdsa.c wc_xmss.c wc_xmss_impl.c wolfentropy.c wolfevent.c wolfmath.c
test README.md include.am test-VS2022.sln test-VS2022.vcxproj test-VS2022.vcxproj.user test.c test.h test.sln test.vcproj test_paths.h.in
wolfssl
openssl aes.h asn1.h asn1t.h bio.h bn.h buffer.h camellia.h cmac.h cms.h compat_types.h conf.h crypto.h des.h dh.h dsa.h ec.h ec25519.h ec448.h ecdh.h ecdsa.h ed25519.h ed448.h engine.h err.h evp.h fips_rand.h hmac.h include.am kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pkcs12.h pkcs7.h rand.h rc4.h ripemd.h rsa.h safestack.h sha.h sha3.h srp.h ssl.h ssl23.h stack.h tls1.h txt_db.h ui.h x509.h x509_vfy.h x509v3.h
wolfcrypt
port
Espressif esp-sdk-lib.h esp32-crypt.h esp_crt_bundle.h
Renesas renesas-fspsm-crypt.h renesas-fspsm-types.h renesas-rx64-hw-crypt.h renesas-tsip-crypt.h renesas_cmn.h renesas_fspsm_internal.h renesas_sync.h renesas_tsip_internal.h renesas_tsip_types.h
af_alg afalg_hash.h wc_afalg.h
aria aria-crypt.h aria-cryptocb.h
arm cryptoCell.h
atmel atmel.h
autosar CryIf.h Crypto.h Csm.h StandardTypes.h
caam caam_driver.h caam_error.h caam_qnx.h wolfcaam.h wolfcaam_aes.h wolfcaam_cmac.h wolfcaam_ecdsa.h wolfcaam_fsl_nxp.h wolfcaam_hash.h wolfcaam_qnx.h wolfcaam_rsa.h wolfcaam_seco.h wolfcaam_sha.h wolfcaam_x25519.h
cavium cavium_nitrox.h cavium_octeon_sync.h
cypress psoc6_crypto.h
devcrypto wc_devcrypto.h
intel quickassist.h quickassist_mem.h quickassist_sync.h
iotsafe iotsafe.h
kcapi kcapi_dh.h kcapi_ecc.h kcapi_hash.h kcapi_hmac.h kcapi_rsa.h wc_kcapi.h
liboqs liboqs.h
maxim max3266x-cryptocb.h max3266x.h maxq10xx.h
nxp casper_port.h dcp_port.h hashcrypt_port.h ksdk_port.h se050_port.h
pic32 pic32mz-crypt.h
psa psa.h
riscv riscv-64-asm.h
rpi_pico pico.h
silabs silabs_aes.h silabs_ecc.h silabs_hash.h silabs_random.h
st stm32.h stsafe.h
ti ti-ccm.h ti-hash.h
tropicsquare tropic01.h
xilinx xil-sha3.h xil-versal-glue.h xil-versal-trng.h
nrf51.h
aes.h arc4.h ascon.h asn.h asn_public.h async.h blake2-impl.h blake2-int.h blake2.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cpuid.h cryptocb.h curve25519.h curve448.h des3.h dh.h dilithium.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h falcon.h fe_448.h fe_operations.h fips_test.h ge_448.h ge_operations.h hash.h hmac.h hpke.h include.am integer.h kdf.h libwolfssl_sources.h libwolfssl_sources_asm.h logging.h md2.h md4.h md5.h mem_track.h memory.h misc.h mpi_class.h mpi_superclass.h oid_sum.h pkcs11.h pkcs12.h pkcs7.h poly1305.h puf.h pwdbased.h random.h rc2.h ripemd.h rng_bank.h rsa.h sakke.h selftest.h settings.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h sm2.h sm3.h sm4.h sp.h sp_int.h srp.h tfm.h types.h visibility.h wc_encrypt.h wc_lms.h wc_mlkem.h wc_pkcs11.h wc_port.h wc_she.h wc_slhdsa.h wc_xmss.h wolfentropy.h wolfevent.h wolfmath.h
callbacks.h certs_test.h certs_test_sm.h crl.h error-ssl.h include.am internal.h ocsp.h options.h.in quic.h sniffer.h sniffer_error.h sniffer_error.rc ssl.h test.h version.h version.h.in wolfio.h
wrapper
Ada
examples
src aes_verify_main.adb rsa_verify_main.adb sha256_main.adb spark_sockets.adb spark_sockets.ads spark_terminal.adb spark_terminal.ads tls_client.adb tls_client.ads tls_client_main.adb tls_server.adb tls_server.ads tls_server_main.adb
.gitignore alire.toml examples.gpr
tests
src
support test_support.adb test_support.ads tests_root_suite.adb tests_root_suite.ads
aes_bindings_tests.adb aes_bindings_tests.ads rsa_verify_bindings_tests.adb rsa_verify_bindings_tests.ads sha256_bindings_tests.adb sha256_bindings_tests.ads tests.adb
.gitignore README.md alire.toml tests.gpr valgrind.supp
.gitignore README.md ada_binding.c alire.toml default.gpr include.am restricted.adc user_settings.h wolfssl-full_runtime.adb wolfssl-full_runtime.ads wolfssl.adb wolfssl.ads wolfssl.gpr
CSharp
wolfCrypt-Test
Properties AssemblyInfo.cs
App.config wolfCrypt-Test.cs wolfCrypt-Test.csproj
wolfSSL-DTLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-PSK-Server.cs wolfSSL-DTLS-PSK-Server.csproj
wolfSSL-DTLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-Server.cs wolfSSL-DTLS-Server.csproj
wolfSSL-Example-IOCallbacks
Properties AssemblyInfo.cs
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csproj
wolfSSL-TLS-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Client.cs wolfSSL-TLS-Client.csproj
wolfSSL-TLS-PSK-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Client.cs wolfSSL-TLS-PSK-Client.csproj
wolfSSL-TLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Server.cs wolfSSL-TLS-PSK-Server.csproj
wolfSSL-TLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Server.cs wolfSSL-TLS-Server.csproj
wolfSSL-TLS-ServerThreaded
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csproj
wolfSSL_CSharp
Properties AssemblyInfo.cs Resources.Designer.cs Resources.resx
X509.cs wolfCrypt.cs wolfSSL.cs wolfSSL_CSharp.csproj
README.md include.am user_settings.h wolfSSL_CSharp.sln wolfssl.vcxproj
python README.md
rust
wolfssl-wolfcrypt
src aes.rs blake2.rs chacha20_poly1305.rs cmac.rs cmac_mac.rs curve25519.rs dh.rs dilithium.rs ecc.rs ecdsa.rs ed25519.rs ed448.rs fips.rs hkdf.rs hmac.rs hmac_mac.rs kdf.rs lib.rs lms.rs mlkem.rs mlkem_kem.rs pbkdf2_password_hash.rs prf.rs random.rs rsa.rs rsa_pkcs1v15.rs sha.rs sha_digest.rs sys.rs
tests
common mod.rs
test_aes.rs test_blake2.rs test_chacha20_poly1305.rs test_cmac.rs test_cmac_mac.rs test_curve25519.rs test_dh.rs test_dilithium.rs test_ecc.rs test_ecdsa.rs test_ed25519.rs test_ed448.rs test_hkdf.rs test_hmac.rs test_hmac_mac.rs test_kdf.rs test_lms.rs test_mlkem.rs test_mlkem_kem.rs test_pbkdf2_password_hash.rs test_prf.rs test_random.rs test_rsa.rs test_rsa_pkcs1v15.rs test_sha.rs test_sha_digest.rs test_wolfcrypt.rs
CHANGELOG.md Cargo.lock Cargo.toml Makefile README.md build.rs headers.h
Makefile README.md include.am
include.am
zephyr
samples
wolfssl_benchmark
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_test
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_sock
boards native_sim.conf
src tls_sock.c
CMakeLists.txt README install_sample.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_thread
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
src tls_threaded.c
CMakeLists.txt README install_sample.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl options.h
CMakeLists.txt Kconfig Kconfig.tls-generic README.md include.am module.yml user_settings-no-malloc.h user_settings.h zephyr_init.c
.codespellexcludelines .cyignore .editorconfig .gitignore .wolfssl_known_macro_extras AUTHORS CMakeLists.txt CMakePresets.json CMakeSettings.json COPYING ChangeLog.md INSTALL LICENSING LPCExpresso.cproject LPCExpresso.project Makefile.am README README-async.md README.md SCRIPTS-LIST SECURITY-POLICY.md SECURITY-REPORT-TEMPLATE.md Vagrantfile autogen.sh commit-tests.sh configure.ac fips-check.sh fips-hash.sh gencertbuf.pl input pull_to_vagrant.sh quit resource.h stamp-h.in valgrind-bash.supp valgrind-error.sh wnr-example.conf wolfssl-VS2022.vcxproj wolfssl.rc wolfssl.vcproj wolfssl.vcxproj wolfssl64.sln
.clangd .gitignore DOCS.md Makefile README.md assert.c core.c crypto.c env.c fs.c http.c ini.c json.c log.c luna.h main.c makext.mk path.c process.c request.c sqlite.c stash.c template.c util.c
wolfssl/wolfcrypt/src/asn_orig.c raw
   1/* asn_orig.c
   2 *
   3 * Copyright (C) 2006-2026 wolfSSL Inc.
   4 *
   5 * This file is part of wolfSSL.
   6 *
   7 * wolfSSL is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 3 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * wolfSSL is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20 */
  21
  22/*
  23 * Original (non-template) ASN.1 implementations.
  24 * This file is included from asn.c when building without WOLFSSL_ASN_TEMPLATE.
  25 * It must not be compiled as a separate translation unit.
  26 */
  27
  28#ifdef HAVE_CONFIG_H
  29    #include <config.h>
  30#endif
  31#include <wolfssl/wolfcrypt/settings.h>
  32
  33#ifndef WOLFSSL_ASN_ORIG_INCLUDED
  34    #ifndef WOLFSSL_IGNORE_FILE_WARN
  35        #warning asn_orig.c does not need to be compiled separately from asn.c
  36    #endif
  37#else
  38
  39/* Forward declarations for static functions defined later in this file. */
  40static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx);
  41#ifndef NO_DSA
  42static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap, int ints);
  43#endif
  44#ifndef NO_CERTS
  45static int GetCertHeader(DecodedCert* cert);
  46static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx);
  47static int GetValidity(DecodedCert* cert, int verify, int maxIdx);
  48#endif
  49static word32 SetOctetString8Bit(word32 len, byte* output);
  50static word32 SetDigest(const byte* digest, word32 digSz, byte* output);
  51#ifndef NO_CERTS
  52static void AddAltName(DecodedCert* cert, DNS_entry* dnsEntry);
  53#if defined(WOLFSSL_SEP)
  54static int DecodeSepHwAltName(DecodedCert* cert, const byte* input, word32* idxIn, word32 sz);
  55#endif
  56static int DecodeConstructedOtherName(DecodedCert* cert, const byte* input, word32* idx, word32 sz, int oid);
  57#ifdef WOLFSSL_CERT_GEN
  58#ifdef WOLFSSL_CERT_REQ
  59static word32 SetPrintableString(word32 len, byte* output);
  60static word32 SetUTF8String(word32 len, byte* output);
  61#endif
  62static int CopyValidity(byte* output, Cert* cert);
  63static int SetExtensions(byte* out, word32 outSz, int *IdxInOut, const byte* ext, int extSz);
  64static int SetExtensionsHeader(byte* out, word32 outSz, word32 extSz);
  65static int SetCaWithPathLen(byte* out, word32 outSz, byte pathLen);
  66static int SetCaEx(byte* out, word32 outSz, byte isCa);
  67static int SetCa(byte* out, word32 outSz);
  68static int SetBC(byte* out, word32 outSz);
  69#ifdef WOLFSSL_CERT_EXT
  70static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz, byte *in, word32 inSz);
  71static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length);
  72static int SetAKID(byte* output, word32 outSz, byte *input, word32 length, byte rawAkid);
  73static int SetKeyUsage(byte* output, word32 outSz, word16 input);
  74static int SetOjectIdValue(byte* output, word32 outSz, word32* idx, const byte* oid, word32 oidSz);
  75#ifndef IGNORE_NETSCAPE_CERT_TYPE
  76static int SetNsCertType(Cert* cert, byte* output, word32 outSz, byte input);
  77#endif
  78static int SetCRLInfo(Cert* cert, byte* output, word32 outSz, byte* input, int inSz);
  79#endif
  80#ifdef WOLFSSL_ALT_NAMES
  81static int SetAltNames(byte *output, word32 outSz, const byte *input, word32 length, int critical);
  82#endif
  83#ifdef WOLFSSL_CERT_REQ
  84static word32 SetReqAttribSingle(byte* output, word32* idx, char* attr, word32 attrSz, const byte* oid, word32 oidSz, byte printable, word32 extSz);
  85static int SetReqAttrib(byte* output, Cert* cert, word32 extSz);
  86#ifdef WOLFSSL_CUSTOM_OID
  87static int SetCustomObjectId(Cert* cert, byte* output, word32 outSz, CertOidField* custom);
  88#endif
  89#endif
  90#endif
  91#endif
  92#if defined(HAVE_ECC) || !defined(NO_DSA)
  93static word32 is_leading_bit_set(const byte* input, word32 sz);
  94static word32 trim_leading_zeros(const byte** input, word32 sz);
  95#endif
  96#ifdef HAVE_ECC
  97#ifdef WOLFSSL_CUSTOM_CURVES
  98static int ASNToHexString(const byte* input, word32* inOutIdx, char** out, word32 inSz, void* heap, int heapType);
  99static int EccKeyParamCopy(char** dst, char* src, void* heap);
 100#endif
 101#endif
 102#if (defined(HAVE_OCSP) || defined(HAVE_CRL)) && !defined(WOLFCRYPT_ONLY)
 103static int GetBasicDate(const byte* source, word32* idx, byte* date, byte* format, int maxIdx);
 104#endif
 105#if defined(HAVE_OCSP) && !defined(WOLFCRYPT_ONLY)
 106static int GetEnumerated(const byte* input, word32* inOutIdx, int *value, int sz);
 107#endif
 108
 109int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
 110                                  word32 oidType, word32 maxIdx)
 111{
 112    int ret, length;
 113
 114    WOLFSSL_ENTER("GetObjectId");
 115
 116    ret = GetASNObjectId(input, inOutIdx, &length, maxIdx);
 117    if (ret != 0)
 118        return ret;
 119
 120    return GetOID(input, inOutIdx, oid, oidType, length);
 121}
 122
 123static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
 124{
 125    word32 idx = *inOutIdx;
 126    int    length;
 127    int ret;
 128
 129    ret = GetASNObjectId(input, &idx, &length, maxIdx);
 130    if (ret != 0)
 131        return ret;
 132
 133    idx += (word32)length;
 134    *inOutIdx = idx;
 135
 136    return 0;
 137}
 138
 139static int GetAlgoIdImpl(const byte* input, word32* inOutIdx, word32* oid,
 140                     word32 oidType, word32 maxIdx, byte *absentParams)
 141{
 142    int    length;
 143    word32 idx = *inOutIdx;
 144    int    ret;
 145    *oid = 0;
 146
 147    WOLFSSL_ENTER("GetAlgoId");
 148
 149    if (GetSequence(input, &idx, &length, maxIdx) < 0)
 150        return ASN_PARSE_E;
 151
 152    if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)
 153        return ASN_OBJECT_ID_E;
 154
 155    /* could have NULL tag and 0 terminator, but may not */
 156    if (idx < maxIdx) {
 157        word32 localIdx = idx; /*use localIdx to not advance when checking tag*/
 158        byte   tag;
 159
 160        if (GetASNTag(input, &localIdx, &tag, maxIdx) == 0) {
 161            if (tag == ASN_TAG_NULL) {
 162                ret = GetASNNull(input, &idx, maxIdx);
 163                if (ret != 0)
 164                    return ret;
 165
 166                if (absentParams != NULL) {
 167                    *absentParams = FALSE;
 168                }
 169            }
 170        }
 171    }
 172
 173    *inOutIdx = idx;
 174
 175    return 0;
 176}
 177
 178#ifndef NO_RSA
 179static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
 180    RsaKey* key, int* keySz, word32 inSz)
 181{
 182    int version, length;
 183    word32 algId = 0;
 184    int i;
 185
 186    if (inOutIdx == NULL || input == NULL || (key == NULL && keySz == NULL)) {
 187        return BAD_FUNC_ARG;
 188    }
 189
 190    /* if has pkcs8 header skip it */
 191    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
 192        /* ignore error, did not have pkcs8 header */
 193    }
 194
 195    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 196        return ASN_PARSE_E;
 197
 198    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
 199        return ASN_PARSE_E;
 200
 201    if (key == NULL) {
 202        /* Modulus */
 203        if (GetASNInt(input, inOutIdx, keySz, inSz) < 0) {
 204            return ASN_PARSE_E;
 205        }
 206        *inOutIdx += (word32)*keySz;
 207        for (i = 1; i < RSA_INTS; i++) {
 208            if (SkipInt(input, inOutIdx, inSz) < 0) {
 209                return ASN_RSA_KEY_E;
 210            }
 211        }
 212    }
 213    else {
 214        key->type = RSA_PRIVATE;
 215
 216    #ifdef WOLFSSL_CHECK_MEM_ZERO
 217        mp_memzero_add("Decode RSA key d", &key->d);
 218        mp_memzero_add("Decode RSA key p", &key->p);
 219        mp_memzero_add("Decode RSA key q", &key->q);
 220    #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
 221        !defined(RSA_LOW_MEM)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
 222        mp_memzero_add("Decode RSA key dP", &key->dP);
 223        mp_memzero_add("Decode RSA key dQ", &key->dQ);
 224        mp_memzero_add("Decode RSA key u", &key->u);
 225    #endif
 226    #endif
 227
 228        /* Extract all public fields. */
 229        for (i = 0; i < RSA_INT_CNT; i++) {
 230            if (GetInt(GetRsaInt(key, i),  input, inOutIdx, inSz) < 0) {
 231                for (i--; i >= 0; i--) {
 232                    mp_clear(GetRsaInt(key, i));
 233                }
 234                return ASN_RSA_KEY_E;
 235            }
 236         }
 237    #if RSA_INT_CNT != RSA_MAX_INT_CNT
 238        for (; i < RSA_MAX_INT_CNT; i++) {
 239             if (SkipInt(input, inOutIdx, inSz) < 0) {
 240                for (i = RSA_INT_CNT - 1; i >= 0; i--) {
 241                    mp_clear(GetRsaInt(key, i));
 242                }
 243                return ASN_RSA_KEY_E;
 244            }
 245         }
 246   #endif
 247
 248    #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
 249        if (wc_InitRsaHw(key) != 0) {
 250            return BAD_STATE_E;
 251        }
 252    #endif
 253    }
 254
 255    return 0;
 256}
 257
 258#endif
 259int ToTraditionalInline_ex2(const byte* input, word32* inOutIdx, word32 sz,
 260                            word32* algId, word32* eccOid)
 261{
 262    word32 idx;
 263    int    version, length;
 264    int    ret;
 265    byte   tag;
 266
 267    if (input == NULL || inOutIdx == NULL)
 268        return BAD_FUNC_ARG;
 269
 270    idx = *inOutIdx;
 271
 272    if (GetSequence(input, &idx, &length, sz) < 0)
 273        return ASN_PARSE_E;
 274
 275    if (GetMyVersion(input, &idx, &version, sz) < 0)
 276        return ASN_PARSE_E;
 277
 278    if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
 279        return ASN_PARSE_E;
 280
 281    if (GetASNTag(input, &idx, &tag, sz) < 0)
 282        return ASN_PARSE_E;
 283    idx = idx - 1; /* reset idx after finding tag */
 284
 285#if defined(WC_RSA_PSS) && !defined(NO_RSA)
 286    if (*algId == RSAPSSk && tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
 287        word32 seqIdx = idx;
 288        int seqLen;
 289        /* Not set when -1. */
 290        enum wc_HashType hash = WC_HASH_TYPE_NONE;
 291        int mgf = -1;
 292        int saltLen = 0;
 293
 294        if (GetSequence(input, &idx, &seqLen, sz) < 0) {
 295            return ASN_PARSE_E;
 296        }
 297        /* Get the private key parameters. */
 298        ret = DecodeRsaPssParams(input + seqIdx,
 299            seqLen + idx - seqIdx, &hash, &mgf, &saltLen);
 300        if (ret != 0) {
 301            return ASN_PARSE_E;
 302        }
 303        /* TODO: store parameters so that usage can be checked. */
 304        idx += seqLen;
 305    }
 306#endif /* WC_RSA_PSS && !NO_RSA */
 307
 308    if (tag == ASN_OBJECT_ID) {
 309        if ((*algId == ECDSAk) && (eccOid != NULL)) {
 310            if (GetObjectId(input, &idx, eccOid, oidCurveType, sz) < 0)
 311                return ASN_PARSE_E;
 312        }
 313        else {
 314            if (SkipObjectId(input, &idx, sz) < 0)
 315                return ASN_PARSE_E;
 316        }
 317    }
 318
 319    ret = GetOctetString(input, &idx, &length, sz);
 320    if (ret < 0) {
 321        if (ret == WC_NO_ERR_TRACE(BUFFER_E))
 322            return ASN_PARSE_E;
 323        /* Some private keys don't expect an octet string - ignore error. */
 324        WOLFSSL_MSG("Couldn't find Octet string");
 325        length = 0;
 326    }
 327
 328    *inOutIdx = idx;
 329
 330    return length;
 331}
 332
 333#if defined(HAVE_PKCS8)
 334int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
 335        int algoID, const byte* curveOID, word32 oidSz)
 336{
 337    word32 keyIdx = 0;
 338    word32 tmpSz  = 0;
 339    word32 sz;
 340    word32 tmpAlgId = 0;
 341
 342    /* If out is NULL then return the max size needed
 343     * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
 344    if (out == NULL && outSz != NULL) {
 345        *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
 346                 + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;
 347
 348        if (curveOID != NULL)
 349            *outSz += oidSz + MAX_LENGTH_SZ + 1;
 350
 351        WOLFSSL_MSG("Checking size of PKCS8");
 352
 353        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
 354    }
 355
 356    WOLFSSL_ENTER("wc_CreatePKCS8Key");
 357
 358    if (key == NULL || out == NULL || outSz == NULL) {
 359        return BAD_FUNC_ARG;
 360    }
 361
 362    /* check the buffer has enough room for largest possible size */
 363    if (curveOID != NULL) {
 364        sz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ + MAX_LENGTH_SZ +
 365            MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ;
 366        if ((keySz > sz) || (oidSz > sz) || (*outSz < sz))
 367            return BUFFER_E;
 368    }
 369    else {
 370        oidSz = 0; /* with no curveOID oid size must be 0 */
 371        sz= keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ + MAX_LENGTH_SZ +
 372            MAX_LENGTH_SZ + 2;
 373        if ((keySz > sz) || (*outSz < sz))
 374            return BUFFER_E;
 375    }
 376
 377    /* sanity check: make sure the key doesn't already have a PKCS 8 header */
 378    if (ToTraditionalInline_ex(key, &keyIdx, keySz, &tmpAlgId) >= 0) {
 379        (void)tmpAlgId;
 380        return ASN_PARSE_E;
 381    }
 382
 383    /* PrivateKeyInfo ::= SEQUENCE */
 384    keyIdx = MAX_SEQ_SZ; /* save room for sequence */
 385
 386    /*  version Version
 387     *  no header information just INTEGER */
 388    sz = (word32)SetMyVersion(PKCS8v0, out + keyIdx, 0);
 389    tmpSz += sz; keyIdx += sz;
 390    /*  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */
 391    sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */
 392    if (curveOID != NULL && oidSz > 0) {
 393        byte buf[MAX_LENGTH_SZ];
 394        sz = SetLength(oidSz, buf);
 395        sz += 1; /* plus one for ASN object id */
 396    }
 397    sz = (word32)SetAlgoID(algoID, out + keyIdx, oidKeyType, (int)(oidSz + sz));
 398    tmpSz += sz; keyIdx += sz;
 399
 400    /*  privateKey          PrivateKey *
 401     * pkcs8 ecc uses slightly different format. Places curve oid in
 402     * buffer */
 403    if (curveOID != NULL && oidSz > 0) {
 404        sz = (word32)SetObjectId((int)oidSz, out + keyIdx);
 405        keyIdx += sz; tmpSz += sz;
 406        XMEMCPY(out + keyIdx, curveOID, oidSz);
 407        keyIdx += oidSz; tmpSz += oidSz;
 408    }
 409
 410    sz = (word32)SetOctetString(keySz, out + keyIdx);
 411    keyIdx += sz; tmpSz += sz;
 412    XMEMCPY(out + keyIdx, key, keySz);
 413    tmpSz += keySz;
 414
 415    /*  attributes          optional
 416     * No attributes currently added */
 417
 418    /* rewind and add sequence */
 419    sz = SetSequence(tmpSz, out);
 420    XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
 421
 422    *outSz = tmpSz + sz;
 423    return (int)(tmpSz + sz);
 424}
 425
 426#endif
 427#ifndef NO_PWDBASED
 428#ifdef HAVE_PKCS8
 429int DecryptContent(byte* input, word32 sz, const char* password, int passwordSz)
 430{
 431    word32 inOutIdx = 0, seqEnd, oid, shaOid = 0, seqPkcs5End = sz;
 432    int    ret = 0, first, second, length = 0, version, saltSz, id = 0;
 433    int    iterations = 0, keySz = 0;
 434#ifdef WOLFSSL_SMALL_STACK
 435    byte*  salt = NULL;
 436    byte*  cbcIv = NULL;
 437#else
 438    byte   salt[MAX_SALT_SIZE];
 439    byte   cbcIv[MAX_IV_SIZE];
 440#endif
 441    byte   tag;
 442
 443    if (passwordSz < 0) {
 444        WOLFSSL_MSG("Bad password size");
 445        return BAD_FUNC_ARG;
 446    }
 447
 448    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
 449        ERROR_OUT(ASN_PARSE_E, exit_dc);
 450    }
 451
 452    first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
 453    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
 454
 455    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
 456        ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
 457    }
 458
 459    if (version == PKCS5v2) {
 460        if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
 461            ERROR_OUT(ASN_PARSE_E, exit_dc);
 462        }
 463        seqPkcs5End = inOutIdx + length;
 464
 465        if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
 466            ERROR_OUT(ASN_PARSE_E, exit_dc);
 467        }
 468
 469        if (oid != PBKDF2_OID) {
 470            ERROR_OUT(ASN_PARSE_E, exit_dc);
 471        }
 472    }
 473
 474    if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
 475        ERROR_OUT(ASN_PARSE_E, exit_dc);
 476    }
 477    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
 478     * DEFAULT items. */
 479    seqEnd = inOutIdx + (word32)length;
 480
 481    ret = GetOctetString(input, &inOutIdx, &saltSz, seqEnd);
 482    if (ret < 0)
 483        goto exit_dc;
 484
 485    if (saltSz > MAX_SALT_SIZE) {
 486        ERROR_OUT(ASN_PARSE_E, exit_dc);
 487    }
 488
 489    WC_ALLOC_VAR_EX(salt, byte, MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER,
 490        ERROR_OUT(MEMORY_E,exit_dc));
 491
 492    XMEMCPY(salt, &input[inOutIdx], (size_t)saltSz);
 493    inOutIdx += (word32)saltSz;
 494
 495    if (GetShortInt(input, &inOutIdx, &iterations, seqEnd) < 0) {
 496        ERROR_OUT(ASN_PARSE_E, exit_dc);
 497    }
 498
 499    /* OPTIONAL key length */
 500    if (seqEnd > inOutIdx) {
 501        word32 localIdx = inOutIdx;
 502
 503        if (GetASNTag(input, &localIdx, &tag, seqEnd) < 0) {
 504            ERROR_OUT(ASN_PARSE_E, exit_dc);
 505        }
 506
 507        if (tag == ASN_INTEGER &&
 508                GetShortInt(input, &inOutIdx, &keySz, seqEnd) < 0) {
 509            ERROR_OUT(ASN_PARSE_E, exit_dc);
 510        }
 511    }
 512
 513    /* DEFAULT HMAC is SHA-1 */
 514    if (seqEnd > inOutIdx) {
 515        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, seqEnd) < 0) {
 516            ERROR_OUT(ASN_PARSE_E, exit_dc);
 517        }
 518
 519        shaOid = oid;
 520    }
 521
 522    WC_ALLOC_VAR_EX(cbcIv, byte, MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER,
 523        ERROR_OUT(MEMORY_E,exit_dc));
 524
 525    if (version == PKCS5v2) {
 526        /* get encryption algo */
 527        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, seqPkcs5End) < 0) {
 528            ERROR_OUT(ASN_PARSE_E, exit_dc);
 529        }
 530
 531        if (CheckAlgoV2((int)oid, &id, NULL) < 0) {
 532            ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
 533        }
 534
 535        if (shaOid == 0)
 536            shaOid = oid;
 537
 538        ret = GetOctetString(input, &inOutIdx, &length, seqPkcs5End);
 539        if (ret < 0)
 540            goto exit_dc;
 541
 542        if (length > MAX_IV_SIZE) {
 543            ERROR_OUT(ASN_PARSE_E, exit_dc);
 544        }
 545
 546        XMEMCPY(cbcIv, &input[inOutIdx], (size_t)length);
 547        inOutIdx += (word32)length;
 548    }
 549
 550    if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) {
 551        ERROR_OUT(ASN_PARSE_E, exit_dc);
 552    }
 553
 554    if (tag != (ASN_CONTEXT_SPECIFIC | 0) && tag != ASN_OCTET_STRING) {
 555        ERROR_OUT(ASN_PARSE_E, exit_dc);
 556    }
 557
 558    if (GetLength(input, &inOutIdx, &length, sz) < 0) {
 559        ERROR_OUT(ASN_PARSE_E, exit_dc);
 560    }
 561
 562    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
 563                   input + inOutIdx, length, version, cbcIv, 0, (int)shaOid);
 564
 565exit_dc:
 566    WC_FREE_VAR_EX(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 567    WC_FREE_VAR_EX(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 568
 569    if (ret == 0) {
 570        XMEMMOVE(input, input + inOutIdx, (size_t)length);
 571        ret = length;
 572    }
 573
 574    return ret;
 575}
 576
 577#endif
 578#ifdef HAVE_PKCS12
 579int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
 580        const char* password, int passwordSz, int vPKCS, int vAlgo,
 581        int encAlgId, byte* salt, word32 saltSz, int itt, int hmacOid,
 582        WC_RNG* rng, void* heap)
 583{
 584    word32 sz;
 585    word32 inOutIdx = 0;
 586    word32 tmpIdx   = 0;
 587    word32 totalSz  = 0;
 588    word32 seqSz;
 589    word32 innerSz;
 590    int    ret;
 591    int    version, id = PBE_NONE, blockSz = 0;
 592#ifdef WOLFSSL_SMALL_STACK
 593    byte*  saltTmp = NULL;
 594    byte*  cbcIv   = NULL;
 595#else
 596    byte   saltTmp[MAX_SALT_SIZE];
 597    byte   cbcIv[MAX_IV_SIZE];
 598#endif
 599    byte   seq[MAX_SEQ_SZ];
 600    byte   shr[MAX_SHORT_SZ];
 601    word32 maxShr = MAX_SHORT_SZ;
 602    word32 algoSz;
 603    const  byte* algoName;
 604
 605    (void)encAlgId;
 606    (void)hmacOid;
 607    (void)heap;
 608
 609    (void)EncryptContentPBES2;
 610
 611    WOLFSSL_ENTER("EncryptContent");
 612
 613    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0)
 614        return ASN_INPUT_E;  /* Algo ID error */
 615
 616    if (version == PKCS5v2) {
 617        WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
 618        return BAD_FUNC_ARG;
 619    }
 620
 621    if (saltSz > MAX_SALT_SIZE)
 622        return ASN_PARSE_E;
 623
 624    if (outSz == NULL) {
 625        return BAD_FUNC_ARG;
 626    }
 627
 628    /* calculate size */
 629    /* size of constructed string at end */
 630    sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz);
 631    totalSz  = ASN_TAG_SZ;
 632    totalSz += SetLength(sz, seq);
 633    totalSz += sz;
 634
 635    /* size of sequence holding object id and sub sequence of salt and itt */
 636    algoName = OidFromId((word32)id, oidPBEType, &algoSz);
 637    if (algoName == NULL) {
 638        WOLFSSL_MSG("Unknown Algorithm");
 639        return 0;
 640    }
 641    innerSz = (word32)SetObjectId((int)algoSz, seq);
 642    innerSz += algoSz;
 643
 644    /* get subsequence of salt and itt */
 645    if (salt == NULL || saltSz == 0) {
 646        sz = 8;
 647    }
 648    else {
 649        sz = saltSz;
 650    }
 651    seqSz  = SetOctetString(sz, seq);
 652    seqSz += sz;
 653
 654    tmpIdx = 0;
 655    ret = SetShortInt(shr, &tmpIdx, (word32)itt, maxShr);
 656    if (ret >= 0) {
 657        seqSz += (word32)ret;
 658    }
 659    else {
 660        return ret;
 661    }
 662    innerSz += seqSz + SetSequence(seqSz, seq);
 663    totalSz += innerSz + SetSequence(innerSz, seq);
 664
 665    if (out == NULL) {
 666        *outSz = totalSz;
 667        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
 668    }
 669
 670    inOutIdx = 0;
 671    if (totalSz > *outSz)
 672        return BUFFER_E;
 673
 674    inOutIdx += SetSequence(innerSz, out + inOutIdx);
 675    inOutIdx += (word32)SetObjectId((int)algoSz, out + inOutIdx);
 676    XMEMCPY(out + inOutIdx, algoName, algoSz);
 677    inOutIdx += algoSz;
 678    inOutIdx += SetSequence(seqSz, out + inOutIdx);
 679
 680    /* create random salt if one not provided */
 681    if (salt == NULL || saltSz == 0) {
 682        saltSz = 8;
 683        WC_ALLOC_VAR_EX(saltTmp, byte, saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER,
 684            return MEMORY_E);
 685        salt = saltTmp;
 686
 687        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
 688            WOLFSSL_MSG("Error generating random salt");
 689            WC_FREE_VAR_EX(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
 690            return ret;
 691        }
 692    }
 693    inOutIdx += SetOctetString(saltSz, out + inOutIdx);
 694    if (saltSz + inOutIdx > *outSz) {
 695        WC_FREE_VAR_EX(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
 696        return BUFFER_E;
 697    }
 698    XMEMCPY(out + inOutIdx, salt, saltSz);
 699    inOutIdx += saltSz;
 700
 701    /* place iteration setting in buffer */
 702    ret = SetShortInt(out, &inOutIdx, (word32)itt, *outSz);
 703    if (ret < 0) {
 704        WC_FREE_VAR_EX(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
 705        return ret;
 706    }
 707
 708    if (inOutIdx + 1 > *outSz) {
 709        WC_FREE_VAR_EX(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
 710        return BUFFER_E;
 711    }
 712    out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0;
 713
 714    /* get pad size and verify buffer room */
 715    sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz);
 716    if (sz + inOutIdx > *outSz) {
 717        WC_FREE_VAR_EX(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
 718        return BUFFER_E;
 719    }
 720    inOutIdx += SetLength(sz, out + inOutIdx);
 721
 722    /* copy input to output buffer and pad end */
 723    XMEMCPY(out + inOutIdx, input, inputSz);
 724    sz = wc_PkcsPad(out + inOutIdx, inputSz, (word32)blockSz);
 725#ifdef WOLFSSL_SMALL_STACK
 726    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
 727    if (cbcIv == NULL) {
 728        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
 729        return MEMORY_E;
 730    }
 731#endif
 732
 733    /* encrypt */
 734    if ((ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, id,
 735                   out + inOutIdx, (int)sz, version, cbcIv, 1, 0)) < 0) {
 736
 737        WC_FREE_VAR_EX(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
 738        WC_FREE_VAR_EX(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
 739        return ret;  /* encrypt failure */
 740    }
 741
 742    WC_FREE_VAR_EX(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
 743    WC_FREE_VAR_EX(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
 744
 745    (void)rng;
 746
 747    return (int)(inOutIdx + sz);
 748}
 749
 750#endif
 751#endif
 752#ifndef NO_RSA
 753#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
 754static int RsaPublicKeyDecodeRawIndex(const byte* input, word32* inOutIdx,
 755                                      word32 inSz, word32* key_n,
 756                                      word32* key_n_len, word32* key_e,
 757                                      word32* key_e_len)
 758{
 759    int ret = 0;
 760    int length = 0;
 761
 762#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
 763    byte b;
 764#endif
 765
 766    if (input == NULL || inOutIdx == NULL)
 767        return BAD_FUNC_ARG;
 768
 769    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 770        return ASN_PARSE_E;
 771
 772#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
 773    if ((*inOutIdx + 1) > inSz)
 774        return BUFFER_E;
 775
 776    b = input[*inOutIdx];
 777    if (b != ASN_INTEGER) {
 778        /* not from decoded cert, will have algo id, skip past */
 779        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 780            return ASN_PARSE_E;
 781
 782        if (SkipObjectId(input, inOutIdx, inSz) < 0)
 783            return ASN_PARSE_E;
 784
 785        /* Option NULL ASN.1 tag */
 786        if (*inOutIdx  >= inSz) {
 787            return BUFFER_E;
 788        }
 789        if (input[*inOutIdx] == ASN_TAG_NULL) {
 790            ret = GetASNNull(input, inOutIdx, inSz);
 791            if (ret != 0)
 792                return ret;
 793        }
 794        /* TODO: support RSA PSS */
 795
 796        /* should have bit tag length and seq next */
 797        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
 798        if (ret != 0)
 799            return ret;
 800
 801        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 802            return ASN_PARSE_E;
 803    }
 804#endif /* OPENSSL_EXTRA */
 805
 806    /* Get modulus */
 807    ret = GetASNInt(input, inOutIdx, &length, inSz);
 808    *key_n += *inOutIdx;
 809    if (ret < 0) {
 810        return ASN_RSA_KEY_E;
 811    }
 812    if (key_n_len)
 813        *key_n_len = length;
 814    *inOutIdx += length;
 815
 816    /* Get exponent */
 817    ret = GetASNInt(input, inOutIdx, &length, inSz);
 818    *key_e += *inOutIdx;
 819    if (ret < 0) {
 820        return ASN_RSA_KEY_E;
 821    }
 822    if (key_e_len)
 823        *key_e_len = length;
 824    return ret;
 825}
 826
 827#endif
 828int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
 829    const byte** n, word32* nSz, const byte** e, word32* eSz)
 830{
 831    int ret = 0;
 832    int length = 0;
 833    int firstLen = 0;
 834    word32 seqEndIdx = inSz;
 835#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
 836    word32 localIdx;
 837    byte   tag;
 838#endif
 839
 840    if (input == NULL || inOutIdx == NULL)
 841        return BAD_FUNC_ARG;
 842
 843    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 844        return ASN_PARSE_E;
 845
 846#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
 847    localIdx = *inOutIdx;
 848    if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
 849        return BUFFER_E;
 850
 851    if (tag != ASN_INTEGER) {
 852        /* not from decoded cert, will have algo id, skip past */
 853        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 854            return ASN_PARSE_E;
 855
 856        if (SkipObjectId(input, inOutIdx, inSz) < 0)
 857            return ASN_PARSE_E;
 858
 859        /* Option NULL ASN.1 tag */
 860        if (*inOutIdx  >= inSz) {
 861            return BUFFER_E;
 862        }
 863
 864        localIdx = *inOutIdx;
 865        if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
 866            return ASN_PARSE_E;
 867
 868        if (tag == ASN_TAG_NULL) {
 869            ret = GetASNNull(input, inOutIdx, inSz);
 870            if (ret != 0)
 871                return ret;
 872        }
 873    #ifdef WC_RSA_PSS
 874        /* Skip RSA PSS parameters. */
 875        else if (tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
 876            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 877                return ASN_PARSE_E;
 878            *inOutIdx += length;
 879        }
 880    #endif
 881
 882        /* should have bit tag length and seq next */
 883        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
 884        if (ret != 0)
 885            return ret;
 886
 887        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 888            return ASN_PARSE_E;
 889
 890        /* Calculate where the sequence should end for public key validation */
 891        seqEndIdx = *inOutIdx + (word32)length;
 892    }
 893#endif /* OPENSSL_EXTRA */
 894
 895    /* Get modulus */
 896    ret = GetASNInt(input, inOutIdx, &firstLen, seqEndIdx);
 897    if (ret < 0) {
 898        return ASN_RSA_KEY_E;
 899    }
 900    if (nSz)
 901        *nSz = (word32)firstLen;
 902    if (n)
 903        *n = &input[*inOutIdx];
 904    *inOutIdx += (word32)firstLen;
 905
 906    /* Get exponent */
 907    ret = GetASNInt(input, inOutIdx, &length, seqEndIdx);
 908    if (ret < 0) {
 909        return ASN_RSA_KEY_E;
 910    }
 911    if (eSz)
 912        *eSz = (word32)length;
 913    if (e)
 914        *e = &input[*inOutIdx];
 915    *inOutIdx += (word32)length;
 916
 917    /* Detect if this is an RSA private key being passed as public key.
 918     * An RSA private key has: version (small), modulus (large), exponent,
 919     * followed by more integers (d, p, q, etc.).
 920     * An RSA public key has: modulus (large), exponent, and nothing more.
 921     * If the first integer is small (like version 0) AND there is more data
 922     * remaining in the sequence, this is likely a private key. */
 923    if (firstLen <= MAX_VERSION_SZ && *inOutIdx < seqEndIdx) {
 924        /* First integer is small and there's more data - looks like
 925         * version field of a private key, not a modulus */
 926        return ASN_RSA_KEY_E;
 927    }
 928
 929    return ret;
 930}
 931
 932#endif
 933#ifndef NO_DH
 934int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
 935{
 936    int ret = 0;
 937    int length;
 938#ifdef WOLFSSL_DH_EXTRA
 939    #if !defined(HAVE_FIPS) || \
 940        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
 941    word32 oid = 0, temp = 0;
 942    #endif
 943#endif
 944
 945    WOLFSSL_ENTER("wc_DhKeyDecode");
 946
 947    if (inOutIdx == NULL)
 948        return BAD_FUNC_ARG;
 949
 950    if (key == NULL)
 951        return BAD_FUNC_ARG;
 952
 953    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 954        return ASN_PARSE_E;
 955
 956#ifdef WOLFSSL_DH_EXTRA
 957    #if !defined(HAVE_FIPS) || \
 958        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
 959    temp = *inOutIdx;
 960    #endif
 961#endif
 962    /* Assume input started after 1.2.840.113549.1.3.1 dhKeyAgreement */
 963    if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
 964        ret = ASN_DH_KEY_E;
 965    }
 966    if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
 967        mp_clear(&key->p);
 968        ret = ASN_DH_KEY_E;
 969    }
 970
 971#ifdef WOLFSSL_DH_EXTRA
 972    #if !defined(HAVE_FIPS) || \
 973        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
 974    /* If ASN_DH_KEY_E: Check if input started at beginning of key */
 975    if (ret == WC_NO_ERR_TRACE(ASN_DH_KEY_E)) {
 976        *inOutIdx = temp;
 977
 978        /* the version (0) - private only (for public skip) */
 979        if (GetASNInt(input, inOutIdx, &length, inSz) == 0) {
 980            *inOutIdx += (word32)length;
 981        }
 982
 983        /* Size of dhKeyAgreement section */
 984        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 985            return ASN_PARSE_E;
 986
 987        /* Check for dhKeyAgreement */
 988        ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
 989        if (oid != DHk || ret < 0)
 990            return ASN_DH_KEY_E;
 991
 992        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
 993            return ASN_PARSE_E;
 994
 995        if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
 996            return ASN_DH_KEY_E;
 997        }
 998        if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
 999            mp_clear(&key->p);
1000            return ASN_DH_KEY_E;
1001        }
1002    }
1003
1004    temp = *inOutIdx;
1005    ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
1006    if (ret > 0) {
1007        /* Found Bit String */
1008        if (GetInt(&key->pub, input, inOutIdx, inSz) == 0) {
1009            WOLFSSL_MSG("Found Public Key");
1010            ret = 0;
1011        }
1012    } else {
1013        *inOutIdx = temp;
1014        ret = (GetOctetString(input, inOutIdx, &length, inSz) >= 0);
1015        if (ret > 0) {
1016            /* Found Octet String */
1017            if (GetInt(&key->priv, input, inOutIdx, inSz) == 0) {
1018                WOLFSSL_MSG("Found Private Key");
1019
1020                /* Compute public */
1021                ret = mp_exptmod(&key->g, &key->priv, &key->p, &key->pub);
1022            }
1023        } else {
1024            /* Don't use length from failed CheckBitString/GetOctetString */
1025            *inOutIdx = temp;
1026            ret = 0;
1027        }
1028    }
1029    #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
1030#endif /* WOLFSSL_DH_EXTRA */
1031
1032    WOLFSSL_LEAVE("wc_DhKeyDecode", ret);
1033
1034    return ret;
1035}
1036
1037#ifdef WOLFSSL_DH_EXTRA
1038int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv)
1039{
1040    int ret, privSz = 0, pubSz = 0;
1041    word32 keySz, idx, len, total;
1042
1043    if (key == NULL || outSz == NULL) {
1044        return BAD_FUNC_ARG;
1045    }
1046
1047    /* determine size */
1048    if (exportPriv) {
1049        /* octet string: priv */
1050        privSz = SetASNIntMP(&key->priv, -1, NULL);
1051        if (privSz < 0)
1052            return privSz;
1053        idx = 1 + SetLength((word32)privSz, NULL) +
1054            (word32)privSz; /* +1 for ASN_OCTET_STRING */
1055    }
1056    else {
1057        /* bit string: public */
1058        pubSz = SetASNIntMP(&key->pub, -1, NULL);
1059        if (pubSz < 0)
1060            return pubSz;
1061        idx = SetBitString((word32)pubSz, 0, NULL) + (word32)pubSz;
1062    }
1063    keySz = idx;
1064
1065    /* DH Parameters sequence with P and G */
1066    total = 0;
1067    ret = wc_DhParamsToDer(key, NULL, &total);
1068    if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
1069        return ret;
1070    idx += total;
1071
1072    /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
1073    idx += (word32)SetObjectId(sizeof(keyDhOid), NULL);
1074    idx += (word32)sizeof(keyDhOid);
1075    len = idx - keySz;
1076    /* sequence - all but pub/priv */
1077    idx += SetSequence(len, NULL);
1078    if (exportPriv) {
1079        /* version: 0 (ASN_INTEGER, 0x01, 0x00) */
1080        idx += 3;
1081    }
1082    /* sequence */
1083    total = idx + SetSequence(idx, NULL);
1084
1085    /* if no output, then just getting size */
1086    if (output == NULL) {
1087        *outSz = total;
1088        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
1089    }
1090
1091    /* make sure output fits in buffer */
1092    if (total > *outSz) {
1093        return BUFFER_E;
1094    }
1095    total = idx;
1096
1097    /* sequence */
1098    idx = SetSequence(total, output);
1099    if (exportPriv) {
1100        /* version: 0 */
1101        idx += (word32)SetMyVersion(0, output + idx, 0);
1102    }
1103    /* sequence - all but pub/priv */
1104    idx += SetSequence(len, output + idx);
1105    /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
1106    idx += (word32)SetObjectId(sizeof(keyDhOid), output + idx);
1107    XMEMCPY(output + idx, keyDhOid, sizeof(keyDhOid));
1108    idx += sizeof(keyDhOid);
1109
1110    /* DH Parameters sequence with P and G */
1111    total = *outSz - idx;
1112    ret = wc_DhParamsToDer(key, output + idx, &total);
1113    if (ret < 0)
1114        return ret;
1115    idx += total;
1116
1117    /* octet string: priv */
1118    if (exportPriv) {
1119        idx += (word32)SetOctetString((word32)privSz, output + idx);
1120        idx += (word32)SetASNIntMP(&key->priv, -1, output + idx);
1121    }
1122    else {
1123        /* bit string: public */
1124        idx += (word32)SetBitString((word32)pubSz, 0, output + idx);
1125        idx += (word32)SetASNIntMP(&key->pub, -1, output + idx);
1126    }
1127    *outSz = idx;
1128
1129    return (int)idx;
1130}
1131
1132int wc_DhParamsToDer(DhKey* key, byte* output, word32* outSz)
1133{
1134    int ret;
1135    word32 idx, total;
1136
1137    if (key == NULL || outSz == NULL) {
1138        return BAD_FUNC_ARG;
1139    }
1140
1141    /* determine size */
1142    /* integer - g */
1143    ret = SetASNIntMP(&key->g, -1, NULL);
1144    if (ret < 0)
1145        return ret;
1146    idx = (word32)ret;
1147    /* integer - p */
1148    ret = SetASNIntMP(&key->p, -1, NULL);
1149    if (ret < 0)
1150        return ret;
1151    idx += (word32)ret;
1152    total = idx;
1153     /* sequence */
1154    idx += SetSequence(idx, NULL);
1155
1156    if (output == NULL) {
1157        *outSz = idx;
1158        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
1159    }
1160    /* make sure output fits in buffer */
1161    if (idx > *outSz) {
1162        return BUFFER_E;
1163    }
1164
1165
1166    /* write DH parameters */
1167    /* sequence - for P and G only */
1168    idx = SetSequence(total, output);
1169    /* integer - p */
1170    ret = SetASNIntMP(&key->p, -1, output + idx);
1171    if (ret < 0)
1172        return ret;
1173    idx += (word32)ret;
1174    /* integer - g */
1175    ret = SetASNIntMP(&key->g, -1, output + idx);
1176    if (ret < 0)
1177        return ret;
1178    idx += (word32)ret;
1179    *outSz = idx;
1180
1181    return (int)idx;
1182}
1183
1184#endif
1185int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
1186                 byte* g, word32* gInOutSz)
1187{
1188    word32 idx = 0;
1189    int    ret;
1190    int    length;
1191
1192    if (GetSequence(input, &idx, &length, inSz) <= 0)
1193        return ASN_PARSE_E;
1194
1195    ret = GetASNInt(input, &idx, &length, inSz);
1196    if (ret != 0)
1197        return ret;
1198
1199    if (length <= (int)*pInOutSz) {
1200        XMEMCPY(p, &input[idx], (size_t)length);
1201        *pInOutSz = (word32)length;
1202    }
1203    else {
1204        return BUFFER_E;
1205    }
1206    idx += (word32)length;
1207
1208    ret = GetASNInt(input, &idx, &length, inSz);
1209    if (ret != 0)
1210        return ret;
1211
1212    if (length <= (int)*gInOutSz) {
1213        XMEMCPY(g, &input[idx], (size_t)length);
1214        *gInOutSz = (word32)length;
1215    }
1216    else {
1217        return BUFFER_E;
1218    }
1219
1220    return 0;
1221}
1222
1223#endif
1224#ifndef NO_DSA
1225int wc_DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
1226                          word32 inSz)
1227{
1228    int    length;
1229    int    ret = 0;
1230    word32 oid;
1231    word32 maxIdx;
1232
1233    if (input == NULL || inOutIdx == NULL || key == NULL)
1234        return BAD_FUNC_ARG;
1235
1236    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1237        return ASN_PARSE_E;
1238
1239    maxIdx = (word32)(*inOutIdx + (word32)length);
1240    if (GetInt(&key->p,  input, inOutIdx, maxIdx) < 0 ||
1241        GetInt(&key->q,  input, inOutIdx, maxIdx) < 0 ||
1242        GetInt(&key->g,  input, inOutIdx, maxIdx) < 0 ||
1243        GetInt(&key->y,  input, inOutIdx, maxIdx) < 0 )
1244        ret = ASN_DH_KEY_E;
1245
1246    if (ret != 0) {
1247        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1248            return ASN_PARSE_E;
1249
1250        ret = GetObjectId(input, inOutIdx, &oid, oidIgnoreType, inSz);
1251        if (ret != 0)
1252            return ret;
1253
1254        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1255            return ASN_PARSE_E;
1256
1257        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
1258            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
1259            GetInt(&key->g,  input, inOutIdx, inSz) < 0)
1260            return ASN_DH_KEY_E;
1261
1262        if (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) < 0)
1263            return ASN_PARSE_E;
1264
1265        if (GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
1266            return ASN_DH_KEY_E;
1267
1268        ret = 0;
1269    }
1270
1271    key->type = DSA_PUBLIC;
1272    return ret;
1273}
1274
1275int wc_DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
1276                           word32 inSz)
1277{
1278    int length, version, ret = 0, temp = 0;
1279    word32 algId = 0;
1280
1281    /* Sanity checks on input */
1282    if (input == NULL || inOutIdx == NULL || key == NULL) {
1283        return BAD_FUNC_ARG;
1284    }
1285
1286    /* if has pkcs8 header skip it */
1287    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
1288        /* ignore error, did not have pkcs8 header */
1289    }
1290
1291    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1292        return ASN_PARSE_E;
1293
1294    temp = (int)*inOutIdx;
1295
1296    /* Default case expects a certificate with OctetString but no version ID */
1297    ret = GetInt(&key->p, input, inOutIdx, inSz);
1298    if (ret < 0) {
1299        mp_clear(&key->p);
1300        ret = ASN_PARSE_E;
1301    }
1302    else {
1303        ret = GetInt(&key->q, input, inOutIdx, inSz);
1304        if (ret < 0) {
1305            mp_clear(&key->p);
1306            mp_clear(&key->q);
1307            ret = ASN_PARSE_E;
1308        }
1309        else {
1310            ret = GetInt(&key->g, input, inOutIdx, inSz);
1311            if (ret < 0) {
1312                mp_clear(&key->p);
1313                mp_clear(&key->q);
1314                mp_clear(&key->g);
1315                ret = ASN_PARSE_E;
1316            }
1317            else {
1318                ret = GetOctetString(input, inOutIdx, &length, inSz);
1319                if (ret < 0) {
1320                    mp_clear(&key->p);
1321                    mp_clear(&key->q);
1322                    mp_clear(&key->g);
1323                    ret = ASN_PARSE_E;
1324                }
1325                else {
1326                    ret = GetInt(&key->y, input, inOutIdx, inSz);
1327                    if (ret < 0) {
1328                        mp_clear(&key->p);
1329                        mp_clear(&key->q);
1330                        mp_clear(&key->g);
1331                        mp_clear(&key->y);
1332                        ret = ASN_PARSE_E;
1333                    }
1334                }
1335            }
1336        }
1337    }
1338    /* An alternate pass if default certificate fails parsing */
1339    if (ret == WC_NO_ERR_TRACE(ASN_PARSE_E)) {
1340        *inOutIdx = (word32)temp;
1341        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
1342            return ASN_PARSE_E;
1343
1344        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
1345            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
1346            GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
1347            GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
1348            GetInt(&key->x,  input, inOutIdx, inSz) < 0 )
1349            return ASN_DH_KEY_E;
1350    }
1351
1352    key->type = DSA_PRIVATE;
1353    return 0;
1354}
1355
1356/* Release Tmp DSA resources */
1357static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap, int ints)
1358{
1359    int i;
1360
1361    for (i = 0; i < ints; i++)
1362        XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
1363
1364    (void)heap;
1365}
1366
1367#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
1368defined(WOLFSSL_CERT_GEN))
1369int wc_SetDsaPublicKey(byte* output, DsaKey* key, int outLen, int with_header)
1370{
1371    /* p, g, q = DSA params, y = public exponent */
1372#ifdef WOLFSSL_SMALL_STACK
1373    byte* p = NULL;
1374    byte* g = NULL;
1375    byte* q = NULL;
1376    byte* y = NULL;
1377#else
1378    byte p[MAX_DSA_INT_SZ];
1379    byte g[MAX_DSA_INT_SZ];
1380    byte q[MAX_DSA_INT_SZ];
1381    byte y[MAX_DSA_INT_SZ];
1382#endif
1383    byte innerSeq[MAX_SEQ_SZ];
1384    byte outerSeq[MAX_SEQ_SZ];
1385    byte bitString[1 + MAX_LENGTH_SZ + 1];
1386    int pSz, gSz, qSz, ySz;
1387    word32 idx, innerSeqSz, outerSeqSz, bitStringSz = 0;
1388    WOLFSSL_ENTER("wc_SetDsaPublicKey");
1389
1390    if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ) {
1391        return BAD_FUNC_ARG;
1392    }
1393
1394    /* p */
1395    WC_ALLOC_VAR_EX(p, byte, MAX_DSA_INT_SZ, key->heap,
1396        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
1397    if ((pSz = SetASNIntMP(&key->p, MAX_DSA_INT_SZ, p)) < 0) {
1398        WOLFSSL_MSG("SetASNIntMP Error with p");
1399        WC_FREE_VAR_EX(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1400        return pSz;
1401    }
1402
1403    /* q */
1404    WC_ALLOC_VAR_EX(q, byte, MAX_DSA_INT_SZ, key->heap,
1405        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
1406    if ((qSz = SetASNIntMP(&key->q, MAX_DSA_INT_SZ, q)) < 0) {
1407        WOLFSSL_MSG("SetASNIntMP Error with q");
1408        WC_FREE_VAR_EX(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1409        WC_FREE_VAR_EX(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1410        return qSz;
1411    }
1412
1413    /* g */
1414    WC_ALLOC_VAR_EX(g, byte, MAX_DSA_INT_SZ, key->heap,
1415        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
1416    if ((gSz = SetASNIntMP(&key->g, MAX_DSA_INT_SZ, g)) < 0) {
1417        WOLFSSL_MSG("SetASNIntMP Error with g");
1418        WC_FREE_VAR_EX(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1419        WC_FREE_VAR_EX(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1420        WC_FREE_VAR_EX(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1421        return gSz;
1422    }
1423
1424    /* y */
1425    WC_ALLOC_VAR_EX(y, byte, MAX_DSA_INT_SZ, key->heap,
1426        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
1427    if ((ySz = SetASNIntMP(&key->y, MAX_DSA_INT_SZ, y)) < 0) {
1428        WOLFSSL_MSG("SetASNIntMP Error with y");
1429        WC_FREE_VAR_EX(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1430        WC_FREE_VAR_EX(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1431        WC_FREE_VAR_EX(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1432        WC_FREE_VAR_EX(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1433        return ySz;
1434    }
1435
1436    if (with_header) {
1437        word32 algoSz;
1438#ifdef WOLFSSL_SMALL_STACK
1439        byte* algo = NULL;
1440
1441        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1442        if (algo == NULL) {
1443            XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1444            XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1445            XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1446            XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1447            return MEMORY_E;
1448        }
1449#else
1450        byte algo[MAX_ALGO_SZ];
1451#endif
1452        innerSeqSz  = SetSequence((word32)(pSz + qSz + gSz), innerSeq);
1453        algoSz = SetAlgoID(DSAk, algo, oidKeyType, 0);
1454        bitStringSz  = SetBitString((word32)ySz, 0, bitString);
1455        outerSeqSz = SetSequence(algoSz + innerSeqSz +
1456                                 (word32)(pSz + qSz + gSz), outerSeq);
1457
1458        idx = SetSequence(algoSz + innerSeqSz + (word32)(pSz + qSz + gSz) +
1459                          bitStringSz + (word32)ySz + outerSeqSz, output);
1460
1461        /* check output size */
1462        if ((idx + algoSz + bitStringSz + innerSeqSz +
1463             (word32)(pSz + qSz + gSz + ySz)) > (word32)outLen)
1464        {
1465                WC_FREE_VAR_EX(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1466                WC_FREE_VAR_EX(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1467                WC_FREE_VAR_EX(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1468                WC_FREE_VAR_EX(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1469                WC_FREE_VAR_EX(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1470            WOLFSSL_MSG("Error, output size smaller than outlen");
1471            return BUFFER_E;
1472        }
1473
1474        /* outerSeq */
1475        XMEMCPY(output + idx, outerSeq, outerSeqSz);
1476        idx += outerSeqSz;
1477        /* algo */
1478        XMEMCPY(output + idx, algo, algoSz);
1479        idx += algoSz;
1480        WC_FREE_VAR_EX(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1481    } else {
1482        innerSeqSz  = SetSequence((word32)(pSz + qSz + gSz + ySz), innerSeq);
1483
1484        /* check output size */
1485        if ((innerSeqSz + (word32)(pSz + qSz + gSz + ySz)) > (word32)outLen) {
1486            WC_FREE_VAR_EX(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1487            WC_FREE_VAR_EX(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1488            WC_FREE_VAR_EX(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1489            WC_FREE_VAR_EX(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1490            WOLFSSL_MSG("Error, output size smaller than outlen");
1491            return BUFFER_E;
1492        }
1493
1494        idx = 0;
1495    }
1496
1497    /* innerSeq */
1498    XMEMCPY(output + idx, innerSeq, innerSeqSz);
1499    idx += innerSeqSz;
1500    /* p */
1501    XMEMCPY(output + idx, p, (size_t)pSz);
1502    idx += (word32)pSz;
1503    /* q */
1504    XMEMCPY(output + idx, q, (size_t)qSz);
1505    idx += (word32)qSz;
1506    /* g */
1507    XMEMCPY(output + idx, g, (size_t)gSz);
1508    idx += (word32)gSz;
1509    /* bit string */
1510    if (bitStringSz > 0) {
1511        XMEMCPY(output + idx, bitString, bitStringSz);
1512        idx += bitStringSz;
1513    }
1514    /* y */
1515    XMEMCPY(output + idx, y, (size_t)ySz);
1516    idx += (word32)ySz;
1517
1518    WC_FREE_VAR_EX(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1519    WC_FREE_VAR_EX(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1520    WC_FREE_VAR_EX(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1521    WC_FREE_VAR_EX(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1522    return (int)idx;
1523}
1524
1525#endif
1526static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32* inLen,
1527                           int ints, int includeVersion)
1528{
1529    word32 seqSz = 0, verSz = 0, intTotalLen = 0, outLen, j;
1530    word32 sizes[DSA_INTS];
1531    int    i, ret = 0;
1532
1533    byte  seq[MAX_SEQ_SZ];
1534    byte  ver[MAX_VERSION_SZ];
1535    byte* tmps[DSA_INTS];
1536
1537    if (ints > DSA_INTS || inLen == NULL)
1538        return BAD_FUNC_ARG;
1539
1540    XMEMSET(sizes, 0, sizeof(sizes));
1541    for (i = 0; i < ints; i++)
1542        tmps[i] = NULL;
1543
1544    /* write all big ints from key to DER tmps */
1545    for (i = 0; i < ints; i++) {
1546        int mpSz;
1547        mp_int* keyInt = GetDsaInt(key, i);
1548        word32 rawLen = (word32)mp_unsigned_bin_size(keyInt) + 1;
1549
1550        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
1551                                                              DYNAMIC_TYPE_DSA);
1552        if (tmps[i] == NULL) {
1553            ret = MEMORY_E;
1554            break;
1555        }
1556
1557        mpSz = SetASNIntMP(keyInt, -1, tmps[i]);
1558        if (mpSz < 0) {
1559            ret = mpSz;
1560            break;
1561        }
1562        sizes[i] = (word32)mpSz;
1563        intTotalLen += (word32)mpSz;
1564    }
1565
1566    if (ret != 0) {
1567        FreeTmpDsas(tmps, key->heap, ints);
1568        return ret;
1569    }
1570
1571    /* make headers */
1572    if (includeVersion)
1573        verSz = (word32)SetMyVersion(0, ver, FALSE);
1574    seqSz = SetSequence(verSz + intTotalLen, seq);
1575
1576    outLen = seqSz + verSz + intTotalLen;
1577    if (output == NULL) {
1578        *inLen = outLen;
1579        FreeTmpDsas(tmps, key->heap, ints);
1580        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
1581    }
1582    if (outLen > *inLen) {
1583        FreeTmpDsas(tmps, key->heap, ints);
1584        return BAD_FUNC_ARG;
1585    }
1586    *inLen = outLen;
1587
1588    /* write to output */
1589    XMEMCPY(output, seq, seqSz);
1590    j = seqSz;
1591    if (includeVersion) {
1592        XMEMCPY(output + j, ver, verSz);
1593        j += verSz;
1594    }
1595
1596    for (i = 0; i < ints; i++) {
1597        XMEMCPY(output + j, tmps[i], sizes[i]);
1598        j += sizes[i];
1599    }
1600    FreeTmpDsas(tmps, key->heap, ints);
1601
1602    return (int)outLen;
1603}
1604
1605#endif
1606#ifndef NO_CERTS
1607static int GetCertHeader(DecodedCert* cert)
1608{
1609    int ret = 0, len;
1610
1611    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
1612        return ASN_PARSE_E;
1613
1614    /* Reset the max index for the size indicated in the outer wrapper. */
1615    cert->maxIdx = (word32)len + cert->srcIdx;
1616    cert->certBegin = cert->srcIdx;
1617
1618    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
1619        return ASN_PARSE_E;
1620
1621    cert->sigIndex = (word32)len + cert->srcIdx;
1622    if (cert->sigIndex > cert->maxIdx)
1623        return ASN_PARSE_E;
1624
1625    if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
1626                                                            cert->sigIndex) < 0)
1627        return ASN_PARSE_E;
1628
1629    ret = wc_GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
1630        &cert->serialSz, cert->sigIndex);
1631    if (ret < 0) {
1632        return ret;
1633    }
1634
1635    return ret;
1636}
1637
1638#endif
1639#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
1640static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
1641                           int with_header, int comp)
1642{
1643    int ret;
1644    word32 idx = 0, curveSz, algoSz, pubSz, bitStringSz;
1645    byte bitString[1 + MAX_LENGTH_SZ + 1]; /* 6 */
1646    byte algo[MAX_ALGO_SZ];  /* 20 */
1647
1648    /* public size */
1649    pubSz = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
1650    if (comp)
1651        pubSz = 1 + pubSz;
1652    else
1653        pubSz = 1 + 2 * pubSz;
1654
1655    /* check for buffer overflow */
1656    if (output != NULL && pubSz > (word32)outLen) {
1657        return BUFFER_E;
1658    }
1659
1660    /* headers */
1661    if (with_header) {
1662        ret = SetCurve(key, NULL, 0);
1663        if (ret <= 0) {
1664            return ret;
1665        }
1666        curveSz = (word32)ret;
1667        ret = 0;
1668
1669        /* calculate size */
1670        algoSz  = SetAlgoID(ECDSAk, algo, oidKeyType, (int)curveSz);
1671        bitStringSz = SetBitString(pubSz, 0, bitString);
1672        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, NULL);
1673
1674        /* check for buffer overflow */
1675        if (output != NULL &&
1676                curveSz + algoSz + bitStringSz + idx + pubSz > (word32)outLen) {
1677            return BUFFER_E;
1678        }
1679
1680        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz,
1681            output);
1682        /* algo */
1683        if (output)
1684            XMEMCPY(output + idx, algo, algoSz);
1685        idx += algoSz;
1686        /* curve */
1687        if (output)
1688            (void)SetCurve(key, output + idx, curveSz);
1689        idx += curveSz;
1690        /* bit string */
1691        if (output)
1692            XMEMCPY(output + idx, bitString, bitStringSz);
1693        idx += bitStringSz;
1694    }
1695
1696    /* pub */
1697    if (output) {
1698        PRIVATE_KEY_UNLOCK();
1699        ret = wc_ecc_export_x963_ex(key, output + idx, &pubSz, comp);
1700        PRIVATE_KEY_LOCK();
1701        if (ret != 0) {
1702            return ret;
1703        }
1704    }
1705    idx += pubSz;
1706
1707    return (int)idx;
1708}
1709
1710#endif
1711#ifdef WC_ENABLE_ASYM_KEY_EXPORT
1712int SetAsymKeyDerPublic(const byte* pubKey, word32 pubKeyLen,
1713    byte* output, word32 outLen, int keyType, int withHeader)
1714{
1715    int ret = 0;
1716    word32 idx = 0;
1717    word32 seqDataSz = 0;
1718    word32 sz;
1719
1720    /* validate parameters */
1721    if (pubKey == NULL){
1722        return BAD_FUNC_ARG;
1723    }
1724    if (output != NULL && outLen == 0) {
1725        return BUFFER_E;
1726    }
1727
1728    /* calculate size */
1729    if (withHeader) {
1730        word32 algoSz      = SetAlgoID(keyType, NULL, oidKeyType, 0);
1731        word32 bitStringSz = SetBitString(pubKeyLen, 0, NULL);
1732
1733        seqDataSz = algoSz + bitStringSz + pubKeyLen;
1734        sz = SetSequence(seqDataSz, NULL) + seqDataSz;
1735    }
1736    else {
1737        sz = pubKeyLen;
1738    }
1739
1740    /* checkout output size */
1741    if (output != NULL && sz > outLen) {
1742        ret = BUFFER_E;
1743    }
1744
1745    /* headers */
1746    if (ret == 0 && output != NULL && withHeader) {
1747        /* sequence */
1748        idx = SetSequence(seqDataSz, output);
1749        /* algo */
1750        idx += SetAlgoID(keyType, output + idx, oidKeyType, 0);
1751        /* bit string */
1752        idx += SetBitString(pubKeyLen, 0, output + idx);
1753    }
1754
1755    if (ret == 0 && output != NULL) {
1756        /* pub */
1757        XMEMCPY(output + idx, pubKey, pubKeyLen);
1758        idx += pubKeyLen;
1759
1760        sz = idx;
1761    }
1762
1763    if (ret == 0) {
1764        ret = (int)sz;
1765    }
1766    return ret;
1767}
1768
1769#endif
1770#if !defined(NO_RSA) && !defined(NO_CERTS)
1771static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx,
1772                       word32 maxIdx)
1773{
1774    int    length;
1775    int    pubLen;
1776    word32 pubIdx;
1777
1778    if (CheckBitString(source, srcIdx, &pubLen, maxIdx, 1, NULL) != 0)
1779        return ASN_PARSE_E;
1780    pubIdx = *srcIdx;
1781
1782    if (GetSequence(source, srcIdx, &length, pubIdx + (word32)pubLen) < 0)
1783        return ASN_PARSE_E;
1784
1785#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
1786    cert->sigCtx.CertAtt.pubkey_n_start =
1787            cert->sigCtx.CertAtt.pubkey_e_start = pubIdx;
1788#endif
1789    cert->pubKeySize = (word32)pubLen;
1790    cert->publicKey = source + pubIdx;
1791#ifdef WOLFSSL_MAXQ10XX_TLS
1792    cert->publicKeyIndex = pubIdx;
1793#endif
1794    *srcIdx += (word32)length;
1795
1796#ifdef HAVE_OCSP
1797    return CalcHashId_ex(cert->publicKey, cert->pubKeySize,
1798        cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
1799#else
1800    return 0;
1801#endif
1802}
1803
1804#endif
1805#if defined(HAVE_ECC) && !defined(NO_CERTS)
1806static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx,
1807                       word32 maxIdx, const byte* pubKey, word32 pubKeyLen)
1808{
1809    int ret;
1810    word32 localIdx;
1811    byte* publicKey;
1812    byte  tag;
1813    int length;
1814
1815    if (pubKey == NULL) {
1816        return BAD_FUNC_ARG;
1817    }
1818
1819    localIdx = *srcIdx;
1820    if (GetASNTag(source, &localIdx, &tag, maxIdx) < 0)
1821        return ASN_PARSE_E;
1822
1823    if (tag != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
1824        if (GetObjectId(source, srcIdx, &cert->pkCurveOID, oidCurveType,
1825                                                                    maxIdx) < 0)
1826            return ASN_PARSE_E;
1827
1828        if ((ret = CheckCurve(cert->pkCurveOID)) < 0)
1829            return ECC_CURVE_OID_E;
1830
1831    #if defined(WOLFSSL_RENESAS_FSPSM_TLS) || defined(WOLFSSL_RENESAS_TSIP_TLS)
1832        cert->sigCtx.CertAtt.curve_id = ret;
1833    #else
1834        (void)ret;
1835    #endif
1836        /* key header */
1837        ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
1838        if (ret != 0)
1839            return ret;
1840    #if defined(WOLFSSL_RENESAS_FSPSM_TLS) || defined(WOLFSSL_RENESAS_TSIP_TLS)
1841        cert->sigCtx.CertAtt.pubkey_n_start =
1842                cert->sigCtx.CertAtt.pubkey_e_start = (*srcIdx + 1);
1843        cert->sigCtx.CertAtt.pubkey_n_len = ((length - 1) >> 1);
1844        cert->sigCtx.CertAtt.pubkey_e_start +=
1845                cert->sigCtx.CertAtt.pubkey_n_len;
1846        cert->sigCtx.CertAtt.pubkey_e_len   =
1847                cert->sigCtx.CertAtt.pubkey_n_len;
1848    #endif
1849    #ifdef WOLFSSL_MAXQ10XX_TLS
1850        cert->publicKeyIndex = *srcIdx + 1;
1851    #endif
1852
1853    #ifdef HAVE_OCSP
1854        ret = CalcHashId_ex(source + *srcIdx, (word32)length,
1855            cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
1856        if (ret != 0)
1857            return ret;
1858    #endif
1859        *srcIdx += (word32)length;
1860    }
1861
1862    publicKey = (byte*)XMALLOC(pubKeyLen, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
1863    if (publicKey == NULL)
1864        return MEMORY_E;
1865    XMEMCPY(publicKey, pubKey, pubKeyLen);
1866    cert->publicKey = publicKey;
1867    cert->pubKeyStored = 1;
1868    cert->pubKeySize   = pubKeyLen;
1869
1870    return 0;
1871}
1872
1873#endif
1874#ifndef NO_CERTS
1875#if !defined(NO_DSA)
1876static int ParseDsaKey(const byte* source, word32* srcIdx, word32 maxIdx,
1877                       void* heap)
1878{
1879    int ret;
1880    int length;
1881
1882    (void)heap;
1883
1884    ret = GetSequence(source, srcIdx, &length, maxIdx);
1885    if (ret < 0)
1886        return ret;
1887
1888    ret = SkipInt(source, srcIdx, maxIdx);
1889    if (ret != 0)
1890        return ret;
1891    ret = SkipInt(source, srcIdx, maxIdx);
1892    if (ret != 0)
1893        return ret;
1894    ret = SkipInt(source, srcIdx, maxIdx);
1895    if (ret != 0)
1896        return ret;
1897
1898    ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
1899    if (ret != 0)
1900        return ret;
1901
1902    ret = GetASNInt(source, srcIdx, &length, maxIdx);
1903    if (ret != 0)
1904        return ASN_PARSE_E;
1905
1906    *srcIdx += (word32)length;
1907
1908    return 0;
1909}
1910
1911#endif
1912#endif
1913static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
1914                       const byte* input, word32* inOutIdx, word32 maxIdx)
1915{
1916    int    length;  /* length of all distinguished names */
1917    int    dummy;
1918    int    ret;
1919    word32 idx;
1920    word32 srcIdx = *inOutIdx;
1921#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
1922    !defined(WOLFCRYPT_ONLY)
1923    WOLFSSL_X509_NAME* dName = NULL;
1924#endif
1925
1926    WOLFSSL_MSG("Getting Cert Name");
1927
1928    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
1929     * calculated over the entire DER encoding of the Name field, including
1930     * the tag and length. */
1931    if (CalcHashId_ex(input + *inOutIdx, maxIdx - *inOutIdx, hash,
1932            HashIdAlg(cert->signatureOID)) != 0) {
1933        return ASN_PARSE_E;
1934    }
1935
1936#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
1937    !defined(WOLFCRYPT_ONLY)
1938    dName = wolfSSL_X509_NAME_new_ex(cert->heap);
1939    if (dName == NULL) {
1940        return MEMORY_E;
1941    }
1942#endif /* OPENSSL_EXTRA */
1943
1944    if (GetSequence(input, &srcIdx, &length, maxIdx) < 0) {
1945#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
1946            !defined(WOLFCRYPT_ONLY)
1947        wolfSSL_X509_NAME_free(dName);
1948#endif /* OPENSSL_EXTRA */
1949        return ASN_PARSE_E;
1950    }
1951
1952#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
1953    /* store pointer to raw issuer */
1954    if (nameType == ASN_ISSUER) {
1955        cert->issuerRaw = &input[srcIdx];
1956        cert->issuerRawLen = length;
1957    }
1958#endif
1959#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
1960    if (nameType == ASN_SUBJECT) {
1961        cert->subjectRaw = &input[srcIdx];
1962        cert->subjectRawLen = length;
1963    }
1964#endif
1965
1966    length += (int)srcIdx;
1967    idx = 0;
1968
1969    while (srcIdx < (word32)length) {
1970        byte        b       = 0;
1971        byte        joint[3];
1972        byte        tooBig  = FALSE;
1973        int         oidSz;
1974        const char* copy    = NULL;
1975        int         copyLen = 0;
1976        int         strLen  = 0;
1977        byte        id      = 0;
1978    #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
1979                && !defined(WOLFCRYPT_ONLY)
1980         int        nid = WC_NID_undef;
1981         int        enc;
1982    #endif /* OPENSSL_EXTRA */
1983
1984        if (GetSet(input, &srcIdx, &dummy, maxIdx) < 0) {
1985            WOLFSSL_MSG("Cert name lacks set header, trying sequence");
1986        }
1987
1988        if (GetSequence(input, &srcIdx, &dummy, maxIdx) <= 0) {
1989        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
1990            !defined(WOLFCRYPT_ONLY)
1991            wolfSSL_X509_NAME_free(dName);
1992        #endif /* OPENSSL_EXTRA */
1993            return ASN_PARSE_E;
1994        }
1995
1996        ret = GetASNObjectId(input, &srcIdx, &oidSz, maxIdx);
1997        if (ret != 0) {
1998        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
1999            !defined(WOLFCRYPT_ONLY)
2000            wolfSSL_X509_NAME_free(dName);
2001        #endif /* OPENSSL_EXTRA */
2002            return ret;
2003        }
2004
2005        /* make sure there is room for joint */
2006        if ((srcIdx + sizeof(joint)) > (word32)maxIdx) {
2007        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
2008            !defined(WOLFCRYPT_ONLY)
2009            wolfSSL_X509_NAME_free(dName);
2010        #endif /* OPENSSL_EXTRA */
2011            return ASN_PARSE_E;
2012        }
2013
2014        XMEMCPY(joint, &input[srcIdx], sizeof(joint));
2015
2016        /* v1 name types */
2017        if (joint[0] == 0x55 && joint[1] == 0x04) {
2018            srcIdx += 3;
2019            id = joint[2];
2020            if (GetHeader(input, &b, &srcIdx, &strLen, maxIdx, 1) < 0) {
2021            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
2022            !defined(WOLFCRYPT_ONLY)
2023                wolfSSL_X509_NAME_free(dName);
2024            #endif /* OPENSSL_EXTRA */
2025                return ASN_PARSE_E;
2026            }
2027
2028        #ifndef WOLFSSL_NO_ASN_STRICT
2029            /* RFC 5280 section 4.1.2.4 lists a DirectoryString as being
2030             * 1..MAX in length */
2031            if (strLen < 1) {
2032                WOLFSSL_MSG("Non conforming DirectoryString of length 0 was"
2033                            " found");
2034                WOLFSSL_MSG("Use WOLFSSL_NO_ASN_STRICT if wanting to allow"
2035                            " empty DirectoryString's");
2036            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
2037            !defined(WOLFCRYPT_ONLY)
2038                wolfSSL_X509_NAME_free(dName);
2039            #endif /* OPENSSL_EXTRA */
2040                return ASN_PARSE_E;
2041            }
2042        #endif
2043
2044            if (id == ASN_COMMON_NAME) {
2045                if (nameType == ASN_SUBJECT) {
2046                    cert->subjectCN = (char *)&input[srcIdx];
2047                    cert->subjectCNLen = strLen;
2048                    cert->subjectCNEnc = (char)b;
2049                }
2050            #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)) && \
2051                defined(WOLFSSL_HAVE_ISSUER_NAMES)
2052                else if (nameType == ASN_ISSUER) {
2053                    cert->issuerCN = (char*)&input[srcIdx];
2054                    cert->issuerCNLen = strLen;
2055                    cert->issuerCNEnc = (char)b;
2056                }
2057            #endif
2058
2059                copy = WOLFSSL_COMMON_NAME;
2060                copyLen = sizeof(WOLFSSL_COMMON_NAME) - 1;
2061            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
2062                && !defined(WOLFCRYPT_ONLY)
2063                nid = WC_NID_commonName;
2064            #endif /* OPENSSL_EXTRA */
2065            }
2066        #ifdef WOLFSSL_CERT_NAME_ALL
2067            else if (id == ASN_NAME) {
2068                copy = WOLFSSL_NAME;
2069                copyLen = sizeof(WOLFSSL_NAME) - 1;
2070                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2071                    if (nameType == ASN_SUBJECT) {
2072                        cert->subjectN = (char*)&input[srcIdx];
2073                        cert->subjectNLen = strLen;
2074                        cert->subjectNEnc = b;
2075                    }
2076                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2077                #if (defined(OPENSSL_EXTRA) || \
2078                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2079                        && !defined(WOLFCRYPT_ONLY)
2080                    nid = WC_NID_name;
2081                #endif /* OPENSSL_EXTRA */
2082            }
2083            else if (id == ASN_INITIALS) {
2084                copy = WOLFSSL_INITIALS;
2085                copyLen = sizeof(WOLFSSL_INITIALS) - 1;
2086                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2087                    if (nameType == ASN_SUBJECT) {
2088                        cert->subjectI = (char*)&input[srcIdx];
2089                        cert->subjectILen = strLen;
2090                        cert->subjectIEnc = b;
2091                    }
2092                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2093                #if (defined(OPENSSL_EXTRA) || \
2094                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2095                        && !defined(WOLFCRYPT_ONLY)
2096                    nid = WC_NID_initials;
2097                #endif /* OPENSSL_EXTRA */
2098            }
2099            else if (id == ASN_GIVEN_NAME) {
2100                copy = WOLFSSL_GIVEN_NAME;
2101                copyLen = sizeof(WOLFSSL_GIVEN_NAME) - 1;
2102                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2103                    if (nameType == ASN_SUBJECT) {
2104                        cert->subjectGN = (char*)&input[srcIdx];
2105                        cert->subjectGNLen = strLen;
2106                        cert->subjectGNEnc = b;
2107                    }
2108                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2109                #if (defined(OPENSSL_EXTRA) || \
2110                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2111                        && !defined(WOLFCRYPT_ONLY)
2112                    nid = WC_NID_givenName;
2113                #endif /* OPENSSL_EXTRA */
2114            }
2115            else if (id == ASN_DNQUALIFIER) {
2116                copy = WOLFSSL_DNQUALIFIER;
2117                copyLen = sizeof(WOLFSSL_DNQUALIFIER) - 1;
2118                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2119                    if (nameType == ASN_SUBJECT) {
2120                        cert->subjectDNQ = (char*)&input[srcIdx];
2121                        cert->subjectDNQLen = strLen;
2122                        cert->subjectDNQEnc = b;
2123                    }
2124                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2125                #if (defined(OPENSSL_EXTRA) || \
2126                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2127                        && !defined(WOLFCRYPT_ONLY)
2128                    nid = WC_NID_dnQualifier;
2129                #endif /* OPENSSL_EXTRA */
2130            }
2131        #endif /* WOLFSSL_CERT_NAME_ALL */
2132            else if (id == ASN_SUR_NAME) {
2133                copy = WOLFSSL_SUR_NAME;
2134                copyLen = sizeof(WOLFSSL_SUR_NAME) - 1;
2135                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2136                    if (nameType == ASN_SUBJECT) {
2137                        cert->subjectSN = (char*)&input[srcIdx];
2138                        cert->subjectSNLen = strLen;
2139                        cert->subjectSNEnc = (char)b;
2140                    }
2141                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
2142                    else if (nameType == ASN_ISSUER) {
2143                        cert->issuerSN = (char*)&input[srcIdx];
2144                        cert->issuerSNLen = strLen;
2145                        cert->issuerSNEnc = (char)b;
2146                    }
2147                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
2148                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2149                #if (defined(OPENSSL_EXTRA) || \
2150                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2151                        && !defined(WOLFCRYPT_ONLY)
2152                    nid = WC_NID_surname;
2153                #endif /* OPENSSL_EXTRA */
2154            }
2155            else if (id == ASN_COUNTRY_NAME) {
2156                copy = WOLFSSL_COUNTRY_NAME;
2157                copyLen = sizeof(WOLFSSL_COUNTRY_NAME) - 1;
2158                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2159                    if (nameType == ASN_SUBJECT) {
2160                        cert->subjectC = (char*)&input[srcIdx];
2161                        cert->subjectCLen = strLen;
2162                        cert->subjectCEnc = (char)b;
2163                    }
2164                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
2165                    else if (nameType == ASN_ISSUER) {
2166                        cert->issuerC = (char*)&input[srcIdx];
2167                        cert->issuerCLen = strLen;
2168                        cert->issuerCEnc = (char)b;
2169                    }
2170                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
2171                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2172                #if (defined(OPENSSL_EXTRA) || \
2173                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2174                        && !defined(WOLFCRYPT_ONLY)
2175                    nid = WC_NID_countryName;
2176                #endif /* OPENSSL_EXTRA */
2177            }
2178            else if (id == ASN_LOCALITY_NAME) {
2179                copy = WOLFSSL_LOCALITY_NAME;
2180                copyLen = sizeof(WOLFSSL_LOCALITY_NAME) - 1;
2181                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2182                    if (nameType == ASN_SUBJECT) {
2183                        cert->subjectL = (char*)&input[srcIdx];
2184                        cert->subjectLLen = strLen;
2185                        cert->subjectLEnc = (char)b;
2186                    }
2187                    #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
2188                    else if (nameType == ASN_ISSUER) {
2189                        cert->issuerL = (char*)&input[srcIdx];
2190                        cert->issuerLLen = strLen;
2191                        cert->issuerLEnc = (char)b;
2192                    }
2193                    #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
2194                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2195                #if (defined(OPENSSL_EXTRA) || \
2196                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2197                        && !defined(WOLFCRYPT_ONLY)
2198                    nid = WC_NID_localityName;
2199                #endif /* OPENSSL_EXTRA */
2200            }
2201            else if (id == ASN_STATE_NAME) {
2202                copy = WOLFSSL_STATE_NAME;
2203                copyLen = sizeof(WOLFSSL_STATE_NAME) - 1;
2204                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2205                    if (nameType == ASN_SUBJECT) {
2206                        cert->subjectST = (char*)&input[srcIdx];
2207                        cert->subjectSTLen = strLen;
2208                        cert->subjectSTEnc = (char)b;
2209                    }
2210                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
2211                    else if (nameType == ASN_ISSUER) {
2212                        cert->issuerST = (char*)&input[srcIdx];
2213                        cert->issuerSTLen = strLen;
2214                        cert->issuerSTEnc = (char)b;
2215                    }
2216                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
2217                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT*/
2218                #if (defined(OPENSSL_EXTRA) || \
2219                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2220                        && !defined(WOLFCRYPT_ONLY)
2221                    nid = WC_NID_stateOrProvinceName;
2222                #endif /* OPENSSL_EXTRA */
2223            }
2224            else if (id == ASN_ORG_NAME) {
2225                copy = WOLFSSL_ORG_NAME;
2226                copyLen = sizeof(WOLFSSL_ORG_NAME) - 1;
2227                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2228                    if (nameType == ASN_SUBJECT) {
2229                        cert->subjectO = (char*)&input[srcIdx];
2230                        cert->subjectOLen = strLen;
2231                        cert->subjectOEnc = (char)b;
2232                    }
2233                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
2234                    else if (nameType == ASN_ISSUER) {
2235                        cert->issuerO = (char*)&input[srcIdx];
2236                        cert->issuerOLen = strLen;
2237                        cert->issuerOEnc = (char)b;
2238                    }
2239                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
2240                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2241                #if (defined(OPENSSL_EXTRA) || \
2242                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2243                        && !defined(WOLFCRYPT_ONLY)
2244                    nid = WC_NID_organizationName;
2245                #endif /* OPENSSL_EXTRA */
2246            }
2247            else if (id == ASN_ORGUNIT_NAME) {
2248                copy = WOLFSSL_ORGUNIT_NAME;
2249                copyLen = sizeof(WOLFSSL_ORGUNIT_NAME) - 1;
2250                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2251                    if (nameType == ASN_SUBJECT) {
2252                        cert->subjectOU = (char*)&input[srcIdx];
2253                        cert->subjectOULen = strLen;
2254                        cert->subjectOUEnc = (char)b;
2255                    }
2256                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
2257                    else if (nameType == ASN_ISSUER) {
2258                        cert->issuerOU = (char*)&input[srcIdx];
2259                        cert->issuerOULen = strLen;
2260                        cert->issuerOUEnc = (char)b;
2261                    }
2262                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
2263                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2264                #if (defined(OPENSSL_EXTRA) || \
2265                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2266                        && !defined(WOLFCRYPT_ONLY)
2267                    nid = WC_NID_organizationalUnitName;
2268                #endif /* OPENSSL_EXTRA */
2269            }
2270            else if (id == ASN_SERIAL_NUMBER) {
2271                copy = WOLFSSL_SERIAL_NUMBER;
2272                copyLen = sizeof(WOLFSSL_SERIAL_NUMBER) - 1;
2273                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2274                    if (nameType == ASN_SUBJECT) {
2275                        cert->subjectSND = (char*)&input[srcIdx];
2276                        cert->subjectSNDLen = strLen;
2277                        cert->subjectSNDEnc = (char)b;
2278                    }
2279                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
2280                    else if (nameType == ASN_ISSUER) {
2281                        cert->issuerSND = (char*)&input[srcIdx];
2282                        cert->issuerSNDLen = strLen;
2283                        cert->issuerSNDEnc = (char)b;
2284                    }
2285                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
2286                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2287                #if (defined(OPENSSL_EXTRA) || \
2288                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2289                        && !defined(WOLFCRYPT_ONLY)
2290                    nid = WC_NID_serialNumber;
2291                #endif /* OPENSSL_EXTRA */
2292            }
2293            else if (id == ASN_USER_ID) {
2294                copy = WOLFSSL_USER_ID;
2295                copyLen = sizeof(WOLFSSL_USER_ID) - 1;
2296                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2297                    if (nameType == ASN_SUBJECT) {
2298                        cert->subjectUID = (char*)&input[srcIdx];
2299                        cert->subjectUIDLen = strLen;
2300                        cert->subjectUIDEnc = (char)b;
2301                    }
2302                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2303                #if (defined(OPENSSL_EXTRA) || \
2304                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2305                        && !defined(WOLFCRYPT_ONLY)
2306                    nid = WC_NID_userId;
2307                #endif /* OPENSSL_EXTRA */
2308            }
2309        #ifdef WOLFSSL_CERT_EXT
2310            else if (id == ASN_STREET_ADDR) {
2311                copy = WOLFSSL_STREET_ADDR_NAME;
2312                copyLen = sizeof(WOLFSSL_STREET_ADDR_NAME) - 1;
2313                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2314                    if (nameType == ASN_SUBJECT) {
2315                        cert->subjectStreet = (char*)&input[srcIdx];
2316                        cert->subjectStreetLen = strLen;
2317                        cert->subjectStreetEnc = (char)b;
2318                    }
2319                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2320                #if (defined(OPENSSL_EXTRA) || \
2321                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2322                        && !defined(WOLFCRYPT_ONLY)
2323                    nid = WC_NID_streetAddress;
2324                #endif /* OPENSSL_EXTRA */
2325            }
2326            else if (id == ASN_BUS_CAT) {
2327                copy = WOLFSSL_BUS_CAT;
2328                copyLen = sizeof(WOLFSSL_BUS_CAT) - 1;
2329            #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2330                if (nameType == ASN_SUBJECT) {
2331                    cert->subjectBC = (char*)&input[srcIdx];
2332                    cert->subjectBCLen = strLen;
2333                    cert->subjectBCEnc = (char)b;
2334                }
2335            #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2336            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
2337                        && !defined(WOLFCRYPT_ONLY)
2338                nid = WC_NID_businessCategory;
2339            #endif /* OPENSSL_EXTRA */
2340            }
2341            else if (id == ASN_POSTAL_CODE) {
2342                copy = WOLFSSL_POSTAL_NAME;
2343                copyLen = sizeof(WOLFSSL_POSTAL_NAME) - 1;
2344                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2345                    if (nameType == ASN_SUBJECT) {
2346                        cert->subjectPC = (char*)&input[srcIdx];
2347                        cert->subjectPCLen = strLen;
2348                        cert->subjectPCEnc = (char)b;
2349                    }
2350                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT*/
2351                #if (defined(OPENSSL_EXTRA) || \
2352                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2353                        && !defined(WOLFCRYPT_ONLY)
2354                    nid = WC_NID_postalCode;
2355                #endif /* OPENSSL_EXTRA */
2356            }
2357        #endif /* WOLFSSL_CERT_EXT */
2358        }
2359    #ifdef WOLFSSL_CERT_EXT
2360        else if ((srcIdx + ASN_JOI_PREFIX_SZ + 2 <= (word32)maxIdx) &&
2361                 (0 == XMEMCMP(&input[srcIdx], ASN_JOI_PREFIX,
2362                               ASN_JOI_PREFIX_SZ)) &&
2363                 ((input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_C) ||
2364                  (input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_ST)))
2365        {
2366            srcIdx += ASN_JOI_PREFIX_SZ;
2367            id = input[srcIdx++];
2368            b = input[srcIdx++]; /* encoding */
2369
2370            if (GetLength(input, &srcIdx, &strLen,
2371                          maxIdx) < 0) {
2372            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
2373            !defined(WOLFCRYPT_ONLY)
2374                wolfSSL_X509_NAME_free(dName);
2375            #endif /* OPENSSL_EXTRA */
2376                return ASN_PARSE_E;
2377            }
2378
2379            /* Check for jurisdiction of incorporation country name */
2380            if (id == ASN_JOI_C) {
2381                copy = WOLFSSL_JOI_C;
2382                copyLen = sizeof(WOLFSSL_JOI_C) - 1;
2383                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2384                    if (nameType == ASN_SUBJECT) {
2385                        cert->subjectJC = (char*)&input[srcIdx];
2386                        cert->subjectJCLen = strLen;
2387                        cert->subjectJCEnc = (char)b;
2388                    }
2389                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2390                #if (defined(OPENSSL_EXTRA) || \
2391                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2392                        && !defined(WOLFCRYPT_ONLY)
2393                    nid = WC_NID_jurisdictionCountryName;
2394                #endif /* OPENSSL_EXTRA */
2395            }
2396
2397            /* Check for jurisdiction of incorporation state name */
2398            else if (id == ASN_JOI_ST) {
2399                copy = WOLFSSL_JOI_ST;
2400                copyLen = sizeof(WOLFSSL_JOI_ST) - 1;
2401                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2402                    if (nameType == ASN_SUBJECT) {
2403                        cert->subjectJS = (char*)&input[srcIdx];
2404                        cert->subjectJSLen = strLen;
2405                        cert->subjectJSEnc = (char)b;
2406                    }
2407                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2408                #if (defined(OPENSSL_EXTRA) || \
2409                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2410                        && !defined(WOLFCRYPT_ONLY)
2411                    nid = WC_NID_jurisdictionStateOrProvinceName;
2412                #endif /* OPENSSL_EXTRA */
2413            }
2414
2415            if ((strLen + copyLen) > (int)(WC_ASN_NAME_MAX - idx)) {
2416                WOLFSSL_MSG("ASN Name too big, skipping");
2417                tooBig = TRUE;
2418            }
2419        }
2420    #endif /* WOLFSSL_CERT_EXT */
2421        else {
2422            /* skip */
2423            byte email = FALSE;
2424            byte pilot = FALSE;
2425
2426            if (joint[0] == 0x2a && joint[1] == 0x86) {  /* email id hdr 42.134.* */
2427                id = ASN_EMAIL_NAME;
2428                email = TRUE;
2429            }
2430
2431            if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr 9.146.* */
2432                /* last value of OID is the type of pilot attribute */
2433                id    = input[srcIdx + (word32)oidSz - 1];
2434                if (id == 0x01)
2435                    id = ASN_USER_ID;
2436                pilot = TRUE;
2437            }
2438
2439            srcIdx += (word32)oidSz + 1;
2440
2441            if (GetLength(input, &srcIdx, &strLen, maxIdx) < 0) {
2442            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
2443            !defined(WOLFCRYPT_ONLY)
2444                wolfSSL_X509_NAME_free(dName);
2445            #endif /* OPENSSL_EXTRA */
2446                return ASN_PARSE_E;
2447            }
2448
2449            if (strLen > (int)(WC_ASN_NAME_MAX - idx)) {
2450                WOLFSSL_MSG("ASN name too big, skipping");
2451                tooBig = TRUE;
2452            }
2453
2454            if (email) {
2455                copyLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
2456                if ((copyLen + strLen) > (int)(WC_ASN_NAME_MAX - idx)) {
2457                    WOLFSSL_MSG("ASN name too big, skipping");
2458                    tooBig = TRUE;
2459                }
2460                else {
2461                    copy = WOLFSSL_EMAIL_ADDR;
2462                }
2463
2464                #if !defined(IGNORE_NAME_CONSTRAINTS) || \
2465                     defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
2466                    if (nameType == ASN_SUBJECT) {
2467                        cert->subjectEmail = (char*)&input[srcIdx];
2468                        cert->subjectEmailLen = strLen;
2469                    }
2470                #if defined(WOLFSSL_HAVE_ISSUER_NAMES) && \
2471                    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT))
2472                    else if (nameType == ASN_ISSUER) {
2473                        cert->issuerEmail = (char*)&input[srcIdx];
2474                        cert->issuerEmailLen = strLen;
2475                    }
2476                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
2477                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
2478                #if (defined(OPENSSL_EXTRA) || \
2479                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2480                        && !defined(WOLFCRYPT_ONLY)
2481                    nid = WC_NID_emailAddress;
2482                #endif /* OPENSSL_EXTRA */
2483            }
2484
2485            if (pilot) {
2486                switch (id) {
2487                    case ASN_USER_ID:
2488                        copy = WOLFSSL_USER_ID;
2489                        copyLen = sizeof(WOLFSSL_USER_ID) - 1;
2490                    #if (defined(OPENSSL_EXTRA) || \
2491                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2492                        && !defined(WOLFCRYPT_ONLY)
2493                        nid = WC_NID_userId;
2494                    #endif /* OPENSSL_EXTRA */
2495                        break;
2496                    case ASN_DOMAIN_COMPONENT:
2497                        copy = WOLFSSL_DOMAIN_COMPONENT;
2498                        copyLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
2499                    #if (defined(OPENSSL_EXTRA) || \
2500                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2501                        && !defined(WOLFCRYPT_ONLY)
2502                        nid = WC_NID_domainComponent;
2503                    #endif /* OPENSSL_EXTRA */
2504                        break;
2505                    case ASN_RFC822_MAILBOX:
2506                        copy = WOLFSSL_RFC822_MAILBOX;
2507                        copyLen = sizeof(WOLFSSL_RFC822_MAILBOX) - 1;
2508                    #if (defined(OPENSSL_EXTRA) || \
2509                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2510                        && !defined(WOLFCRYPT_ONLY)
2511                        nid = WC_NID_rfc822Mailbox;
2512                    #endif /* OPENSSL_EXTRA */
2513                        break;
2514                    case ASN_FAVOURITE_DRINK:
2515                        copy = WOLFSSL_FAVOURITE_DRINK;
2516                        copyLen = sizeof(WOLFSSL_FAVOURITE_DRINK) - 1;
2517                    #if (defined(OPENSSL_EXTRA) || \
2518                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2519                        && !defined(WOLFCRYPT_ONLY)
2520                        nid = WC_NID_favouriteDrink;
2521                    #endif /* OPENSSL_EXTRA */
2522                        break;
2523                    case ASN_CONTENT_TYPE:
2524                        copy = WOLFSSL_CONTENT_TYPE;
2525                        copyLen = sizeof(WOLFSSL_CONTENT_TYPE) - 1;
2526                    #if (defined(OPENSSL_EXTRA) || \
2527                        defined(OPENSSL_EXTRA_X509_SMALL)) \
2528                        && !defined(WOLFCRYPT_ONLY)
2529                        nid = WC_NID_pkcs9_contentType;
2530                    #endif /* OPENSSL_EXTRA */
2531                        break;
2532                    default:
2533                        WOLFSSL_MSG("Unknown pilot attribute type");
2534                    #if (defined(OPENSSL_EXTRA) || \
2535                                defined(OPENSSL_EXTRA_X509_SMALL)) && \
2536                                !defined(WOLFCRYPT_ONLY)
2537                        wolfSSL_X509_NAME_free(dName);
2538                    #endif /* OPENSSL_EXTRA */
2539                        return ASN_PARSE_E;
2540                }
2541            }
2542        }
2543        if ((copyLen + strLen) > (int)(WC_ASN_NAME_MAX - idx))
2544        {
2545            WOLFSSL_MSG("ASN Name too big, skipping");
2546            tooBig = TRUE;
2547        }
2548        if ((copy != NULL) && !tooBig) {
2549            XMEMCPY(&full[idx], copy, (size_t)copyLen);
2550            idx += (word32)copyLen;
2551            XMEMCPY(&full[idx], &input[srcIdx], (size_t)strLen);
2552            idx += (word32)strLen;
2553        }
2554        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
2555            !defined(WOLFCRYPT_ONLY)
2556        switch (b) {
2557            case CTC_UTF8:
2558                enc = WOLFSSL_MBSTRING_UTF8;
2559                break;
2560            case CTC_PRINTABLE:
2561                enc = WOLFSSL_V_ASN1_PRINTABLESTRING;
2562                break;
2563            default:
2564                WOLFSSL_MSG("Unknown encoding type, using UTF8 by default");
2565                enc = WOLFSSL_MBSTRING_UTF8;
2566        }
2567
2568        if (nid != WC_NID_undef) {
2569            if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc,
2570                            &input[srcIdx], strLen, -1, -1) !=
2571                            WOLFSSL_SUCCESS) {
2572                wolfSSL_X509_NAME_free(dName);
2573                return ASN_PARSE_E;
2574            }
2575        }
2576        #endif /* OPENSSL_EXTRA */
2577        srcIdx += (word32)strLen;
2578    }
2579    full[idx++] = 0;
2580
2581#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
2582            !defined(WOLFCRYPT_ONLY)
2583    if (nameType == ASN_ISSUER) {
2584#if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)) &&\
2585    (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT))
2586        dName->rawLen = min(cert->issuerRawLen, WC_ASN_NAME_MAX);
2587        XMEMCPY(dName->raw, cert->issuerRaw, dName->rawLen);
2588#endif
2589        cert->issuerName = dName;
2590    }
2591    else {
2592#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
2593        dName->rawLen = min(cert->subjectRawLen, WC_ASN_NAME_MAX);
2594        XMEMCPY(dName->raw, cert->subjectRaw, dName->rawLen);
2595#endif
2596        cert->subjectName = dName;
2597    }
2598#endif
2599
2600    *inOutIdx = srcIdx;
2601
2602    return 0;
2603}
2604
2605int GetName(DecodedCert* cert, int nameType, int maxIdx)
2606{
2607    char*  full;
2608    byte*  hash;
2609    int    length;
2610    word32 localIdx;
2611    byte   tag;
2612
2613    WOLFSSL_MSG("Getting Name");
2614
2615    if (nameType == ASN_ISSUER) {
2616        full = cert->issuer;
2617        hash = cert->issuerHash;
2618    }
2619    else {
2620        full = cert->subject;
2621        hash = cert->subjectHash;
2622    }
2623
2624    if (cert->srcIdx >= (word32)maxIdx) {
2625        return BUFFER_E;
2626    }
2627
2628    localIdx = cert->srcIdx;
2629    if (GetASNTag(cert->source, &localIdx, &tag, (word32)maxIdx) < 0) {
2630        return ASN_PARSE_E;
2631    }
2632
2633    if (tag == ASN_OBJECT_ID) {
2634        WOLFSSL_MSG("Trying optional prefix...");
2635
2636        if (SkipObjectId(cert->source, &cert->srcIdx, (word32)maxIdx) < 0)
2637            return ASN_PARSE_E;
2638        WOLFSSL_MSG("Got optional prefix");
2639    }
2640
2641    localIdx = cert->srcIdx;
2642    if (GetASNTag(cert->source, &localIdx, &tag, (word32)maxIdx) < 0) {
2643        return ASN_PARSE_E;
2644    }
2645    localIdx = cert->srcIdx + 1;
2646    if (GetLength(cert->source, &localIdx, &length, (word32)maxIdx) < 0) {
2647        return ASN_PARSE_E;
2648    }
2649    length += (int)(localIdx - cert->srcIdx);
2650
2651    return GetCertName(cert, full, hash, nameType, cert->source, &cert->srcIdx,
2652                       cert->srcIdx + (word32)length);
2653}
2654
2655static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
2656                        byte* pFormat, int* pLength, word32 maxIdx)
2657{
2658    int length;
2659    byte format;
2660
2661    if (source == NULL || idx == NULL)
2662        return BAD_FUNC_ARG;
2663
2664    /* get ASN format header */
2665    if (*idx+1 > maxIdx)
2666        return BUFFER_E;
2667    format = source[*idx];
2668    *idx += 1;
2669    if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME) {
2670        WOLFSSL_ERROR_VERBOSE(ASN_TIME_E);
2671        return ASN_TIME_E;
2672    }
2673
2674    /* get length */
2675    if (GetLength(source, idx, &length, maxIdx) < 0)
2676        return ASN_PARSE_E;
2677    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
2678        return ASN_DATE_SZ_E;
2679
2680    /* return format, date and length */
2681    if (pFormat)
2682        *pFormat = format;
2683    if (pDate)
2684        *pDate = &source[*idx];
2685    if (pLength)
2686        *pLength = length;
2687
2688    *idx += (word32)length;
2689
2690    return 0;
2691}
2692
2693#ifndef NO_CERTS
2694static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx)
2695{
2696    int    ret, length;
2697    const byte *datePtr = NULL;
2698    byte   date[MAX_DATE_SIZE];
2699    byte   format;
2700    word32 startIdx = 0;
2701
2702    if (dateType == ASN_BEFORE)
2703        cert->beforeDate = &cert->source[cert->srcIdx];
2704    else
2705        cert->afterDate = &cert->source[cert->srcIdx];
2706    startIdx = cert->srcIdx;
2707
2708    ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
2709                      &length, (word32)maxIdx);
2710    if (ret < 0)
2711        return ret;
2712
2713    XMEMSET(date, 0, MAX_DATE_SIZE);
2714    XMEMCPY(date, datePtr, (size_t)length);
2715
2716    if (dateType == ASN_BEFORE)
2717        cert->beforeDateLen = (int)(cert->srcIdx - startIdx);
2718    else
2719        cert->afterDateLen  = (int)(cert->srcIdx - startIdx);
2720
2721#ifndef NO_ASN_TIME_CHECK
2722    if (verify != NO_VERIFY && verify != VERIFY_SKIP_DATE &&
2723            (! AsnSkipDateCheck) &&
2724            !XVALIDATE_DATE(date, format, dateType, length)) {
2725        if (dateType == ASN_BEFORE) {
2726            WOLFSSL_ERROR_VERBOSE(ASN_BEFORE_DATE_E);
2727            return ASN_BEFORE_DATE_E;
2728        }
2729        else {
2730            WOLFSSL_ERROR_VERBOSE(ASN_AFTER_DATE_E);
2731            return ASN_AFTER_DATE_E;
2732        }
2733    }
2734#else
2735    (void)verify;
2736#endif
2737
2738    return 0;
2739}
2740
2741static int GetValidity(DecodedCert* cert, int verify, int maxIdx)
2742{
2743    int length;
2744    int badDate = 0;
2745
2746    if (GetSequence(cert->source, &cert->srcIdx, &length, (word32)maxIdx) < 0)
2747        return ASN_PARSE_E;
2748
2749    maxIdx = (int)cert->srcIdx + length;
2750
2751    if (GetDate(cert, ASN_BEFORE, verify, maxIdx) < 0)
2752        badDate = ASN_BEFORE_DATE_E; /* continue parsing */
2753
2754    if (GetDate(cert, ASN_AFTER, verify, maxIdx) < 0)
2755        return ASN_AFTER_DATE_E;
2756
2757    if (badDate != 0)
2758        return badDate;
2759
2760    return 0;
2761}
2762#endif
2763
2764#ifndef NO_CERTS
2765static int GetSigAlg(DecodedCert* cert, word32* sigOid, word32 maxIdx)
2766{
2767    int length;
2768    word32 endSeqIdx;
2769
2770    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)
2771        return ASN_PARSE_E;
2772    endSeqIdx = cert->srcIdx + (word32)length;
2773
2774    if (GetObjectId(cert->source, &cert->srcIdx, sigOid, oidSigType,
2775                    maxIdx) < 0) {
2776        return ASN_OBJECT_ID_E;
2777    }
2778
2779    if (cert->srcIdx != endSeqIdx) {
2780#ifdef WC_RSA_PSS
2781        if (*sigOid == CTC_RSASSAPSS) {
2782            /* cert->srcIdx is at start of parameters TLV (NULL or SEQUENCE) */
2783            word32 tmpIdx = cert->srcIdx;
2784            byte tag;
2785            int len;
2786
2787            WOLFSSL_MSG("Cert sigAlg is RSASSA-PSS; decoding params");
2788            if (GetHeader(cert->source, &tag, &tmpIdx, &len, endSeqIdx, 1) < 0) {
2789                return ASN_PARSE_E;
2790            }
2791            cert->sigParamsIndex  = cert->srcIdx;
2792            cert->sigParamsLength = (word32)((tmpIdx - cert->srcIdx) + len);
2793        }
2794        else
2795#endif
2796        /* Only allowed a ASN NULL header with zero length. */
2797        if  (endSeqIdx - cert->srcIdx != 2)
2798            return ASN_PARSE_E;
2799        else {
2800            byte tag;
2801            if (GetASNTag(cert->source, &cert->srcIdx, &tag, endSeqIdx) != 0)
2802                return ASN_PARSE_E;
2803            if (tag != ASN_TAG_NULL)
2804                return ASN_PARSE_E;
2805        }
2806    }
2807
2808    cert->srcIdx = endSeqIdx;
2809
2810    return 0;
2811}
2812#endif
2813
2814#ifndef NO_CERTS
2815int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
2816{
2817    int ret;
2818
2819    if (cert == NULL || badDate == NULL)
2820        return BAD_FUNC_ARG;
2821
2822    *badDate = 0;
2823    if ( (ret = GetCertHeader(cert)) < 0)
2824        return ret;
2825
2826    WOLFSSL_MSG("Got Cert Header");
2827
2828#ifdef WOLFSSL_CERT_REQ
2829    if (!cert->isCSR) {
2830#endif
2831        /* Using the sigIndex as the upper bound because that's where the
2832         * actual certificate data ends. */
2833        if ((ret = GetSigAlg(cert, &cert->signatureOID, cert->sigIndex)) < 0)
2834            return ret;
2835
2836        WOLFSSL_MSG("Got Algo ID");
2837
2838        if ( (ret = GetName(cert, ASN_ISSUER, (int)cert->sigIndex)) < 0)
2839            return ret;
2840
2841        if ( (ret = GetValidity(cert, verify, (int)cert->sigIndex)) < 0)
2842            *badDate = ret;
2843#ifdef WOLFSSL_CERT_REQ
2844    }
2845#endif
2846
2847    if ( (ret = GetName(cert, ASN_SUBJECT, (int)cert->sigIndex)) < 0)
2848        return ret;
2849
2850    WOLFSSL_MSG("Got Subject Name");
2851    return ret;
2852}
2853
2854int DecodeToKey(DecodedCert* cert, int verify)
2855{
2856    int badDate = 0;
2857    int ret;
2858
2859#if defined(HAVE_RPK)
2860
2861    /* Raw Public Key certificate has only a SubjectPublicKeyInfo structure
2862     * as its contents. So try to call GetCertKey to get public key from it.
2863     * If it fails, the cert should be a X509 cert and proceed to process as
2864     * x509 cert. */
2865    ret = GetCertKey(cert, cert->source, &cert->srcIdx, cert->maxIdx);
2866    if (ret == 0) {
2867        WOLFSSL_MSG("Raw Public Key certificate found and parsed");
2868        cert->isRPK = 1;
2869        return ret;
2870    }
2871#endif /* HAVE_RPK */
2872
2873    if ( (ret = wc_GetPubX509(cert, verify, &badDate)) < 0)
2874        return ret;
2875
2876    /* Determine if self signed */
2877#ifdef WOLFSSL_CERT_REQ
2878    if (cert->isCSR)
2879        cert->selfSigned = 1;
2880    else
2881#endif
2882    {
2883        cert->selfSigned = XMEMCMP(cert->issuerHash, cert->subjectHash,
2884            KEYID_SIZE) == 0 ? 1 : 0;
2885    }
2886
2887    ret = GetCertKey(cert, cert->source, &cert->srcIdx, cert->maxIdx);
2888    if (ret != 0)
2889        return ret;
2890
2891    WOLFSSL_MSG("Got Key");
2892
2893    if (badDate != 0)
2894        return badDate;
2895
2896    return ret;
2897}
2898
2899static int GetSignature(DecodedCert* cert)
2900{
2901    int length;
2902    int ret;
2903
2904    ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,
2905                         NULL);
2906    if (ret != 0)
2907        return ret;
2908
2909    cert->sigLength = (word32)length;
2910    cert->signature = &cert->source[cert->srcIdx];
2911    cert->srcIdx += cert->sigLength;
2912
2913    if (cert->srcIdx != cert->maxIdx)
2914        return ASN_PARSE_E;
2915
2916    return 0;
2917}
2918
2919#endif
2920/* Set an octet header when length is only 7-bit.
2921 *
2922 * @param [in] len     Length of data in OCTET_STRING. Value must be <= 127.
2923 * @param [in] output  Buffer to encode ASN.1 header.
2924 * @return  Length of ASN.1 header.
2925 */
2926static word32 SetOctetString8Bit(word32 len, byte* output)
2927{
2928    output[0] = ASN_OCTET_STRING;
2929    output[1] = (byte)len;
2930    return 2;
2931}
2932static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
2933{
2934    word32 idx = SetOctetString8Bit(digSz, output);
2935    XMEMCPY(&output[idx], digest, digSz);
2936
2937    return idx + digSz;
2938}
2939
2940static word32 SetAlgoIDImpl(int algoOID, byte* output, int type, int curveSz,
2941                            byte absentParams)
2942{
2943    word32 tagSz, idSz, seqSz, algoSz = 0;
2944    const  byte* algoName = 0;
2945    byte   ID_Length[1 + MAX_LENGTH_SZ];
2946    byte   seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
2947    word32    length = 0;
2948
2949    tagSz = ((type == oidHashType ||
2950             (type == oidSigType && !IsSigAlgoNoParams((word32)algoOID)) ||
2951             (type == oidKeyType && algoOID == RSAk)) &&
2952                (absentParams == FALSE)) ? 2U : 0U;
2953    algoName = OidFromId((word32)algoOID, (word32)type, &algoSz);
2954    if (algoName == NULL) {
2955        WOLFSSL_MSG("Unknown Algorithm");
2956        return 0;
2957    }
2958
2959    idSz  = (word32)SetObjectId((int)algoSz, ID_Length);
2960    seqSz = SetSequence(idSz + algoSz + tagSz + (word32)curveSz, seqArray);
2961
2962    /* Copy only algo to output for DSA keys */
2963    if (algoOID == DSAk && output) {
2964        XMEMCPY(output, ID_Length, idSz);
2965        XMEMCPY(output + idSz, algoName, algoSz);
2966        if (tagSz == 2)
2967            SetASNNull(&output[seqSz + idSz + algoSz]);
2968    }
2969    else if (output) {
2970        XMEMCPY(output, seqArray, seqSz);
2971        XMEMCPY(output + seqSz, ID_Length, idSz);
2972        XMEMCPY(output + seqSz + idSz, algoName, algoSz);
2973        if (tagSz == 2)
2974            SetASNNull(&output[seqSz + idSz + algoSz]);
2975    }
2976
2977    if (algoOID == DSAk)
2978        length = idSz + algoSz + tagSz;
2979    else
2980        length = seqSz + idSz + algoSz + tagSz;
2981
2982    return length;
2983}
2984
2985word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
2986                          int hashOID)
2987{
2988    byte digArray[MAX_ENCODED_DIG_SZ];
2989    byte algoArray[MAX_ALGO_SZ];
2990    byte seqArray[MAX_SEQ_SZ];
2991    word32 encDigSz, algoSz, seqSz;
2992
2993    encDigSz = SetDigest(digest, digSz, digArray);
2994    algoSz   = SetAlgoID(hashOID, algoArray, oidHashType, 0);
2995    seqSz    = SetSequence(encDigSz + algoSz, seqArray);
2996
2997    XMEMCPY(out, seqArray, seqSz);
2998    XMEMCPY(out + seqSz, algoArray, algoSz);
2999    XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
3000
3001    return encDigSz + algoSz + seqSz;
3002}
3003
3004#ifndef NO_CERTS
3005static void AddAltName(DecodedCert* cert, DNS_entry* dnsEntry)
3006{
3007#if (defined(WOLFSSL_ASN_ALL) || defined(OPENSSL_EXTRA)) && \
3008    !defined(WOLFSSL_ALT_NAMES_NO_REV)
3009    /* logic to add alt name to end of list */
3010    dnsEntry->next = NULL;
3011    if (cert->altNames == NULL) {
3012        /* First on list */
3013        cert->altNames = dnsEntry;
3014    }
3015    else {
3016        DNS_entry* temp = cert->altNames;
3017
3018        /* Find end */
3019        for (; (temp->next != NULL); temp = temp->next);
3020
3021        /* Add to end */
3022        temp->next = dnsEntry;
3023    }
3024#else
3025    dnsEntry->next = cert->altNames;
3026    cert->altNames = dnsEntry;
3027#endif
3028}
3029
3030#if defined(WOLFSSL_SEP)
3031/* return 0 on success */
3032static int DecodeSepHwAltName(DecodedCert* cert, const byte* input,
3033    word32* idxIn, word32 sz)
3034{
3035    word32 idx = *idxIn;
3036    int  strLen;
3037    int  ret;
3038    byte tag;
3039
3040    /* Certificates issued with this OID in the subject alt name are for
3041     * verifying signatures created on a module.
3042     * RFC 4108 Section 5. */
3043    if (cert->hwType != NULL) {
3044        WOLFSSL_MSG("\tAlready seen Hardware Module Name");
3045        return ASN_PARSE_E;
3046    }
3047
3048    if (GetASNTag(input, &idx, &tag, sz) < 0) {
3049        return ASN_PARSE_E;
3050    }
3051
3052    if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
3053        WOLFSSL_MSG("\twrong type");
3054        return ASN_PARSE_E;
3055    }
3056
3057    if (GetLength(input, &idx, &strLen, sz) < 0) {
3058        WOLFSSL_MSG("\tfail: str len");
3059        return ASN_PARSE_E;
3060    }
3061
3062    if (GetSequence(input, &idx, &strLen, sz) < 0) {
3063        WOLFSSL_MSG("\tBad Sequence");
3064        return ASN_PARSE_E;
3065    }
3066
3067    ret = GetASNObjectId(input, &idx, &strLen, sz);
3068    if (ret != 0) {
3069        WOLFSSL_MSG("\tbad OID");
3070        return ret;
3071    }
3072
3073    cert->hwType = (byte*)XMALLOC((size_t)strLen, cert->heap,
3074                                  DYNAMIC_TYPE_X509_EXT);
3075    if (cert->hwType == NULL) {
3076        WOLFSSL_MSG("\tOut of Memory");
3077        return MEMORY_E;
3078    }
3079
3080    XMEMCPY(cert->hwType, &input[idx], (size_t)strLen);
3081    cert->hwTypeSz = strLen;
3082    idx += (word32)strLen;
3083
3084    ret = GetOctetString(input, &idx, &strLen, sz);
3085    if (ret < 0) {
3086        XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
3087        cert->hwType = NULL;
3088        return ret;
3089    }
3090
3091    cert->hwSerialNum = (byte*)XMALLOC((size_t)strLen + 1, cert->heap,
3092                                       DYNAMIC_TYPE_X509_EXT);
3093    if (cert->hwSerialNum == NULL) {
3094        WOLFSSL_MSG("\tOut of Memory");
3095        XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
3096        cert->hwType = NULL;
3097        return MEMORY_E;
3098    }
3099
3100    XMEMCPY(cert->hwSerialNum, &input[idx], (size_t)strLen);
3101    cert->hwSerialNum[strLen] = '\0';
3102    cert->hwSerialNumSz = strLen;
3103    idx += (word32)strLen;
3104
3105    *idxIn = idx;
3106    return 0;
3107}
3108#endif
3109
3110/* return 0 on success */
3111static int DecodeConstructedOtherName(DecodedCert* cert, const byte* input,
3112        word32* idx, word32 sz, int oid)
3113{
3114    int ret    = 0;
3115    int strLen = 0;
3116    byte tag;
3117    DNS_entry* dnsEntry = NULL;
3118
3119    if (GetASNTag(input, idx, &tag, sz) < 0) {
3120        ret = ASN_PARSE_E;
3121    }
3122
3123    if (ret == 0 && (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))) {
3124        ret = ASN_PARSE_E;
3125    }
3126
3127    if (ret == 0 && (GetLength(input, idx, &strLen, sz) < 0)) {
3128        ret = ASN_PARSE_E;
3129    }
3130
3131    if (ret == 0) {
3132        dnsEntry = AltNameNew(cert->heap);
3133        if (dnsEntry == NULL) {
3134            WOLFSSL_MSG("\tOut of Memory");
3135            return MEMORY_E;
3136        }
3137
3138        switch (oid) {
3139        #ifdef WOLFSSL_FPKI
3140            case FASCN_OID:
3141                ret = GetOctetString(input, idx, &strLen, sz);
3142                if (ret > 0) {
3143                    ret = 0;
3144                }
3145                break;
3146        #endif /* WOLFSSL_FPKI */
3147            case UPN_OID:
3148                if (GetASNTag(input, idx, &tag, sz) < 0) {
3149                    ret = ASN_PARSE_E;
3150                }
3151
3152                if (ret == 0 &&
3153                        tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
3154                                    tag != ASN_IA5_STRING) {
3155                    WOLFSSL_MSG("Was expecting a string for UPN");
3156                    ret = ASN_PARSE_E;
3157                }
3158
3159                if (ret == 0 && (GetLength(input, idx, &strLen, sz) < 0)) {
3160                    WOLFSSL_MSG("Was expecting a string for UPN");
3161                    ret = ASN_PARSE_E;
3162                }
3163                break;
3164
3165            default:
3166                WOLFSSL_MSG("Unknown constructed other name, skipping");
3167                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
3168                dnsEntry = NULL;
3169        }
3170    }
3171
3172    if (ret == 0 && dnsEntry != NULL) {
3173        dnsEntry->type = ASN_OTHER_TYPE;
3174        dnsEntry->len = strLen;
3175        dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
3176            DYNAMIC_TYPE_ALTNAME);
3177    #ifdef WOLFSSL_FPKI
3178        dnsEntry->oidSum = oid;
3179    #endif /* WOLFSSL_FPKI */
3180        if (dnsEntry->name == NULL) {
3181            WOLFSSL_MSG("\tOut of Memory");
3182            ret = MEMORY_E;
3183        }
3184        else {
3185            dnsEntry->nameStored = 1;
3186            XMEMCPY((void *)(wc_ptr_t)dnsEntry->name, &input[*idx],
3187                    (size_t)strLen);
3188            ((char *)(wc_ptr_t)dnsEntry->name)[strLen] = '\0';
3189            AddAltName(cert, dnsEntry);
3190        }
3191    }
3192
3193    if (ret == 0) {
3194        *idx += (word32)strLen;
3195    }
3196    else {
3197        XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
3198    }
3199
3200    return ret;
3201}
3202
3203/* Reject IA5String SAN content that cannot legally appear in
3204 * dNSName / rfc822Name / URI per RFC 5280 4.2.1.6. Currently just NUL. */
3205static int DecodeGeneralNameCheckChars(const byte* input, int len)
3206{
3207    int i;
3208    for (i = 0; i < len; i++) {
3209        if (input[i] == 0) {
3210            return ASN_PARSE_E;
3211        }
3212    }
3213    return 0;
3214}
3215
3216static int DecodeAltNames(const byte* input, word32 sz, DecodedCert* cert)
3217{
3218    word32 idx = 0;
3219    int length = 0;
3220    word32 numNames = 0;
3221
3222    WOLFSSL_ENTER("DecodeAltNames");
3223
3224    if (GetSequence(input, &idx, &length, sz) < 0) {
3225        WOLFSSL_MSG("\tBad Sequence");
3226        return ASN_PARSE_E;
3227    }
3228
3229    if (length == 0) {
3230        /* RFC 5280 4.2.1.6.  Subject Alternative Name
3231           If the subjectAltName extension is present, the sequence MUST
3232           contain at least one entry. */
3233        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
3234        return ASN_PARSE_E;
3235    }
3236
3237#ifdef OPENSSL_ALL
3238    cert->extSubjAltNameSrc = input;
3239    cert->extSubjAltNameSz = sz;
3240#endif
3241
3242    cert->weOwnAltNames = 1;
3243
3244    while (length > 0) {
3245        byte current_byte;
3246
3247        /* Verify idx can't overflow input buffer */
3248        if (idx >= (word32)sz) {
3249            WOLFSSL_MSG("\tBad Index");
3250            return BUFFER_E;
3251        }
3252
3253        numNames++;
3254        if (numNames > WOLFSSL_MAX_ALT_NAMES) {
3255            WOLFSSL_MSG("\tToo many subject alternative names");
3256            return ASN_ALT_NAME_E;
3257        }
3258
3259        current_byte = input[idx++];
3260        length--;
3261
3262        /* Save DNS Type names in the altNames list. */
3263        /* Save Other Type names in the cert's OidMap */
3264        if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
3265            DNS_entry* dnsEntry;
3266            int strLen;
3267            word32 lenStartIdx = idx;
3268
3269            if (GetLength(input, &idx, &strLen, sz) < 0) {
3270                WOLFSSL_MSG("\tfail: str length");
3271                return ASN_PARSE_E;
3272            }
3273            length -= (int)(idx - lenStartIdx);
3274
3275            if ((word32)strLen + idx > sz) {
3276                return BUFFER_E;
3277            }
3278            if (DecodeGeneralNameCheckChars(&input[idx], strLen) != 0) {
3279                return ASN_PARSE_E;
3280            }
3281
3282            dnsEntry = AltNameNew(cert->heap);
3283            if (dnsEntry == NULL) {
3284                WOLFSSL_MSG("\tOut of Memory");
3285                return MEMORY_E;
3286            }
3287
3288            dnsEntry->type = ASN_DNS_TYPE;
3289            dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
3290                                         DYNAMIC_TYPE_ALTNAME);
3291            if (dnsEntry->name == NULL) {
3292                WOLFSSL_MSG("\tOut of Memory");
3293                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
3294                return MEMORY_E;
3295            }
3296            dnsEntry->nameStored = 1;
3297            dnsEntry->len = strLen;
3298            XMEMCPY((void *)(wc_ptr_t)dnsEntry->name, &input[idx],
3299                    (size_t)strLen);
3300            ((char *)(wc_ptr_t)dnsEntry->name)[strLen] = '\0';
3301
3302            AddAltName(cert, dnsEntry);
3303
3304            if (strLen > length) {
3305                return ASN_PARSE_E;
3306            }
3307            length -= strLen;
3308            idx    += (word32)strLen;
3309        }
3310    #ifndef IGNORE_NAME_CONSTRAINTS
3311        else if (current_byte ==
3312                (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
3313            DNS_entry* dirEntry;
3314            int strLen;
3315            word32 lenStartIdx = idx;
3316
3317            if (GetLength(input, &idx, &strLen, sz) < 0) {
3318                WOLFSSL_MSG("\tfail: str length");
3319                return ASN_PARSE_E;
3320            }
3321
3322            if (GetSequence(input, &idx, &strLen, sz) < 0) {
3323                WOLFSSL_MSG("\tfail: seq length");
3324                return ASN_PARSE_E;
3325            }
3326            length -= (int)(idx - lenStartIdx);
3327
3328            dirEntry = AltNameNew(cert->heap);
3329            if (dirEntry == NULL) {
3330                WOLFSSL_MSG("\tOut of Memory");
3331                return MEMORY_E;
3332            }
3333
3334            dirEntry->type = ASN_DIR_TYPE;
3335            dirEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
3336                                         DYNAMIC_TYPE_ALTNAME);
3337            if (dirEntry->name == NULL) {
3338                WOLFSSL_MSG("\tOut of Memory");
3339                XFREE(dirEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
3340                return MEMORY_E;
3341            }
3342            dirEntry->nameStored = 1;
3343            dirEntry->len = strLen;
3344            XMEMCPY((void *)(wc_ptr_t)dirEntry->name, &input[idx],
3345                    (size_t)strLen);
3346            ((char *)(wc_ptr_t)dirEntry->name)[strLen] = '\0';
3347            dirEntry->next = cert->altDirNames;
3348            cert->altDirNames = dirEntry;
3349
3350            if (strLen > length) {
3351                return ASN_PARSE_E;
3352            }
3353            length -= strLen;
3354            idx    += (word32)strLen;
3355        }
3356        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
3357            DNS_entry* emailEntry;
3358            int strLen;
3359            word32 lenStartIdx = idx;
3360
3361            if (GetLength(input, &idx, &strLen, sz) < 0) {
3362                WOLFSSL_MSG("\tfail: str length");
3363                return ASN_PARSE_E;
3364            }
3365            length -= (int)(idx - lenStartIdx);
3366
3367            if ((word32)strLen + idx > sz) {
3368                return BUFFER_E;
3369            }
3370            if (DecodeGeneralNameCheckChars(&input[idx], strLen) != 0) {
3371                return ASN_PARSE_E;
3372            }
3373
3374            emailEntry = AltNameNew(cert->heap);
3375            if (emailEntry == NULL) {
3376                WOLFSSL_MSG("\tOut of Memory");
3377                return MEMORY_E;
3378            }
3379            emailEntry->nameStored = 1;
3380            emailEntry->type = ASN_RFC822_TYPE;
3381            emailEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
3382                                         DYNAMIC_TYPE_ALTNAME);
3383            if (emailEntry->name == NULL) {
3384                WOLFSSL_MSG("\tOut of Memory");
3385                XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
3386                return MEMORY_E;
3387            }
3388            emailEntry->len = strLen;
3389            XMEMCPY((void *)(wc_ptr_t)emailEntry->name, &input[idx],
3390                    (size_t)strLen);
3391            ((char *)(wc_ptr_t)emailEntry->name)[strLen] = '\0';
3392
3393            emailEntry->next = cert->altEmailNames;
3394            cert->altEmailNames = emailEntry;
3395
3396            if (strLen > length) {
3397                return ASN_PARSE_E;
3398            }
3399            length -= strLen;
3400            idx    += (word32)strLen;
3401        }
3402        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
3403            DNS_entry* uriEntry;
3404            int strLen;
3405            word32 lenStartIdx = idx;
3406
3407            WOLFSSL_MSG("\tPutting URI into list but not using");
3408            if (GetLength(input, &idx, &strLen, sz) < 0) {
3409                WOLFSSL_MSG("\tfail: str length");
3410                return ASN_PARSE_E;
3411            }
3412            length -= (int)(idx - lenStartIdx);
3413
3414            /* check that strLen at index is not past input buffer */
3415            if ((word32)strLen + idx > sz) {
3416                return BUFFER_E;
3417            }
3418
3419            if (DecodeGeneralNameCheckChars(&input[idx], strLen) != 0) {
3420                return ASN_PARSE_E;
3421            }
3422
3423        #if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)
3424            /* Verify RFC 5280 Sec 4.2.1.6 rule:
3425                "The name MUST NOT be a relative URI"
3426                As per RFC 3986 Sec 4.3, an absolute URI is only required to contain
3427                a scheme and hier-part.  So the only strict requirement is a ':'
3428                being present after the scheme.  If a '/' is present as part of the
3429                hier-part, it must come after the ':' (see RFC 3986 Sec 3). */
3430
3431            {
3432                word32 i;
3433
3434                /* skip past scheme (i.e http,ftp,...) finding first ':' char */
3435                for (i = 0; i < (word32)strLen; i++) {
3436                    if (input[idx + i] == ':') {
3437                        break;
3438                    }
3439                    if (input[idx + i] == '/') {
3440                        WOLFSSL_MSG("\tAlt Name must be absolute URI");
3441                        WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
3442                        return ASN_ALT_NAME_E;
3443                    }
3444                }
3445
3446                /* test hier-part is empty */
3447                if (i == 0 || i == (word32)strLen) {
3448                    WOLFSSL_MSG("\tEmpty or malformed URI");
3449                    WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
3450                    return ASN_ALT_NAME_E;
3451                }
3452
3453                /* test if scheme is missing */
3454                if (input[idx + i] != ':') {
3455                    WOLFSSL_MSG("\tAlt Name must be absolute URI");
3456                    WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
3457                    return ASN_ALT_NAME_E;
3458                }
3459            }
3460        #endif
3461
3462            uriEntry = AltNameNew(cert->heap);
3463            if (uriEntry == NULL) {
3464                WOLFSSL_MSG("\tOut of Memory");
3465                return MEMORY_E;
3466            }
3467            uriEntry->nameStored = 1;
3468            uriEntry->type = ASN_URI_TYPE;
3469            uriEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
3470                                         DYNAMIC_TYPE_ALTNAME);
3471            if (uriEntry->name == NULL) {
3472                WOLFSSL_MSG("\tOut of Memory");
3473                XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
3474                return MEMORY_E;
3475            }
3476            uriEntry->len = strLen;
3477            XMEMCPY((void *)(wc_ptr_t)uriEntry->name, &input[idx],
3478                    (size_t)strLen);
3479            ((char *)(wc_ptr_t)uriEntry->name)[strLen] = '\0';
3480
3481            AddAltName(cert, uriEntry);
3482
3483            if (strLen > length) {
3484                return ASN_PARSE_E;
3485            }
3486            length -= strLen;
3487            idx    += (word32)strLen;
3488        }
3489        /* iPAddress is parsed unconditionally so ConfirmNameConstraints
3490         * can enforce permitted/excluded iPAddress subtrees
3491         * (RFC 5280 Sec. 4.2.1.10). WOLFSSL_IP_ALT_NAME only gates the
3492         * human-readable ipString form. */
3493        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
3494            DNS_entry* ipAddr;
3495            int strLen;
3496            word32 lenStartIdx = idx;
3497            WOLFSSL_MSG("Decoding Subject Alt. Name: IP Address");
3498
3499            if (GetLength(input, &idx, &strLen, sz) < 0) {
3500                WOLFSSL_MSG("\tfail: str length");
3501                return ASN_PARSE_E;
3502            }
3503            length -= (idx - lenStartIdx);
3504            /* check that strLen at index is not past input buffer */
3505            if (strLen + idx > sz) {
3506                return BUFFER_E;
3507            }
3508
3509            ipAddr = AltNameNew(cert->heap);
3510            if (ipAddr == NULL) {
3511                WOLFSSL_MSG("\tOut of Memory");
3512                return MEMORY_E;
3513            }
3514            ipAddr->nameStored = 1;
3515            ipAddr->type = ASN_IP_TYPE;
3516            ipAddr->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
3517                                         DYNAMIC_TYPE_ALTNAME);
3518            if (ipAddr->name == NULL) {
3519                WOLFSSL_MSG("\tOut of Memory");
3520                XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
3521                return MEMORY_E;
3522            }
3523            ipAddr->len = strLen;
3524            XMEMCPY((void *)(wc_ptr_t)ipAddr->name, &input[idx], strLen);
3525            ((char *)(wc_ptr_t)ipAddr->name)[strLen] = '\0';
3526
3527#ifdef WOLFSSL_IP_ALT_NAME
3528            if (GenerateDNSEntryIPString(ipAddr, cert->heap) != 0) {
3529                WOLFSSL_MSG("\tOut of Memory for IP string");
3530                XFREE((void *)(wc_ptr_t)ipAddr->name, cert->heap,
3531                      DYNAMIC_TYPE_ALTNAME);
3532                XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
3533                return MEMORY_E;
3534            }
3535#endif /* WOLFSSL_IP_ALT_NAME */
3536            AddAltName(cert, ipAddr);
3537
3538            if (strLen > length) {
3539                return ASN_PARSE_E;
3540            }
3541            length -= strLen;
3542            idx    += (word32)strLen;
3543        }
3544        /* registeredID is parsed unconditionally so ConfirmNameConstraints
3545         * can enforce permitted/excluded subtrees (RFC 5280 Sec. 4.2.1.10).
3546         * WOLFSSL_RID_ALT_NAME only gates the human-readable ridString. */
3547        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_RID_TYPE)) {
3548            DNS_entry* rid;
3549            int strLen;
3550            word32 lenStartIdx = idx;
3551            WOLFSSL_MSG("Decoding Subject Alt. Name: Registered Id");
3552
3553            if (GetLength(input, &idx, &strLen, sz) < 0) {
3554                WOLFSSL_MSG("\tfail: str length");
3555                return ASN_PARSE_E;
3556            }
3557            length -= (idx - lenStartIdx);
3558            /* check that strLen at index is not past input buffer */
3559            if (strLen + idx > sz) {
3560                return BUFFER_E;
3561            }
3562
3563            rid = AltNameNew(cert->heap);
3564            if (rid == NULL) {
3565                WOLFSSL_MSG("\tOut of Memory");
3566                return MEMORY_E;
3567            }
3568
3569            rid->type = ASN_RID_TYPE;
3570            rid->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
3571                                         DYNAMIC_TYPE_ALTNAME);
3572            if (rid->name == NULL) {
3573                WOLFSSL_MSG("\tOut of Memory");
3574                XFREE(rid, cert->heap, DYNAMIC_TYPE_ALTNAME);
3575                return MEMORY_E;
3576            }
3577            rid->nameStored = 1;
3578            rid->len = strLen;
3579            XMEMCPY((void *)(wc_ptr_t)rid->name, &input[idx], strLen);
3580            ((char *)(wc_ptr_t)rid->name)[strLen] = '\0';
3581
3582#ifdef WOLFSSL_RID_ALT_NAME
3583            if (GenerateDNSEntryRIDString(rid, cert->heap) != 0) {
3584                WOLFSSL_MSG("\tOut of Memory for registered Id string");
3585                XFREE((void *)(wc_ptr_t)rid->name, cert->heap,
3586                      DYNAMIC_TYPE_ALTNAME);
3587                XFREE(rid, cert->heap, DYNAMIC_TYPE_ALTNAME);
3588                return MEMORY_E;
3589            }
3590#endif /* WOLFSSL_RID_ALT_NAME */
3591
3592            AddAltName(cert, rid);
3593
3594            if (strLen > length) {
3595                return ASN_PARSE_E;
3596            }
3597            length -= strLen;
3598            idx    += (word32)strLen;
3599        }
3600#endif /* IGNORE_NAME_CONSTRAINTS */
3601        else if (current_byte ==
3602                (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) {
3603            int strLen;
3604            word32 lenStartIdx = idx;
3605            word32 oid = 0;
3606            int    ret = 0;
3607
3608            if (GetLength(input, &idx, &strLen, sz) < 0) {
3609                WOLFSSL_MSG("\tfail: other name length");
3610                return ASN_PARSE_E;
3611            }
3612            /* Consume the rest of this sequence. */
3613            if ((int)((word32)strLen + idx - lenStartIdx) > length) {
3614                return ASN_PARSE_E;
3615            }
3616            length -= (int)(((word32)strLen + idx - lenStartIdx));
3617
3618        #ifndef IGNORE_NAME_CONSTRAINTS
3619            /* Store the raw OtherName encoding (OID || [0] EXPLICIT value)
3620             * on the dedicated altOtherNamesRaw list so
3621             * ConfirmNameConstraints() can byte-match it against the
3622             * issuing CA's subtree (RFC 5280 4.2.1.10). Kept separate from
3623             * altNames so OpenSSL-compat APIs see exactly what the SAN
3624             * extension carries. */
3625            {
3626                DNS_entry* rawEntry = AltNameNew(cert->heap);
3627                if (rawEntry == NULL) {
3628                    WOLFSSL_MSG("\tOut of Memory");
3629                    return MEMORY_E;
3630                }
3631                rawEntry->type = ASN_OTHER_TYPE;
3632                rawEntry->len  = strLen;
3633                rawEntry->name = (char*)XMALLOC((size_t)strLen + 1,
3634                    cert->heap, DYNAMIC_TYPE_ALTNAME);
3635                if (rawEntry->name == NULL) {
3636                    XFREE(rawEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
3637                    return MEMORY_E;
3638                }
3639                rawEntry->nameStored = 1;
3640                XMEMCPY((void*)(wc_ptr_t)rawEntry->name, &input[idx],
3641                    (size_t)strLen);
3642                ((char*)(wc_ptr_t)rawEntry->name)[strLen] = '\0';
3643                rawEntry->next = cert->altOtherNamesRaw;
3644                cert->altOtherNamesRaw = rawEntry;
3645            }
3646        #endif /* IGNORE_NAME_CONSTRAINTS */
3647
3648            if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {
3649                WOLFSSL_MSG("\tbad OID");
3650                return ASN_PARSE_E;
3651            }
3652
3653            /* handle parsing other type alt names */
3654            switch (oid) {
3655            #ifdef WOLFSSL_SEP
3656                case HW_NAME_OID:
3657                    ret = DecodeSepHwAltName(cert, input, &idx, sz);
3658                    if (ret != 0)
3659                        return ret;
3660                    break;
3661            #endif /* WOLFSSL_SEP */
3662            #ifdef WOLFSSL_FPKI
3663                case FASCN_OID:
3664                case UPN_OID:
3665                    ret = DecodeConstructedOtherName(cert, input, &idx, sz,
3666                            oid);
3667                    if (ret != 0)
3668                        return ret;
3669                    break;
3670            #endif /* WOLFSSL_FPKI */
3671
3672                default:
3673                    WOLFSSL_MSG("\tUnsupported other name type, skipping");
3674                    if (GetLength(input, &idx, &strLen, sz) < 0) {
3675                        /* check to skip constructed other names too */
3676                        if (DecodeConstructedOtherName(cert, input, &idx, sz,
3677                                    (int)oid) != 0) {
3678                            WOLFSSL_MSG("\tfail: unsupported other name length");
3679                            return ASN_PARSE_E;
3680                        }
3681                    }
3682                    else {
3683                        idx += (word32)strLen;
3684                    }
3685            }
3686            (void)ret;
3687        }
3688        else {
3689            int strLen;
3690            word32 lenStartIdx = idx;
3691
3692            WOLFSSL_MSG("\tUnsupported name type, skipping");
3693
3694            if (GetLength(input, &idx, &strLen, sz) < 0) {
3695                WOLFSSL_MSG("\tfail: unsupported name length");
3696                return ASN_PARSE_E;
3697            }
3698            if ((int)((word32)strLen + idx - lenStartIdx) > length) {
3699                return ASN_PARSE_E;
3700            }
3701            length -= (int)((word32)strLen + idx - lenStartIdx);
3702            idx += (word32)strLen;
3703        }
3704    }
3705
3706    return 0;
3707}
3708
3709int DecodeBasicCaConstraint(const byte* input, int sz, byte *isCa,
3710                            word16 *pathLength, byte *pathLengthSet)
3711{
3712    word32 idx = 0;
3713    int length = 0;
3714    int ret;
3715
3716    WOLFSSL_ENTER("DecodeBasicCaConstraint");
3717
3718    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
3719        WOLFSSL_MSG("\tfail: bad SEQUENCE");
3720        return ASN_PARSE_E;
3721    }
3722
3723    if (length == 0)
3724        return 0;
3725
3726    /* If the basic ca constraint is false, this extension may be named, but
3727     * left empty. So, if the length is 0, just return. */
3728
3729    ret = GetBoolean(input, &idx, (word32)sz);
3730
3731    /* Removed logic for WOLFSSL_X509_BASICCONS_INT which was mistreating the
3732     * pathlen value as if it were the CA Boolean value 7/2/2021 - KH.
3733     * When CA Boolean not asserted use the default value "False" */
3734    if (ret < 0) {
3735        WOLFSSL_MSG("\tfail: constraint not valid BOOLEAN, set default FALSE");
3736        ret = 0;
3737    }
3738
3739    *isCa = ret ? 1 : 0;
3740
3741    /* If there isn't any more data, return. */
3742    if (idx >= (word32)sz) {
3743        return 0;
3744    }
3745
3746    ret = GetInteger16Bit(input, &idx, (word32)sz);
3747    if (ret < 0)
3748        return ret;
3749    else if (ret > WOLFSSL_MAX_PATH_LEN) {
3750        WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E);
3751        return ASN_PATHLEN_SIZE_E;
3752    }
3753
3754    *pathLength = (word16)ret;
3755    *pathLengthSet = 1;
3756
3757    return 0;
3758}
3759
3760static int DecodeCrlDist(const byte* input, word32 sz, DecodedCert* cert)
3761{
3762    word32 idx = 0, localIdx;
3763    int length = 0;
3764    byte tag   = 0;
3765
3766    WOLFSSL_ENTER("DecodeCrlDist");
3767
3768    cert->extCrlInfoRaw = input;
3769    cert->extCrlInfoRawSz = (int)sz;
3770
3771    /* Unwrap the list of Distribution Points*/
3772    if (GetSequence(input, &idx, &length, sz) < 0)
3773        return ASN_PARSE_E;
3774
3775    /* Unwrap a single Distribution Point */
3776    if (GetSequence(input, &idx, &length, sz) < 0)
3777        return ASN_PARSE_E;
3778
3779    /* The Distribution Point has three explicit optional members
3780     *  First check for a DistributionPointName
3781     */
3782    localIdx = idx;
3783    if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
3784            tag == (ASN_CONSTRUCTED | DISTRIBUTION_POINT))
3785    {
3786        idx++;
3787        if (GetLength(input, &idx, &length, sz) < 0)
3788            return ASN_PARSE_E;
3789
3790        localIdx = idx;
3791        if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
3792                tag == (ASN_CONSTRUCTED | CRLDP_FULL_NAME))
3793        {
3794            idx++;
3795            if (GetLength(input, &idx, &length, sz) < 0)
3796                return ASN_PARSE_E;
3797
3798            localIdx = idx;
3799            if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
3800                    tag == GENERALNAME_URI)
3801            {
3802                idx++;
3803                if (GetLength(input, &idx, &length, sz) < 0)
3804                    return ASN_PARSE_E;
3805
3806                cert->extCrlInfoSz = length;
3807                cert->extCrlInfo = input + idx;
3808                idx += (word32)length;
3809            }
3810            else
3811                /* This isn't a URI, skip it. */
3812                idx += (word32)length;
3813        }
3814        else {
3815            /* This isn't a FULLNAME, skip it. */
3816            idx += (word32)length;
3817        }
3818    }
3819
3820    /* Check for reasonFlags */
3821    localIdx = idx;
3822    if (idx < (word32)sz &&
3823        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
3824        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
3825    {
3826        idx++;
3827        if (GetLength(input, &idx, &length, sz) < 0)
3828            return ASN_PARSE_E;
3829        idx += (word32)length;
3830    }
3831
3832    /* Check for cRLIssuer */
3833    localIdx = idx;
3834    if (idx < (word32)sz &&
3835        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
3836        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
3837    {
3838        idx++;
3839        if (GetLength(input, &idx, &length, sz) < 0)
3840            return ASN_PARSE_E;
3841        idx += (word32)length;
3842    }
3843
3844    if (idx < (word32)sz)
3845    {
3846        WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
3847                   "but we only use the first one.");
3848    }
3849
3850    return 0;
3851}
3852
3853static int DecodeAuthInfo(const byte* input, word32 sz, DecodedCert* cert)
3854{
3855    word32 idx = 0;
3856    int length = 0;
3857    byte b = 0;
3858    word32 oid;
3859    int aiaIdx;
3860
3861    WOLFSSL_ENTER("DecodeAuthInfo");
3862
3863    /* Unwrap the list of AIAs */
3864    if (GetSequence(input, &idx, &length, sz) < 0)
3865        return ASN_PARSE_E;
3866
3867    while ((idx < (word32)sz)) {
3868        /* Unwrap a single AIA */
3869        if (GetSequence(input, &idx, &length, sz) < 0)
3870            return ASN_PARSE_E;
3871
3872        oid = 0;
3873        if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0) {
3874            return ASN_PARSE_E;
3875        }
3876
3877        /* Only supporting URIs right now. */
3878        if (GetASNTag(input, &idx, &b, sz) < 0)
3879            return ASN_PARSE_E;
3880
3881        if (GetLength(input, &idx, &length, sz) < 0)
3882            return ASN_PARSE_E;
3883
3884        if (b == GENERALNAME_URI) {
3885            /* Add to AIA list if space. */
3886            aiaIdx = cert->extAuthInfoListSz;
3887            if (aiaIdx < WOLFSSL_MAX_AIA_ENTRIES) {
3888                cert->extAuthInfoList[aiaIdx].method = oid;
3889                cert->extAuthInfoList[aiaIdx].uri = input + idx;
3890                cert->extAuthInfoList[aiaIdx].uriSz = (word32)length;
3891                cert->extAuthInfoListSz++;
3892            }
3893            else {
3894                cert->extAuthInfoListOverflow = 1;
3895                WOLFSSL_MSG("AIA list overflow");
3896            }
3897        }
3898
3899        /* Set first ocsp entry */
3900        if (b == GENERALNAME_URI && oid == AIA_OCSP_OID &&
3901                cert->extAuthInfo == NULL) {
3902            cert->extAuthInfoSz = length;
3903            cert->extAuthInfo = input + idx;
3904        }
3905    #ifdef WOLFSSL_ASN_CA_ISSUER
3906        /* Set first CaIssuers entry */
3907        else if ((b == GENERALNAME_URI) && oid == AIA_CA_ISSUER_OID &&
3908                cert->extAuthInfoCaIssuer == NULL)
3909        {
3910            cert->extAuthInfoCaIssuerSz = length;
3911            cert->extAuthInfoCaIssuer = input + idx;
3912        }
3913    #endif
3914        idx += (word32)length;
3915    }
3916
3917    return 0;
3918}
3919
3920int DecodeAuthKeyId(const byte* input, word32 sz, const byte **extAuthKeyId,
3921        word32 *extAuthKeyIdSz, const byte **extAuthKeyIdIssuer,
3922        word32 *extAuthKeyIdIssuerSz, const byte **extAuthKeyIdIssuerSN,
3923        word32 *extAuthKeyIdIssuerSNSz)
3924{
3925    word32 idx = 0;
3926    int length = 0;
3927    byte tag;
3928
3929    WOLFSSL_ENTER("DecodeAuthKeyId");
3930
3931    if (extAuthKeyId)
3932        *extAuthKeyId = NULL;
3933    if (extAuthKeyIdSz)
3934        *extAuthKeyIdSz = 0;
3935
3936    if (extAuthKeyIdIssuer)
3937        *extAuthKeyIdIssuer = NULL;
3938    if (extAuthKeyIdIssuerSz)
3939        *extAuthKeyIdIssuerSz = 0;
3940
3941    if (extAuthKeyIdIssuerSN)
3942        *extAuthKeyIdIssuerSN = NULL;
3943    if (extAuthKeyIdIssuerSNSz)
3944        *extAuthKeyIdIssuerSNSz = 0;
3945
3946    if (GetSequence(input, &idx, &length, sz) < 0) {
3947        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
3948        return ASN_PARSE_E;
3949    }
3950
3951    if (GetASNTag(input, &idx, &tag, sz) < 0) {
3952        return ASN_PARSE_E;
3953    }
3954
3955    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
3956        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
3957        return 0;
3958    }
3959
3960    if (GetLength(input, &idx, &length, sz) <= 0) {
3961        WOLFSSL_MSG("\tfail: extension data length");
3962        return ASN_PARSE_E;
3963    }
3964
3965    if (extAuthKeyIdSz)
3966        *extAuthKeyIdSz = length;
3967    if (extAuthKeyId)
3968        *extAuthKeyId = &input[idx];
3969    return 0;
3970
3971}
3972
3973int DecodeKeyUsage(const byte* input, word32 sz, word16 *extKeyUsage)
3974{
3975    word32 idx = 0;
3976    int length;
3977    int ret;
3978    WOLFSSL_ENTER("DecodeKeyUsage");
3979
3980    ret = CheckBitString(input, &idx, &length, sz, 0, NULL);
3981    if (ret != 0)
3982        return ret;
3983
3984    if (length == 0 || length > 2)
3985        return ASN_PARSE_E;
3986
3987    *extKeyUsage = (word16)(input[idx]);
3988    if (length == 2)
3989        *extKeyUsage |= (word16)(input[idx+1] << 8);
3990
3991    return 0;
3992}
3993
3994int DecodeExtKeyUsage(const byte* input, word32 sz,
3995        const byte **extExtKeyUsageSrc, word32 *extExtKeyUsageSz,
3996        word32 *extExtKeyUsageCount, byte *extExtKeyUsage,
3997        byte *extExtKeyUsageSsh)
3998{
3999    word32 idx = 0, oid;
4000    int length, ret;
4001
4002    WOLFSSL_ENTER("DecodeExtKeyUsage");
4003
4004    (void) extExtKeyUsageSrc;
4005    (void) extExtKeyUsageSz;
4006    (void) extExtKeyUsageCount;
4007    (void) extExtKeyUsageSsh;
4008
4009#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
4010    *extExtKeyUsageSrc = NULL;
4011    *extExtKeyUsageSz = 0;
4012    *extExtKeyUsageCount = 0;
4013#endif
4014    *extExtKeyUsage = 0;
4015#ifdef WOLFSSL_WOLFSSH
4016    *extExtKeyUsageSsh = 0;
4017#endif
4018
4019    if (GetSequence(input, &idx, &length, sz) < 0) {
4020        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
4021        return ASN_PARSE_E;
4022    }
4023
4024#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
4025    *extExtKeyUsageSrc = input + idx;
4026    *extExtKeyUsageSz = length;
4027#endif
4028
4029    while (idx < (word32)sz) {
4030        ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
4031        if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E))
4032            continue;
4033        else if (ret < 0)
4034            return ret;
4035
4036        switch (oid) {
4037            case EKU_ANY_OID:
4038                *extExtKeyUsage |= EXTKEYUSE_ANY;
4039                break;
4040            case EKU_SERVER_AUTH_OID:
4041                *extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
4042                break;
4043            case EKU_CLIENT_AUTH_OID:
4044                *extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
4045                break;
4046            case EKU_CODESIGNING_OID:
4047                *extExtKeyUsage |= EXTKEYUSE_CODESIGN;
4048                break;
4049            case EKU_EMAILPROTECT_OID:
4050                *extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
4051                break;
4052            case EKU_TIMESTAMP_OID:
4053                *extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
4054                break;
4055            case EKU_OCSP_SIGN_OID:
4056                *extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
4057                break;
4058            #ifdef WOLFSSL_WOLFSSH
4059            case EKU_SSH_CLIENT_AUTH_OID:
4060                *extExtKeyUsageSsh |= EXTKEYUSE_SSH_CLIENT_AUTH;
4061                break;
4062            case EKU_SSH_MSCL_OID:
4063                *extExtKeyUsageSsh |= EXTKEYUSE_SSH_MSCL;
4064                break;
4065            case EKU_SSH_KP_CLIENT_AUTH_OID:
4066                *extExtKeyUsageSsh |= EXTKEYUSE_SSH_KP_CLIENT_AUTH;
4067                break;
4068            #endif /* WOLFSSL_WOLFSSH */
4069            default:
4070                break;
4071        }
4072
4073    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
4074        (*extExtKeyUsageCount)++;
4075    #endif
4076    }
4077
4078    return 0;
4079}
4080
4081#ifndef IGNORE_NAME_CONSTRAINTS
4082/* See doc on the WOLFSSL_ASN_TEMPLATE definition in asn.c. hasUnsupported
4083 * must not be NULL. */
4084static int DecodeSubtree(const byte* input, word32 sz, Base_entry** head,
4085                         word32 limit, byte* hasUnsupported, void* heap)
4086{
4087    word32 idx = 0;
4088    int ret = 0;
4089    word32 cnt = 0;
4090
4091    (void)heap;
4092
4093    while (idx < (word32)sz) {
4094        int seqLength, strLength;
4095        word32 nameIdx;
4096        byte b, bType;
4097
4098        if (limit > 0) {
4099            cnt++;
4100            if (cnt > limit) {
4101                WOLFSSL_MSG("too many name constraints");
4102                return ASN_NAME_INVALID_E;
4103            }
4104        }
4105
4106        if (GetSequence(input, &idx, &seqLength, sz) < 0) {
4107            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
4108            return ASN_PARSE_E;
4109        }
4110
4111        if (idx >= (word32)sz) {
4112            WOLFSSL_MSG("\tfail: expecting tag");
4113            return ASN_PARSE_E;
4114        }
4115
4116        nameIdx = idx;
4117        b = input[nameIdx++];
4118
4119        if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
4120            WOLFSSL_MSG("\tinvalid length");
4121            return ASN_PARSE_E;
4122        }
4123
4124        /* Get type, LSB 4-bits */
4125        bType = (byte)(b & ASN_TYPE_MASK);
4126
4127        /* registeredID is included so ConfirmNameConstraints can enforce
4128         * permitted/excluded subtrees of OIDs (RFC 5280 Sec. 4.2.1.10). */
4129        if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||
4130            bType == ASN_DIR_TYPE || bType == ASN_IP_TYPE ||
4131            bType == ASN_URI_TYPE || bType == ASN_OTHER_TYPE ||
4132            bType == ASN_RID_TYPE) {
4133            Base_entry* entry;
4134
4135            /* directoryName is encoded as [4] CONSTRUCTED { Name } where
4136             * Name is a SEQUENCE; strip the inner SEQUENCE header.
4137             * otherName is encoded as [0] CONSTRUCTED { OID, [0] EXPLICIT
4138             * value }; the inner content is NOT a SEQUENCE so keep it
4139             * as-is (matches the WOLFSSL_ASN_TEMPLATE path). */
4140            if ((b & ASN_CONSTRUCTED) && bType != ASN_OTHER_TYPE) {
4141                if (GetSequence(input, &nameIdx, &strLength, sz) < 0) {
4142                    WOLFSSL_MSG("\tfail: constructed be a SEQUENCE");
4143                    return ASN_PARSE_E;
4144                }
4145            }
4146
4147            entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
4148                                                          DYNAMIC_TYPE_ALTNAME);
4149            if (entry == NULL) {
4150                WOLFSSL_MSG("allocate error");
4151                return MEMORY_E;
4152            }
4153
4154            entry->name = (char*)XMALLOC((size_t)strLength+1, heap,
4155                DYNAMIC_TYPE_ALTNAME);
4156            if (entry->name == NULL) {
4157                WOLFSSL_MSG("allocate error");
4158                XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
4159                return MEMORY_E;
4160            }
4161
4162            XMEMCPY(entry->name, &input[nameIdx], (size_t)strLength);
4163            entry->name[strLength] = '\0';
4164            entry->nameSz = strLength;
4165            entry->type = bType;
4166
4167            entry->next = *head;
4168            *head = entry;
4169        }
4170        else {
4171            /* GeneralName form (e.g. registeredID, x400Address,
4172             * ediPartyName) we do not enforce. Record so the caller can
4173             * fail-closed when the nameConstraints extension is critical
4174             * (RFC 5280 4.2.1.10). */
4175            *hasUnsupported = 1;
4176        }
4177
4178        idx += (word32)seqLength;
4179    }
4180
4181    return ret;
4182}
4183
4184static int DecodeNameConstraints(const byte* input, word32 sz,
4185    DecodedCert* cert)
4186{
4187    word32 idx = 0;
4188    int length = 0;
4189    byte hasUnsupported = 0;
4190
4191    WOLFSSL_ENTER("DecodeNameConstraints");
4192
4193    if (GetSequence(input, &idx, &length, sz) < 0) {
4194        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
4195        return ASN_PARSE_E;
4196    }
4197
4198    while (idx < (word32)sz) {
4199        byte b = input[idx++];
4200        Base_entry** subtree = NULL;
4201
4202        if (GetLength(input, &idx, &length, sz) <= 0) {
4203            WOLFSSL_MSG("\tinvalid length");
4204            return ASN_PARSE_E;
4205        }
4206
4207        if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
4208            subtree = &cert->permittedNames;
4209        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
4210            subtree = &cert->excludedNames;
4211        else {
4212            WOLFSSL_MSG("\tinvalid subtree");
4213            return ASN_PARSE_E;
4214        }
4215
4216        if (DecodeSubtree(input + idx, (word32)length, subtree,
4217                WOLFSSL_MAX_NAME_CONSTRAINTS, &hasUnsupported,
4218                cert->heap) < 0) {
4219            WOLFSSL_MSG("\terror parsing subtree");
4220            return ASN_PARSE_E;
4221        }
4222
4223        idx += (word32)length;
4224    }
4225
4226    if (hasUnsupported)
4227        cert->extNameConstraintHasUnsupported = 1;
4228
4229    return 0;
4230}
4231
4232#endif
4233#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
4234static int DecodeCertPolicy(const byte* input, word32 sz, DecodedCert* cert)
4235{
4236    word32 idx = 0;
4237    word32 oldIdx;
4238    int policy_length = 0;
4239    int ret;
4240    int total_length = 0;
4241#if defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_DUP_CERTPOL)
4242    int i;
4243#endif
4244
4245    WOLFSSL_ENTER("DecodeCertPolicy");
4246
4247    /* Check if cert is null before dereferencing below */
4248    if (cert == NULL)
4249        return BAD_FUNC_ARG;
4250
4251#if defined(WOLFSSL_CERT_EXT)
4252        cert->extCertPoliciesNb = 0;
4253#endif
4254
4255    if (GetSequence(input, &idx, &total_length, sz) < 0) {
4256        WOLFSSL_MSG("\tGet CertPolicy total seq failed");
4257        return ASN_PARSE_E;
4258    }
4259
4260    /* Validate total length */
4261    if (total_length > (int)(sz - idx)) {
4262        WOLFSSL_MSG("\tCertPolicy length mismatch");
4263        return ASN_PARSE_E;
4264    }
4265
4266    /* Unwrap certificatePolicies */
4267    do {
4268        int length = 0;
4269
4270        if (GetSequence(input, &idx, &policy_length, sz) < 0) {
4271            WOLFSSL_MSG("\tGet CertPolicy seq failed");
4272            return ASN_PARSE_E;
4273        }
4274
4275        oldIdx = idx;
4276        ret = GetASNObjectId(input, &idx, &length, sz);
4277        if (ret != 0)
4278            return ret;
4279        policy_length -= (int)(idx - oldIdx);
4280
4281        if (length > 0) {
4282            /* Verify length won't overrun buffer */
4283            if (length > (int)(sz - idx)) {
4284                WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
4285                return ASN_PARSE_E;
4286            }
4287
4288    #ifdef WOLFSSL_SEP
4289            if (cert->deviceType == NULL) {
4290                cert->deviceType = (byte*)XMALLOC((size_t)length, cert->heap,
4291                                                        DYNAMIC_TYPE_X509_EXT);
4292                if (cert->deviceType == NULL) {
4293                    WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
4294                    return MEMORY_E;
4295                }
4296                cert->deviceTypeSz = length;
4297                XMEMCPY(cert->deviceType, input + idx, (size_t)length);
4298            }
4299    #endif
4300
4301    #ifdef WOLFSSL_CERT_EXT
4302            /* decode cert policy */
4303            if (DecodePolicyOID(cert->extCertPolicies[
4304                                cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
4305                                input + idx, length) <= 0) {
4306                WOLFSSL_MSG("\tCouldn't decode CertPolicy");
4307                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
4308                return ASN_PARSE_E;
4309            }
4310        #ifndef WOLFSSL_DUP_CERTPOL
4311            /* From RFC 5280 section 4.2.1.4 "A certificate policy OID MUST
4312             * NOT appear more than once in a certificate policies
4313             * extension". This is a sanity check for duplicates.
4314             * extCertPolicies should only have OID values, additional
4315             * qualifiers need to be stored in a separate array. */
4316            for (i = 0; i < cert->extCertPoliciesNb; i++) {
4317                if (XMEMCMP(cert->extCertPolicies[i],
4318                            cert->extCertPolicies[cert->extCertPoliciesNb],
4319                            MAX_CERTPOL_SZ) == 0) {
4320                    WOLFSSL_MSG("Duplicate policy OIDs not allowed");
4321                    WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
4322                    WOLFSSL_ERROR_VERBOSE(CERTPOLICIES_E);
4323                    return CERTPOLICIES_E;
4324                }
4325            }
4326        #endif /* !WOLFSSL_DUP_CERTPOL */
4327            cert->extCertPoliciesNb++;
4328    #endif
4329        }
4330        idx += (word32)policy_length;
4331    } while((int)idx < total_length
4332    #ifdef WOLFSSL_CERT_EXT
4333        && cert->extCertPoliciesNb < MAX_CERTPOL_NB
4334    #endif
4335    );
4336
4337    WOLFSSL_LEAVE("DecodeCertPolicy", 0);
4338    return 0;
4339}
4340
4341#endif
4342#ifdef WOLFSSL_SUBJ_DIR_ATTR
4343static int DecodeSubjDirAttr(const byte* input, word32 sz, DecodedCert* cert)
4344{
4345    word32 idx = 0;
4346    int length = 0;
4347    int ret = 0;
4348
4349    WOLFSSL_ENTER("DecodeSubjDirAttr");
4350
4351#ifdef OPENSSL_ALL
4352    cert->extSubjDirAttrSrc = input;
4353    cert->extSubjDirAttrSz = sz;
4354#endif /* OPENSSL_ALL */
4355
4356    /* Unwrap the list of Attributes */
4357    if (GetSequence(input, &idx, &length, sz) < 0)
4358        return ASN_PARSE_E;
4359
4360    if (length == 0) {
4361        /* RFC 5280 4.2.1.8.  Subject Directory Attributes
4362           If the subjectDirectoryAttributes extension is present, the
4363           sequence MUST contain at least one entry. */
4364        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
4365        return ASN_PARSE_E;
4366    }
4367
4368    /* length is the length of the list contents */
4369    while (idx < (word32)sz) {
4370        word32 oid;
4371
4372        if (GetSequence(input, &idx, &length, sz) < 0)
4373            return ASN_PARSE_E;
4374
4375        if (GetObjectId(input, &idx, &oid, oidSubjDirAttrType, sz) < 0)
4376            return ASN_PARSE_E;
4377
4378        if (GetSet(input, &idx, &length, sz) < 0)
4379            return ASN_PARSE_E;
4380
4381        /* There may be more than one countryOfCitizenship, but save the
4382         * first one for now. */
4383        if (oid == SDA_COC_OID) {
4384            byte tag;
4385
4386            if (GetHeader(input, &tag, &idx, &length, sz, 1) < 0)
4387                return ASN_PARSE_E;
4388
4389            if (length != COUNTRY_CODE_LEN)
4390                return ASN_PARSE_E;
4391
4392            if (tag == ASN_PRINTABLE_STRING) {
4393                XMEMCPY(cert->countryOfCitizenship,
4394                        input + idx, COUNTRY_CODE_LEN);
4395                cert->countryOfCitizenship[COUNTRY_CODE_LEN] = 0;
4396            }
4397        }
4398        idx += length;
4399    }
4400
4401    return ret;
4402}
4403
4404#endif
4405static int DecodeCertExtensions(DecodedCert* cert)
4406{
4407    int ret = 0;
4408    word32 idx = 0;
4409    word32 sz = (word32)cert->extensionsSz;
4410    const byte* input = cert->extensions;
4411    int length;
4412    word32 oid;
4413    byte critical = 0;
4414    byte criticalFail = 0;
4415    byte tag = 0;
4416
4417    WOLFSSL_ENTER("DecodeCertExtensions");
4418
4419    if (input == NULL || sz == 0)
4420        return BAD_FUNC_ARG;
4421
4422#ifdef WOLFSSL_CERT_REQ
4423    if (!cert->isCSR)
4424#endif
4425    { /* Not included in CSR */
4426        if (GetASNTag(input, &idx, &tag, sz) < 0) {
4427            return ASN_PARSE_E;
4428        }
4429
4430        if (tag != ASN_EXTENSIONS) {
4431            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
4432            return ASN_PARSE_E;
4433        }
4434
4435        if (GetLength(input, &idx, &length, sz) < 0) {
4436            WOLFSSL_MSG("\tfail: invalid length");
4437            return ASN_PARSE_E;
4438        }
4439    }
4440
4441    if (GetSequence(input, &idx, &length, sz) < 0) {
4442        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
4443        return ASN_PARSE_E;
4444    }
4445
4446    while (idx < (word32)sz) {
4447        word32 localIdx;
4448
4449        if (GetSequence(input, &idx, &length, sz) < 0) {
4450            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
4451            return ASN_PARSE_E;
4452        }
4453
4454        oid = 0;
4455        if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {
4456            WOLFSSL_MSG("\tfail: OBJECT ID");
4457            return ret;
4458        }
4459
4460        /* check for critical flag */
4461        critical = 0;
4462        if ((idx + 1) > (word32)sz) {
4463            WOLFSSL_MSG("\tfail: malformed buffer");
4464            return BUFFER_E;
4465        }
4466
4467        localIdx = idx;
4468        if (GetASNTag(input, &localIdx, &tag, sz) == 0) {
4469            if (tag == ASN_BOOLEAN) {
4470                ret = GetBoolean(input, &idx, sz);
4471                if (ret < 0) {
4472                    WOLFSSL_MSG("\tfail: critical boolean");
4473                    return ret;
4474                }
4475
4476                critical = (byte)ret;
4477            }
4478        }
4479
4480        /* process the extension based on the OID */
4481        ret = GetOctetString(input, &idx, &length, sz);
4482        if (ret < 0) {
4483            WOLFSSL_MSG("\tfail: bad OCTET STRING");
4484            return ret;
4485        }
4486
4487        ret = DecodeExtensionType(input + idx, (word32)length, oid, critical,
4488            cert, NULL);
4489        if (ret == WC_NO_ERR_TRACE(ASN_CRIT_EXT_E)) {
4490            ret = 0;
4491            criticalFail = 1;
4492        }
4493        if (ret < 0)
4494            goto end;
4495        idx += (word32)length;
4496    }
4497
4498    ret = criticalFail ? ASN_CRIT_EXT_E : 0;
4499end:
4500    return ret;
4501}
4502
4503#if defined(WOLFSSL_SMALL_CERT_VERIFY) || defined(OPENSSL_EXTRA)
4504static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
4505        void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID, int req)
4506{
4507#if !defined(WOLFSSL_SMALL_STACK) || defined(WOLFSSL_NO_MALLOC)
4508    SignatureCtx  sigCtx[1];
4509#else
4510    SignatureCtx* sigCtx;
4511#endif
4512    byte          hash[KEYID_SIZE];
4513    Signer*       ca = NULL;
4514    word32        idx = 0;
4515    int           len;
4516    word32        tbsCertIdx = 0;
4517    word32        sigIndex   = 0;
4518    word32        signatureOID = 0;
4519    word32        oid = 0;
4520    word32        issuerIdx = 0;
4521    word32        issuerSz  = 0;
4522#ifndef NO_SKID
4523    int           extLen = 0;
4524    word32        extIdx = 0;
4525    word32        extEndIdx = 0;
4526    int           extAuthKeyIdSet = 0;
4527#endif
4528    int           ret = 0;
4529    word32        localIdx;
4530    byte          tag;
4531    const byte*   sigParams = NULL;
4532    word32        sigParamsSz = 0;
4533
4534
4535    if (cert == NULL) {
4536        return BAD_FUNC_ARG;
4537    }
4538
4539#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
4540    sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);
4541    if (sigCtx == NULL)
4542        return MEMORY_E;
4543#endif
4544
4545    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
4546
4547    /* Certificate SEQUENCE */
4548    if (GetSequence(cert, &idx, &len, certSz) < 0)
4549        ret = ASN_PARSE_E;
4550    if (ret == 0) {
4551        tbsCertIdx = idx;
4552
4553        /* TBSCertificate SEQUENCE */
4554        if (GetSequence(cert, &idx, &len, certSz) < 0)
4555            ret = ASN_PARSE_E;
4556    }
4557    if (ret == 0) {
4558        sigIndex = len + idx;
4559
4560        if ((idx + 1) > certSz)
4561            ret = BUFFER_E;
4562    }
4563    if (ret == 0) {
4564        /* version - optional */
4565        localIdx = idx;
4566        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
4567            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
4568                idx++;
4569                if (GetLength(cert, &idx, &len, certSz) < 0)
4570                    ret = ASN_PARSE_E;
4571                idx += len;
4572            }
4573        }
4574    }
4575
4576    if (ret == 0) {
4577        /* serialNumber */
4578        if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)
4579            ret = ASN_PARSE_E;
4580    }
4581    if (ret == 0) {
4582        idx += len;
4583
4584        /* signature */
4585        if (!req) {
4586            if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)
4587                ret = ASN_PARSE_E;
4588        #ifdef WC_RSA_PSS
4589            else if (signatureOID == CTC_RSASSAPSS) {
4590                int start = idx;
4591                sigParams = cert + idx;
4592                if (GetSequence(cert, &idx, &len, certSz) < 0)
4593                    ret = ASN_PARSE_E;
4594                if (ret == 0) {
4595                    idx += len;
4596                    sigParamsSz = idx - start;
4597                }
4598            }
4599        #endif
4600        }
4601    }
4602
4603    if (ret == 0) {
4604        issuerIdx = idx;
4605        /* issuer for cert or subject for csr */
4606        if (GetSequence(cert, &idx, &len, certSz) < 0)
4607            ret = ASN_PARSE_E;
4608    }
4609    if (ret == 0) {
4610        issuerSz = len + idx - issuerIdx;
4611    }
4612#ifndef NO_SKID
4613    if (!req && ret == 0) {
4614        idx += len;
4615
4616        /* validity */
4617        if (GetSequence(cert, &idx, &len, certSz) < 0)
4618            ret = ASN_PARSE_E;
4619    }
4620    if (!req && ret == 0) {
4621        idx += len;
4622
4623        /* subject */
4624        if (GetSequence(cert, &idx, &len, certSz) < 0)
4625            ret = ASN_PARSE_E;
4626    }
4627    if (ret == 0) {
4628        idx += len;
4629
4630        /* subjectPublicKeyInfo */
4631        if (GetSequence(cert, &idx, &len, certSz) < 0)
4632            ret = ASN_PARSE_E;
4633    }
4634    if (req && ret == 0) {
4635        idx += len;
4636
4637        /* attributes */
4638        if (GetASNHeader_ex(cert,
4639                ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &idx,
4640                &len, certSz, 1) < 0)
4641            ret = ASN_PARSE_E;
4642    }
4643    if (!req) {
4644        if (ret == 0) {
4645            idx += len;
4646
4647            if ((idx + 1) > certSz)
4648                ret = BUFFER_E;
4649        }
4650        if (ret == 0) {
4651            /* issuerUniqueID - optional */
4652            localIdx = idx;
4653            if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
4654                if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
4655                    idx++;
4656                    if (GetLength(cert, &idx, &len, certSz) < 0)
4657                        ret = ASN_PARSE_E;
4658                    idx += len;
4659                }
4660            }
4661        }
4662        if (ret == 0) {
4663            if ((idx + 1) > certSz)
4664                ret = BUFFER_E;
4665        }
4666        if (ret == 0) {
4667            /* subjectUniqueID - optional */
4668            localIdx = idx;
4669            if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
4670                if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
4671                    idx++;
4672                    if (GetLength(cert, &idx, &len, certSz) < 0)
4673                        ret = ASN_PARSE_E;
4674                    idx += len;
4675                }
4676            }
4677        }
4678
4679        if (ret == 0) {
4680            if ((idx + 1) > certSz)
4681                ret = BUFFER_E;
4682        }
4683        /* extensions - optional */
4684        localIdx = idx;
4685        if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
4686                tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
4687            idx++;
4688            if (GetLength(cert, &idx, &extLen, certSz) < 0)
4689                ret = ASN_PARSE_E;
4690            if (ret == 0) {
4691                if (GetSequence(cert, &idx, &extLen, certSz) < 0)
4692                    ret = ASN_PARSE_E;
4693            }
4694            if (ret == 0) {
4695                extEndIdx = idx + extLen;
4696
4697                /* Check each extension for the ones we want. */
4698                while (ret == 0 && idx < extEndIdx) {
4699                    if (GetSequence(cert, &idx, &len, certSz) < 0)
4700                        ret = ASN_PARSE_E;
4701                    if (ret == 0) {
4702                        extIdx = idx;
4703                        if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,
4704                                                                  certSz) < 0) {
4705                            ret = ASN_PARSE_E;
4706                        }
4707
4708                        if (ret == 0) {
4709                            if ((extIdx + 1) > certSz)
4710                                ret = BUFFER_E;
4711                        }
4712                    }
4713
4714                    if (ret == 0) {
4715                        localIdx = extIdx;
4716                        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
4717                                tag == ASN_BOOLEAN) {
4718                            if (GetBoolean(cert, &extIdx, certSz) < 0)
4719                                ret = ASN_PARSE_E;
4720                        }
4721                    }
4722                    if (ret == 0) {
4723                        if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)
4724                            ret = ASN_PARSE_E;
4725                    }
4726
4727                    if (ret == 0) {
4728                        switch (oid) {
4729                        case AUTH_KEY_OID:
4730                            if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
4731                                ret = ASN_PARSE_E;
4732
4733                            if (ret == 0 && (extIdx + 1) >= certSz)
4734                                ret = BUFFER_E;
4735
4736                            if (ret == 0 &&
4737                                    GetASNTag(cert, &extIdx, &tag, certSz) == 0 &&
4738                                    tag == (ASN_CONTEXT_SPECIFIC | 0)) {
4739                                if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
4740                                    ret = ASN_PARSE_E;
4741                                if (ret == 0) {
4742                                    extAuthKeyIdSet = 1;
4743                                    /* Get the hash or hash of the hash if wrong
4744                                     * size. */
4745                                    ret = GetHashId(cert + extIdx, extLen,
4746                                        hash, HashIdAlg(signatureOID));
4747                                }
4748                            }
4749                            break;
4750
4751                        default:
4752                            break;
4753                        }
4754                    }
4755                    idx += len;
4756                }
4757            }
4758        }
4759    }
4760    else if (ret == 0) {
4761        idx += len;
4762    }
4763
4764    if (ret == 0 && pubKey == NULL) {
4765        if (extAuthKeyIdSet)
4766            ca = GetCA(cm, hash);
4767        if (ca == NULL) {
4768            ret = CalcHashId_ex(cert + issuerIdx, issuerSz, hash,
4769                HashIdAlg(signatureOID));
4770            if (ret == 0)
4771                ca = GetCAByName(cm, hash);
4772        }
4773    }
4774#else
4775    if (ret == 0 && pubKey == NULL) {
4776        ret = CalcHashId_ex(cert + issuerIdx, issuerSz, hash,
4777            HashIdAlg(signatureOID));
4778        if (ret == 0)
4779            ca = GetCA(cm, hash);
4780    }
4781#endif /* !NO_SKID */
4782    if (ca == NULL && pubKey == NULL)
4783        ret = ASN_NO_SIGNER_E;
4784
4785    if (ret == 0) {
4786        idx = sigIndex;
4787        /* signatureAlgorithm */
4788        if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)
4789            ret = ASN_PARSE_E;
4790    #ifdef WC_RSA_PSS
4791        else if (signatureOID == CTC_RSASSAPSS) {
4792            word32 sz = idx;
4793            const byte* params = cert + idx;
4794            if (GetSequence(cert, &idx, &len, certSz) < 0)
4795                ret = ASN_PARSE_E;
4796            if (ret == 0) {
4797                idx += len;
4798                sz = idx - sz;
4799
4800                if (req) {
4801                    if ((sz != sigParamsSz) ||
4802                                        (XMEMCMP(sigParams, params, sz) != 0)) {
4803                        ret = ASN_PARSE_E;
4804                    }
4805                }
4806                else {
4807                    sigParams = params;
4808                    sigParamsSz = sz;
4809                }
4810            }
4811        }
4812    #endif
4813        /* In CSR signature data is not present in body */
4814        if (req)
4815            signatureOID = oid;
4816    }
4817    if (ret == 0) {
4818        if (oid != signatureOID)
4819            ret = ASN_SIG_OID_E;
4820    }
4821    if (ret == 0) {
4822        /* signatureValue */
4823        if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)
4824            ret = ASN_PARSE_E;
4825    }
4826
4827    if (ret == 0) {
4828        if (pubKey != NULL) {
4829            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
4830                sigIndex - tbsCertIdx, pubKey, pubKeySz, pubKeyOID,
4831                cert + idx, len, signatureOID, sigParams, sigParamsSz, NULL);
4832        }
4833        else {
4834            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
4835                sigIndex - tbsCertIdx, ca->publicKey, ca->pubKeySize,
4836                ca->keyOID, cert + idx, len, signatureOID, sigParams,
4837                sigParamsSz, NULL);
4838        }
4839        if (ret != 0) {
4840            WOLFSSL_ERROR_VERBOSE(ret);
4841            WOLFSSL_MSG("Confirm signature failed");
4842        }
4843    }
4844
4845    FreeSignatureCtx(sigCtx);
4846    WC_FREE_VAR_EX(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
4847    return ret;
4848}
4849
4850#endif
4851#endif
4852int wc_GetSerialNumber(const byte* input, word32* inOutIdx,
4853    byte* serial, int* serialSz, word32 maxIdx)
4854{
4855    int result = 0;
4856    int ret;
4857
4858    WOLFSSL_ENTER("wc_GetSerialNumber");
4859
4860    if (serial == NULL || input == NULL || serialSz == NULL) {
4861        return BAD_FUNC_ARG;
4862    }
4863
4864    /* First byte is ASN type */
4865    if ((*inOutIdx+1) > maxIdx) {
4866        WOLFSSL_MSG("Bad idx first");
4867        return BUFFER_E;
4868    }
4869
4870    ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);
4871    if (ret != 0)
4872        return ret;
4873
4874    if (*serialSz > EXTERNAL_SERIAL_SIZE || *serialSz <= 0) {
4875        WOLFSSL_MSG("Serial size bad");
4876        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
4877        return ASN_PARSE_E;
4878    }
4879
4880    /* return serial */
4881    XMEMCPY(serial, &input[*inOutIdx], (size_t)*serialSz);
4882    *inOutIdx += (word32)*serialSz;
4883
4884    return result;
4885}
4886
4887#ifndef NO_CERTS
4888#if !defined(NO_RSA) && \
4889(defined(WOLFSSL_KEY_TO_DER) || defined(WOLFSSL_CERT_GEN))
4890static int SetRsaPublicKey(byte* output, RsaKey* key, int outLen,
4891                           int with_header)
4892{
4893    int  nSz, eSz;
4894    word32 seqSz, algoSz = 0, headSz = 0, bitStringSz = 0, idx;
4895    byte seq[MAX_SEQ_SZ];
4896    byte headSeq[MAX_SEQ_SZ];
4897    byte bitString[1 + MAX_LENGTH_SZ + 1];
4898    byte algo[MAX_ALGO_SZ]; /* 20 bytes */
4899
4900    if (key == NULL) {
4901        return BAD_FUNC_ARG;
4902    }
4903
4904    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, NULL);
4905
4906    if (nSz < 0)
4907        return nSz;
4908
4909    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, NULL);
4910
4911    if (eSz < 0)
4912        return eSz;
4913    seqSz = SetSequence((word32)(nSz + eSz), seq);
4914
4915    /* headers */
4916    if (with_header) {
4917        algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
4918        bitStringSz = SetBitString(seqSz + (word32)(nSz + eSz), 0, bitString);
4919        headSz = SetSequence((word32)(nSz + eSz) + seqSz + bitStringSz + algoSz,
4920                             headSeq);
4921    }
4922
4923    /* if getting length only */
4924    if (output == NULL) {
4925        return (int)(headSz + algoSz + bitStringSz + seqSz) + nSz + eSz;
4926    }
4927
4928    /* check output size */
4929    if (((int)(headSz + algoSz + bitStringSz + seqSz) + nSz + eSz) > outLen) {
4930        return BUFFER_E;
4931    }
4932
4933    /* write output */
4934    idx = 0;
4935    if (with_header) {
4936        /* header size */
4937        XMEMCPY(output + idx, headSeq, headSz);
4938        idx += headSz;
4939        /* algo */
4940        XMEMCPY(output + idx, algo, algoSz);
4941        idx += algoSz;
4942        /* bit string */
4943        XMEMCPY(output + idx, bitString, bitStringSz);
4944        idx += bitStringSz;
4945    }
4946
4947    /* seq */
4948    XMEMCPY(output + idx, seq, seqSz);
4949    idx += seqSz;
4950    /* n */
4951    nSz = SetASNIntMP(&key->n, nSz, output + idx);
4952    idx += (word32)nSz;
4953    /* e */
4954    eSz = SetASNIntMP(&key->e, eSz, output + idx);
4955    idx += (word32)eSz;
4956
4957    return (int)idx;
4958}
4959
4960#endif
4961#endif
4962#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
4963int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
4964{
4965    int ret = 0, i;
4966    int mpSz;
4967    word32 seqSz = 0, verSz = 0, intTotalLen = 0, outLen = 0;
4968    byte  seq[MAX_SEQ_SZ];
4969    byte  ver[MAX_VERSION_SZ];
4970    mp_int* keyInt;
4971#ifndef WOLFSSL_NO_MALLOC
4972    word32 rawLen;
4973    byte* tmps[RSA_INTS];
4974    word32 sizes[RSA_INTS];
4975#endif
4976
4977    if (key == NULL)
4978        return BAD_FUNC_ARG;
4979
4980    if (key->type != RSA_PRIVATE)
4981        return BAD_FUNC_ARG;
4982
4983#ifndef WOLFSSL_NO_MALLOC
4984    for (i = 0; i < RSA_INTS; i++)
4985        tmps[i] = NULL;
4986#endif
4987
4988    /* write all big ints from key to DER tmps */
4989    for (i = 0; i < RSA_INTS; i++) {
4990        keyInt = GetRsaInt(key, i);
4991        ret = mp_unsigned_bin_size(keyInt);
4992        if (ret < 0)
4993            break;
4994#ifndef WOLFSSL_NO_MALLOC
4995        rawLen = (word32)ret + 1;
4996        ret = 0;
4997        if (output != NULL) {
4998            tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
4999                                 DYNAMIC_TYPE_RSA);
5000            if (tmps[i] == NULL) {
5001                ret = MEMORY_E;
5002                break;
5003            }
5004        }
5005        mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
5006#else
5007        ret = 0;
5008        mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, NULL);
5009#endif
5010        if (mpSz < 0) {
5011            ret = mpSz;
5012            break;
5013        }
5014    #ifndef WOLFSSL_NO_MALLOC
5015        sizes[i] = (word32)mpSz;
5016    #endif
5017        intTotalLen += (word32)mpSz;
5018    }
5019
5020    if (ret == 0) {
5021        /* make headers */
5022        ret = SetMyVersion(0, ver, FALSE);
5023    }
5024
5025    if (ret >= 0) {
5026        verSz = (word32)ret;
5027        ret = 0;
5028        seqSz = SetSequence(verSz + intTotalLen, seq);
5029        outLen = seqSz + verSz + intTotalLen;
5030        if (output != NULL && outLen > inLen)
5031            ret = BUFFER_E;
5032    }
5033    if (ret == 0 && output != NULL) {
5034        word32 j;
5035
5036        /* write to output */
5037        XMEMCPY(output, seq, seqSz);
5038        j = seqSz;
5039        XMEMCPY(output + j, ver, verSz);
5040        j += verSz;
5041
5042        for (i = 0; i < RSA_INTS; i++) {
5043/* copy from tmps if we have malloc, otherwise re-export with buffer */
5044#ifndef WOLFSSL_NO_MALLOC
5045            XMEMCPY(output + j, tmps[i], sizes[i]);
5046            j += sizes[i];
5047#else
5048            keyInt = GetRsaInt(key, i);
5049            ret = mp_unsigned_bin_size(keyInt);
5050            if (ret < 0)
5051                break;
5052            ret = 0;
5053            /* This won't overrun output due to the outLen check above */
5054            mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, output + j);
5055            if (mpSz < 0) {
5056                ret = mpSz;
5057                break;
5058            }
5059            j += mpSz;
5060#endif
5061        }
5062    }
5063
5064#ifndef WOLFSSL_NO_MALLOC
5065    for (i = 0; i < RSA_INTS; i++) {
5066        if (tmps[i])
5067            XFREE(tmps[i], key->heap, DYNAMIC_TYPE_RSA);
5068    }
5069#endif
5070
5071    if (ret == 0)
5072        ret = (int)outLen;
5073    return ret;
5074}
5075
5076#endif
5077#ifndef NO_CERTS
5078#ifdef WOLFSSL_CERT_GEN
5079#ifdef WOLFSSL_CERT_REQ
5080
5081/* Write a set header to output */
5082static word32 SetPrintableString(word32 len, byte* output)
5083{
5084    output[0] = ASN_PRINTABLE_STRING;
5085    return SetLength(len, output + 1) + 1;
5086}
5087
5088static word32 SetUTF8String(word32 len, byte* output)
5089{
5090    output[0] = ASN_UTF8STRING;
5091    return SetLength(len, output + 1) + 1;
5092}
5093
5094
5095#endif
5096
5097/* Copy Dates from cert, return bytes written */
5098static int CopyValidity(byte* output, Cert* cert)
5099{
5100    word32 seqSz;
5101
5102    WOLFSSL_ENTER("CopyValidity");
5103
5104    /* headers and output */
5105    seqSz = SetSequence((word32)(cert->beforeDateSz + cert->afterDateSz),
5106                        output);
5107    if (output) {
5108        XMEMCPY(output + seqSz, cert->beforeDate, (size_t)cert->beforeDateSz);
5109        XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
5110                (size_t)cert->afterDateSz);
5111    }
5112    return (int)seqSz + cert->beforeDateSz + cert->afterDateSz;
5113}
5114
5115
5116/*
5117 Extensions ::= SEQUENCE OF Extension
5118
5119 Extension ::= SEQUENCE {
5120 extnId     OBJECT IDENTIFIER,
5121 critical   BOOLEAN DEFAULT FALSE,
5122 extnValue  OCTET STRING }
5123 */
5124
5125/* encode all extensions, return total bytes written */
5126static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
5127                         const byte* ext, int extSz)
5128{
5129    if (out == NULL || IdxInOut == NULL || ext == NULL)
5130        return BAD_FUNC_ARG;
5131
5132    if (outSz < (word32)(*IdxInOut+extSz))
5133        return BUFFER_E;
5134
5135    XMEMCPY(&out[*IdxInOut], ext, (size_t)extSz);  /* extensions */
5136    *IdxInOut += extSz;
5137
5138    return *IdxInOut;
5139}
5140
5141/* encode extensions header, return total bytes written */
5142static int SetExtensionsHeader(byte* out, word32 outSz, word32 extSz)
5143{
5144    byte sequence[MAX_SEQ_SZ];
5145    byte len[MAX_LENGTH_SZ];
5146    word32 seqSz, lenSz, idx = 0;
5147
5148    if (out == NULL)
5149        return BAD_FUNC_ARG;
5150
5151    if (outSz < 3)
5152        return BUFFER_E;
5153
5154    seqSz = SetSequence(extSz, sequence);
5155
5156    /* encode extensions length provided */
5157    lenSz = SetLength(extSz+seqSz, len);
5158
5159    if (outSz < (word32)(lenSz+seqSz+1))
5160        return BUFFER_E;
5161
5162    out[idx++] = ASN_EXTENSIONS; /* extensions id */
5163    XMEMCPY(&out[idx], len, lenSz);  /* length */
5164    idx += lenSz;
5165
5166    XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */
5167    idx += seqSz;
5168
5169    return (int)idx;
5170}
5171
5172
5173/* encode CA basic constraints true with path length
5174 * return total bytes written */
5175static int SetCaWithPathLen(byte* out, word32 outSz, byte pathLen)
5176{
5177    /* ASN1->DER sequence for Basic Constraints True and path length */
5178    const byte caPathLenBasicConstASN1[] = {
5179        0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04,
5180        0x08, 0x30, 0x06, 0x01, 0x01, 0xFF, 0x02, 0x01,
5181        0x00
5182    };
5183
5184    if (out == NULL)
5185        return BAD_FUNC_ARG;
5186
5187    if (outSz < sizeof(caPathLenBasicConstASN1))
5188        return BUFFER_E;
5189
5190    XMEMCPY(out, caPathLenBasicConstASN1, sizeof(caPathLenBasicConstASN1));
5191
5192    out[sizeof(caPathLenBasicConstASN1)-1] = pathLen;
5193
5194    return (int)sizeof(caPathLenBasicConstASN1);
5195}
5196
5197/* encode CA basic constraints
5198 * return total bytes written */
5199static int SetCaEx(byte* out, word32 outSz, byte isCa)
5200{
5201    /* ASN1->DER sequence for Basic Constraints True */
5202    const byte caBasicConstASN1[] = {
5203        0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
5204        0x05, 0x30, 0x03, 0x01, 0x01, 0xff
5205    };
5206
5207    if (out == NULL)
5208        return BAD_FUNC_ARG;
5209
5210    if (outSz < sizeof(caBasicConstASN1))
5211        return BUFFER_E;
5212
5213    XMEMCPY(out, caBasicConstASN1, sizeof(caBasicConstASN1));
5214
5215    if (!isCa) {
5216        out[sizeof(caBasicConstASN1)-1] = isCa;
5217    }
5218
5219    return (int)sizeof(caBasicConstASN1);
5220}
5221
5222/* encode CA basic constraints true
5223 * return total bytes written */
5224static int SetCa(byte* out, word32 outSz)
5225{
5226    return SetCaEx(out, outSz, 1);
5227}
5228
5229/* encode basic constraints without CA Boolean
5230 * return total bytes written */
5231static int SetBC(byte* out, word32 outSz)
5232{
5233    /* ASN1->DER sequence for Basic Constraint without CA Boolean */
5234 const byte BasicConstASN1[] = {
5235        0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
5236        0x02, 0x30, 0x00
5237    };
5238
5239    if (out == NULL)
5240        return BAD_FUNC_ARG;
5241
5242    if (outSz < sizeof(BasicConstASN1))
5243        return BUFFER_E;
5244
5245    XMEMCPY(out, BasicConstASN1, sizeof(BasicConstASN1));
5246
5247    return (int)sizeof(BasicConstASN1);
5248}
5249
5250#ifdef WOLFSSL_CERT_EXT
5251/* encode OID and associated value, return total bytes written */
5252static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
5253                       byte *in, word32 inSz)
5254{
5255    word32 idx = 0;
5256
5257    if (out == NULL || oid == NULL || in == NULL)
5258        return BAD_FUNC_ARG;
5259    if (inSz >= ASN_LONG_LENGTH)
5260        return BAD_FUNC_ARG;
5261    if (oidSz >= ASN_LONG_LENGTH)
5262        return BAD_FUNC_ARG;
5263    if (inSz + oidSz + 1 >= ASN_LONG_LENGTH)
5264        return BAD_FUNC_ARG;
5265
5266    if (outSz < 3)
5267        return BUFFER_E;
5268
5269    /* sequence,  + 1 => byte to put value size */
5270    idx = SetSequence(inSz + oidSz + 1, out);
5271
5272    if ((idx + inSz + oidSz + 1) > outSz)
5273        return BUFFER_E;
5274
5275    XMEMCPY(out+idx, oid, oidSz);
5276    idx += oidSz;
5277    out[idx++] = (byte)inSz;
5278    XMEMCPY(out+idx, in, inSz);
5279
5280    return (int)(idx+inSz);
5281}
5282
5283/* encode Subject Key Identifier, return total bytes written
5284 * RFC5280 : non-critical */
5285static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)
5286{
5287    byte skid_len[1 + MAX_LENGTH_SZ];
5288    byte skid_enc_len[MAX_LENGTH_SZ];
5289    word32 idx = 0, skid_lenSz, skid_enc_lenSz;
5290    const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
5291
5292    if (output == NULL || input == NULL)
5293        return BAD_FUNC_ARG;
5294
5295    /* Octet String header */
5296    skid_lenSz = SetOctetString(length, skid_len);
5297
5298    /* length of encoded value */
5299    skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);
5300
5301    if (outSz < 3)
5302        return BUFFER_E;
5303
5304    idx = SetSequence(length + (word32)sizeof(skid_oid) + skid_lenSz +
5305                      skid_enc_lenSz, output);
5306
5307    if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)
5308        return BUFFER_E;
5309
5310    /* put oid */
5311    XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
5312    idx += sizeof(skid_oid);
5313
5314    /* put encoded len */
5315    XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
5316    idx += skid_enc_lenSz;
5317
5318    /* put octet header */
5319    XMEMCPY(output+idx, skid_len, skid_lenSz);
5320    idx += skid_lenSz;
5321
5322    /* put value */
5323    XMEMCPY(output+idx, input, length);
5324    idx += length;
5325
5326    return (int)idx;
5327}
5328
5329/* encode Authority Key Identifier, return total bytes written
5330 * RFC5280 : non-critical */
5331static int SetAKID(byte* output, word32 outSz, byte *input, word32 length,
5332                   byte rawAkid)
5333{
5334    int     enc_valSz;
5335    byte enc_val_buf[MAX_KID_SZ];
5336    byte* enc_val;
5337    const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23 };
5338    const byte akid_cs[] = { 0x80 };
5339    word32 inSeqSz, idx;
5340
5341    (void)rawAkid;
5342
5343    if (output == NULL || input == NULL)
5344        return BAD_FUNC_ARG;
5345
5346#ifdef WOLFSSL_AKID_NAME
5347    if (rawAkid) {
5348        enc_val = input;
5349        enc_valSz = length;
5350    }
5351    else
5352#endif
5353    {
5354        enc_val = enc_val_buf;
5355        enc_valSz = (int)length + 3 + (int)sizeof(akid_cs);
5356        if (enc_valSz > (int)sizeof(enc_val_buf))
5357            return BAD_FUNC_ARG;
5358
5359        /* sequence for ContentSpec & value */
5360        enc_valSz = SetOidValue(enc_val, (word32)enc_valSz, akid_cs,
5361                                sizeof(akid_cs), input, length);
5362        if (enc_valSz <= 0)
5363            return enc_valSz;
5364    }
5365
5366    /* The size of the extension sequence contents */
5367    inSeqSz = (word32)sizeof(akid_oid) +
5368        SetOctetString((word32)enc_valSz, NULL) + (word32)enc_valSz;
5369
5370    if (SetSequence(inSeqSz, NULL) + inSeqSz > outSz)
5371        return BAD_FUNC_ARG;
5372
5373    /* Write out the sequence header */
5374    idx = SetSequence(inSeqSz, output);
5375
5376    /* Write out OID */
5377    XMEMCPY(output + idx, akid_oid, sizeof(akid_oid));
5378    idx += sizeof(akid_oid);
5379
5380    /* Write out AKID */
5381    idx += SetOctetString((word32)enc_valSz, output + idx);
5382    XMEMCPY(output + idx, enc_val, (size_t)enc_valSz);
5383
5384    return (int)idx + enc_valSz;
5385}
5386
5387#ifdef WOLFSSL_ACME_OID
5388/* encode RFC 8737 id-pe-acmeIdentifier extension, return total bytes written
5389 * RFC8737 : critical */
5390static int SetAcmeIdentifier(byte* output, word32 outSz, const byte* digest,
5391                             word32 digestSz)
5392{
5393    byte inner[1 + MAX_LENGTH_SZ + WC_SHA256_DIGEST_SIZE];
5394    word32 innerSz;
5395    const byte acmeId_oid[] = { 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07,
5396                                0x01, 0x1F, 0x01, 0x01, 0xFF, 0x04 };
5397
5398    if (output == NULL || digest == NULL)
5399        return BAD_FUNC_ARG;
5400    if (digestSz != WC_SHA256_DIGEST_SIZE)
5401        return BAD_FUNC_ARG;
5402
5403    innerSz = SetOctetString(digestSz, inner);
5404    XMEMCPY(inner + innerSz, digest, digestSz);
5405    innerSz += digestSz;
5406
5407    return SetOidValue(output, outSz, acmeId_oid, sizeof(acmeId_oid),
5408                       inner, innerSz);
5409}
5410#endif /* WOLFSSL_ACME_OID */
5411
5412/* encode Key Usage, return total bytes written
5413 * RFC5280 : critical */
5414static int SetKeyUsage(byte* output, word32 outSz, word16 input)
5415{
5416    byte ku[5];
5417    word32 idx;
5418    const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
5419                                         0x01, 0x01, 0xff, 0x04};
5420    if (output == NULL)
5421        return BAD_FUNC_ARG;
5422
5423    idx = SetBitString16Bit(input, ku);
5424    return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
5425                       ku, idx);
5426}
5427
5428static int SetOjectIdValue(byte* output, word32 outSz, word32* idx,
5429    const byte* oid, word32 oidSz)
5430{
5431    /* verify room */
5432    if (*idx + 2 + oidSz >= outSz)
5433        return ASN_PARSE_E;
5434
5435    *idx += (word32)SetObjectId((int)oidSz, &output[*idx]);
5436    XMEMCPY(&output[*idx], oid, oidSz);
5437    *idx += oidSz;
5438
5439    return 0;
5440}
5441
5442static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
5443{
5444    word32 idx = 0, oidListSz = 0, totalSz;
5445    int ret = 0;
5446    const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
5447
5448    if (output == NULL)
5449        return BAD_FUNC_ARG;
5450
5451    /* Skip to OID List */
5452    totalSz = 2 + sizeof(extkeyusage_oid) + 4;
5453    idx = totalSz;
5454
5455    /* Build OID List */
5456    /* If any set, then just use it */
5457    if (input & EXTKEYUSE_ANY) {
5458        ret |= SetOjectIdValue(output, outSz, &idx,
5459            extExtKeyUsageAnyOid, sizeof(extExtKeyUsageAnyOid));
5460    }
5461    else {
5462        if (input & EXTKEYUSE_SERVER_AUTH)
5463            ret |= SetOjectIdValue(output, outSz, &idx,
5464                extExtKeyUsageServerAuthOid, sizeof(extExtKeyUsageServerAuthOid));
5465        if (input & EXTKEYUSE_CLIENT_AUTH)
5466            ret |= SetOjectIdValue(output, outSz, &idx,
5467                extExtKeyUsageClientAuthOid, sizeof(extExtKeyUsageClientAuthOid));
5468        if (input & EXTKEYUSE_CODESIGN)
5469            ret |= SetOjectIdValue(output, outSz, &idx,
5470                extExtKeyUsageCodeSigningOid, sizeof(extExtKeyUsageCodeSigningOid));
5471        if (input & EXTKEYUSE_EMAILPROT)
5472            ret |= SetOjectIdValue(output, outSz, &idx,
5473                extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid));
5474        if (input & EXTKEYUSE_TIMESTAMP)
5475            ret |= SetOjectIdValue(output, outSz, &idx,
5476                extExtKeyUsageTimestampOid, sizeof(extExtKeyUsageTimestampOid));
5477        if (input & EXTKEYUSE_OCSP_SIGN)
5478            ret |= SetOjectIdValue(output, outSz, &idx,
5479                extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
5480    #ifdef WOLFSSL_EKU_OID
5481        /* iterate through OID values */
5482        if (input & EXTKEYUSE_USER) {
5483            int i, sz;
5484            for (i = 0; i < CTC_MAX_EKU_NB; i++) {
5485                sz = cert->extKeyUsageOIDSz[i];
5486                if (sz > 0) {
5487                    ret |= SetOjectIdValue(output, outSz, &idx,
5488                        cert->extKeyUsageOID[i], sz);
5489                }
5490            }
5491        }
5492    #endif /* WOLFSSL_EKU_OID */
5493    }
5494    if (ret != 0)
5495        return ASN_PARSE_E;
5496
5497    /* Calculate Sizes */
5498    oidListSz = idx - totalSz;
5499    totalSz = idx - 2; /* exclude first seq/len (2) */
5500
5501    /* 1. Seq + Total Len (2) */
5502    idx = SetSequence(totalSz, output);
5503
5504    /* 2. Object ID (2) */
5505    XMEMCPY(&output[idx], extkeyusage_oid, sizeof(extkeyusage_oid));
5506    idx += sizeof(extkeyusage_oid);
5507
5508    /* 3. Octet String (2) */
5509    idx += SetOctetString(totalSz - idx, &output[idx]);
5510
5511    /* 4. Seq + OidListLen (2) */
5512    idx += SetSequence(oidListSz, &output[idx]);
5513
5514    /* 5. Oid List (already set in-place above) */
5515    idx += oidListSz;
5516
5517    (void)cert;
5518    return (int)idx;
5519}
5520
5521#ifndef IGNORE_NETSCAPE_CERT_TYPE
5522static int SetNsCertType(Cert* cert, byte* output, word32 outSz, byte input)
5523{
5524    word32 idx;
5525    byte unusedBits = 0;
5526    byte nsCertType = input;
5527    word32 totalSz;
5528    word32 bitStrSz;
5529    const byte nscerttype_oid[] = { 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
5530                                    0x86, 0xF8, 0x42, 0x01, 0x01 };
5531
5532    if (cert == NULL || output == NULL ||
5533            input == 0)
5534        return BAD_FUNC_ARG;
5535
5536    totalSz = sizeof(nscerttype_oid);
5537
5538    /* Get amount of lsb zero's */
5539    for (;(input & 1) == 0; input >>= 1)
5540        unusedBits++;
5541
5542    /* 1 byte of NS Cert Type extension */
5543    bitStrSz = SetBitString(1, unusedBits, NULL) + 1;
5544    totalSz += SetOctetString(bitStrSz, NULL) + bitStrSz;
5545
5546    if (SetSequence(totalSz, NULL) + totalSz > outSz)
5547        return BAD_FUNC_ARG;
5548
5549    /* 1. Seq + Total Len */
5550    idx = SetSequence(totalSz, output);
5551
5552    /* 2. Object ID */
5553    XMEMCPY(&output[idx], nscerttype_oid, sizeof(nscerttype_oid));
5554    idx += sizeof(nscerttype_oid);
5555
5556    /* 3. Octet String */
5557    idx += SetOctetString(bitStrSz, &output[idx]);
5558
5559    /* 4. Bit String */
5560    idx += SetBitString(1, unusedBits, &output[idx]);
5561    output[idx++] = nsCertType;
5562
5563    return (int)idx;
5564}
5565
5566#endif
5567static int SetCRLInfo(Cert* cert, byte* output, word32 outSz, byte* input,
5568                      int inSz)
5569{
5570    word32 idx;
5571    word32 totalSz;
5572    const byte crlinfo_oid[] = { 0x06, 0x03, 0x55, 0x1D, 0x1F };
5573
5574    if (cert == NULL || output == NULL ||
5575            input == 0 || inSz <= 0)
5576        return BAD_FUNC_ARG;
5577
5578    totalSz = (word32)sizeof(crlinfo_oid) + SetOctetString((word32)inSz, NULL) +
5579        (word32)inSz;
5580
5581    if (SetSequence(totalSz, NULL) + totalSz > outSz)
5582        return BAD_FUNC_ARG;
5583
5584    /* 1. Seq + Total Len */
5585    idx = SetSequence(totalSz, output);
5586
5587    /* 2. Object ID */
5588    XMEMCPY(&output[idx], crlinfo_oid, sizeof(crlinfo_oid));
5589    idx += sizeof(crlinfo_oid);
5590
5591    /* 3. Octet String */
5592    idx += SetOctetString((word32)inSz, &output[idx]);
5593
5594    /* 4. CRL Info */
5595    XMEMCPY(&output[idx], input, (size_t)inSz);
5596    idx += (word32)inSz;
5597
5598    return (int)idx;
5599}
5600
5601static int SetCertificatePolicies(byte *output,
5602                                  word32 outputSz,
5603                                  char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
5604                                  word16 nb_certpol,
5605                                  void* heap)
5606{
5607    byte    oid[MAX_OID_SZ];
5608    byte    der_oid[MAX_CERTPOL_NB][MAX_OID_SZ];
5609    byte    out[MAX_CERTPOL_SZ];
5610    word32  oidSz;
5611    word32  outSz;
5612    word32  i = 0;
5613    word32  der_oidSz[MAX_CERTPOL_NB];
5614    int     ret;
5615
5616    const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
5617    const byte oid_oid[] = { 0x06 };
5618
5619    if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
5620        return BAD_FUNC_ARG;
5621
5622    for (i = 0; i < nb_certpol; i++) {
5623        oidSz = sizeof(oid);
5624        XMEMSET(oid, 0, oidSz);
5625
5626        ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
5627        if (ret != 0)
5628            return ret;
5629
5630        /* compute sequence value for the oid */
5631        ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
5632                          sizeof(oid_oid), oid, oidSz);
5633        if (ret <= 0)
5634            return ret;
5635        else
5636            der_oidSz[i] = (word32)ret;
5637    }
5638
5639    /* concatenate oid, keep two byte for sequence/size of the created value */
5640    for (i = 0, outSz = 2; i < nb_certpol; i++) {
5641        XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
5642        outSz += der_oidSz[i];
5643    }
5644
5645    /* add sequence */
5646    ret = (int)SetSequence(outSz-2, out);
5647    if (ret <= 0)
5648        return ret;
5649
5650    /* add Policy OID to compute final value */
5651    return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
5652                      out, outSz);
5653}
5654
5655#endif
5656#ifdef WOLFSSL_ALT_NAMES
5657/* encode Alternative Names, return total bytes written */
5658static int SetAltNames(byte *output, word32 outSz,
5659        const byte *input, word32 length, int critical)
5660{
5661    byte san_len[1 + MAX_LENGTH_SZ];
5662    const byte san_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x11 };
5663    const byte san_crit[] = { 0x01, 0x01, 0xff };
5664    word32 seqSz, san_lenSz, idx = 0;
5665
5666    if (output == NULL || input == NULL)
5667        return BAD_FUNC_ARG;
5668
5669    if (outSz < length)
5670        return BUFFER_E;
5671
5672    /* Octet String header */
5673    san_lenSz = SetOctetString(length, san_len);
5674
5675    seqSz = length + (word32)sizeof(san_oid) + san_lenSz;
5676    if (critical)
5677        seqSz += sizeof(san_crit);
5678    /* Tag plus encoded length. */
5679    if (outSz < 1 + ASN_LEN_ENC_LEN(seqSz))
5680        return BUFFER_E;
5681    idx = SetSequence(seqSz, output);
5682
5683    if (idx + seqSz > outSz)
5684        return BUFFER_E;
5685
5686    /* put oid */
5687    XMEMCPY(output+idx, san_oid, sizeof(san_oid));
5688    idx += sizeof(san_oid);
5689
5690    if (critical) {
5691        XMEMCPY(output+idx, san_crit, sizeof(san_crit));
5692        idx += sizeof(san_crit);
5693    }
5694
5695    /* put octet header */
5696    XMEMCPY(output+idx, san_len, san_lenSz);
5697    idx += san_lenSz;
5698
5699    /* put value */
5700    XMEMCPY(output+idx, input, length);
5701    idx += length;
5702
5703    return (int)idx;
5704}
5705
5706#endif
5707#endif
5708#if defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
5709static int EncodeName(EncodedName* name, const char* nameStr,
5710                    byte nameTag, byte type, byte emailTag, CertName* cname)
5711{
5712    word32 idx = 0;
5713    /* bottom up */
5714    byte firstLen[1 + MAX_LENGTH_SZ];
5715    byte secondLen[MAX_LENGTH_SZ];
5716    byte sequence[MAX_SEQ_SZ];
5717    byte set[MAX_SET_SZ];
5718
5719    word32 strLen;
5720    word32 thisLen;
5721    word32 firstSz, secondSz, seqSz, setSz;
5722
5723    if (nameStr == NULL) {
5724        name->used = 0;
5725        return 0;
5726    }
5727
5728    thisLen = strLen = (word32)XSTRLEN(nameStr);
5729#ifdef WOLFSSL_CUSTOM_OID
5730    if (type == ASN_CUSTOM_NAME) {
5731        if (cname == NULL || cname->custom.oidSz == 0) {
5732            name->used = 0;
5733            return 0;
5734        }
5735        thisLen = strLen = (word32)cname->custom.valSz;
5736    }
5737#else
5738    (void)cname;
5739#endif
5740
5741    if (strLen == 0) { /* no user data for this item */
5742        name->used = 0;
5743        return 0;
5744    }
5745
5746    /* Restrict country code size */
5747    if (type == ASN_COUNTRY_NAME && strLen != CTC_COUNTRY_SIZE) {
5748        WOLFSSL_MSG("Country code size error");
5749        WOLFSSL_ERROR_VERBOSE(ASN_COUNTRY_SIZE_E);
5750        return ASN_COUNTRY_SIZE_E;
5751    }
5752
5753    secondSz = SetLength(strLen, secondLen);
5754    thisLen += secondSz;
5755    switch (type) {
5756        case ASN_EMAIL_NAME: /* email */
5757            thisLen += (int)sizeof(attrEmailOid);
5758            firstSz  = (int)sizeof(attrEmailOid);
5759            break;
5760        case ASN_DOMAIN_COMPONENT:
5761            thisLen += (int)sizeof(dcOid);
5762            firstSz  = (int)sizeof(dcOid);
5763            break;
5764        case ASN_USER_ID:
5765            thisLen += (int)sizeof(uidOid);
5766            firstSz  = (int)sizeof(uidOid);
5767            break;
5768        case ASN_RFC822_MAILBOX:
5769            thisLen += (int)sizeof(rfc822Mlbx);
5770            firstSz  = (int)sizeof(rfc822Mlbx);
5771            break;
5772        case ASN_FAVOURITE_DRINK:
5773            thisLen += (int)sizeof(fvrtDrk);
5774            firstSz  = (int)sizeof(fvrtDrk);
5775            break;
5776    #ifdef WOLFSSL_CUSTOM_OID
5777        case ASN_CUSTOM_NAME:
5778            thisLen += cname->custom.oidSz;
5779            firstSz = cname->custom.oidSz;
5780            break;
5781    #endif
5782    #ifdef WOLFSSL_CERT_REQ
5783        case ASN_CONTENT_TYPE:
5784            thisLen += (int)sizeof(attrPkcs9ContentTypeOid);
5785            firstSz  = (int)sizeof(attrPkcs9ContentTypeOid);
5786            break;
5787    #endif
5788        default:
5789            thisLen += DN_OID_SZ;
5790            firstSz  = DN_OID_SZ;
5791    }
5792    thisLen++; /* id  type */
5793    firstSz  = (word32)SetObjectId((int)firstSz, firstLen);
5794    thisLen += firstSz;
5795
5796    seqSz = SetSequence(thisLen, sequence);
5797    thisLen += seqSz;
5798    setSz = SetSet(thisLen, set);
5799    thisLen += setSz;
5800
5801    if (thisLen > (int)sizeof(name->encoded)) {
5802        return BUFFER_E;
5803    }
5804
5805    /* store it */
5806    idx = 0;
5807    /* set */
5808    XMEMCPY(name->encoded, set, setSz);
5809    idx += setSz;
5810    /* seq */
5811    XMEMCPY(name->encoded + idx, sequence, seqSz);
5812    idx += seqSz;
5813    /* asn object id */
5814    XMEMCPY(name->encoded + idx, firstLen, firstSz);
5815    idx += firstSz;
5816    switch (type) {
5817        case ASN_EMAIL_NAME:
5818            /* email joint id */
5819            XMEMCPY(name->encoded + idx, attrEmailOid, sizeof(attrEmailOid));
5820            idx += (int)sizeof(attrEmailOid);
5821            name->encoded[idx++] = emailTag;
5822            break;
5823        case ASN_DOMAIN_COMPONENT:
5824            XMEMCPY(name->encoded + idx, dcOid, sizeof(dcOid)-1);
5825            idx += (int)sizeof(dcOid)-1;
5826            /* id type */
5827            name->encoded[idx++] = type;
5828            /* str type */
5829            name->encoded[idx++] = nameTag;
5830            break;
5831        case ASN_USER_ID:
5832            XMEMCPY(name->encoded + idx, uidOid, sizeof(uidOid));
5833            idx += (int)sizeof(uidOid);
5834            /* str type */
5835            name->encoded[idx++] = nameTag;
5836            break;
5837        case ASN_RFC822_MAILBOX:
5838            XMEMCPY(name->encoded + idx, rfc822Mlbx, sizeof(rfc822Mlbx));
5839            idx += (int)sizeof(rfc822Mlbx);
5840            /* str type */
5841            name->encoded[idx++] = nameTag;
5842            break;
5843        case ASN_FAVOURITE_DRINK:
5844            XMEMCPY(name->encoded + idx, fvrtDrk, sizeof(fvrtDrk));
5845            idx += (int)sizeof(fvrtDrk);
5846            /* str type */
5847            name->encoded[idx++] = nameTag;
5848            break;
5849    #ifdef WOLFSSL_CUSTOM_OID
5850        case ASN_CUSTOM_NAME:
5851            XMEMCPY(name->encoded + idx, cname->custom.oid,
5852                    cname->custom.oidSz);
5853            idx += cname->custom.oidSz;
5854            /* str type */
5855            name->encoded[idx++] = nameTag;
5856            break;
5857    #endif
5858    #ifdef WOLFSSL_CERT_REQ
5859        case ASN_CONTENT_TYPE:
5860            XMEMCPY(name->encoded + idx, attrPkcs9ContentTypeOid,
5861                    sizeof(attrPkcs9ContentTypeOid));
5862            idx += (int)sizeof(attrPkcs9ContentTypeOid);
5863            /* str type */
5864            name->encoded[idx++] = nameTag;
5865            break;
5866    #endif
5867        default:
5868            name->encoded[idx++] = 0x55;
5869            name->encoded[idx++] = 0x04;
5870            /* id type */
5871            name->encoded[idx++] = type;
5872            /* str type */
5873            name->encoded[idx++] = nameTag;
5874    }
5875    /* second length */
5876    XMEMCPY(name->encoded + idx, secondLen, secondSz);
5877    idx += secondSz;
5878    /* str value */
5879    XMEMCPY(name->encoded + idx, nameStr, strLen);
5880    idx += strLen;
5881
5882    name->type = type;
5883    name->totalLen = (int)idx;
5884    name->used = 1;
5885
5886    return (int)idx;
5887}
5888
5889#endif
5890#ifdef WOLFSSL_CERT_GEN
5891int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap)
5892{
5893    int ret;
5894    int i;
5895    word32 idx, totalBytes = 0;
5896    WC_DECLARE_VAR(names, EncodedName, NAME_ENTRIES, 0);
5897#ifdef WOLFSSL_MULTI_ATTRIB
5898    EncodedName addNames[CTC_MAX_ATTRIB];
5899    int j, type;
5900#endif
5901
5902    if (output == NULL || name == NULL)
5903        return BAD_FUNC_ARG;
5904
5905    if (outputSz < 3)
5906        return BUFFER_E;
5907
5908    WC_ALLOC_VAR_EX(names, EncodedName, NAME_ENTRIES, NULL,
5909        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
5910
5911    for (i = 0; i < NAME_ENTRIES; i++) {
5912        const char* nameStr = GetOneCertName(name, i);
5913
5914        ret = EncodeName(&names[i], nameStr, (byte)GetNameType(name, i),
5915                          GetCertNameId(i), ASN_IA5_STRING, name);
5916        if (ret < 0) {
5917            WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5918            WOLFSSL_MSG("EncodeName failed");
5919            return BUFFER_E;
5920        }
5921        totalBytes += (word32)ret;
5922    }
5923#ifdef WOLFSSL_MULTI_ATTRIB
5924    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
5925        if (name->name[i].sz > 0) {
5926            ret = EncodeName(&addNames[i], name->name[i].value,
5927                             (byte)name->name[i].type, (byte)name->name[i].id,
5928                        ASN_IA5_STRING, NULL);
5929            if (ret < 0) {
5930                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5931                WOLFSSL_MSG("EncodeName on multiple attributes failed");
5932                return BUFFER_E;
5933            }
5934            totalBytes += (word32)ret;
5935        }
5936        else {
5937            addNames[i].used = 0;
5938        }
5939    }
5940#endif /* WOLFSSL_MULTI_ATTRIB */
5941
5942    /* header */
5943    idx = SetSequence(totalBytes, output);
5944    totalBytes += idx;
5945    if (totalBytes > WC_ASN_NAME_MAX) {
5946        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5947        WOLFSSL_MSG("Total Bytes is greater than WC_ASN_NAME_MAX");
5948        return BUFFER_E;
5949    }
5950
5951    for (i = 0; i < NAME_ENTRIES; i++) {
5952    #ifdef WOLFSSL_MULTI_ATTRIB
5953        type = GetCertNameId(i);
5954        for (j = 0; j < CTC_MAX_ATTRIB; j++) {
5955            if (name->name[j].sz > 0 && type == name->name[j].id) {
5956                if (outputSz < idx + (word32)addNames[j].totalLen) {
5957                    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5958                    WOLFSSL_MSG("Not enough space left for DC value");
5959                    return BUFFER_E;
5960                }
5961
5962                XMEMCPY(output + idx, addNames[j].encoded,
5963                        (size_t)addNames[j].totalLen);
5964                idx += (word32)addNames[j].totalLen;
5965            }
5966        }
5967    #endif /* WOLFSSL_MULTI_ATTRIB */
5968
5969        if (names[i].used) {
5970            if (outputSz < idx + (word32)names[i].totalLen) {
5971                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5972                return BUFFER_E;
5973            }
5974
5975            XMEMCPY(output + idx, names[i].encoded, (size_t)names[i].totalLen);
5976            idx += (word32)names[i].totalLen;
5977        }
5978    }
5979
5980    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5981    (void)heap;
5982
5983    return (int)totalBytes;
5984}
5985
5986/* Set Date validity from now until now + daysValid
5987 * return size in bytes written to output, 0 on error */
5988/* TODO https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.5
5989 * "MUST always encode certificate validity dates through the year 2049 as
5990 *  UTCTime; certificate validity dates in 2050 or later MUST be encoded as
5991 *  GeneralizedTime." */
5992static int SetValidity(byte* output, int daysValid)
5993{
5994#ifndef NO_ASN_TIME
5995    byte before[MAX_DATE_SIZE];
5996    byte  after[MAX_DATE_SIZE];
5997
5998    word32 beforeSz, afterSz, seqSz;
5999
6000    time_t now;
6001    time_t then;
6002    struct tm* tmpTime;
6003    struct tm* expandedTime;
6004    struct tm localTime;
6005
6006#if defined(NEED_TMP_TIME)
6007    /* for use with gmtime_r */
6008    struct tm tmpTimeStorage;
6009    tmpTime = &tmpTimeStorage;
6010#else
6011    tmpTime = NULL;
6012#endif
6013    (void)tmpTime;
6014
6015    now = wc_Time(0);
6016
6017    /* before now */
6018    before[0] = ASN_GENERALIZED_TIME;
6019    beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
6020
6021    /* subtract 1 day of seconds for more compliance */
6022    then = now - 86400;
6023    expandedTime = XGMTIME(&then, tmpTime);
6024    if (ValidateGmtime(expandedTime)) {
6025        WOLFSSL_MSG("XGMTIME failed");
6026        return 0;   /* error */
6027    }
6028    localTime = *expandedTime;
6029
6030    /* adjust */
6031    localTime.tm_year += 1900;
6032    localTime.tm_mon +=    1;
6033
6034    SetTime(&localTime, before + beforeSz);
6035    beforeSz += ASN_GEN_TIME_SZ;
6036
6037    after[0] = ASN_GENERALIZED_TIME;
6038    afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
6039
6040    /* add daysValid of seconds */
6041    then = now + (daysValid * (time_t)86400);
6042    expandedTime = XGMTIME(&then, tmpTime);
6043    if (ValidateGmtime(expandedTime)) {
6044        WOLFSSL_MSG("XGMTIME failed");
6045        return 0;   /* error */
6046    }
6047    localTime = *expandedTime;
6048
6049    /* adjust */
6050    localTime.tm_year += 1900;
6051    localTime.tm_mon  +=    1;
6052
6053    SetTime(&localTime, after + afterSz);
6054    afterSz += ASN_GEN_TIME_SZ;
6055
6056    /* headers and output */
6057    seqSz = SetSequence(beforeSz + afterSz, output);
6058    XMEMCPY(output + seqSz, before, beforeSz);
6059    XMEMCPY(output + seqSz + beforeSz, after, afterSz);
6060
6061    return (int)(seqSz + beforeSz + afterSz);
6062#else
6063    (void)output;
6064    (void)daysValid;
6065    return NOT_COMPILED_IN;
6066#endif
6067}
6068
6069/* encode info from cert into DER encoded format */
6070static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
6071                      WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key,
6072                      ed448_key* ed448Key, falcon_key* falconKey,
6073                      dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey)
6074{
6075    int ret;
6076
6077    if (cert == NULL || der == NULL || rng == NULL)
6078        return BAD_FUNC_ARG;
6079
6080    /* make sure at least one key type is provided */
6081    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
6082        dsaKey == NULL && ed448Key == NULL && falconKey == NULL &&
6083        dilithiumKey == NULL && slhDsaKey == NULL) {
6084        return PUBLIC_KEY_E;
6085    }
6086
6087    /* init */
6088    XMEMSET(der, 0, sizeof(DerCert));
6089
6090    /* version */
6091    der->versionSz = SetMyVersion((word32)cert->version, der->version, TRUE);
6092
6093    /* serial number (must be positive) */
6094    if (cert->serialSz == 0) {
6095        /* generate random serial */
6096        cert->serialSz = CTC_GEN_SERIAL_SZ;
6097        ret = wc_RNG_GenerateBlock(rng, cert->serial, (word32)cert->serialSz);
6098        if (ret != 0)
6099            return ret;
6100        /* Clear the top bit to avoid a negative value */
6101        cert->serial[0] &= 0x7f;
6102    }
6103    der->serialSz = SetSerialNumber(cert->serial, (word32)cert->serialSz,
6104                                    der->serial, sizeof(der->serial),
6105                                    CTC_SERIAL_SIZE);
6106    if (der->serialSz < 0)
6107        return der->serialSz;
6108
6109    /* signature algo */
6110    der->sigAlgoSz = (int)SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
6111    if (der->sigAlgoSz <= 0)
6112        return ALGO_ID_E;
6113
6114    /* public key */
6115#ifndef NO_RSA
6116    if (cert->keyType == RSA_KEY) {
6117        if (rsaKey == NULL)
6118            return PUBLIC_KEY_E;
6119        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
6120                                           sizeof(der->publicKey), 1);
6121    }
6122#endif
6123
6124#ifdef HAVE_ECC
6125    if (cert->keyType == ECC_KEY) {
6126        if (eccKey == NULL)
6127            return PUBLIC_KEY_E;
6128        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
6129                                           sizeof(der->publicKey), 1, 0);
6130    }
6131#endif
6132
6133#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
6134    if (cert->keyType == DSA_KEY) {
6135        if (dsaKey == NULL)
6136            return PUBLIC_KEY_E;
6137        der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
6138                                              sizeof(der->publicKey), 1);
6139    }
6140#endif
6141
6142#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
6143    if (cert->keyType == ED25519_KEY) {
6144        if (ed25519Key == NULL)
6145            return PUBLIC_KEY_E;
6146        der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
6147            (word32)sizeof(der->publicKey), 1);
6148    }
6149#endif
6150
6151#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
6152    if (cert->keyType == ED448_KEY) {
6153        if (ed448Key == NULL)
6154            return PUBLIC_KEY_E;
6155        der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
6156            (word32)sizeof(der->publicKey), 1);
6157    }
6158#endif
6159
6160#if defined(HAVE_FALCON)
6161    if ((cert->keyType == FALCON_LEVEL1_KEY) ||
6162        (cert->keyType == FALCON_LEVEL5_KEY)) {
6163        if (falconKey == NULL)
6164            return PUBLIC_KEY_E;
6165
6166        der->publicKeySz =
6167            wc_Falcon_PublicKeyToDer(falconKey, der->publicKey,
6168                                     (word32)sizeof(der->publicKey), 1);
6169    }
6170#endif /* HAVE_FALCON */
6171#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_ASN1)
6172    if ((cert->keyType == ML_DSA_LEVEL2_KEY) ||
6173        (cert->keyType == ML_DSA_LEVEL3_KEY) ||
6174        (cert->keyType == ML_DSA_LEVEL5_KEY)
6175    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
6176     || (cert->keyType == DILITHIUM_LEVEL2_KEY)
6177     || (cert->keyType == DILITHIUM_LEVEL3_KEY)
6178     || (cert->keyType == DILITHIUM_LEVEL5_KEY)
6179    #endif
6180        ) {
6181        if (dilithiumKey == NULL)
6182            return PUBLIC_KEY_E;
6183
6184        der->publicKeySz =
6185            wc_Dilithium_PublicKeyToDer(dilithiumKey, der->publicKey,
6186                                     (word32)sizeof(der->publicKey), 1);
6187    }
6188#endif /* HAVE_DILITHIUM */
6189#if defined(WOLFSSL_HAVE_SLHDSA)
6190    if ((cert->keyType == SLH_DSA_SHAKE_128F_KEY) ||
6191        (cert->keyType == SLH_DSA_SHAKE_192F_KEY) ||
6192        (cert->keyType == SLH_DSA_SHAKE_256F_KEY) ||
6193        (cert->keyType == SLH_DSA_SHAKE_128S_KEY) ||
6194        (cert->keyType == SLH_DSA_SHAKE_192S_KEY) ||
6195        (cert->keyType == SLH_DSA_SHAKE_256S_KEY)
6196    #ifdef WOLFSSL_SLHDSA_SHA2
6197     || (cert->keyType == SLH_DSA_SHA2_128F_KEY) ||
6198        (cert->keyType == SLH_DSA_SHA2_192F_KEY) ||
6199        (cert->keyType == SLH_DSA_SHA2_256F_KEY) ||
6200        (cert->keyType == SLH_DSA_SHA2_128S_KEY) ||
6201        (cert->keyType == SLH_DSA_SHA2_192S_KEY) ||
6202        (cert->keyType == SLH_DSA_SHA2_256S_KEY)
6203    #endif
6204        ) {
6205        if (slhDsaKey == NULL)
6206            return PUBLIC_KEY_E;
6207
6208        der->publicKeySz =
6209            wc_SlhDsaKey_PublicKeyToDer(slhDsaKey, der->publicKey,
6210                                      (word32)sizeof(der->publicKey), 1);
6211    }
6212#endif /* WOLFSSL_HAVE_SLHDSA */
6213
6214    if (der->publicKeySz <= 0)
6215        return PUBLIC_KEY_E;
6216
6217    der->validitySz = 0;
6218    /* copy date validity if already set in cert struct */
6219    if (cert->beforeDateSz && cert->afterDateSz) {
6220        der->validitySz = CopyValidity(der->validity, cert);
6221        if (der->validitySz <= 0)
6222            return DATE_E;
6223    }
6224
6225    /* set date validity using daysValid if not set already */
6226    if (der->validitySz == 0) {
6227        der->validitySz = SetValidity(der->validity, cert->daysValid);
6228        if (der->validitySz <= 0)
6229            return DATE_E;
6230    }
6231
6232    /* subject name */
6233#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
6234    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
6235        /* Use the raw subject */
6236        word32 idx;
6237
6238        der->subjectSz = (int)min((word32)sizeof(der->subject),
6239                                  (word32)XSTRLEN((const char*)cert->sbjRaw));
6240        /* header */
6241        idx = SetSequence((word32)der->subjectSz, der->subject);
6242        if ((word32)der->subjectSz + idx > (word32)sizeof(der->subject)) {
6243            return SUBJECT_E;
6244        }
6245
6246        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
6247                (size_t)der->subjectSz);
6248        der->subjectSz += (int)idx;
6249    }
6250    else
6251#endif
6252    {
6253        /* Use the name structure */
6254        der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
6255                &cert->subject, cert->heap);
6256    }
6257    if (der->subjectSz <= 0)
6258        return SUBJECT_E;
6259
6260    /* issuer name */
6261#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
6262    if (XSTRLEN((const char*)cert->issRaw) > 0) {
6263        /* Use the raw issuer */
6264        word32 idx;
6265
6266        der->issuerSz = (int)min((word32)sizeof(der->issuer),
6267                                 (word32)XSTRLEN((const char*)cert->issRaw));
6268
6269        /* header */
6270        idx = SetSequence((word32)der->issuerSz, der->issuer);
6271        if ((word32)der->issuerSz + idx > (word32)sizeof(der->issuer)) {
6272            return ISSUER_E;
6273        }
6274
6275        XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,
6276                (size_t)der->issuerSz);
6277        der->issuerSz += (int)idx;
6278    }
6279    else
6280#endif
6281    {
6282        /* Use the name structure */
6283        der->issuerSz = SetNameEx(der->issuer, sizeof(der->issuer),
6284                cert->selfSigned ? &cert->subject : &cert->issuer, cert->heap);
6285    }
6286    if (der->issuerSz <= 0)
6287        return ISSUER_E;
6288
6289    /* set the extensions */
6290    der->extensionsSz = 0;
6291
6292    /* RFC 5280 : 4.2.1.9. Basic Constraints
6293     * The pathLenConstraint field is meaningful only if the CA boolean is
6294     * asserted and the key usage extension, if present, asserts the
6295     * keyCertSign bit */
6296    /* Set CA and path length */
6297    if ((cert->isCA) && (cert->pathLenSet)
6298#ifdef WOLFSSL_CERT_EXT
6299        && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
6300#endif
6301        ) {
6302        der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
6303        if (der->caSz <= 0)
6304            return CA_TRUE_E;
6305
6306        der->extensionsSz += der->caSz;
6307    }
6308#ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE
6309    /* Set CA */
6310    else if (cert->isCaSet) {
6311        der->caSz = SetCaEx(der->ca, sizeof(der->ca), cert->isCA);
6312        if (der->caSz <= 0)
6313            return EXTENSIONS_E;
6314
6315        der->extensionsSz += der->caSz;
6316    }
6317#endif
6318    /* Set CA true */
6319    else if (cert->isCA) {
6320        der->caSz = SetCa(der->ca, sizeof(der->ca));
6321        if (der->caSz <= 0)
6322            return CA_TRUE_E;
6323
6324        der->extensionsSz += der->caSz;
6325    }
6326    /* Set Basic Constraint */
6327    else if (cert->basicConstSet) {
6328        der->caSz = SetBC(der->ca, sizeof(der->ca));
6329        if (der->caSz <= 0)
6330            return EXTENSIONS_E;
6331
6332        der->extensionsSz += der->caSz;
6333    }
6334    else
6335        der->caSz = 0;
6336
6337#ifdef WOLFSSL_ALT_NAMES
6338    /* Alternative Name */
6339    if (cert->altNamesSz) {
6340        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
6341                                      cert->altNames, (word32)cert->altNamesSz,
6342                                      cert->altNamesCrit);
6343        if (der->altNamesSz <= 0)
6344            return ALT_NAME_E;
6345
6346        der->extensionsSz += der->altNamesSz;
6347    }
6348    else
6349        der->altNamesSz = 0;
6350#endif
6351
6352#ifdef WOLFSSL_CERT_EXT
6353    /* SKID */
6354    if (cert->skidSz) {
6355        /* check the provided SKID size */
6356        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
6357            return SKID_E;
6358
6359        /* Note: different skid buffers sizes for der (MAX_KID_SZ) and
6360            cert (CTC_MAX_SKID_SIZE). */
6361        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
6362                              cert->skid, (word32)cert->skidSz);
6363        if (der->skidSz <= 0)
6364            return SKID_E;
6365
6366        der->extensionsSz += der->skidSz;
6367    }
6368    else
6369        der->skidSz = 0;
6370
6371    /* AKID */
6372    if (cert->akidSz) {
6373        /* check the provided AKID size */
6374        if ((
6375#ifdef WOLFSSL_AKID_NAME
6376             !cert->rawAkid &&
6377#endif
6378              cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
6379#ifdef WOLFSSL_AKID_NAME
6380          || (cert->rawAkid && cert->akidSz > (int)sizeof(der->akid))
6381#endif
6382             )
6383            return AKID_E;
6384
6385        der->akidSz = SetAKID(der->akid, sizeof(der->akid), cert->akid,
6386                              (word32)cert->akidSz,
6387#ifdef WOLFSSL_AKID_NAME
6388                              cert->rawAkid
6389#else
6390                              0
6391#endif
6392                              );
6393        if (der->akidSz <= 0)
6394            return AKID_E;
6395
6396        der->extensionsSz += der->akidSz;
6397    }
6398    else
6399        der->akidSz = 0;
6400
6401    /* Key Usage */
6402    if (cert->keyUsage != 0){
6403        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
6404                                      cert->keyUsage);
6405        if (der->keyUsageSz <= 0)
6406            return KEYUSAGE_E;
6407
6408        der->extensionsSz += der->keyUsageSz;
6409    }
6410    else
6411        der->keyUsageSz = 0;
6412
6413    /* Extended Key Usage */
6414    if (cert->extKeyUsage != 0){
6415        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
6416                                sizeof(der->extKeyUsage), cert->extKeyUsage);
6417        if (der->extKeyUsageSz <= 0)
6418            return EXTKEYUSAGE_E;
6419
6420        der->extensionsSz += der->extKeyUsageSz;
6421    }
6422    else
6423        der->extKeyUsageSz = 0;
6424
6425#ifndef IGNORE_NETSCAPE_CERT_TYPE
6426    /* Netscape Certificate Type */
6427    if (cert->nsCertType != 0) {
6428        der->nsCertTypeSz = SetNsCertType(cert, der->nsCertType,
6429                                sizeof(der->nsCertType), cert->nsCertType);
6430        if (der->nsCertTypeSz <= 0)
6431            return EXTENSIONS_E;
6432
6433        der->extensionsSz += der->nsCertTypeSz;
6434    }
6435    else
6436        der->nsCertTypeSz = 0;
6437#endif
6438
6439    if (cert->crlInfoSz > 0) {
6440        der->crlInfoSz = SetCRLInfo(cert, der->crlInfo, sizeof(der->crlInfo),
6441                                cert->crlInfo, cert->crlInfoSz);
6442        if (der->crlInfoSz <= 0)
6443            return EXTENSIONS_E;
6444
6445        der->extensionsSz += der->crlInfoSz;
6446    }
6447    else
6448        der->crlInfoSz = 0;
6449
6450    /* Certificate Policies */
6451    if (cert->certPoliciesNb != 0) {
6452        der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
6453                                                     sizeof(der->certPolicies),
6454                                                     cert->certPolicies,
6455                                                     cert->certPoliciesNb,
6456                                                     cert->heap);
6457        if (der->certPoliciesSz <= 0)
6458            return CERTPOLICIES_E;
6459
6460        der->extensionsSz += der->certPoliciesSz;
6461    }
6462    else
6463        der->certPoliciesSz = 0;
6464#endif /* WOLFSSL_CERT_EXT */
6465
6466#ifdef WOLFSSL_ACME_OID
6467    /* RFC 8737 id-pe-acmeIdentifier (TLS-ALPN-01 challenge cert).
6468     * Always critical=TRUE. */
6469    if (cert->acmeIdentifierSz == WC_SHA256_DIGEST_SIZE) {
6470        der->acmeIdSz = SetAcmeIdentifier(der->acmeId, sizeof(der->acmeId),
6471                                          cert->acmeIdentifier,
6472                                          (word32)cert->acmeIdentifierSz);
6473        if (der->acmeIdSz <= 0)
6474            return EXTENSIONS_E;
6475
6476        der->extensionsSz += der->acmeIdSz;
6477    }
6478    else
6479        der->acmeIdSz = 0;
6480#endif
6481
6482    /* put extensions */
6483    if (der->extensionsSz > 0) {
6484
6485        /* put the start of extensions sequence (ID, Size) */
6486        der->extensionsSz = SetExtensionsHeader(der->extensions,
6487                                                sizeof(der->extensions),
6488                                                (word32)der->extensionsSz);
6489        if (der->extensionsSz <= 0)
6490            return EXTENSIONS_E;
6491
6492        /* put CA */
6493        if (der->caSz) {
6494            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6495                                &der->extensionsSz,
6496                                der->ca, der->caSz);
6497            if (ret == 0)
6498                return EXTENSIONS_E;
6499        }
6500
6501#ifdef WOLFSSL_ALT_NAMES
6502        /* put Alternative Names */
6503        if (der->altNamesSz) {
6504            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6505                                &der->extensionsSz,
6506                                der->altNames, der->altNamesSz);
6507            if (ret <= 0)
6508                return EXTENSIONS_E;
6509        }
6510#endif
6511
6512#ifdef WOLFSSL_CERT_EXT
6513        /* put SKID */
6514        if (der->skidSz) {
6515            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6516                                &der->extensionsSz,
6517                                der->skid, der->skidSz);
6518            if (ret <= 0)
6519                return EXTENSIONS_E;
6520        }
6521
6522        /* put AKID */
6523        if (der->akidSz) {
6524            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6525                                &der->extensionsSz,
6526                                der->akid, der->akidSz);
6527            if (ret <= 0)
6528                return EXTENSIONS_E;
6529        }
6530
6531        /* put CRL Distribution Points */
6532        if (der->crlInfoSz) {
6533            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6534                                &der->extensionsSz,
6535                                der->crlInfo, der->crlInfoSz);
6536            if (ret <= 0)
6537                return EXTENSIONS_E;
6538        }
6539
6540        /* put KeyUsage */
6541        if (der->keyUsageSz) {
6542            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6543                                &der->extensionsSz,
6544                                der->keyUsage, der->keyUsageSz);
6545            if (ret <= 0)
6546                return EXTENSIONS_E;
6547        }
6548
6549        /* put ExtendedKeyUsage */
6550        if (der->extKeyUsageSz) {
6551            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6552                                &der->extensionsSz,
6553                                der->extKeyUsage, der->extKeyUsageSz);
6554            if (ret <= 0)
6555                return EXTENSIONS_E;
6556        }
6557
6558        /* put Netscape Cert Type */
6559#ifndef IGNORE_NETSCAPE_CERT_TYPE
6560        if (der->nsCertTypeSz) {
6561            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6562                                &der->extensionsSz,
6563                                der->nsCertType, der->nsCertTypeSz);
6564            if (ret <= 0)
6565                return EXTENSIONS_E;
6566        }
6567#endif
6568
6569        /* put Certificate Policies */
6570        if (der->certPoliciesSz) {
6571            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6572                                &der->extensionsSz,
6573                                der->certPolicies, der->certPoliciesSz);
6574            if (ret <= 0)
6575                return EXTENSIONS_E;
6576        }
6577#endif /* WOLFSSL_CERT_EXT */
6578
6579#ifdef WOLFSSL_ACME_OID
6580        /* put ACME Identifier */
6581        if (der->acmeIdSz) {
6582            ret = SetExtensions(der->extensions, sizeof(der->extensions),
6583                                &der->extensionsSz,
6584                                der->acmeId, der->acmeIdSz);
6585            if (ret <= 0)
6586                return EXTENSIONS_E;
6587        }
6588#endif
6589    }
6590
6591    der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
6592        der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
6593        der->extensionsSz;
6594
6595    return 0;
6596}
6597
6598
6599/* write DER encoded cert to buffer, size already checked */
6600static int WriteCertBody(DerCert* der, byte* buf)
6601{
6602    word32 idx;
6603
6604    /* signed part header */
6605    idx = SetSequence((word32)der->total, buf);
6606    /* version */
6607    XMEMCPY(buf + idx, der->version, (size_t)der->versionSz);
6608    idx += (word32)der->versionSz;
6609    /* serial */
6610    XMEMCPY(buf + idx, der->serial, (size_t)der->serialSz);
6611    idx += (word32)der->serialSz;
6612    /* sig algo */
6613    XMEMCPY(buf + idx, der->sigAlgo, (size_t)der->sigAlgoSz);
6614    idx += (word32)der->sigAlgoSz;
6615    /* issuer */
6616    XMEMCPY(buf + idx, der->issuer, (size_t)der->issuerSz);
6617    idx += (word32)der->issuerSz;
6618    /* validity */
6619    XMEMCPY(buf + idx, der->validity, (size_t)der->validitySz);
6620    idx += (word32)der->validitySz;
6621    /* subject */
6622    XMEMCPY(buf + idx, der->subject, (size_t)der->subjectSz);
6623    idx += (word32)der->subjectSz;
6624    /* public key */
6625    XMEMCPY(buf + idx, der->publicKey, (size_t)der->publicKeySz);
6626    idx += (word32)der->publicKeySz;
6627    if (der->extensionsSz) {
6628        /* extensions */
6629        XMEMCPY(buf + idx, der->extensions,
6630                min((word32)der->extensionsSz,
6631                    (word32)sizeof(der->extensions)));
6632        idx += (word32)der->extensionsSz;
6633    }
6634
6635    return (int)idx;
6636}
6637
6638int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
6639                        int sigAlgoType)
6640{
6641    byte seq[MAX_SEQ_SZ];
6642    word32 idx, seqSz;
6643
6644    if ((bodySz < 0) || (sigSz < 0))
6645        return BUFFER_E;
6646
6647    idx = (word32)bodySz;
6648
6649    /* algo */
6650    idx += SetAlgoID(sigAlgoType, buf ? buf + idx : NULL, oidSigType, 0);
6651    /* bit string */
6652    idx += SetBitString((word32)sigSz, 0, buf ? buf + idx : NULL);
6653    /* signature */
6654    if (buf)
6655        XMEMCPY(buf + idx, sig, (size_t)sigSz);
6656    idx += (word32)sigSz;
6657
6658    /* make room for overall header */
6659    seqSz = SetSequence(idx, seq);
6660    if (buf) {
6661        XMEMMOVE(buf + seqSz, buf, idx);
6662        XMEMCPY(buf, seq, seqSz);
6663    }
6664
6665    return (int)(idx + seqSz);
6666}
6667
6668static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
6669                       RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
6670                       DsaKey* dsaKey, ed25519_key* ed25519Key,
6671                       ed448_key* ed448Key, falcon_key* falconKey,
6672                       dilithium_key* dilithiumKey, SlhDsaKey* slhDsaKey)
6673{
6674    int ret;
6675    WC_DECLARE_VAR(der, DerCert, 1, 0);
6676
6677    if (derBuffer == NULL)
6678        return BAD_FUNC_ARG;
6679
6680    if (eccKey)
6681        cert->keyType = ECC_KEY;
6682    else if (rsaKey)
6683        cert->keyType = RSA_KEY;
6684    else if (dsaKey)
6685        cert->keyType = DSA_KEY;
6686    else if (ed25519Key)
6687        cert->keyType = ED25519_KEY;
6688    else if (ed448Key)
6689        cert->keyType = ED448_KEY;
6690#ifdef HAVE_FALCON
6691    else if ((falconKey != NULL) && (falconKey->level == 1))
6692        cert->keyType = FALCON_LEVEL1_KEY;
6693    else if ((falconKey != NULL) && (falconKey->level == 5))
6694        cert->keyType = FALCON_LEVEL5_KEY;
6695#endif /* HAVE_FALCON */
6696#ifdef HAVE_DILITHIUM
6697    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
6698    else if ((dilithiumKey != NULL) &&
6699                (dilithiumKey->params->level == WC_ML_DSA_44_DRAFT)) {
6700        cert->keyType = DILITHIUM_LEVEL2_KEY;
6701    }
6702    else if ((dilithiumKey != NULL) &&
6703                (dilithiumKey->params->level == WC_ML_DSA_65_DRAFT)) {
6704        cert->keyType = DILITHIUM_LEVEL3_KEY;
6705    }
6706    else if ((dilithiumKey != NULL) &&
6707                (dilithiumKey->params->level == WC_ML_DSA_87_DRAFT)) {
6708        cert->keyType = DILITHIUM_LEVEL5_KEY;
6709    }
6710    #endif
6711    else if ((dilithiumKey != NULL) &&
6712                (dilithiumKey->params->level == WC_ML_DSA_44)) {
6713        cert->keyType = ML_DSA_LEVEL2_KEY;
6714    }
6715    else if ((dilithiumKey != NULL) &&
6716                (dilithiumKey->params->level == WC_ML_DSA_65)) {
6717        cert->keyType = ML_DSA_LEVEL3_KEY;
6718    }
6719    else if ((dilithiumKey != NULL) &&
6720                (dilithiumKey->params->level == WC_ML_DSA_87)) {
6721        cert->keyType = ML_DSA_LEVEL5_KEY;
6722    }
6723#endif /* HAVE_DILITHIUM */
6724#ifdef WOLFSSL_HAVE_SLHDSA
6725    else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) &&
6726             (SlhDsaParamToKeyType(slhDsaKey->params->param) != 0)) {
6727        cert->keyType = SlhDsaParamToKeyType(slhDsaKey->params->param);
6728    }
6729#endif /* WOLFSSL_HAVE_SLHDSA */
6730    else
6731        return BAD_FUNC_ARG;
6732
6733    WC_ALLOC_VAR_EX(der, DerCert, 1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER,
6734        return MEMORY_E);
6735
6736    ret = EncodeCert(cert, der, rsaKey, eccKey, rng, dsaKey, ed25519Key,
6737                     ed448Key, falconKey, dilithiumKey, slhDsaKey);
6738    if (ret == 0) {
6739        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
6740            ret = BUFFER_E;
6741        else
6742            ret = cert->bodySz = WriteCertBody(der, derBuffer);
6743    }
6744
6745    WC_FREE_VAR_EX(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
6746
6747    return ret;
6748}
6749
6750#ifdef WOLFSSL_CERT_REQ
6751/* return size of data set on success
6752 * if getting size only then attr and oid should be NULL
6753 */
6754static word32 SetReqAttribSingle(byte* output, word32* idx, char* attr,
6755        word32 attrSz, const byte* oid, word32 oidSz, byte printable,
6756        word32 extSz)
6757{
6758    word32 totalSz = 0;
6759    word32 seqSz = 0;
6760    word32 setSz = 0;
6761    word32 strSz = 0;
6762    byte seq[MAX_SEQ_SZ];
6763    byte set[MAX_SET_SZ];
6764    byte str[MAX_PRSTR_SZ];
6765
6766    totalSz = (word32)SetObjectId((int)oidSz, NULL);
6767    totalSz += oidSz;
6768    if (extSz > 0) {
6769        totalSz += setSz = SetSet(extSz, set);
6770        totalSz += seqSz = SetSequence(totalSz + extSz, seq);
6771        totalSz += extSz;
6772    }
6773    else {
6774        if (printable) {
6775            strSz = SetPrintableString(attrSz, str);
6776            totalSz += strSz;
6777        }
6778        else {
6779            totalSz += strSz = SetUTF8String(attrSz, str);
6780        }
6781        totalSz += setSz = SetSet(strSz + attrSz, set);
6782        totalSz += seqSz = SetSequence(totalSz + attrSz, seq);
6783        totalSz += attrSz;
6784    }
6785
6786    if (oid) {
6787        XMEMCPY(&output[*idx], seq, seqSz);
6788        *idx += seqSz;
6789        *idx += (word32)SetObjectId((int)oidSz, output + *idx);
6790        XMEMCPY(&output[*idx], oid, oidSz);
6791        *idx += oidSz;
6792        XMEMCPY(&output[*idx], set, setSz);
6793        *idx += setSz;
6794        if (strSz > 0) {
6795            XMEMCPY(&output[*idx], str, strSz);
6796            *idx += strSz;
6797            if (attrSz > 0) {
6798                XMEMCPY(&output[*idx], attr, attrSz);
6799                *idx += attrSz;
6800            }
6801        }
6802    }
6803    return totalSz;
6804}
6805
6806
6807
6808static int SetReqAttrib(byte* output, Cert* cert, word32 extSz)
6809{
6810    word32 sz      = 0; /* overall size */
6811    word32 setSz   = 0;
6812
6813    output[0] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
6814    sz++;
6815
6816    if (cert->challengePw[0]) {
6817        setSz += SetReqAttribSingle(output, &sz, NULL,
6818                (word32)XSTRLEN(cert->challengePw), NULL,
6819                sizeof(attrChallengePasswordOid),
6820                (byte)cert->challengePwPrintableString, 0);
6821    }
6822
6823    if (cert->unstructuredName[0]) {
6824        setSz += SetReqAttribSingle(output, &sz, NULL,
6825                (word32)XSTRLEN(cert->unstructuredName), NULL,
6826                sizeof(attrUnstructuredNameOid), 1, 0);
6827    }
6828
6829    if (extSz) {
6830        setSz += SetReqAttribSingle(output, &sz, NULL, 0, NULL,
6831                sizeof(attrExtensionRequestOid), 1, extSz);
6832    }
6833
6834    /* Put the pieces together. */
6835    sz += SetLength(setSz, &output[sz]);
6836    if (sz + setSz - extSz > MAX_ATTRIB_SZ) {
6837        WOLFSSL_MSG("Attribute Buffer is not big enough!");
6838        return REQ_ATTRIBUTE_E;
6839    }
6840
6841    if (cert->challengePw[0]) {
6842        SetReqAttribSingle(output, &sz, cert->challengePw,
6843                (word32)XSTRLEN(cert->challengePw),
6844                &attrChallengePasswordOid[0],
6845                sizeof(attrChallengePasswordOid),
6846                (byte)cert->challengePwPrintableString, 0);
6847    }
6848
6849    if (cert->unstructuredName[0]) {
6850        SetReqAttribSingle(output, &sz, cert->unstructuredName,
6851                (word32)XSTRLEN(cert->unstructuredName),
6852                &attrUnstructuredNameOid[0],
6853                sizeof(attrUnstructuredNameOid), 1, 0);
6854    }
6855
6856    if (extSz) {
6857        SetReqAttribSingle(output, &sz, NULL, 0, &attrExtensionRequestOid[0],
6858                sizeof(attrExtensionRequestOid), 1, extSz);
6859        /* The actual extension data will be tacked onto the output later. */
6860    }
6861
6862    return (int)sz;
6863}
6864
6865#ifdef WOLFSSL_CUSTOM_OID
6866/* encode a custom oid and value */
6867static int SetCustomObjectId(Cert* cert, byte* output, word32 outSz,
6868    CertOidField* custom)
6869{
6870    int idx = 0, cust_lenSz, cust_oidSz;
6871
6872    if (cert == NULL || output == NULL || custom == NULL) {
6873        return BAD_FUNC_ARG;
6874    }
6875    if (custom->oid == NULL || custom->oidSz <= 0) {
6876        return 0; /* none set */
6877    }
6878
6879    /* Octet String header */
6880    cust_lenSz = SetOctetString(custom->valSz, NULL);
6881    cust_oidSz = SetObjectId(custom->oidSz, NULL);
6882
6883    /* check for output buffer room */
6884    if ((word32)(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz) >
6885                                                                        outSz) {
6886        return BUFFER_E;
6887    }
6888
6889    /* put sequence with total */
6890    idx = SetSequence(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz,
6891                      output);
6892
6893    /* put oid header */
6894    idx += SetObjectId(custom->oidSz, output+idx);
6895    XMEMCPY(output+idx, custom->oid, custom->oidSz);
6896    idx += custom->oidSz;
6897
6898    /* put value */
6899    idx += SetOctetString(custom->valSz, output+idx);
6900    XMEMCPY(output+idx, custom->val, custom->valSz);
6901    idx += custom->valSz;
6902
6903    return idx;
6904}
6905#endif /* WOLFSSL_CUSTOM_OID */
6906
6907
6908/* encode info from cert into DER encoded format */
6909static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
6910                         DsaKey* dsaKey, ecc_key* eccKey,
6911                         ed25519_key* ed25519Key, ed448_key* ed448Key,
6912                         falcon_key* falconKey, dilithium_key* dilithiumKey,
6913                         SlhDsaKey* slhDsaKey)
6914{
6915    int ret;
6916
6917    (void)eccKey;
6918    (void)ed25519Key;
6919    (void)ed448Key;
6920    (void)falconKey;
6921    (void)dilithiumKey;
6922    (void)slhDsaKey;
6923
6924    if (cert == NULL || der == NULL)
6925        return BAD_FUNC_ARG;
6926
6927    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
6928        dsaKey == NULL && ed448Key == NULL && falconKey == NULL &&
6929        dilithiumKey == NULL && slhDsaKey == NULL) {
6930        return PUBLIC_KEY_E;
6931    }
6932
6933    /* init */
6934    XMEMSET(der, 0, sizeof(DerCert));
6935
6936    /* version */
6937    der->versionSz = SetMyVersion((word32)cert->version, der->version, FALSE);
6938
6939    /* subject name */
6940#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
6941    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
6942        /* Use the raw subject */
6943        int idx;
6944
6945        der->subjectSz = (int)min(sizeof(der->subject),
6946                (word32)XSTRLEN((const char*)cert->sbjRaw));
6947        /* header */
6948        idx = (int)SetSequence((word32)der->subjectSz, der->subject);
6949        if (der->subjectSz + idx > (int)sizeof(der->subject)) {
6950            return SUBJECT_E;
6951        }
6952
6953        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
6954                (size_t)der->subjectSz);
6955        der->subjectSz += idx;
6956    }
6957    else
6958#endif
6959    {
6960        der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
6961                &cert->subject, cert->heap);
6962    }
6963    if (der->subjectSz <= 0)
6964        return SUBJECT_E;
6965
6966    /* public key */
6967#ifndef NO_RSA
6968    if (cert->keyType == RSA_KEY) {
6969        if (rsaKey == NULL)
6970            return PUBLIC_KEY_E;
6971        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
6972                                           sizeof(der->publicKey), 1);
6973    }
6974#endif
6975
6976#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
6977    if (cert->keyType == DSA_KEY) {
6978        if (dsaKey == NULL)
6979            return PUBLIC_KEY_E;
6980        der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
6981                                           sizeof(der->publicKey), 1);
6982    }
6983#endif
6984
6985#ifdef HAVE_ECC
6986    if (cert->keyType == ECC_KEY) {
6987        if (eccKey == NULL)
6988            return PUBLIC_KEY_E;
6989        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
6990                                           sizeof(der->publicKey), 1, 0);
6991    }
6992#endif
6993
6994#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
6995    if (cert->keyType == ED25519_KEY) {
6996        if (ed25519Key == NULL)
6997            return PUBLIC_KEY_E;
6998        der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
6999            (word32)sizeof(der->publicKey), 1);
7000    }
7001#endif
7002
7003#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
7004    if (cert->keyType == ED448_KEY) {
7005        if (ed448Key == NULL)
7006            return PUBLIC_KEY_E;
7007        der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
7008            (word32)sizeof(der->publicKey), 1);
7009    }
7010#endif
7011#if defined(HAVE_FALCON)
7012    if ((cert->keyType == FALCON_LEVEL1_KEY) ||
7013        (cert->keyType == FALCON_LEVEL5_KEY)) {
7014        if (falconKey == NULL)
7015            return PUBLIC_KEY_E;
7016        der->publicKeySz = wc_Falcon_PublicKeyToDer(falconKey,
7017            der->publicKey, (word32)sizeof(der->publicKey), 1);
7018    }
7019#endif
7020#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_ASN1)
7021    if ((cert->keyType == ML_DSA_LEVEL2_KEY) ||
7022        (cert->keyType == ML_DSA_LEVEL3_KEY) ||
7023        (cert->keyType == ML_DSA_LEVEL5_KEY)
7024    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
7025     || (cert->keyType == DILITHIUM_LEVEL2_KEY)
7026     || (cert->keyType == DILITHIUM_LEVEL3_KEY)
7027     || (cert->keyType == DILITHIUM_LEVEL5_KEY)
7028   #endif
7029        ) {
7030        if (dilithiumKey == NULL)
7031            return PUBLIC_KEY_E;
7032        der->publicKeySz = wc_Dilithium_PublicKeyToDer(dilithiumKey,
7033            der->publicKey, (word32)sizeof(der->publicKey), 1);
7034    }
7035#endif
7036#if defined(WOLFSSL_HAVE_SLHDSA)
7037    if ((cert->keyType == SLH_DSA_SHAKE_128F_KEY) ||
7038        (cert->keyType == SLH_DSA_SHAKE_192F_KEY) ||
7039        (cert->keyType == SLH_DSA_SHAKE_256F_KEY) ||
7040        (cert->keyType == SLH_DSA_SHAKE_128S_KEY) ||
7041        (cert->keyType == SLH_DSA_SHAKE_192S_KEY) ||
7042        (cert->keyType == SLH_DSA_SHAKE_256S_KEY)
7043    #ifdef WOLFSSL_SLHDSA_SHA2
7044     || (cert->keyType == SLH_DSA_SHA2_128F_KEY) ||
7045        (cert->keyType == SLH_DSA_SHA2_192F_KEY) ||
7046        (cert->keyType == SLH_DSA_SHA2_256F_KEY) ||
7047        (cert->keyType == SLH_DSA_SHA2_128S_KEY) ||
7048        (cert->keyType == SLH_DSA_SHA2_192S_KEY) ||
7049        (cert->keyType == SLH_DSA_SHA2_256S_KEY)
7050    #endif
7051        ) {
7052        if (slhDsaKey == NULL)
7053            return PUBLIC_KEY_E;
7054        der->publicKeySz = wc_SlhDsaKey_PublicKeyToDer(slhDsaKey,
7055            der->publicKey, (word32)sizeof(der->publicKey), 1);
7056    }
7057#endif
7058
7059    if (der->publicKeySz <= 0)
7060        return PUBLIC_KEY_E;
7061
7062    /* set the extensions */
7063    der->extensionsSz = 0;
7064
7065    /* RFC 5280 : 4.2.1.9. Basic Constraints
7066     * The pathLenConstraint field is meaningful only if the CA boolean is
7067     * asserted and the key usage extension, if present, asserts the
7068     * keyCertSign bit */
7069    /* Set CA and path length */
7070    if ((cert->isCA) && (cert->pathLenSet)
7071#ifdef WOLFSSL_CERT_EXT
7072        && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
7073#endif
7074        ) {
7075        der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
7076        if (der->caSz <= 0)
7077            return CA_TRUE_E;
7078
7079        der->extensionsSz += der->caSz;
7080    }
7081#ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE
7082    /* Set CA */
7083    else if (cert->isCaSet) {
7084        der->caSz = SetCaEx(der->ca, sizeof(der->ca), cert->isCA);
7085        if (der->caSz <= 0)
7086            return EXTENSIONS_E;
7087
7088        der->extensionsSz += der->caSz;
7089    }
7090#endif
7091    /* Set CA true */
7092    else if (cert->isCA) {
7093        der->caSz = SetCa(der->ca, sizeof(der->ca));
7094        if (der->caSz <= 0)
7095            return CA_TRUE_E;
7096
7097        der->extensionsSz += der->caSz;
7098    }
7099    /* Set Basic Constraint */
7100    else if (cert->basicConstSet) {
7101        der->caSz = SetBC(der->ca, sizeof(der->ca));
7102        if (der->caSz <= 0)
7103            return EXTENSIONS_E;
7104
7105        der->extensionsSz += der->caSz;
7106    }
7107    else
7108        der->caSz = 0;
7109
7110#ifdef WOLFSSL_ALT_NAMES
7111    /* Alternative Name */
7112    if (cert->altNamesSz) {
7113        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
7114                                      cert->altNames, (word32)cert->altNamesSz,
7115                                      cert->altNamesCrit);
7116        if (der->altNamesSz <= 0)
7117            return ALT_NAME_E;
7118
7119        der->extensionsSz += der->altNamesSz;
7120    }
7121    else
7122        der->altNamesSz = 0;
7123#endif
7124
7125#ifdef WOLFSSL_CERT_EXT
7126    /* SKID */
7127    if (cert->skidSz) {
7128        /* check the provided SKID size */
7129        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
7130            return SKID_E;
7131
7132        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
7133                              cert->skid, (word32)cert->skidSz);
7134        if (der->skidSz <= 0)
7135            return SKID_E;
7136
7137        der->extensionsSz += der->skidSz;
7138    }
7139    else
7140        der->skidSz = 0;
7141
7142    /* Key Usage */
7143    if (cert->keyUsage != 0) {
7144        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
7145                                      cert->keyUsage);
7146        if (der->keyUsageSz <= 0)
7147            return KEYUSAGE_E;
7148
7149        der->extensionsSz += der->keyUsageSz;
7150    }
7151    else
7152        der->keyUsageSz = 0;
7153
7154    /* Extended Key Usage */
7155    if (cert->extKeyUsage != 0) {
7156        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
7157                                sizeof(der->extKeyUsage), cert->extKeyUsage);
7158        if (der->extKeyUsageSz <= 0)
7159            return EXTKEYUSAGE_E;
7160
7161        der->extensionsSz += der->extKeyUsageSz;
7162    }
7163    else
7164        der->extKeyUsageSz = 0;
7165
7166#endif /* WOLFSSL_CERT_EXT */
7167
7168#ifdef WOLFSSL_CUSTOM_OID
7169    /* encode a custom oid and value */
7170    /* zero returns, means none set */
7171    ret = SetCustomObjectId(cert, der->extCustom,
7172        sizeof(der->extCustom), &cert->extCustom);
7173    if (ret < 0)
7174        return ret;
7175    der->extCustomSz = ret;
7176    der->extensionsSz += der->extCustomSz;
7177#endif
7178
7179    /* put extensions */
7180    if (der->extensionsSz > 0) {
7181        /* put the start of sequence (ID, Size) */
7182        der->extensionsSz = (int)SetSequence((word32)der->extensionsSz,
7183                                             der->extensions);
7184        if (der->extensionsSz <= 0)
7185            return EXTENSIONS_E;
7186
7187        /* put CA */
7188        if (der->caSz) {
7189            ret = SetExtensions(der->extensions, sizeof(der->extensions),
7190                                &der->extensionsSz,
7191                                der->ca, der->caSz);
7192            if (ret <= 0)
7193                return EXTENSIONS_E;
7194        }
7195
7196#ifdef WOLFSSL_ALT_NAMES
7197        /* put Alternative Names */
7198        if (der->altNamesSz) {
7199            ret = SetExtensions(der->extensions, sizeof(der->extensions),
7200                                &der->extensionsSz,
7201                                der->altNames, der->altNamesSz);
7202            if (ret <= 0)
7203                return EXTENSIONS_E;
7204        }
7205#endif
7206
7207#ifdef WOLFSSL_CERT_EXT
7208        /* put SKID */
7209        if (der->skidSz) {
7210            ret = SetExtensions(der->extensions, sizeof(der->extensions),
7211                                &der->extensionsSz,
7212                                der->skid, der->skidSz);
7213            if (ret <= 0)
7214                return EXTENSIONS_E;
7215        }
7216
7217        /* put AKID */
7218        if (der->akidSz) {
7219            ret = SetExtensions(der->extensions, sizeof(der->extensions),
7220                                &der->extensionsSz,
7221                                der->akid, der->akidSz);
7222            if (ret <= 0)
7223                return EXTENSIONS_E;
7224        }
7225
7226        /* put KeyUsage */
7227        if (der->keyUsageSz) {
7228            ret = SetExtensions(der->extensions, sizeof(der->extensions),
7229                                &der->extensionsSz,
7230                                der->keyUsage, der->keyUsageSz);
7231            if (ret <= 0)
7232                return EXTENSIONS_E;
7233        }
7234
7235        /* put ExtendedKeyUsage */
7236        if (der->extKeyUsageSz) {
7237            ret = SetExtensions(der->extensions, sizeof(der->extensions),
7238                                &der->extensionsSz,
7239                                der->extKeyUsage, der->extKeyUsageSz);
7240            if (ret <= 0)
7241                return EXTENSIONS_E;
7242        }
7243
7244    #ifdef WOLFSSL_CUSTOM_OID
7245        if (der->extCustomSz) {
7246            ret = SetExtensions(der->extensions, sizeof(der->extensions),
7247                                &der->extensionsSz,
7248                                der->extCustom, der->extCustomSz);
7249            if (ret <= 0)
7250                return EXTENSIONS_E;
7251        }
7252    #endif
7253#endif /* WOLFSSL_CERT_EXT */
7254    }
7255
7256    der->attribSz = SetReqAttrib(der->attrib, cert, (word32)der->extensionsSz);
7257    if (der->attribSz <= 0)
7258        return REQ_ATTRIBUTE_E;
7259
7260    der->total = der->versionSz + der->subjectSz + der->publicKeySz +
7261        der->extensionsSz + der->attribSz;
7262
7263    return 0;
7264}
7265
7266
7267/* write DER encoded cert req to buffer, size already checked */
7268static int WriteCertReqBody(DerCert* der, byte* buf)
7269{
7270    int idx;
7271
7272    /* signed part header */
7273    idx = (int)SetSequence((word32)der->total, buf);
7274    /* version */
7275    if (buf)
7276        XMEMCPY(buf + idx, der->version, (size_t)der->versionSz);
7277    idx += der->versionSz;
7278    /* subject */
7279    if (buf)
7280        XMEMCPY(buf + idx, der->subject, (size_t)der->subjectSz);
7281    idx += der->subjectSz;
7282    /* public key */
7283    if (buf)
7284        XMEMCPY(buf + idx, der->publicKey, (size_t)der->publicKeySz);
7285    idx += der->publicKeySz;
7286    /* attributes */
7287    if (buf)
7288        XMEMCPY(buf + idx, der->attrib, (size_t)der->attribSz);
7289    idx += der->attribSz;
7290    /* extensions */
7291    if (der->extensionsSz) {
7292        if (buf)
7293            XMEMCPY(buf + idx, der->extensions, min((word32)der->extensionsSz,
7294                                               sizeof(der->extensions)));
7295        idx += der->extensionsSz;
7296    }
7297
7298    return idx;
7299}
7300
7301static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
7302                   RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey,
7303                   ed25519_key* ed25519Key, ed448_key* ed448Key,
7304                   falcon_key* falconKey, dilithium_key* dilithiumKey,
7305                   SlhDsaKey* slhDsaKey)
7306{
7307    int ret;
7308    WC_DECLARE_VAR(der, DerCert, 1, 0);
7309
7310    if (eccKey)
7311        cert->keyType = ECC_KEY;
7312    else if (rsaKey)
7313        cert->keyType = RSA_KEY;
7314    else if (dsaKey)
7315        cert->keyType = DSA_KEY;
7316    else if (ed25519Key)
7317        cert->keyType = ED25519_KEY;
7318    else if (ed448Key)
7319        cert->keyType = ED448_KEY;
7320#ifdef HAVE_FALCON
7321    else if ((falconKey != NULL) && (falconKey->level == 1))
7322        cert->keyType = FALCON_LEVEL1_KEY;
7323    else if ((falconKey != NULL) && (falconKey->level == 5))
7324        cert->keyType = FALCON_LEVEL5_KEY;
7325#endif /* HAVE_FALCON */
7326#ifdef HAVE_DILITHIUM
7327    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
7328    else if ((dilithiumKey != NULL) &&
7329                (dilithiumKey->params->level == WC_ML_DSA_44_DRAFT)) {
7330        cert->keyType = DILITHIUM_LEVEL2_KEY;
7331    }
7332    else if ((dilithiumKey != NULL) &&
7333                (dilithiumKey->params->level == WC_ML_DSA_65_DRAFT)) {
7334        cert->keyType = DILITHIUM_LEVEL3_KEY;
7335    }
7336    else if ((dilithiumKey != NULL) &&
7337                (dilithiumKey->params->level == WC_ML_DSA_87_DRAFT)) {
7338        cert->keyType = DILITHIUM_LEVEL5_KEY;
7339    }
7340    #endif
7341    else if ((dilithiumKey != NULL) &&
7342                (dilithiumKey->params->level == WC_ML_DSA_44)) {
7343        cert->keyType = ML_DSA_LEVEL2_KEY;
7344    }
7345    else if ((dilithiumKey != NULL) &&
7346                (dilithiumKey->params->level == WC_ML_DSA_65)) {
7347        cert->keyType = ML_DSA_LEVEL3_KEY;
7348    }
7349    else if ((dilithiumKey != NULL) &&
7350                (dilithiumKey->params->level == WC_ML_DSA_87)) {
7351        cert->keyType = ML_DSA_LEVEL5_KEY;
7352    }
7353#endif /* HAVE_DILITHIUM */
7354#ifdef WOLFSSL_HAVE_SLHDSA
7355    else if ((slhDsaKey != NULL) && (slhDsaKey->params != NULL) &&
7356             (SlhDsaParamToKeyType(slhDsaKey->params->param) != 0)) {
7357        cert->keyType = SlhDsaParamToKeyType(slhDsaKey->params->param);
7358    }
7359#endif /* WOLFSSL_HAVE_SLHDSA */
7360    else
7361        return BAD_FUNC_ARG;
7362
7363    WC_ALLOC_VAR_EX(der, DerCert, 1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER,
7364        return MEMORY_E);
7365
7366    ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key,
7367                        falconKey, dilithiumKey, slhDsaKey);
7368
7369    if (ret == 0) {
7370        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
7371            ret = BUFFER_E;
7372        else
7373            ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
7374    }
7375
7376    WC_FREE_VAR_EX(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
7377
7378    return ret;
7379}
7380
7381#endif
7382#endif
7383#endif
7384#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
7385int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g)
7386{
7387    word32 idx = 0;
7388    word32 total;
7389
7390    WOLFSSL_ENTER("StoreDHparams");
7391
7392    if (out == NULL) {
7393        WOLFSSL_MSG("Null buffer error");
7394        return BUFFER_E;
7395    }
7396
7397    /* determine size */
7398    /* integer - g */
7399    idx = SetASNIntMP(g, -1, NULL);
7400    /* integer - p */
7401    idx += SetASNIntMP(p, -1, NULL);
7402    total = idx;
7403     /* sequence */
7404    idx += SetSequence(idx, NULL);
7405
7406    /* make sure output fits in buffer */
7407    if (idx > *outLen) {
7408        return BUFFER_E;
7409    }
7410
7411    /* write DH parameters */
7412    /* sequence - for P and G only */
7413    idx = SetSequence(total, out);
7414    /* integer - p */
7415    idx += SetASNIntMP(p, -1, out + idx);
7416    /* integer - g */
7417    idx += SetASNIntMP(g, -1, out + idx);
7418    *outLen = idx;
7419
7420    return 0;
7421}
7422
7423#endif
7424#if defined(HAVE_ECC) || !defined(NO_DSA)
7425int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
7426{
7427    word32 idx = 0;
7428    int    rSz;                           /* encoding size */
7429    int    sSz;
7430    int    headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
7431
7432    /* If the leading bit on the INTEGER is a 1, add a leading zero */
7433    int rLeadingZero = mp_leading_bit(r);
7434    int sLeadingZero = mp_leading_bit(s);
7435    int rLen = mp_unsigned_bin_size(r);   /* big int size */
7436    int sLen = mp_unsigned_bin_size(s);
7437
7438    if (*outLen < (word32)((rLen + rLeadingZero + sLen + sLeadingZero +
7439            headerSz + 2)))  /* SEQ_TAG + LEN(ENUM) */
7440        return BUFFER_E;
7441
7442    idx = SetSequence((word32)(rLen + rLeadingZero + sLen + sLeadingZero +
7443        headerSz), out);
7444
7445    /* store r */
7446    rSz = SetASNIntMP(r, (int)(*outLen - idx), &out[idx]);
7447    if (rSz < 0)
7448        return rSz;
7449    idx += (word32)rSz;
7450
7451    /* store s */
7452    sSz = SetASNIntMP(s, (int)(*outLen - idx), &out[idx]);
7453    if (sSz < 0)
7454        return sSz;
7455    idx += (word32)sSz;
7456
7457    *outLen = idx;
7458
7459    return 0;
7460}
7461
7462/* determine if leading bit is set */
7463static word32 is_leading_bit_set(const byte* input, word32 sz)
7464{
7465    byte c = 0;
7466    if (sz > 0)
7467        c = input[0];
7468    return (c & 0x80) != 0;
7469}
7470static word32 trim_leading_zeros(const byte** input, word32 sz)
7471{
7472    int i;
7473    word32 leadingZeroCount = 0;
7474    const byte* tmp = *input;
7475    for (i=0; i<(int)sz; i++) {
7476        if (tmp[i] != 0)
7477            break;
7478        leadingZeroCount++;
7479    }
7480    /* catch all zero case */
7481    if (sz > 0 && leadingZeroCount == sz) {
7482        leadingZeroCount--;
7483    }
7484    *input += leadingZeroCount;
7485    sz -= leadingZeroCount;
7486    return sz;
7487}
7488
7489int StoreECC_DSA_Sig_Bin(byte* out, word32* outLen, const byte* r, word32 rLen,
7490    const byte* s, word32 sLen)
7491{
7492    int ret;
7493    word32 idx;
7494    word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
7495    word32 rAddLeadZero, sAddLeadZero;
7496
7497    if ((out == NULL) || (outLen == NULL) || (r == NULL) || (s == NULL))
7498        return BAD_FUNC_ARG;
7499
7500    /* Trim leading zeros */
7501    rLen = trim_leading_zeros(&r, rLen);
7502    sLen = trim_leading_zeros(&s, sLen);
7503    /* If the leading bit on the INTEGER is a 1, add a leading zero */
7504    /* Add leading zero if MSB is set */
7505    rAddLeadZero = is_leading_bit_set(r, rLen);
7506    sAddLeadZero = is_leading_bit_set(s, sLen);
7507
7508    if (*outLen < (rLen + rAddLeadZero + sLen + sAddLeadZero +
7509                   headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
7510        return BUFFER_E;
7511
7512    idx = SetSequence(rLen+rAddLeadZero + sLen+sAddLeadZero + headerSz, out);
7513
7514    /* store r */
7515    ret = SetASNInt((int)rLen, (byte)(rAddLeadZero ? 0x80U : 0x00U), &out[idx]);
7516    if (ret < 0)
7517        return ret;
7518    idx += (word32)ret;
7519    XMEMCPY(&out[idx], r, rLen);
7520    idx += rLen;
7521
7522    /* store s */
7523    ret = SetASNInt((int)sLen, (byte)(sAddLeadZero ? 0x80U : 0x00U), &out[idx]);
7524    if (ret < 0)
7525        return ret;
7526    idx += (word32)ret;
7527    XMEMCPY(&out[idx], s, sLen);
7528    idx += sLen;
7529
7530    *outLen = idx;
7531
7532    return 0;
7533}
7534
7535int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen,
7536    byte* s, word32* sLen)
7537{
7538    int    ret;
7539    word32 idx = 0;
7540    int    len = 0;
7541
7542    if (GetSequence(sig, &idx, &len, sigLen) < 0) {
7543        return ASN_ECC_KEY_E;
7544    }
7545
7546#ifndef NO_STRICT_ECDSA_LEN
7547    /* enable strict length checking for signature */
7548    if (sigLen != idx + (word32)len) {
7549        return ASN_ECC_KEY_E;
7550    }
7551#else
7552    /* allow extra signature bytes at end */
7553    if ((word32)len > (sigLen - idx)) {
7554        return ASN_ECC_KEY_E;
7555    }
7556#endif
7557
7558    ret = GetASNInt(sig, &idx, &len, sigLen);
7559    if (ret != 0)
7560        return ret;
7561    if (rLen) {
7562        if (*rLen >= (word32)len)
7563            *rLen = (word32)len;
7564        else {
7565            /* Buffer too small to hold r value */
7566            return BUFFER_E;
7567        }
7568    }
7569    if (r)
7570        XMEMCPY(r, (byte*)sig + idx, (size_t)len);
7571    idx += (word32)len;
7572
7573    ret = GetASNInt(sig, &idx, &len, sigLen);
7574    if (ret != 0)
7575        return ret;
7576    if (sLen) {
7577        if (*sLen >= (word32)len)
7578            *sLen = (word32)len;
7579        else {
7580            /* Buffer too small to hold s value */
7581            return BUFFER_E;
7582        }
7583    }
7584    if (s)
7585        XMEMCPY(s, (byte*)sig + idx, (size_t)len);
7586
7587#ifndef NO_STRICT_ECDSA_LEN
7588    /* sanity check that the index has been advanced all the way to the end of
7589     * the buffer */
7590    if (idx + (word32)len != sigLen) {
7591        ret = ASN_ECC_KEY_E;
7592    }
7593#endif
7594
7595    return ret;
7596}
7597
7598int DecodeECC_DSA_Sig_Ex(const byte* sig, word32 sigLen, mp_int* r, mp_int* s,
7599    int init)
7600{
7601    word32 idx = 0;
7602    int    len = 0;
7603
7604    if (GetSequence(sig, &idx, &len, sigLen) < 0) {
7605        return ASN_ECC_KEY_E;
7606    }
7607
7608#ifndef NO_STRICT_ECDSA_LEN
7609    /* enable strict length checking for signature */
7610    if (sigLen != idx + (word32)len) {
7611        return ASN_ECC_KEY_E;
7612    }
7613#else
7614    /* allow extra signature bytes at end */
7615    if ((word32)len > (sigLen - idx)) {
7616        return ASN_ECC_KEY_E;
7617    }
7618#endif
7619
7620    if (GetIntPositive(r, sig, &idx, sigLen, init) < 0) {
7621        return ASN_ECC_KEY_E;
7622    }
7623
7624    if (GetIntPositive(s, sig, &idx, sigLen, init) < 0) {
7625        mp_clear(r);
7626        return ASN_ECC_KEY_E;
7627    }
7628
7629#ifndef NO_STRICT_ECDSA_LEN
7630    /* sanity check that the index has been advanced all the way to the end of
7631     * the buffer */
7632    if (idx != sigLen) {
7633        mp_clear(r);
7634        mp_clear(s);
7635        return ASN_ECC_KEY_E;
7636    }
7637#endif
7638
7639    return 0;
7640}
7641
7642#endif
7643#ifdef HAVE_ECC
7644WOLFSSL_ABI
7645int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
7646                        word32 inSz)
7647{
7648    word32 oidSum;
7649    int    version, length;
7650    int    privSz, pubSz = 0;
7651    byte   b;
7652    int    ret = 0;
7653    int    curve_id = ECC_CURVE_DEF;
7654#ifdef WOLFSSL_SMALL_STACK
7655    byte* priv;
7656    byte* pub = NULL;
7657#else
7658    byte priv[ECC_MAXSIZE+1];
7659    byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
7660#endif
7661    word32 algId = 0;
7662    byte* pubData = NULL;
7663
7664    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
7665        return BAD_FUNC_ARG;
7666
7667    /* if has pkcs8 header skip it */
7668    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
7669        /* ignore error, did not have pkcs8 header */
7670    }
7671    else {
7672        curve_id = wc_ecc_get_oid(algId, NULL, NULL);
7673    }
7674
7675    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7676        return ASN_PARSE_E;
7677
7678    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
7679        return ASN_PARSE_E;
7680
7681    if (*inOutIdx >= inSz)
7682        return ASN_PARSE_E;
7683
7684    b = input[*inOutIdx];
7685    *inOutIdx += 1;
7686
7687    /* priv type */
7688    if (b != 4 && b != 6 && b != 7)
7689        return ASN_PARSE_E;
7690
7691    if (GetLength(input, inOutIdx, &length, inSz) < 0)
7692        return ASN_PARSE_E;
7693    privSz = length;
7694
7695    if (privSz > ECC_MAXSIZE)
7696        return BUFFER_E;
7697
7698    WC_ALLOC_VAR_EX(priv, byte, privSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER,
7699        return MEMORY_E);
7700
7701    /* priv key */
7702    XMEMCPY(priv, &input[*inOutIdx], (size_t)privSz);
7703    *inOutIdx += (word32)length;
7704
7705    if ((*inOutIdx + 1) < inSz) {
7706        /* prefix 0, may have */
7707        b = input[*inOutIdx];
7708        if (b == ECC_PREFIX_0) {
7709            *inOutIdx += 1;
7710
7711            if (GetLength(input, inOutIdx, &length, inSz) <= 0)
7712                ret = ASN_PARSE_E;
7713            else {
7714                ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType,
7715                                  inSz);
7716                if (ret == 0) {
7717                    if ((ret = CheckCurve(oidSum)) < 0)
7718                        ret = ECC_CURVE_OID_E;
7719                    else {
7720                        curve_id = ret;
7721                        ret = 0;
7722                    }
7723                }
7724            }
7725        }
7726    }
7727
7728    if (ret == 0 && (*inOutIdx + 1) < inSz) {
7729        /* prefix 1 */
7730        b = input[*inOutIdx];
7731        *inOutIdx += 1;
7732
7733        if (b != ECC_PREFIX_1) {
7734            ret = ASN_ECC_KEY_E;
7735        }
7736        else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {
7737            ret = ASN_PARSE_E;
7738        }
7739        else {
7740            /* key header */
7741            ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);
7742            if (ret == 0) {
7743                /* pub key */
7744                pubSz = length;
7745                if (pubSz > 2*(ECC_MAXSIZE+1))
7746                    ret = BUFFER_E;
7747                else {
7748                    WC_ALLOC_VAR_EX(pub, byte, pubSz, key->heap,
7749                        DYNAMIC_TYPE_TMP_BUFFER, ret=MEMORY_E);
7750                    if (WC_VAR_OK(pub))
7751                    {
7752                        XMEMCPY(pub, &input[*inOutIdx], (size_t)pubSz);
7753                        *inOutIdx += (word32)length;
7754                        pubData = pub;
7755                    }
7756                }
7757            }
7758        }
7759    }
7760
7761    if (ret == 0) {
7762        ret = wc_ecc_import_private_key_ex(priv, (word32)privSz, pubData,
7763            (word32)pubSz, key, curve_id);
7764    }
7765
7766    WC_FREE_VAR_EX(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
7767    WC_FREE_VAR_EX(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
7768
7769    return ret;
7770}
7771
7772#ifdef WOLFSSL_CUSTOM_CURVES
7773/* returns 0 on success */
7774static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
7775                          word32 inSz, void* heap, int heapType)
7776{
7777    int len;
7778    int i;
7779    char* str;
7780    word32 localIdx;
7781    byte   tag;
7782
7783    if (*inOutIdx >= inSz) {
7784        return BUFFER_E;
7785    }
7786
7787    localIdx = *inOutIdx;
7788    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && tag == ASN_INTEGER) {
7789        if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
7790            return ASN_PARSE_E;
7791    }
7792    else {
7793        if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
7794            return ASN_PARSE_E;
7795    }
7796
7797    str = (char*)XMALLOC((size_t)len * 2 + 1, heap, heapType);
7798    if (str == NULL) {
7799        return MEMORY_E;
7800    }
7801
7802    for (i=0; i<len; i++)
7803        ByteToHexStr(input[*inOutIdx + (word32)i], str + i*2);
7804    str[len*2] = '\0';
7805
7806    *inOutIdx += (word32)len;
7807    *out = str;
7808
7809    (void)heap;
7810    (void)heapType;
7811
7812    return 0;
7813}
7814
7815static int EccKeyParamCopy(char** dst, char* src, void* heap)
7816{
7817    int ret = 0;
7818#ifdef WOLFSSL_ECC_CURVE_STATIC
7819    word32 length;
7820#endif
7821
7822    if (dst == NULL || src == NULL)
7823        return BAD_FUNC_ARG;
7824
7825#ifndef WOLFSSL_ECC_CURVE_STATIC
7826    *dst = src;
7827#else
7828    length = (int)XSTRLEN(src) + 1;
7829    if (length > MAX_ECC_STRING) {
7830        WOLFSSL_MSG("ECC Param too large for buffer");
7831        ret = BUFFER_E;
7832    }
7833    else {
7834        XSTRNCPY(*dst, src, MAX_ECC_STRING);
7835    }
7836    XFREE(src, heap, DYNAMIC_TYPE_ECC_BUFFER);
7837#endif
7838    (void)heap;
7839
7840    return ret;
7841}
7842
7843#endif
7844WOLFSSL_ABI
7845int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
7846                          ecc_key* key, word32 inSz)
7847{
7848    int    ret;
7849    int    version, length;
7850    int    curve_id = ECC_CURVE_DEF;
7851    word32 oidSum, localIdx;
7852    byte   tag, isPrivFormat = 0;
7853
7854    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
7855        return BAD_FUNC_ARG;
7856
7857    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7858        return ASN_PARSE_E;
7859
7860    /* Check if ECC private key is being used and skip private portion */
7861    if (GetMyVersion(input, inOutIdx, &version, inSz) >= 0) {
7862        isPrivFormat = 1;
7863
7864        /* Type private key */
7865        if (*inOutIdx >= inSz)
7866            return ASN_PARSE_E;
7867        tag = input[*inOutIdx];
7868        *inOutIdx += 1;
7869        if (tag != 4 && tag != 6 && tag != 7)
7870            return ASN_PARSE_E;
7871
7872        /* Skip Private Key */
7873        if (GetLength(input, inOutIdx, &length, inSz) < 0)
7874            return ASN_PARSE_E;
7875        if (length > ECC_MAXSIZE)
7876            return BUFFER_E;
7877        *inOutIdx += (word32)length;
7878
7879        /* Private Curve Header */
7880        if (*inOutIdx >= inSz)
7881            return ASN_PARSE_E;
7882        tag = input[*inOutIdx];
7883        *inOutIdx += 1;
7884        if (tag != ECC_PREFIX_0)
7885            return ASN_ECC_KEY_E;
7886        if (GetLength(input, inOutIdx, &length, inSz) <= 0)
7887            return ASN_PARSE_E;
7888    }
7889    /* Standard ECC public key */
7890    else {
7891        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7892            return ASN_PARSE_E;
7893
7894        ret = SkipObjectId(input, inOutIdx, inSz);
7895        if (ret != 0)
7896            return ret;
7897    }
7898
7899    if (*inOutIdx >= inSz) {
7900        return BUFFER_E;
7901    }
7902
7903    localIdx = *inOutIdx;
7904    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 &&
7905            tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
7906#ifdef WOLFSSL_CUSTOM_CURVES
7907        ecc_set_type* curve;
7908        int len;
7909        char* point = NULL;
7910
7911        ret = 0;
7912
7913        curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
7914                                                       DYNAMIC_TYPE_ECC_BUFFER);
7915        if (curve == NULL)
7916            ret = MEMORY_E;
7917
7918        if (ret == 0) {
7919            static const char customName[] = "Custom";
7920            XMEMSET(curve, 0, sizeof(*curve));
7921        #ifndef WOLFSSL_ECC_CURVE_STATIC
7922            curve->name = customName;
7923        #else
7924            XMEMCPY((void*)curve->name, customName, sizeof(customName));
7925        #endif
7926            curve->id = ECC_CURVE_CUSTOM;
7927
7928            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7929                ret = ASN_PARSE_E;
7930        }
7931
7932        if (ret == 0) {
7933            GetInteger7Bit(input, inOutIdx, inSz);
7934            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7935                ret = ASN_PARSE_E;
7936        }
7937        if (ret == 0) {
7938            char* p = NULL;
7939            SkipObjectId(input, inOutIdx, inSz);
7940            ret = ASNToHexString(input, inOutIdx, &p, inSz,
7941                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
7942            if (ret == 0) {
7943#ifndef WOLFSSL_ECC_CURVE_STATIC
7944                ret = EccKeyParamCopy((char**)&curve->prime, p, key->heap);
7945#else
7946                const char *_tmp_ptr = &curve->prime[0];
7947                ret = EccKeyParamCopy((char**)&_tmp_ptr, p, key->heap);
7948#endif
7949            }
7950        }
7951        if (ret == 0) {
7952            curve->size = (int)XSTRLEN(curve->prime) / 2;
7953
7954            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7955                ret = ASN_PARSE_E;
7956        }
7957        if (ret == 0) {
7958            char* af = NULL;
7959            ret = ASNToHexString(input, inOutIdx, &af, inSz,
7960                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
7961            if (ret == 0) {
7962#ifndef WOLFSSL_ECC_CURVE_STATIC
7963                ret = EccKeyParamCopy((char**)&curve->Af, af, key->heap);
7964#else
7965                const char *_tmp_ptr = &curve->Af[0];
7966                ret = EccKeyParamCopy((char**)&_tmp_ptr, af, key->heap);
7967#endif
7968            }
7969        }
7970        if (ret == 0) {
7971            char* bf = NULL;
7972            ret = ASNToHexString(input, inOutIdx, &bf, inSz,
7973                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
7974            if (ret == 0) {
7975#ifndef WOLFSSL_ECC_CURVE_STATIC
7976                ret = EccKeyParamCopy((char**)&curve->Bf, bf, key->heap);
7977#else
7978                const char *_tmp_ptr = &curve->Bf[0];
7979                ret = EccKeyParamCopy((char**)&_tmp_ptr, bf, key->heap);
7980#endif
7981            }
7982        }
7983        if (ret == 0) {
7984            localIdx = *inOutIdx;
7985            if (*inOutIdx < inSz && GetASNTag(input, &localIdx, &tag, inSz)
7986                    == 0 && tag == ASN_BIT_STRING) {
7987                len = 0;
7988                ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
7989                if (ret > 0)
7990                    ret = 0; /* reset on success */
7991                *inOutIdx += (word32)len;
7992            }
7993        }
7994        if (ret == 0) {
7995            ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
7996                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
7997
7998            /* sanity check that point buffer is not smaller than the expected
7999             * size to hold ( 0 4 || Gx || Gy )
8000             * where Gx and Gy are each the size of curve->size * 2 */
8001            if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
8002                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
8003                ret = BUFFER_E;
8004            }
8005        }
8006        if (ret == 0) {
8007        #ifndef WOLFSSL_ECC_CURVE_STATIC
8008            curve->Gx = (const char*)XMALLOC((size_t)curve->size * 2 + 2,
8009                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
8010            curve->Gy = (const char*)XMALLOC((size_t)curve->size * 2 + 2,
8011                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
8012            if (curve->Gx == NULL || curve->Gy == NULL) {
8013                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
8014                ret = MEMORY_E;
8015            }
8016        #else
8017            if (curve->size * 2 + 2 > MAX_ECC_STRING) {
8018                WOLFSSL_MSG("curve size is too large to fit in buffer");
8019                ret = BUFFER_E;
8020            }
8021        #endif
8022        }
8023        if (ret == 0) {
8024            char* o = NULL;
8025
8026            XMEMCPY((char*)curve->Gx, point + 2, (size_t)curve->size * 2);
8027            XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
8028                                                 (size_t)curve->size * 2);
8029            ((char*)curve->Gx)[curve->size * 2] = '\0';
8030            ((char*)curve->Gy)[curve->size * 2] = '\0';
8031            XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
8032            ret = ASNToHexString(input, inOutIdx, &o, inSz,
8033                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
8034            if (ret == 0) {
8035#ifndef WOLFSSL_ECC_CURVE_STATIC
8036                ret = EccKeyParamCopy((char**)&curve->order, o, key->heap);
8037#else
8038                const char *_tmp_ptr = &curve->order[0];
8039                ret = EccKeyParamCopy((char**)&_tmp_ptr, o, key->heap);
8040#endif
8041            }
8042        }
8043        if (ret == 0) {
8044            curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
8045
8046        #ifndef WOLFSSL_ECC_CURVE_STATIC
8047            curve->oid = NULL;
8048        #else
8049            XMEMSET((void*)curve->oid, 0, sizeof(curve->oid));
8050        #endif
8051            curve->oidSz = 0;
8052            curve->oidSum = 0;
8053
8054            if (wc_ecc_set_custom_curve(key, curve) < 0) {
8055                ret = ASN_PARSE_E;
8056            }
8057
8058            key->deallocSet = 1;
8059
8060            curve = NULL;
8061        }
8062        if (curve != NULL)
8063            wc_ecc_free_curve(curve, key->heap);
8064
8065        if (ret < 0)
8066            return ret;
8067#else
8068        return ASN_PARSE_E;
8069#endif /* WOLFSSL_CUSTOM_CURVES */
8070    }
8071    else {
8072        /* ecc params information */
8073        ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
8074        if (ret != 0)
8075            return ret;
8076
8077        /* get curve id */
8078        if ((ret = CheckCurve(oidSum)) < 0)
8079            return ECC_CURVE_OID_E;
8080        else {
8081            curve_id = ret;
8082        }
8083    }
8084
8085    if (isPrivFormat) {
8086        /* Public Curve Header - skip */
8087        if (*inOutIdx >= inSz)
8088            return ASN_PARSE_E;
8089        tag = input[*inOutIdx];
8090        *inOutIdx += 1;
8091        if (tag != ECC_PREFIX_1)
8092            return ASN_ECC_KEY_E;
8093        if (GetLength(input, inOutIdx, &length, inSz) <= 0)
8094            return ASN_PARSE_E;
8095    }
8096
8097    /* key header */
8098    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
8099    if (ret != 0)
8100        return ret;
8101
8102    /* This is the raw point data compressed or uncompressed. */
8103    if (wc_ecc_import_x963_ex(input + *inOutIdx, (word32)length, key,
8104                                                            curve_id) != 0) {
8105        return ASN_ECC_KEY_E;
8106    }
8107
8108    *inOutIdx += (word32)length;
8109
8110    return 0;
8111}
8112
8113#ifdef HAVE_ECC_KEY_EXPORT
8114int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
8115                             int pubIn, int curveIn)
8116{
8117    byte   curve[MAX_ALGO_SZ+2];
8118    byte   ver[MAX_VERSION_SZ];
8119    byte   seq[MAX_SEQ_SZ];
8120    int    ret, curveSz, verSz;
8121    word32 totalSz;
8122    int    privHdrSz  = ASN_ECC_HEADER_SZ;
8123    int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
8124#ifdef WOLFSSL_NO_MALLOC
8125    byte   prv[MAX_ECC_BYTES + ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
8126    byte   pub[(MAX_ECC_BYTES * 2) + 1 + ASN_ECC_CONTEXT_SZ +
8127                              ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
8128#else
8129    byte   *prv = NULL, *pub = NULL;
8130#endif
8131
8132    word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
8133    word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
8134
8135    if (key == NULL || (output == NULL && inLen == NULL))
8136        return BAD_FUNC_ARG;
8137
8138    if (curveIn) {
8139        /* curve */
8140        curve[curveidx++] = ECC_PREFIX_0;
8141        curveidx++ /* to put the size after computation */;
8142        curveSz = SetCurve(key, curve+curveidx, MAX_ALGO_SZ);
8143        if (curveSz < 0)
8144            return curveSz;
8145        /* set computed size */
8146        curve[1] = (byte)curveSz;
8147        curveidx += (word32)curveSz;
8148    }
8149
8150    /* private */
8151    privSz = (word32)key->dp->size;
8152
8153#ifdef WOLFSSL_QNX_CAAM
8154    /* check if is a black key, and add MAC size if needed */
8155    if (key->blackKey > 0 && key->blackKey != CAAM_BLACK_KEY_ECB) {
8156        privSz = privSz + WC_CAAM_MAC_SZ;
8157    }
8158#endif
8159
8160#ifndef WOLFSSL_NO_MALLOC
8161    prv = (byte*)XMALLOC(privSz + (word32)privHdrSz + MAX_SEQ_SZ,
8162                         key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8163    if (prv == NULL) {
8164        return MEMORY_E;
8165    }
8166#else
8167    if (sizeof(prv) < privSz + privHdrSz + MAX_SEQ_SZ) {
8168        return BUFFER_E;
8169    }
8170#endif
8171    if (privSz < ASN_LONG_LENGTH) {
8172        prvidx += SetOctetString8Bit(privSz, &prv[prvidx]);
8173    }
8174    else {
8175        prvidx += SetOctetString(privSz, &prv[prvidx]);
8176    }
8177    ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
8178    if (ret < 0) {
8179    #ifndef WOLFSSL_NO_MALLOC
8180        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8181    #endif
8182        return ret;
8183    }
8184    prvidx += privSz;
8185
8186    /* pubIn */
8187    if (pubIn) {
8188        PRIVATE_KEY_UNLOCK();
8189        ret = wc_ecc_export_x963(key, NULL, &pubSz);
8190        PRIVATE_KEY_LOCK();
8191        if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
8192        #ifndef WOLFSSL_NO_MALLOC
8193            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8194        #endif
8195            return ret;
8196        }
8197
8198    #ifndef WOLFSSL_NO_MALLOC
8199        pub = (byte*)XMALLOC(pubSz + (word32)pubHdrSz + MAX_SEQ_SZ,
8200                             key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8201        if (pub == NULL) {
8202            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8203            return MEMORY_E;
8204        }
8205    #else
8206        if (sizeof(pub) < pubSz + pubHdrSz + MAX_SEQ_SZ) {
8207            return BUFFER_E;
8208        }
8209    #endif
8210
8211        pub[pubidx++] = ECC_PREFIX_1;
8212        if (pubSz > 128) /* leading zero + extra size byte */
8213            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
8214        else /* leading zero */
8215            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
8216
8217        /* SetBitString adds leading zero */
8218        pubidx += SetBitString(pubSz, 0, pub + pubidx);
8219        PRIVATE_KEY_UNLOCK();
8220        ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
8221        PRIVATE_KEY_LOCK();
8222        if (ret != 0) {
8223        #ifndef WOLFSSL_NO_MALLOC
8224            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8225            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8226        #endif
8227            return ret;
8228        }
8229        pubidx += pubSz;
8230    }
8231
8232    /* make headers */
8233    verSz = SetMyVersion(1, ver, FALSE);
8234    seqSz = SetSequence((word32)verSz + prvidx + pubidx + curveidx, seq);
8235
8236    totalSz = prvidx + pubidx + curveidx + (word32)verSz + seqSz;
8237    if (output == NULL) {
8238        *inLen = totalSz;
8239    #ifndef WOLFSSL_NO_MALLOC
8240        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8241        if (pubIn) {
8242            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8243        }
8244    #endif
8245        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
8246    }
8247    if (inLen != NULL && totalSz > *inLen) {
8248        #ifndef WOLFSSL_NO_MALLOC
8249        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8250        if (pubIn) {
8251            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8252        }
8253        #endif
8254        return BAD_FUNC_ARG;
8255    }
8256
8257    /* write out */
8258    /* seq */
8259    XMEMCPY(output + idx, seq, seqSz);
8260    idx = seqSz;
8261
8262    /* ver */
8263    XMEMCPY(output + idx, ver, (size_t)verSz);
8264    idx += (word32)verSz;
8265
8266    /* private */
8267    XMEMCPY(output + idx, prv, prvidx);
8268    idx += prvidx;
8269#ifndef WOLFSSL_NO_MALLOC
8270    XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8271#endif
8272
8273    /* curve */
8274    XMEMCPY(output + idx, curve, curveidx);
8275    idx += curveidx;
8276
8277    /* pubIn */
8278    if (pubIn) {
8279        XMEMCPY(output + idx, pub, pubidx);
8280        /* idx += pubidx;  not used after write, if more data remove comment */
8281    #ifndef WOLFSSL_NO_MALLOC
8282        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8283    #endif
8284    }
8285
8286    return (int)totalSz;
8287}
8288
8289#endif
8290#endif
8291#if (defined(HAVE_OCSP) || defined(HAVE_CRL)) && !defined(WOLFCRYPT_ONLY)
8292
8293/* Get raw Date only, no processing, 0 on success */
8294static int GetBasicDate(const byte* source, word32* idx, byte* date,
8295                        byte* format, int maxIdx)
8296{
8297    int    ret, length;
8298    const byte *datePtr = NULL;
8299
8300    WOLFSSL_ENTER("GetBasicDate");
8301
8302    ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
8303    if (ret < 0)
8304        return ret;
8305
8306    XMEMCPY(date, datePtr, length);
8307
8308    return 0;
8309}
8310
8311#endif /* HAVE_OCSP || HAVE_CRL */
8312
8313#if defined(HAVE_OCSP) && !defined(WOLFCRYPT_ONLY)
8314static int GetEnumerated(const byte* input, word32* inOutIdx, int *value,
8315        int sz)
8316{
8317    word32 idx = *inOutIdx;
8318    word32 len;
8319    byte   tag;
8320
8321    WOLFSSL_ENTER("GetEnumerated");
8322
8323    *value = 0;
8324
8325    if (GetASNTag(input, &idx, &tag, sz) < 0)
8326        return ASN_PARSE_E;
8327
8328    if (tag != ASN_ENUMERATED)
8329        return ASN_PARSE_E;
8330
8331    if ((int)idx >= sz)
8332        return BUFFER_E;
8333
8334    len = input[idx++];
8335    if (len > 4 || (int)(len + idx) > sz)
8336        return ASN_PARSE_E;
8337
8338    while (len--) {
8339        *value  = *value << 8 | input[idx++];
8340    }
8341
8342    *inOutIdx = idx;
8343
8344    return *value;
8345}
8346
8347#ifdef HAVE_OCSP_RESPONDER
8348WC_MAYBE_UNUSED static int EncodeCertID(OcspEntry* entry, byte* out,
8349        word32* outSz)
8350{
8351    (void)entry;
8352    (void)out;
8353    (void)outSz;
8354    /* Encoding ocsp CertID not supported in legacy ASN parsing */
8355    return NOT_COMPILED_IN;
8356}
8357
8358#endif
8359static int OcspDecodeCertIDInt(const byte* input, word32* inOutIdx, word32 inSz,
8360                 OcspEntry* entry)
8361{
8362    int length;
8363    word32 oid;
8364    int ret;
8365    int expectedDigestSz;
8366
8367    /* Hash algorithm */
8368    ret = GetAlgoId(input, inOutIdx, &oid, oidHashType, inSz);
8369    if (ret < 0)
8370        return ret;
8371    entry->hashAlgoOID = oid;
8372
8373    /* Validate hash algorithm and get expected digest size */
8374    expectedDigestSz = wc_HashGetDigestSize(wc_OidGetHash((int)oid));
8375    if (expectedDigestSz <= 0)
8376        return ASN_SIG_HASH_E;
8377
8378    /* Save reference to the hash of CN */
8379    ret = GetOctetString(input, inOutIdx, &length, inSz);
8380    if (ret < 0)
8381        return ret;
8382    if (length != expectedDigestSz || length > (int)sizeof(entry->issuerHash))
8383        return ASN_PARSE_E;
8384    XMEMCPY(entry->issuerHash, input + *inOutIdx, length);
8385    *inOutIdx += length;
8386    /* Save reference to the hash of the issuer public key */
8387    ret = GetOctetString(input, inOutIdx, &length, inSz);
8388    if (ret < 0)
8389        return ret;
8390    if (length != expectedDigestSz || length > (int)sizeof(entry->issuerKeyHash))
8391        return ASN_PARSE_E;
8392    XMEMCPY(entry->issuerKeyHash, input + *inOutIdx, length);
8393    *inOutIdx += length;
8394
8395    /* Get serial number */
8396    if (wc_GetSerialNumber(input, inOutIdx, entry->status->serial,
8397                        &entry->status->serialSz, inSz) < 0)
8398        return ASN_PARSE_E;
8399    return 0;
8400}
8401
8402#ifdef HAVE_OCSP_RESPONDER
8403WC_MAYBE_UNUSED static int EncodeSingleResponse(OcspEntry* single, byte* out,
8404        word32* outSz, void* heap)
8405{
8406    (void)single;
8407    (void)out;
8408    (void)outSz;
8409    (void)heap;
8410    /* Encoding ocsp responses not supported in legacy ASN parsing */
8411    return NOT_COMPILED_IN;
8412}
8413
8414#endif
8415static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
8416                                int wrapperSz, OcspEntry* single)
8417{
8418    word32 idx = *ioIndex, prevIndex, localIdx, certIdIdx;
8419    int length;
8420    int ret;
8421    byte tag;
8422
8423    WOLFSSL_ENTER("DecodeSingleResponse");
8424
8425    prevIndex = idx;
8426
8427    /* Wrapper around the Single Response */
8428    if (GetSequence(source, &idx, &length, size) < 0)
8429        return ASN_PARSE_E;
8430
8431    /* Wrapper around the CertID */
8432    certIdIdx = idx;
8433    if (GetSequence(source, &idx, &length, size) < 0)
8434        return ASN_PARSE_E;
8435    single->rawCertId = source + certIdIdx;
8436    ret = OcspDecodeCertIDInt(source, &idx, size, single);
8437    if (ret < 0)
8438        return ASN_PARSE_E;
8439    single->rawCertIdSize = idx - certIdIdx;
8440
8441    if (idx >= size)
8442        return BUFFER_E;
8443
8444    /* CertStatus */
8445    switch (source[idx++])
8446    {
8447        case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
8448            single->status->status = CERT_GOOD;
8449            idx++;
8450            break;
8451        case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
8452            single->status->status = CERT_REVOKED;
8453            if (GetLength(source, &idx, &length, size) < 0)
8454                return ASN_PARSE_E;
8455            idx += length;
8456            break;
8457        case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
8458            single->status->status = CERT_UNKNOWN;
8459            idx++;
8460            break;
8461        default:
8462            return ASN_PARSE_E;
8463    }
8464
8465    if (idx >= size)
8466        return BUFFER_E;
8467
8468#ifdef WOLFSSL_OCSP_PARSE_STATUS
8469    single->status->thisDateAsn = source + idx;
8470    localIdx = 0;
8471    if (GetDateInfo(single->status->thisDateAsn, &localIdx, NULL,
8472                    (byte*)&single->status->thisDateParsed.type,
8473                    &single->status->thisDateParsed.length, size - idx) < 0)
8474        return ASN_PARSE_E;
8475
8476    if (idx + localIdx >= size)
8477        return BUFFER_E;
8478
8479    XMEMCPY(single->status->thisDateParsed.data,
8480            single->status->thisDateAsn + localIdx - single->status->thisDateParsed.length,
8481            single->status->thisDateParsed.length);
8482#endif
8483    if (GetBasicDate(source, &idx, single->status->thisDate,
8484                     &single->status->thisDateFormat, size) < 0)
8485        return ASN_PARSE_E;
8486
8487#ifndef NO_ASN_TIME_CHECK
8488#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
8489    if ((! AsnSkipDateCheck) && !XVALIDATE_DATE(single->status->thisDate,
8490        single->status->thisDateFormat, ASN_BEFORE, MAX_DATE_SIZE))
8491        return ASN_BEFORE_DATE_E;
8492#endif
8493#endif
8494
8495    /* The following items are optional. Only check for them if there is more
8496     * unprocessed data in the singleResponse wrapper. */
8497    localIdx = idx;
8498    if (((int)(idx - prevIndex) < wrapperSz) &&
8499        GetASNTag(source, &localIdx, &tag, size) == 0 &&
8500        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
8501    {
8502        idx++;
8503        if (GetLength(source, &idx, &length, size) < 0)
8504            return ASN_PARSE_E;
8505#ifdef WOLFSSL_OCSP_PARSE_STATUS
8506        single->status->nextDateAsn = source + idx;
8507        localIdx = 0;
8508        if (GetDateInfo(single->status->nextDateAsn, &localIdx, NULL,
8509                        (byte*)&single->status->nextDateParsed.type,
8510                        &single->status->nextDateParsed.length, size - idx) < 0)
8511            return ASN_PARSE_E;
8512
8513        if (idx + localIdx >= size)
8514            return BUFFER_E;
8515
8516        XMEMCPY(single->status->nextDateParsed.data,
8517                single->status->nextDateAsn + localIdx - single->status->nextDateParsed.length,
8518                single->status->nextDateParsed.length);
8519#endif
8520        if (GetBasicDate(source, &idx, single->status->nextDate,
8521                         &single->status->nextDateFormat, size) < 0)
8522            return ASN_PARSE_E;
8523
8524#ifndef NO_ASN_TIME_CHECK
8525#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
8526        if ((! AsnSkipDateCheck) &&
8527            !XVALIDATE_DATE(single->status->nextDate,
8528                            single->status->nextDateFormat, ASN_AFTER, MAX_DATE_SIZE))
8529            return ASN_AFTER_DATE_E;
8530#endif
8531#endif
8532    }
8533
8534    /* Skip the optional extensions in singleResponse. */
8535    localIdx = idx;
8536    if (((int)(idx - prevIndex) < wrapperSz) &&
8537        GetASNTag(source, &localIdx, &tag, size) == 0 &&
8538        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
8539    {
8540        idx++;
8541        if (GetLength(source, &idx, &length, size) < 0)
8542            return ASN_PARSE_E;
8543        idx += length;
8544    }
8545
8546    *ioIndex = idx;
8547
8548    return 0;
8549}
8550
8551static int DecodeOcspRespExtensions(byte* source, word32* ioIndex,
8552                                    OcspResponse* resp, word32 sz)
8553{
8554    word32 idx = *ioIndex;
8555    int length;
8556    int ext_bound; /* boundary index for the sequence of extensions */
8557    word32 oid;
8558    int ret;
8559    byte tag;
8560
8561    WOLFSSL_ENTER("DecodeOcspRespExtensions");
8562
8563    if ((idx + 1) > sz)
8564        return BUFFER_E;
8565
8566    if (GetASNTag(source, &idx, &tag, sz) < 0)
8567        return ASN_PARSE_E;
8568
8569    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
8570        return ASN_PARSE_E;
8571
8572    if (GetLength(source, &idx, &length, sz) < 0)
8573        return ASN_PARSE_E;
8574
8575    if (GetSequence(source, &idx, &length, sz) < 0)
8576        return ASN_PARSE_E;
8577
8578    ext_bound = idx + length;
8579
8580    while (idx < (word32)ext_bound) {
8581        word32 localIdx;
8582
8583        if (GetSequence(source, &idx, &length, sz) < 0) {
8584            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
8585            return ASN_PARSE_E;
8586        }
8587
8588        oid = 0;
8589        if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {
8590            WOLFSSL_MSG("\tfail: OBJECT ID");
8591            return ASN_PARSE_E;
8592        }
8593
8594        /* check for critical flag */
8595        if ((idx + 1) > (word32)sz) {
8596            WOLFSSL_MSG("\tfail: malformed buffer");
8597            return BUFFER_E;
8598        }
8599
8600        localIdx = idx;
8601        if (GetASNTag(source, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
8602            WOLFSSL_MSG("\tfound optional critical flag, moving past");
8603            ret = GetBoolean(source, &idx, sz);
8604            if (ret < 0)
8605                return ret;
8606        }
8607
8608        ret = GetOctetString(source, &idx, &length, sz);
8609        if (ret < 0)
8610            return ret;
8611
8612        if (oid == OCSP_NONCE_OID) {
8613            /* get data inside extra OCTET_STRING */
8614            ret = GetOctetString(source, &idx, &length, sz);
8615            if (ret < 0)
8616                return ret;
8617
8618            resp->nonce = source + idx;
8619            resp->nonceSz = length;
8620        }
8621
8622        idx += length;
8623    }
8624
8625    *ioIndex = idx;
8626    return 0;
8627}
8628
8629WC_MAYBE_UNUSED static int EncodeOcspRespExtensions(OcspResponse* resp,
8630        byte* out, word32* outSz)
8631{
8632    (void)resp;
8633    (void)out;
8634    (void)outSz;
8635    /* Encoding ocsp responses not supported in legacy ASN parsing */
8636    return NOT_COMPILED_IN;
8637}
8638
8639#ifdef HAVE_OCSP_RESPONDER
8640WC_MAYBE_UNUSED static int EncodeResponseData(OcspResponse* resp, byte* out,
8641        word32* outSz)
8642{
8643    (void)resp;
8644    (void)out;
8645    (void)outSz;
8646    /* Encoding ocsp responses not supported in legacy ASN parsing */
8647    return NOT_COMPILED_IN;
8648}
8649
8650#endif
8651static int DecodeResponseData(byte* source, word32* ioIndex,
8652                              OcspResponse* resp, word32 size)
8653{
8654    word32 idx = *ioIndex, prev_idx, localIdx;
8655    int length;
8656    int version;
8657    int ret;
8658    byte tag;
8659    int wrapperSz;
8660    OcspEntry* single;
8661
8662    WOLFSSL_ENTER("DecodeResponseData");
8663
8664    resp->response = source + idx;
8665    prev_idx = idx;
8666    if (GetSequence(source, &idx, &length, size) < 0)
8667        return ASN_PARSE_E;
8668    resp->responseSz = length + idx - prev_idx;
8669
8670    /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
8671     * item isn't an EXPLICIT[0], then set version to zero and move
8672     * onto the next item.
8673     */
8674    localIdx = idx;
8675    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
8676            tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
8677    {
8678        idx += 2; /* Eat the value and length */
8679        if (GetMyVersion(source, &idx, &version, size) < 0)
8680            return ASN_PARSE_E;
8681    } else
8682        version = 0;
8683
8684    localIdx = idx;
8685    if (GetASNTag(source, &localIdx, &tag, size) != 0)
8686        return ASN_PARSE_E;
8687
8688    resp->responderIdType = OCSP_RESPONDER_ID_INVALID;
8689    /* parse byName */
8690    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
8691    {
8692        idx++; /* advance past ASN tag */
8693        if (GetLength(source, &idx, &length, size) < 0)
8694            return ASN_PARSE_E;
8695        /* compute the hash of the name */
8696        resp->responderIdType = OCSP_RESPONDER_ID_NAME;
8697        ret = CalcHashId_ex(source + idx, length,
8698                resp->responderId.nameHash, OCSP_RESPONDER_ID_HASH_TYPE);
8699        if (ret != 0)
8700            return ret;
8701        idx += length;
8702    }
8703    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))
8704    {
8705        idx++; /* advance past ASN tag */
8706        if (GetLength(source, &idx, &length, size) < 0)
8707            return ASN_PARSE_E;
8708
8709        if (GetOctetString(source, &idx, &length, size) < 0)
8710            return ASN_PARSE_E;
8711
8712        if (length != OCSP_RESPONDER_ID_KEY_SZ)
8713            return ASN_PARSE_E;
8714        resp->responderIdType = OCSP_RESPONDER_ID_KEY;
8715        XMEMCPY(resp->responderId.keyHash, source + idx, length);
8716        idx += length;
8717    }
8718    if (resp->responderIdType == OCSP_RESPONDER_ID_INVALID)
8719        return ASN_PARSE_E;
8720
8721    /* save pointer to the producedAt time */
8722    if (GetBasicDate(source, &idx, resp->producedDate,
8723                                        &resp->producedDateFormat, size) < 0)
8724        return ASN_PARSE_E;
8725
8726    /* Outer wrapper of the SEQUENCE OF Single Responses. */
8727    if (GetSequence(source, &idx, &wrapperSz, size) < 0)
8728        return ASN_PARSE_E;
8729
8730    localIdx = idx;
8731    single = resp->single;
8732    while (idx - localIdx < (word32)wrapperSz) {
8733        ret = DecodeSingleResponse(source, &idx, size, wrapperSz, single);
8734        if (ret < 0)
8735            return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
8736        if (idx - localIdx < (word32)wrapperSz) {
8737            single->next = (OcspEntry*)XMALLOC(sizeof(OcspEntry), resp->heap,
8738                DYNAMIC_TYPE_OCSP_ENTRY);
8739            if (single->next == NULL) {
8740                return MEMORY_E;
8741            }
8742            XMEMSET(single->next, 0, sizeof(OcspEntry));
8743
8744            single->next->status = (CertStatus*)XMALLOC(sizeof(CertStatus),
8745                resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
8746            if (single->next->status == NULL) {
8747                XFREE(single->next, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
8748                single->next = NULL;
8749                return MEMORY_E;
8750            }
8751            XMEMSET(single->next->status, 0, sizeof(CertStatus));
8752
8753            single->next->isDynamic = 1;
8754            single->next->ownStatus = 1;
8755
8756            single = single->next;
8757        }
8758    }
8759
8760    /*
8761     * Check the length of the ResponseData against the current index to
8762     * see if there are extensions, they are optional.
8763     */
8764    if (idx - prev_idx < resp->responseSz)
8765        if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
8766            return ASN_PARSE_E;
8767
8768    *ioIndex = idx;
8769    return 0;
8770}
8771
8772#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
8773
8774static int DecodeCerts(byte* source,
8775                            word32* ioIndex, OcspResponse* resp, word32 size)
8776{
8777    word32 idx = *ioIndex;
8778    byte tag;
8779
8780    WOLFSSL_ENTER("DecodeCerts");
8781
8782    if (GetASNTag(source, &idx, &tag, size) < 0)
8783        return ASN_PARSE_E;
8784
8785    if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
8786    {
8787        int length;
8788
8789        if (GetLength(source, &idx, &length, size) < 0)
8790            return ASN_PARSE_E;
8791
8792        if (GetSequence(source, &idx, &length, size) < 0)
8793            return ASN_PARSE_E;
8794
8795        resp->cert = source + idx;
8796        resp->certSz = length;
8797
8798        idx += length;
8799    }
8800    *ioIndex = idx;
8801    return 0;
8802}
8803
8804#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
8805
8806#ifdef HAVE_OCSP_RESPONDER
8807WC_MAYBE_UNUSED static int EncodeBasicOcspResponse(OcspResponse* resp,
8808        byte* out, word32* outSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
8809{
8810    (void)resp;
8811    (void)out;
8812    (void)outSz;
8813    (void)rsaKey;
8814    (void)eccKey;
8815    (void)rng;
8816    /* Encoding ocsp responses not supported in legacy ASN parsing */
8817    return NOT_COMPILED_IN;
8818}
8819
8820#endif
8821static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
8822            OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify,
8823            int noVerifySignature)
8824{
8825    int    length;
8826    word32 idx = *ioIndex;
8827    #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
8828    word32 end_index;
8829    #endif
8830    int    ret;
8831    int    sigLength;
8832    int    sigValid = 0;
8833    WOLFSSL_ENTER("DecodeBasicOcspResponse");
8834    (void)heap;
8835
8836    if (GetSequence(source, &idx, &length, size) < 0)
8837        return ASN_PARSE_E;
8838
8839    if (idx + length > size)
8840        return ASN_INPUT_E;
8841    #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
8842    end_index = idx + length;
8843    #endif
8844
8845    if ((ret = DecodeResponseData(source, &idx, resp, size)) < 0)
8846        return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
8847
8848    /* Get the signature algorithm */
8849    if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0) {
8850        return ASN_PARSE_E;
8851    }
8852#ifdef WC_RSA_PSS
8853    else if (resp->sigOID == CTC_RSASSAPSS) {
8854        word32 sz;
8855        int len;
8856        byte* params;
8857
8858        sz = idx;
8859        params = source + idx;
8860        if (GetSequence(source, &idx, &len, size) < 0)
8861            return ASN_PARSE_E;
8862        if (ret == 0) {
8863            idx += len;
8864            resp->sigParams = params;
8865            resp->sigParamsSz = idx - sz;
8866        }
8867    }
8868#endif
8869
8870    ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
8871    if (ret != 0)
8872        return ret;
8873
8874    resp->sigSz = sigLength;
8875    resp->sig = source + idx;
8876    idx += sigLength;
8877
8878    /*
8879     * Check the length of the BasicOcspResponse against the current index to
8880     * see if there are certificates, they are optional.
8881     */
8882#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
8883    if (idx < end_index)
8884    {
8885        if (DecodeCerts(source, &idx, resp, size) < 0)
8886            return ASN_PARSE_E;
8887
8888        ret = OcspCheckCert(resp, noVerify, noVerifySignature,
8889            (WOLFSSL_CERT_MANAGER*)cm, heap);
8890        if (ret == 0) {
8891            sigValid = 1;
8892        }
8893        else {
8894            WOLFSSL_MSG("OCSP Internal cert can't verify the response\n");
8895            /* try to verify the OCSP response with CA certs */
8896            ret = 0;
8897        }
8898    }
8899#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
8900    if (!noVerifySignature && !sigValid) {
8901        Signer* ca;
8902        SignatureCtx sigCtx;
8903        ca = OcspFindSigner(resp, (WOLFSSL_CERT_MANAGER*)cm);
8904        if (ca == NULL)
8905            return ASN_NO_SIGNER_E;
8906
8907#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
8908        if (OcspRespCheck(resp, ca, cm) != 0)
8909           return BAD_OCSP_RESPONDER;
8910#endif
8911        InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
8912
8913        /* ConfirmSignature is blocking here */
8914        sigValid = ConfirmSignature(&sigCtx, resp->response,
8915            resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
8916            resp->sig, resp->sigSz, resp->sigOID, resp->sigParams,
8917            resp->sigParamsSz, NULL);
8918        if (sigValid != 0) {
8919            WOLFSSL_MSG("\tOCSP Confirm signature failed");
8920            return ASN_OCSP_CONFIRM_E;
8921        }
8922        (void)noVerify;
8923    }
8924
8925    *ioIndex = idx;
8926    return 0;
8927}
8928
8929#ifdef HAVE_OCSP_RESPONDER
8930int OcspResponseEncode(OcspResponse* resp, byte* out, word32* outSz,
8931        RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
8932{
8933    (void)resp;
8934    (void)out;
8935    (void)outSz;
8936    (void)rsaKey;
8937    (void)eccKey;
8938    (void)rng;
8939    /* Encoding ocsp responses not supported in legacy ASN parsing */
8940    return NOT_COMPILED_IN;
8941}
8942
8943#endif
8944int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap,
8945    int noVerifyCert, int noVerifySignature)
8946{
8947    int ret;
8948    int length = 0;
8949    word32 idx = 0;
8950    byte* source = resp->source;
8951    word32 size = resp->maxIdx;
8952    word32 oid;
8953    byte   tag;
8954
8955    WOLFSSL_ENTER("OcspResponseDecode");
8956
8957    /* peel the outer SEQUENCE wrapper */
8958    if (GetSequence(source, &idx, &length, size) < 0) {
8959        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
8960        return ASN_PARSE_E;
8961    }
8962
8963    /* First get the responseStatus, an ENUMERATED */
8964    if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0) {
8965        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
8966        return ASN_PARSE_E;
8967    }
8968
8969    if (resp->responseStatus != OCSP_SUCCESSFUL) {
8970        WOLFSSL_LEAVE("OcspResponseDecode", 0);
8971        return 0;
8972    }
8973
8974    /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
8975    if (idx >= size) {
8976        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
8977        return ASN_PARSE_E;
8978    }
8979    if (GetASNTag(source, &idx, &tag, size) < 0) {
8980        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
8981        return ASN_PARSE_E;
8982    }
8983    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
8984        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
8985        return ASN_PARSE_E;
8986    }
8987    if (GetLength(source, &idx, &length, size) < 0) {
8988        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
8989        return ASN_PARSE_E;
8990    }
8991
8992    /* Get the responseBytes SEQUENCE */
8993    if (GetSequence(source, &idx, &length, size) < 0) {
8994        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
8995        return ASN_PARSE_E;
8996    }
8997
8998    /* Check ObjectID for the resposeBytes */
8999    if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0) {
9000        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
9001        return ASN_PARSE_E;
9002    }
9003    if (oid != OCSP_BASIC_OID) {
9004        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
9005        return ASN_PARSE_E;
9006    }
9007    ret = GetOctetString(source, &idx, &length, size);
9008    if (ret < 0) {
9009        WOLFSSL_LEAVE("OcspResponseDecode", ret);
9010        return ret;
9011    }
9012
9013    ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap,
9014         noVerifyCert, noVerifySignature);
9015    if (ret < 0) {
9016        WOLFSSL_LEAVE("OcspResponseDecode", ret);
9017        return ret;
9018    }
9019
9020    WOLFSSL_LEAVE("OcspResponseDecode", 0);
9021    return 0;
9022}
9023
9024int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
9025{
9026    byte seqArray[5][MAX_SEQ_SZ];
9027    /* The ASN.1 of the OCSP Request is an onion of sequences */
9028    byte algoArray[MAX_ALGO_SZ];
9029    byte issuerArray[MAX_ENCODED_DIG_SZ];
9030    byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
9031    byte snArray[MAX_SN_SZ];
9032    byte extArray[MAX_OCSP_EXT_SZ];
9033    word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;
9034    int i, snSz;
9035    int keyIdSz;
9036
9037    WOLFSSL_ENTER("EncodeOcspRequest");
9038
9039    algoSz = SetAlgoID(req->hashAlg, algoArray, oidHashType, 0);
9040    keyIdSz = wc_HashGetDigestSize(wc_OidGetHash(req->hashAlg));
9041    if (keyIdSz <= 0 || keyIdSz > WC_MAX_DIGEST_SIZE)
9042        return BAD_FUNC_ARG;
9043
9044    issuerSz    = SetDigest(req->issuerHash,    keyIdSz,    issuerArray);
9045    issuerKeySz = SetDigest(req->issuerKeyHash, keyIdSz,    issuerKeyArray);
9046    snSz        = SetSerialNumber(req->serial,  req->serialSz, snArray,
9047                                                          MAX_SN_SZ, MAX_SN_SZ);
9048    extSz       = 0;
9049
9050    if (snSz < 0)
9051        return snSz;
9052
9053    if (req->nonceSz) {
9054        /* TLS Extensions use this function too - put extensions after
9055         * ASN.1: Context Specific [2].
9056         */
9057        extSz = EncodeOcspRequestExtensions(req, extArray + 2,
9058                                            OCSP_NONCE_EXT_SZ);
9059        extSz += SetExplicit(2, extSz, extArray, 0);
9060    }
9061
9062    totalSz = algoSz + issuerSz + issuerKeySz + snSz;
9063    for (i = 4; i >= 0; i--) {
9064        seqSz[i] = SetSequence(totalSz, seqArray[i]);
9065        totalSz += seqSz[i];
9066        if (i == 2) totalSz += extSz;
9067    }
9068
9069    if (output == NULL)
9070        return totalSz;
9071    if (totalSz > size)
9072        return BUFFER_E;
9073
9074    totalSz = 0;
9075    for (i = 0; i < 5; i++) {
9076        XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
9077        totalSz += seqSz[i];
9078    }
9079
9080    XMEMCPY(output + totalSz, algoArray, algoSz);
9081    totalSz += algoSz;
9082
9083    XMEMCPY(output + totalSz, issuerArray, issuerSz);
9084    totalSz += issuerSz;
9085
9086    XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
9087    totalSz += issuerKeySz;
9088
9089    XMEMCPY(output + totalSz, snArray, snSz);
9090    totalSz += snSz;
9091
9092    if (extSz != 0) {
9093        XMEMCPY(output + totalSz, extArray, extSz);
9094        totalSz += extSz;
9095    }
9096
9097    return totalSz;
9098}
9099
9100#ifdef HAVE_OCSP_RESPONDER
9101int DecodeOcspRequest(OcspRequest* req, const byte* input, word32 size)
9102{
9103    (void)req;
9104    (void)input;
9105    (void)size;
9106    /* Decoding ocsp requests not supported in legacy ASN parsing */
9107    return NOT_COMPILED_IN;
9108}
9109
9110#endif
9111#endif
9112int GetNameHash_ex(const byte* source, word32* idx, byte* hash, int maxIdx,
9113    word32 sigOID)
9114{
9115    int    length;  /* length of all distinguished names */
9116    int    ret;
9117    word32 dummy;
9118    byte   tag;
9119
9120    WOLFSSL_ENTER("GetNameHash");
9121
9122    dummy = *idx;
9123    if (GetASNTag(source, &dummy, &tag, (word32)maxIdx) == 0 &&
9124            tag == ASN_OBJECT_ID) {
9125        WOLFSSL_MSG("Trying optional prefix...");
9126
9127        if (GetLength(source, idx, &length, (word32)maxIdx) < 0)
9128            return ASN_PARSE_E;
9129
9130        *idx += (word32)length;
9131        WOLFSSL_MSG("Got optional prefix");
9132    }
9133
9134    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
9135     * calculated over the entire DER encoding of the Name field, including
9136     * the tag and length. */
9137    dummy = *idx;
9138    if (GetSequence(source, idx, &length, (word32)maxIdx) < 0)
9139        return ASN_PARSE_E;
9140
9141    ret = CalcHashId_ex(source + dummy, (word32)length + *idx - dummy, hash,
9142        HashIdAlg(sigOID));
9143
9144    *idx += (word32)length;
9145
9146    return ret;
9147}
9148
9149#if defined(HAVE_CRL) && !defined(WOLFCRYPT_ONLY)
9150static int GetRevoked(RevokedCert* rcert, const byte* buff, word32* idx,
9151                      DecodedCRL* dcrl, word32 maxIdx)
9152{
9153    int ret;
9154    int len;
9155    word32 end;
9156    RevokedCert* rc;
9157#ifdef CRL_STATIC_REVOKED_LIST
9158    int totalCerts = 0;
9159#endif
9160    WOLFSSL_ENTER("GetRevoked");
9161
9162    if (GetSequence(buff, idx, &len, maxIdx) < 0)
9163        return ASN_PARSE_E;
9164
9165    end = *idx + len;
9166
9167#ifdef CRL_STATIC_REVOKED_LIST
9168    totalCerts = dcrl->totalCerts;
9169
9170    if (totalCerts >= CRL_MAX_REVOKED_CERTS) {
9171        return MEMORY_E;
9172    }
9173
9174    rc = &rcert[totalCerts];
9175    ret = wc_GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,maxIdx);
9176    if (ret < 0) {
9177        WOLFSSL_MSG("wc_GetSerialNumber error");
9178        return ret;
9179    }
9180#else
9181
9182    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
9183                                                          DYNAMIC_TYPE_REVOKED);
9184    if (rc == NULL) {
9185        WOLFSSL_MSG("Alloc Revoked Cert failed");
9186        return MEMORY_E;
9187    }
9188    XMEMSET(rc, 0, sizeof(RevokedCert));
9189    ret = wc_GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,maxIdx);
9190    if (ret < 0) {
9191        WOLFSSL_MSG("wc_GetSerialNumber error");
9192        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
9193        return ret;
9194    }
9195
9196    (void)rcert;
9197#endif /* CRL_STATIC_REVOKED_LIST */
9198    /* get date */
9199#ifndef NO_ASN_TIME
9200    ret = GetBasicDate(buff, idx, rc->revDate, &rc->revDateFormat, maxIdx);
9201    if (ret < 0) {
9202        WOLFSSL_MSG("Expecting Date");
9203#ifndef CRL_STATIC_REVOKED_LIST
9204        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
9205#endif
9206        return ret;
9207    }
9208#endif
9209    /* Initialize reason code to absent */
9210    rc->reasonCode = -1;
9211
9212    /* Parse CRL entry extensions if present */
9213    if (*idx < end) {
9214        word32 extIdx = *idx;
9215        int extLen;
9216        byte tag;
9217
9218        /* Check for SEQUENCE tag (extensions wrapper) */
9219        if (GetASNTag(buff, &extIdx, &tag, end) == 0 &&
9220                tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
9221            word32 seqIdx = extIdx - 1;  /* back up to re-read tag */
9222            if (GetSequence(buff, &seqIdx, &extLen, end) >= 0) {
9223                word32 extEnd = seqIdx + (word32)extLen;
9224
9225#if defined(OPENSSL_EXTRA)
9226                /* Store raw DER of extensions for OpenSSL compat API */
9227                {
9228                    word32 rawStart = *idx;
9229                    word32 rawLen = end - rawStart;
9230                    rc->extensions = (byte*)XMALLOC(rawLen, dcrl->heap,
9231                                                    DYNAMIC_TYPE_REVOKED);
9232                    if (rc->extensions != NULL) {
9233                        XMEMCPY(rc->extensions, buff + rawStart, rawLen);
9234                        rc->extensionsSz = rawLen;
9235                    }
9236                }
9237#endif
9238
9239                ret = ParseCRL_EntryExtensions(buff, seqIdx, extEnd,
9240                    &rc->reasonCode);
9241                if (ret != 0) {
9242#if defined(OPENSSL_EXTRA)
9243                    XFREE(rc->extensions, dcrl->heap, DYNAMIC_TYPE_REVOKED);
9244                    rc->extensions = NULL;
9245                    rc->extensionsSz = 0;
9246#endif
9247#ifndef CRL_STATIC_REVOKED_LIST
9248                    XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
9249#endif
9250                    return ret;
9251                }
9252            }
9253        }
9254    }
9255
9256#ifndef CRL_STATIC_REVOKED_LIST
9257    /* add to list only after all parsing succeeded */
9258    rc->next = dcrl->certs;
9259    dcrl->certs = rc;
9260#endif
9261    dcrl->totalCerts++;
9262
9263    *idx = end;
9264
9265    return 0;
9266}
9267
9268/* Get CRL Signature, 0 on success */
9269static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
9270                            int maxIdx)
9271{
9272    int    length;
9273    int    ret;
9274
9275    WOLFSSL_ENTER("GetCRL_Signature");
9276
9277    ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);
9278    if (ret != 0)
9279        return ret;
9280    dcrl->sigLength = length;
9281
9282    dcrl->signature = (byte*)&source[*idx];
9283    *idx += dcrl->sigLength;
9284
9285    return 0;
9286}
9287
9288static int ParseCRL_CertList(RevokedCert* rcert, DecodedCRL* dcrl,
9289                           const byte* buf,word32* inOutIdx, int sz, int verify)
9290{
9291    word32 oid, dateIdx, idx, checkIdx;
9292    int length;
9293#ifdef WOLFSSL_NO_CRL_NEXT_DATE
9294    int doNextDate = 1;
9295#endif
9296    byte tag;
9297
9298    if (dcrl == NULL || inOutIdx == NULL || buf == NULL) {
9299        return BAD_FUNC_ARG;
9300    }
9301
9302    /* may have version */
9303    idx = *inOutIdx;
9304
9305    checkIdx = idx;
9306    if (GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag == ASN_INTEGER) {
9307        if (GetMyVersion(buf, &idx, &dcrl->version, sz) < 0)
9308            return ASN_PARSE_E;
9309        dcrl->version++;
9310    }
9311
9312    if (GetAlgoId(buf, &idx, &oid, oidIgnoreType, sz) < 0) {
9313        return ASN_PARSE_E;
9314    }
9315#ifdef WC_RSA_PSS
9316    else if (oid == CTC_RSASSAPSS) {
9317        word32 tmpSz;
9318        int len;
9319
9320        tmpSz = idx;
9321        dcrl->sigParamsIndex = idx;
9322        if (GetSequence(buf, &idx, &len, sz) < 0) {
9323            dcrl->sigParamsIndex = 0;
9324            return ASN_PARSE_E;
9325        }
9326        idx += len;
9327        dcrl->sigParamsLength = idx - tmpSz;
9328    }
9329#endif
9330
9331    checkIdx = idx;
9332    if (GetSequence(buf, &checkIdx, &length, sz) < 0) {
9333        return ASN_PARSE_E;
9334    }
9335#ifdef OPENSSL_EXTRA
9336    dcrl->issuerSz = length + (checkIdx - idx);
9337    dcrl->issuer   = (byte*)GetNameFromDer(buf + idx, (int)dcrl->issuerSz);
9338#endif
9339
9340    if (GetNameHash_ex(buf, &idx, dcrl->issuerHash, sz, oid) < 0)
9341        return ASN_PARSE_E;
9342
9343    if (GetBasicDate(buf, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
9344        return ASN_PARSE_E;
9345
9346    dateIdx = idx;
9347
9348    if (GetBasicDate(buf, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
9349    {
9350#ifndef WOLFSSL_NO_CRL_NEXT_DATE
9351        (void)dateIdx;
9352        return ASN_PARSE_E;
9353#else
9354        dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */
9355        doNextDate = 0;
9356        idx = dateIdx;
9357#endif
9358    }
9359
9360#ifdef WOLFSSL_NO_CRL_NEXT_DATE
9361    if (doNextDate)
9362#endif
9363    {
9364#if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_CRL_DATE_CHECK)
9365        if (verify != NO_VERIFY &&
9366            (! AsnSkipDateCheck) &&
9367            !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER,
9368                            MAX_DATE_SIZE)) {
9369            WOLFSSL_MSG("CRL after date is no longer valid");
9370            WOLFSSL_ERROR_VERBOSE(CRL_CERT_DATE_ERR);
9371            return CRL_CERT_DATE_ERR;
9372        }
9373#else
9374        (void)verify;
9375#endif
9376    }
9377
9378    checkIdx = idx;
9379    if ((idx != dcrl->sigIndex) && (GetASNTag(buf, &checkIdx, &tag, sz) == 0) &&
9380            (tag != CRL_EXTENSIONS)) {
9381        int len;
9382        word32 tlen;
9383
9384        if (GetSequence(buf, &idx, &len, sz) < 0)
9385            return ASN_PARSE_E;
9386        tlen = (word32)len + idx;
9387        if (tlen < idx)
9388            return ASN_PARSE_E;
9389
9390        while (idx < tlen) {
9391            if (GetRevoked(rcert, buf, &idx, dcrl, tlen) < 0)
9392                return ASN_PARSE_E;
9393        }
9394    }
9395
9396    *inOutIdx = idx;
9397
9398    return 0;
9399}
9400
9401#ifndef NO_SKID
9402static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl)
9403{
9404    word32 idx = 0;
9405    int length = 0, ret = 0;
9406    byte tag;
9407
9408    WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
9409
9410    if (GetSequence(input, &idx, &length, sz) < 0) {
9411        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
9412        return ASN_PARSE_E;
9413    }
9414
9415    if (GetASNTag(input, &idx, &tag, sz) < 0) {
9416        return ASN_PARSE_E;
9417    }
9418
9419    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
9420        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
9421        return 0;
9422    }
9423
9424    if (GetLength(input, &idx, &length, sz) <= 0) {
9425        WOLFSSL_MSG("\tfail: extension data length");
9426        return ASN_PARSE_E;
9427    }
9428
9429    dcrl->extAuthKeyIdSet = 1;
9430
9431    /* Get the hash or hash of the hash if wrong size. */
9432    ret = GetHashId(input + idx, length, dcrl->extAuthKeyId,
9433        HashIdAlg(dcrl->signatureOID));
9434
9435    return ret;
9436}
9437
9438#endif
9439static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf,
9440        word32* inOutIdx, word32 sz)
9441{
9442    int length;
9443    word32 idx;
9444    word32 ext_bound; /* boundary index for the sequence of extensions */
9445    word32 oid;
9446    byte tag;
9447
9448    WOLFSSL_ENTER("ParseCRL_Extensions");
9449    (void)dcrl;
9450
9451    if (inOutIdx == NULL)
9452        return BAD_FUNC_ARG;
9453
9454    idx = *inOutIdx;
9455
9456    /* CRL Extensions are optional */
9457    if ((idx + 1) > sz)
9458        return 0;
9459
9460    /* CRL Extensions are optional */
9461    if (GetASNTag(buf, &idx, &tag, sz) < 0)
9462        return 0;
9463
9464    /* CRL Extensions are optional */
9465    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
9466        return 0;
9467
9468    if (GetLength(buf, &idx, &length, sz) < 0)
9469        return ASN_PARSE_E;
9470
9471    if (GetSequence(buf, &idx, &length, sz) < 0)
9472        return ASN_PARSE_E;
9473
9474    ext_bound = idx + length;
9475
9476    while (idx < (word32)ext_bound) {
9477        word32 localIdx;
9478        int ret;
9479        int critical = 0;
9480
9481        if (GetSequence(buf, &idx, &length, sz) < 0) {
9482            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
9483            return ASN_PARSE_E;
9484        }
9485
9486        oid = 0;
9487        if (GetObjectId(buf, &idx, &oid, oidCrlExtType, sz) < 0) {
9488            WOLFSSL_MSG("\tfail: OBJECT ID");
9489            return ASN_PARSE_E;
9490        }
9491
9492        /* check for critical flag */
9493        if ((idx + 1) > (word32)sz) {
9494            WOLFSSL_MSG("\tfail: malformed buffer");
9495            return BUFFER_E;
9496        }
9497
9498        localIdx = idx;
9499        if (GetASNTag(buf, &localIdx, &tag, sz) == 0 &&
9500                tag == ASN_BOOLEAN) {
9501            WOLFSSL_MSG("\tfound optional critical flag, moving past");
9502            ret = GetBoolean(buf, &idx, sz);
9503            if (ret < 0)
9504                return ret;
9505            critical = ret;
9506        }
9507
9508        ret = GetOctetString(buf, &idx, &length, sz);
9509        if (ret < 0)
9510            return ret;
9511
9512        if (oid == AUTH_KEY_OID) {
9513        #ifndef NO_SKID
9514            ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
9515            if (ret < 0) {
9516                WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
9517                return ret;
9518            }
9519        #endif
9520        }
9521        else if (oid == CRL_NUMBER_OID) {
9522            localIdx = idx;
9523            if (GetASNTag(buf, &localIdx, &tag, sz) == 0 &&
9524                    tag == ASN_INTEGER) {
9525                word32 rawIdx = idx;
9526                int rawLen = 0;
9527                ret = GetASNInt(buf, &idx, &length, sz);
9528                if (ret < 0) {
9529                    WOLFSSL_MSG("\tcouldn't parse CRL number extension");
9530                    return ret;
9531                }
9532                /* RFC 5280 s5.2.3: CRL number must be non-negative.
9533                 * Check the raw encoding before GetASNInt strips
9534                 * the leading-zero pad: skip past the INTEGER tag
9535                 * and length, then reject if the first content byte
9536                 * has its high bit set (negative value). */
9537                (void)GetASNHeader(buf, ASN_INTEGER,
9538                    &rawIdx, &rawLen, sz);
9539                if (rawLen > 0 && (buf[rawIdx] & 0x80) != 0) {
9540                    WOLFSSL_MSG("CRL number is negative");
9541                    return ASN_PARSE_E;
9542                }
9543                if (length <= CRL_MAX_NUM_SZ) {
9544                    DECL_MP_INT_SIZE_DYN(m, CRL_MAX_NUM_SZ_BITS,
9545                                   CRL_MAX_NUM_SZ_BITS);
9546                    NEW_MP_INT_SIZE(m, CRL_MAX_NUM_SZ_BITS, NULL,
9547                                   DYNAMIC_TYPE_TMP_BUFFER);
9548                #ifdef MP_INT_SIZE_CHECK_NULL
9549                    if (m == NULL) {
9550                        ret = MEMORY_E;
9551                    }
9552                #endif
9553
9554                    if (ret == 0 && ((ret = INIT_MP_INT_SIZE(m, CRL_MAX_NUM_SZ
9555                                    * CHAR_BIT)) != MP_OKAY)) {
9556                        ret = MP_INIT_E;
9557                    }
9558
9559                    if (ret == MP_OKAY)
9560                        ret = mp_read_unsigned_bin(m, buf + idx, length);
9561
9562                    if (ret != MP_OKAY)
9563                        ret = BUFFER_E;
9564
9565                    if (ret == MP_OKAY && mp_toradix(m, (char*)dcrl->crlNumber,
9566                                MP_RADIX_HEX) != MP_OKAY)
9567                        ret = BUFFER_E;
9568
9569                    if (ret == MP_OKAY) {
9570                        dcrl->crlNumberSet = 1;
9571                    }
9572
9573                    FREE_MP_INT_SIZE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9574
9575                    if (ret != MP_OKAY)
9576                        return ret;
9577                } else {
9578                    WOLFSSL_MSG("CRL number exceeds limitation");
9579                    ret = BUFFER_E;
9580                }
9581            }
9582        }
9583        else if (critical) {
9584            WOLFSSL_MSG("Unknown critical CRL extension");
9585            return ASN_CRIT_EXT_E;
9586        }
9587
9588        idx += length;
9589    }
9590
9591    *inOutIdx = idx;
9592
9593    return 0;
9594}
9595
9596int ParseCRL(RevokedCert* rcert, DecodedCRL* dcrl, const byte* buff, word32 sz,
9597             int verify, void* cm)
9598{
9599    Signer*      ca = NULL;
9600    SignatureCtx sigCtx;
9601    int          ret = 0;
9602    int          len;
9603    word32       idx = 0;
9604    const byte* sigParams = NULL;
9605    int sigParamsSz = 0;
9606
9607    WOLFSSL_MSG("ParseCRL");
9608
9609    /* raw crl hash */
9610    /* hash here if needed for optimized comparisons
9611     * wc_Sha sha;
9612     * wc_InitSha(&sha);
9613     * wc_ShaUpdate(&sha, buff, sz);
9614     * wc_ShaFinal(&sha, dcrl->crlHash); */
9615
9616    if (GetSequence(buff, &idx, &len, sz) < 0)
9617        return ASN_PARSE_E;
9618
9619    dcrl->certBegin = idx;
9620    /* Normalize sz for the length inside the outer sequence. */
9621    sz = len + idx;
9622
9623    if (GetSequence(buff, &idx, &len, sz) < 0)
9624        return ASN_PARSE_E;
9625    dcrl->sigIndex = len + idx;
9626
9627    if (ParseCRL_CertList(rcert, dcrl, buff, &idx, dcrl->sigIndex, verify) < 0)
9628        return ASN_PARSE_E;
9629
9630    if (ParseCRL_Extensions(dcrl, buff, &idx, dcrl->sigIndex) < 0)
9631        return ASN_PARSE_E;
9632
9633    idx = dcrl->sigIndex;
9634
9635    if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0) {
9636        return ASN_PARSE_E;
9637    }
9638#ifdef WC_RSA_PSS
9639    else if (dcrl->signatureOID == CTC_RSASSAPSS) {
9640        word32 tmpSz;
9641        const byte* params;
9642
9643        tmpSz = idx;
9644        params = buff + idx;
9645        if (GetSequence(buff, &idx, &len, sz) < 0) {
9646            return ASN_PARSE_E;
9647        }
9648        idx += len;
9649        sigParams = params;
9650        sigParamsSz = idx - tmpSz;
9651    }
9652#endif
9653
9654    if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
9655        return ASN_PARSE_E;
9656
9657    /* openssl doesn't add skid by default for CRLs cause firefox chokes
9658       if experiencing issues uncomment NO_SKID define in CRL section of
9659       wolfssl/wolfcrypt/settings.h */
9660#ifndef NO_SKID
9661    if (dcrl->extAuthKeyIdSet) {
9662        ca = GetCA(cm, dcrl->extAuthKeyId); /* more unique than issuerHash */
9663    }
9664    if (ca != NULL && XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
9665            KEYID_SIZE) != 0) {
9666        ca = NULL;
9667    }
9668    if (ca == NULL) {
9669        ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
9670        /* If AKID is available then this CA doesn't have the public
9671         * key required */
9672        if (ca && dcrl->extAuthKeyIdSet) {
9673            WOLFSSL_MSG("CA SKID doesn't match AKID");
9674            ca = NULL;
9675        }
9676    }
9677#else
9678    ca = GetCA(cm, dcrl->issuerHash);
9679#endif /* !NO_SKID */
9680    WOLFSSL_MSG("About to verify CRL signature");
9681
9682    if (ca == NULL) {
9683        WOLFSSL_MSG("Did NOT find CRL issuer CA");
9684        ret = ASN_CRL_NO_SIGNER_E;
9685        WOLFSSL_ERROR_VERBOSE(ret);
9686        goto end;
9687    }
9688
9689    WOLFSSL_MSG("Found CRL issuer CA");
9690    ret = VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
9691           dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
9692           dcrl->signatureOID, sigParams, sigParamsSz, ca, dcrl->heap);
9693
9694end:
9695    return ret;
9696}
9697
9698#endif
9699#ifdef WOLFSSL_CERT_PIV
9700int wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz)
9701{
9702    int length = 0;
9703    word32 idx = 0;
9704
9705    WOLFSSL_ENTER("wc_ParseCertPIV");
9706
9707    if (piv == NULL || buf == NULL || totalSz == 0)
9708        return BAD_FUNC_ARG;
9709
9710    XMEMSET(piv, 0, sizeof(wc_CertPIV));
9711
9712    /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */
9713    /* Certificate (0A 82 05FA) */
9714    if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) {
9715        /* Identiv Type PIV card */
9716        piv->isIdentiv = 1;
9717
9718        piv->cert =   &buf[idx];
9719        piv->certSz = length;
9720        idx += length;
9721
9722        /* Nonce (0B 14) */
9723        if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) {
9724            piv->nonce =   &buf[idx];
9725            piv->nonceSz = length;
9726            idx += length;
9727        }
9728
9729        /* Signed Nonce (0C 82 0100) */
9730        if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) {
9731            piv->signedNonce =   &buf[idx];
9732            piv->signedNonceSz = length;
9733        }
9734
9735        idx = 0;
9736        buf = piv->cert;
9737        totalSz = piv->certSz;
9738    }
9739
9740    /* Certificate Buffer Total Size (53 82 05F6) */
9741    if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx,
9742                                                   &length, totalSz) < 0) {
9743        return ASN_PARSE_E;
9744    }
9745    /* PIV Certificate (70 82 05ED) */
9746    if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length,
9747                                                         totalSz) < 0) {
9748        return ASN_PARSE_E;
9749    }
9750
9751    /* Capture certificate buffer pointer and length */
9752    piv->cert =   &buf[idx];
9753    piv->certSz = length;
9754    idx += length;
9755
9756    /* PIV Certificate Info (71 01 00) */
9757    if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length,
9758                                                        totalSz) >= 0) {
9759        if (length >= 1) {
9760            piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED);
9761            piv->isX509 =      ((buf[idx] & ASN_PIV_CERT_INFO_ISX509) != 0);
9762        }
9763        idx += length;
9764    }
9765
9766    /* PIV Error Detection (FE 00) */
9767    if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length,
9768                                                        totalSz) >= 0) {
9769        piv->certErrDet =   &buf[idx];
9770        piv->certErrDetSz = length;
9771        idx += length;
9772    }
9773
9774    return 0;
9775}
9776
9777#endif
9778
9779#endif /* WOLFSSL_ASN_ORIG_INCLUDED */