cjson
.github
workflows CI.yml ci-fuzz.yml
CONTRIBUTING.md
fuzzing
inputs test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9
.gitignore CMakeLists.txt afl-prepare-linux.sh afl.c afl.sh cjson_read_fuzzer.c fuzz_main.c json.dict ossfuzz.sh
library_config cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmake
tests
inputs test1 test1.expected test10 test10.expected test11 test11.expected test2 test2.expected test3 test3.expected test4 test4.expected test5 test5.expected test6 test7 test7.expected test8 test8.expected test9 test9.expected
json-patch-tests .editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.json
unity
auto colour_prompt.rb colour_reporter.rb generate_config.yml generate_module.rb generate_test_runner.rb parse_output.rb stylize_as_junit.rb test_file_filter.rb type_sanitizer.rb unity_test_summary.py unity_test_summary.rb unity_to_junit.py
docs ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txt
examples
example_1
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_2
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_3
helper UnityHelper.c UnityHelper.h
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
rakefile.rb rakefile_helper.rb readme.txt target_gcc_32.yml
unity_config.h
extras
eclipse error_parsers.txt
fixture
src unity_fixture.c unity_fixture.h unity_fixture_internals.h unity_fixture_malloc_overrides.h
rakefile.rb rakefile_helper.rb readme.txt
release build.info version.info
src unity.c unity.h unity_internals.h
.gitattributes .gitignore .travis.yml README.md
CMakeLists.txt cjson_add.c common.h compare_tests.c json_patch_tests.c minify_tests.c misc_tests.c misc_utils_tests.c old_utils_tests.c parse_array.c parse_examples.c parse_hex4.c parse_number.c parse_object.c parse_string.c parse_value.c parse_with_opts.c print_array.c print_number.c print_object.c print_string.c print_value.c readme_examples.c unity_setup.c
.editorconfig .gitattributes .gitignore .travis.yml CHANGELOG.md CMakeLists.txt CONTRIBUTORS.md LICENSE Makefile README.md SECURITY.md appveyor.yml cJSON.c cJSON.h cJSON_Utils.c cJSON_Utils.h test.c valgrind.supp
curl
.circleci config.yml
.github
ISSUE_TEMPLATE bug_report.yml config.yml docs.yml
scripts cleancmd.pl cmp-config.pl cmp-pkg-config.sh codespell-ignore.words codespell.sh distfiles.sh pyspelling.words pyspelling.yaml randcurl.pl requirements-docs.txt requirements-proselint.txt requirements.txt shellcheck-ci.sh shellcheck.sh spellcheck.curl trimmarkdownheader.pl typos.sh typos.toml verify-examples.pl verify-synopsis.pl yamlcheck.sh yamlcheck.yaml
workflows appveyor-status.yml checkdocs.yml checksrc.yml checkurls.yml codeql.yml configure-vs-cmake.yml curl-for-win.yml distcheck.yml fuzz.yml http3-linux.yml label.yml linux-old.yml linux.yml macos.yml non-native.yml windows.yml
CODEOWNERS CONTRIBUTING.md FUNDING.yml dependabot.yml labeler.yml lock.yml stale.yml
CMake CurlSymbolHiding.cmake CurlTests.c FindBrotli.cmake FindCares.cmake FindGSS.cmake FindGnuTLS.cmake FindLDAP.cmake FindLibbacktrace.cmake FindLibgsasl.cmake FindLibidn2.cmake FindLibpsl.cmake FindLibssh.cmake FindLibssh2.cmake FindLibuv.cmake FindMbedTLS.cmake FindNGHTTP2.cmake FindNGHTTP3.cmake FindNGTCP2.cmake FindNettle.cmake FindQuiche.cmake FindRustls.cmake FindWolfSSL.cmake FindZstd.cmake Macros.cmake OtherTests.cmake PickyWarnings.cmake Utilities.cmake cmake_uninstall.in.cmake curl-config.in.cmake unix-cache.cmake win32-cache.cmake
LICENSES BSD-4-Clause-UC.txt ISC.txt curl.txt
docs
cmdline-opts .gitignore CMakeLists.txt MANPAGE.md Makefile.am Makefile.inc _AUTHORS.md _BUGS.md _DESCRIPTION.md _ENVIRONMENT.md _EXITCODES.md _FILES.md _GLOBBING.md _NAME.md _OPTIONS.md _OUTPUT.md _PROGRESS.md _PROTOCOLS.md _PROXYPREFIX.md _SEEALSO.md _SYNOPSIS.md _URL.md _VARIABLES.md _VERSION.md _WWW.md abstract-unix-socket.md alt-svc.md anyauth.md append.md aws-sigv4.md basic.md ca-native.md cacert.md capath.md cert-status.md cert-type.md cert.md ciphers.md compressed-ssh.md compressed.md config.md connect-timeout.md connect-to.md continue-at.md cookie-jar.md cookie.md create-dirs.md create-file-mode.md crlf.md crlfile.md curves.md data-ascii.md data-binary.md data-raw.md data-urlencode.md data.md delegation.md digest.md disable-eprt.md disable-epsv.md disable.md disallow-username-in-url.md dns-interface.md dns-ipv4-addr.md dns-ipv6-addr.md dns-servers.md doh-cert-status.md doh-insecure.md doh-url.md dump-ca-embed.md dump-header.md ech.md egd-file.md engine.md etag-compare.md etag-save.md expect100-timeout.md fail-early.md fail-with-body.md fail.md false-start.md follow.md form-escape.md form-string.md form.md ftp-account.md ftp-alternative-to-user.md ftp-create-dirs.md ftp-method.md ftp-pasv.md ftp-port.md ftp-pret.md ftp-skip-pasv-ip.md ftp-ssl-ccc-mode.md ftp-ssl-ccc.md ftp-ssl-control.md get.md globoff.md happy-eyeballs-timeout-ms.md haproxy-clientip.md haproxy-protocol.md head.md header.md help.md hostpubmd5.md hostpubsha256.md hsts.md http0.9.md http1.0.md http1.1.md http2-prior-knowledge.md http2.md http3-only.md http3.md ignore-content-length.md insecure.md interface.md ip-tos.md ipfs-gateway.md ipv4.md ipv6.md json.md junk-session-cookies.md keepalive-cnt.md keepalive-time.md key-type.md key.md knownhosts.md krb.md libcurl.md limit-rate.md list-only.md local-port.md location-trusted.md location.md login-options.md mail-auth.md mail-from.md mail-rcpt-allowfails.md mail-rcpt.md mainpage.idx manual.md max-filesize.md max-redirs.md max-time.md metalink.md mptcp.md negotiate.md netrc-file.md netrc-optional.md netrc.md next.md no-alpn.md no-buffer.md no-clobber.md no-keepalive.md no-npn.md no-progress-meter.md no-sessionid.md noproxy.md ntlm-wb.md ntlm.md oauth2-bearer.md out-null.md output-dir.md output.md parallel-immediate.md parallel-max-host.md parallel-max.md parallel.md pass.md path-as-is.md pinnedpubkey.md post301.md post302.md post303.md preproxy.md progress-bar.md proto-default.md proto-redir.md proto.md proxy-anyauth.md proxy-basic.md proxy-ca-native.md proxy-cacert.md proxy-capath.md proxy-cert-type.md proxy-cert.md proxy-ciphers.md proxy-crlfile.md proxy-digest.md proxy-header.md proxy-http2.md proxy-insecure.md proxy-key-type.md proxy-key.md proxy-negotiate.md proxy-ntlm.md proxy-pass.md proxy-pinnedpubkey.md proxy-service-name.md proxy-ssl-allow-beast.md proxy-ssl-auto-client-cert.md proxy-tls13-ciphers.md proxy-tlsauthtype.md proxy-tlspassword.md proxy-tlsuser.md proxy-tlsv1.md proxy-user.md proxy.md proxy1.0.md proxytunnel.md pubkey.md quote.md random-file.md range.md rate.md raw.md referer.md remote-header-name.md remote-name-all.md remote-name.md remote-time.md remove-on-error.md request-target.md request.md resolve.md retry-all-errors.md retry-connrefused.md retry-delay.md retry-max-time.md retry.md sasl-authzid.md sasl-ir.md service-name.md show-error.md show-headers.md sigalgs.md silent.md skip-existing.md socks4.md socks4a.md socks5-basic.md socks5-gssapi-nec.md socks5-gssapi-service.md socks5-gssapi.md socks5-hostname.md socks5.md speed-limit.md speed-time.md ssl-allow-beast.md ssl-auto-client-cert.md ssl-no-revoke.md ssl-reqd.md ssl-revoke-best-effort.md ssl-sessions.md ssl.md sslv2.md sslv3.md stderr.md styled-output.md suppress-connect-headers.md tcp-fastopen.md tcp-nodelay.md telnet-option.md tftp-blksize.md tftp-no-options.md time-cond.md tls-earlydata.md tls-max.md tls13-ciphers.md tlsauthtype.md tlspassword.md tlsuser.md tlsv1.0.md tlsv1.1.md tlsv1.2.md tlsv1.3.md tlsv1.md tr-encoding.md trace-ascii.md trace-config.md trace-ids.md trace-time.md trace.md unix-socket.md upload-file.md upload-flags.md url-query.md url.md use-ascii.md user-agent.md user.md variable.md verbose.md version.md vlan-priority.md write-out.md xattr.md
examples .checksrc .gitignore 10-at-a-time.c CMakeLists.txt Makefile.am Makefile.example Makefile.inc README.md adddocsref.pl address-scope.c altsvc.c anyauthput.c block_ip.c cacertinmem.c certinfo.c chkspeed.c connect-to.c cookie_interface.c crawler.c debug.c default-scheme.c ephiperfifo.c evhiperfifo.c externalsocket.c fileupload.c ftp-delete.c ftp-wildcard.c ftpget.c ftpgetinfo.c ftpgetresp.c ftpsget.c ftpupload.c ftpuploadfrommem.c ftpuploadresume.c getinfo.c getinmemory.c getredirect.c getreferrer.c ghiper.c headerapi.c hiperfifo.c hsts-preload.c htmltidy.c htmltitle.cpp http-options.c http-post.c http2-download.c http2-pushinmemory.c http2-serverpush.c http2-upload.c http3-present.c http3.c httpcustomheader.c httpput-postfields.c httpput.c https.c imap-append.c imap-authzid.c imap-copy.c imap-create.c imap-delete.c imap-examine.c imap-fetch.c imap-list.c imap-lsub.c imap-multi.c imap-noop.c imap-search.c imap-ssl.c imap-store.c imap-tls.c interface.c ipv6.c keepalive.c localport.c log_failed_transfers.c maxconnects.c multi-app.c multi-debugcallback.c multi-double.c multi-event.c multi-formadd.c multi-legacy.c multi-post.c multi-single.c multi-uv.c netrc.c parseurl.c persistent.c pop3-authzid.c pop3-dele.c pop3-list.c pop3-multi.c pop3-noop.c pop3-retr.c pop3-ssl.c pop3-stat.c pop3-tls.c pop3-top.c pop3-uidl.c post-callback.c postinmemory.c postit2-formadd.c postit2.c progressfunc.c protofeats.c range.c resolve.c rtsp-options.c sendrecv.c sepheaders.c sessioninfo.c sftpget.c sftpuploadresume.c shared-connection-cache.c simple.c simplepost.c simplessl.c smooth-gtk-thread.c smtp-authzid.c smtp-expn.c smtp-mail.c smtp-mime.c smtp-multi.c smtp-ssl.c smtp-tls.c smtp-vrfy.c sslbackend.c synctime.c threaded.c unixsocket.c url2file.c urlapi.c usercertinmem.c version-check.pl websocket-cb.c websocket-updown.c websocket.c xmlstream.c
internals BUFQ.md BUFREF.md CHECKSRC.md CLIENT-READERS.md CLIENT-WRITERS.md CODE_STYLE.md CONNECTION-FILTERS.md CREDENTIALS.md CURLX.md DYNBUF.md HASH.md LLIST.md MID.md MQTT.md MULTI-EV.md NEW-PROTOCOL.md PEERS.md PORTING.md RATELIMITS.md README.md SCORECARD.md SPLAY.md STRPARSE.md THRDPOOL-AND-QUEUE.md TIME-KEEPING.md TLS-SESSIONS.md UINT_SETS.md WEBSOCKET.md
libcurl
opts CMakeLists.txt CURLINFO_ACTIVESOCKET.md CURLINFO_APPCONNECT_TIME.md CURLINFO_APPCONNECT_TIME_T.md CURLINFO_CAINFO.md CURLINFO_CAPATH.md CURLINFO_CERTINFO.md CURLINFO_CONDITION_UNMET.md CURLINFO_CONNECT_TIME.md CURLINFO_CONNECT_TIME_T.md CURLINFO_CONN_ID.md CURLINFO_CONTENT_LENGTH_DOWNLOAD.md CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md CURLINFO_CONTENT_LENGTH_UPLOAD.md CURLINFO_CONTENT_LENGTH_UPLOAD_T.md CURLINFO_CONTENT_TYPE.md CURLINFO_COOKIELIST.md CURLINFO_EARLYDATA_SENT_T.md CURLINFO_EFFECTIVE_METHOD.md CURLINFO_EFFECTIVE_URL.md CURLINFO_FILETIME.md CURLINFO_FILETIME_T.md CURLINFO_FTP_ENTRY_PATH.md CURLINFO_HEADER_SIZE.md CURLINFO_HTTPAUTH_AVAIL.md CURLINFO_HTTPAUTH_USED.md CURLINFO_HTTP_CONNECTCODE.md CURLINFO_HTTP_VERSION.md CURLINFO_LASTSOCKET.md CURLINFO_LOCAL_IP.md CURLINFO_LOCAL_PORT.md CURLINFO_NAMELOOKUP_TIME.md CURLINFO_NAMELOOKUP_TIME_T.md CURLINFO_NUM_CONNECTS.md CURLINFO_OS_ERRNO.md CURLINFO_POSTTRANSFER_TIME_T.md CURLINFO_PRETRANSFER_TIME.md CURLINFO_PRETRANSFER_TIME_T.md CURLINFO_PRIMARY_IP.md CURLINFO_PRIMARY_PORT.md CURLINFO_PRIVATE.md CURLINFO_PROTOCOL.md CURLINFO_PROXYAUTH_AVAIL.md CURLINFO_PROXYAUTH_USED.md CURLINFO_PROXY_ERROR.md CURLINFO_PROXY_SSL_VERIFYRESULT.md CURLINFO_QUEUE_TIME_T.md CURLINFO_REDIRECT_COUNT.md CURLINFO_REDIRECT_TIME.md CURLINFO_REDIRECT_TIME_T.md CURLINFO_REDIRECT_URL.md CURLINFO_REFERER.md CURLINFO_REQUEST_SIZE.md CURLINFO_RESPONSE_CODE.md CURLINFO_RETRY_AFTER.md CURLINFO_RTSP_CLIENT_CSEQ.md CURLINFO_RTSP_CSEQ_RECV.md CURLINFO_RTSP_SERVER_CSEQ.md CURLINFO_RTSP_SESSION_ID.md CURLINFO_SCHEME.md CURLINFO_SIZE_DELIVERED.md CURLINFO_SIZE_DOWNLOAD.md CURLINFO_SIZE_DOWNLOAD_T.md CURLINFO_SIZE_UPLOAD.md CURLINFO_SIZE_UPLOAD_T.md CURLINFO_SPEED_DOWNLOAD.md CURLINFO_SPEED_DOWNLOAD_T.md CURLINFO_SPEED_UPLOAD.md CURLINFO_SPEED_UPLOAD_T.md CURLINFO_SSL_ENGINES.md CURLINFO_SSL_VERIFYRESULT.md CURLINFO_STARTTRANSFER_TIME.md CURLINFO_STARTTRANSFER_TIME_T.md CURLINFO_TLS_SESSION.md CURLINFO_TLS_SSL_PTR.md CURLINFO_TOTAL_TIME.md CURLINFO_TOTAL_TIME_T.md CURLINFO_USED_PROXY.md CURLINFO_XFER_ID.md CURLMINFO_XFERS_ADDED.md CURLMINFO_XFERS_CURRENT.md CURLMINFO_XFERS_DONE.md CURLMINFO_XFERS_PENDING.md CURLMINFO_XFERS_RUNNING.md CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.md CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.md CURLMOPT_MAXCONNECTS.md CURLMOPT_MAX_CONCURRENT_STREAMS.md CURLMOPT_MAX_HOST_CONNECTIONS.md CURLMOPT_MAX_PIPELINE_LENGTH.md CURLMOPT_MAX_TOTAL_CONNECTIONS.md CURLMOPT_NETWORK_CHANGED.md CURLMOPT_NOTIFYDATA.md CURLMOPT_NOTIFYFUNCTION.md CURLMOPT_PIPELINING.md CURLMOPT_PIPELINING_SERVER_BL.md CURLMOPT_PIPELINING_SITE_BL.md CURLMOPT_PUSHDATA.md CURLMOPT_PUSHFUNCTION.md CURLMOPT_QUICK_EXIT.md CURLMOPT_RESOLVE_THREADS_MAX.md CURLMOPT_SOCKETDATA.md CURLMOPT_SOCKETFUNCTION.md CURLMOPT_TIMERDATA.md CURLMOPT_TIMERFUNCTION.md CURLOPT_ABSTRACT_UNIX_SOCKET.md CURLOPT_ACCEPTTIMEOUT_MS.md CURLOPT_ACCEPT_ENCODING.md CURLOPT_ADDRESS_SCOPE.md CURLOPT_ALTSVC.md CURLOPT_ALTSVC_CTRL.md CURLOPT_APPEND.md CURLOPT_AUTOREFERER.md CURLOPT_AWS_SIGV4.md CURLOPT_BUFFERSIZE.md CURLOPT_CAINFO.md CURLOPT_CAINFO_BLOB.md CURLOPT_CAPATH.md CURLOPT_CA_CACHE_TIMEOUT.md CURLOPT_CERTINFO.md CURLOPT_CHUNK_BGN_FUNCTION.md CURLOPT_CHUNK_DATA.md CURLOPT_CHUNK_END_FUNCTION.md CURLOPT_CLOSESOCKETDATA.md CURLOPT_CLOSESOCKETFUNCTION.md CURLOPT_CONNECTTIMEOUT.md CURLOPT_CONNECTTIMEOUT_MS.md CURLOPT_CONNECT_ONLY.md CURLOPT_CONNECT_TO.md CURLOPT_CONV_FROM_NETWORK_FUNCTION.md CURLOPT_CONV_FROM_UTF8_FUNCTION.md CURLOPT_CONV_TO_NETWORK_FUNCTION.md CURLOPT_COOKIE.md CURLOPT_COOKIEFILE.md CURLOPT_COOKIEJAR.md CURLOPT_COOKIELIST.md CURLOPT_COOKIESESSION.md CURLOPT_COPYPOSTFIELDS.md CURLOPT_CRLF.md CURLOPT_CRLFILE.md CURLOPT_CURLU.md CURLOPT_CUSTOMREQUEST.md CURLOPT_DEBUGDATA.md CURLOPT_DEBUGFUNCTION.md CURLOPT_DEFAULT_PROTOCOL.md CURLOPT_DIRLISTONLY.md CURLOPT_DISALLOW_USERNAME_IN_URL.md CURLOPT_DNS_CACHE_TIMEOUT.md CURLOPT_DNS_INTERFACE.md CURLOPT_DNS_LOCAL_IP4.md CURLOPT_DNS_LOCAL_IP6.md CURLOPT_DNS_SERVERS.md CURLOPT_DNS_SHUFFLE_ADDRESSES.md CURLOPT_DNS_USE_GLOBAL_CACHE.md CURLOPT_DOH_SSL_VERIFYHOST.md CURLOPT_DOH_SSL_VERIFYPEER.md CURLOPT_DOH_SSL_VERIFYSTATUS.md CURLOPT_DOH_URL.md CURLOPT_ECH.md CURLOPT_EGDSOCKET.md CURLOPT_ERRORBUFFER.md CURLOPT_EXPECT_100_TIMEOUT_MS.md CURLOPT_FAILONERROR.md CURLOPT_FILETIME.md CURLOPT_FNMATCH_DATA.md CURLOPT_FNMATCH_FUNCTION.md CURLOPT_FOLLOWLOCATION.md CURLOPT_FORBID_REUSE.md CURLOPT_FRESH_CONNECT.md CURLOPT_FTPPORT.md CURLOPT_FTPSSLAUTH.md CURLOPT_FTP_ACCOUNT.md CURLOPT_FTP_ALTERNATIVE_TO_USER.md CURLOPT_FTP_CREATE_MISSING_DIRS.md CURLOPT_FTP_FILEMETHOD.md CURLOPT_FTP_SKIP_PASV_IP.md CURLOPT_FTP_SSL_CCC.md CURLOPT_FTP_USE_EPRT.md CURLOPT_FTP_USE_EPSV.md CURLOPT_FTP_USE_PRET.md CURLOPT_GSSAPI_DELEGATION.md CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.md CURLOPT_HAPROXYPROTOCOL.md CURLOPT_HAPROXY_CLIENT_IP.md CURLOPT_HEADER.md CURLOPT_HEADERDATA.md CURLOPT_HEADERFUNCTION.md CURLOPT_HEADEROPT.md CURLOPT_HSTS.md CURLOPT_HSTSREADDATA.md CURLOPT_HSTSREADFUNCTION.md CURLOPT_HSTSWRITEDATA.md CURLOPT_HSTSWRITEFUNCTION.md CURLOPT_HSTS_CTRL.md CURLOPT_HTTP09_ALLOWED.md CURLOPT_HTTP200ALIASES.md CURLOPT_HTTPAUTH.md CURLOPT_HTTPGET.md CURLOPT_HTTPHEADER.md CURLOPT_HTTPPOST.md CURLOPT_HTTPPROXYTUNNEL.md CURLOPT_HTTP_CONTENT_DECODING.md CURLOPT_HTTP_TRANSFER_DECODING.md CURLOPT_HTTP_VERSION.md CURLOPT_IGNORE_CONTENT_LENGTH.md CURLOPT_INFILESIZE.md CURLOPT_INFILESIZE_LARGE.md CURLOPT_INTERFACE.md CURLOPT_INTERLEAVEDATA.md CURLOPT_INTERLEAVEFUNCTION.md CURLOPT_IOCTLDATA.md CURLOPT_IOCTLFUNCTION.md CURLOPT_IPRESOLVE.md CURLOPT_ISSUERCERT.md CURLOPT_ISSUERCERT_BLOB.md CURLOPT_KEEP_SENDING_ON_ERROR.md CURLOPT_KEYPASSWD.md CURLOPT_KRBLEVEL.md CURLOPT_LOCALPORT.md CURLOPT_LOCALPORTRANGE.md CURLOPT_LOGIN_OPTIONS.md CURLOPT_LOW_SPEED_LIMIT.md CURLOPT_LOW_SPEED_TIME.md CURLOPT_MAIL_AUTH.md CURLOPT_MAIL_FROM.md CURLOPT_MAIL_RCPT.md CURLOPT_MAIL_RCPT_ALLOWFAILS.md CURLOPT_MAXAGE_CONN.md CURLOPT_MAXCONNECTS.md CURLOPT_MAXFILESIZE.md CURLOPT_MAXFILESIZE_LARGE.md CURLOPT_MAXLIFETIME_CONN.md CURLOPT_MAXREDIRS.md CURLOPT_MAX_RECV_SPEED_LARGE.md CURLOPT_MAX_SEND_SPEED_LARGE.md CURLOPT_MIMEPOST.md CURLOPT_MIME_OPTIONS.md CURLOPT_NETRC.md CURLOPT_NETRC_FILE.md CURLOPT_NEW_DIRECTORY_PERMS.md CURLOPT_NEW_FILE_PERMS.md CURLOPT_NOBODY.md CURLOPT_NOPROGRESS.md CURLOPT_NOPROXY.md CURLOPT_NOSIGNAL.md CURLOPT_OPENSOCKETDATA.md CURLOPT_OPENSOCKETFUNCTION.md CURLOPT_PASSWORD.md CURLOPT_PATH_AS_IS.md CURLOPT_PINNEDPUBLICKEY.md CURLOPT_PIPEWAIT.md CURLOPT_PORT.md CURLOPT_POST.md CURLOPT_POSTFIELDS.md CURLOPT_POSTFIELDSIZE.md CURLOPT_POSTFIELDSIZE_LARGE.md CURLOPT_POSTQUOTE.md CURLOPT_POSTREDIR.md CURLOPT_PREQUOTE.md CURLOPT_PREREQDATA.md CURLOPT_PREREQFUNCTION.md CURLOPT_PRE_PROXY.md CURLOPT_PRIVATE.md CURLOPT_PROGRESSDATA.md CURLOPT_PROGRESSFUNCTION.md CURLOPT_PROTOCOLS.md CURLOPT_PROTOCOLS_STR.md CURLOPT_PROXY.md CURLOPT_PROXYAUTH.md CURLOPT_PROXYHEADER.md CURLOPT_PROXYPASSWORD.md CURLOPT_PROXYPORT.md CURLOPT_PROXYTYPE.md CURLOPT_PROXYUSERNAME.md CURLOPT_PROXYUSERPWD.md CURLOPT_PROXY_CAINFO.md CURLOPT_PROXY_CAINFO_BLOB.md CURLOPT_PROXY_CAPATH.md CURLOPT_PROXY_CRLFILE.md CURLOPT_PROXY_ISSUERCERT.md CURLOPT_PROXY_ISSUERCERT_BLOB.md CURLOPT_PROXY_KEYPASSWD.md CURLOPT_PROXY_PINNEDPUBLICKEY.md CURLOPT_PROXY_SERVICE_NAME.md CURLOPT_PROXY_SSLCERT.md CURLOPT_PROXY_SSLCERTTYPE.md CURLOPT_PROXY_SSLCERT_BLOB.md CURLOPT_PROXY_SSLKEY.md CURLOPT_PROXY_SSLKEYTYPE.md CURLOPT_PROXY_SSLKEY_BLOB.md CURLOPT_PROXY_SSLVERSION.md CURLOPT_PROXY_SSL_CIPHER_LIST.md CURLOPT_PROXY_SSL_OPTIONS.md CURLOPT_PROXY_SSL_VERIFYHOST.md CURLOPT_PROXY_SSL_VERIFYPEER.md CURLOPT_PROXY_TLS13_CIPHERS.md CURLOPT_PROXY_TLSAUTH_PASSWORD.md CURLOPT_PROXY_TLSAUTH_TYPE.md CURLOPT_PROXY_TLSAUTH_USERNAME.md CURLOPT_PROXY_TRANSFER_MODE.md CURLOPT_PUT.md CURLOPT_QUICK_EXIT.md CURLOPT_QUOTE.md CURLOPT_RANDOM_FILE.md CURLOPT_RANGE.md CURLOPT_READDATA.md CURLOPT_READFUNCTION.md CURLOPT_REDIR_PROTOCOLS.md CURLOPT_REDIR_PROTOCOLS_STR.md CURLOPT_REFERER.md CURLOPT_REQUEST_TARGET.md CURLOPT_RESOLVE.md CURLOPT_RESOLVER_START_DATA.md CURLOPT_RESOLVER_START_FUNCTION.md CURLOPT_RESUME_FROM.md CURLOPT_RESUME_FROM_LARGE.md CURLOPT_RTSP_CLIENT_CSEQ.md CURLOPT_RTSP_REQUEST.md CURLOPT_RTSP_SERVER_CSEQ.md CURLOPT_RTSP_SESSION_ID.md CURLOPT_RTSP_STREAM_URI.md CURLOPT_RTSP_TRANSPORT.md CURLOPT_SASL_AUTHZID.md CURLOPT_SASL_IR.md CURLOPT_SEEKDATA.md CURLOPT_SEEKFUNCTION.md CURLOPT_SERVER_RESPONSE_TIMEOUT.md CURLOPT_SERVER_RESPONSE_TIMEOUT_MS.md CURLOPT_SERVICE_NAME.md CURLOPT_SHARE.md CURLOPT_SOCKOPTDATA.md CURLOPT_SOCKOPTFUNCTION.md CURLOPT_SOCKS5_AUTH.md CURLOPT_SOCKS5_GSSAPI_NEC.md CURLOPT_SOCKS5_GSSAPI_SERVICE.md CURLOPT_SSH_AUTH_TYPES.md CURLOPT_SSH_COMPRESSION.md CURLOPT_SSH_HOSTKEYDATA.md CURLOPT_SSH_HOSTKEYFUNCTION.md CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md CURLOPT_SSH_KEYDATA.md CURLOPT_SSH_KEYFUNCTION.md CURLOPT_SSH_KNOWNHOSTS.md CURLOPT_SSH_PRIVATE_KEYFILE.md CURLOPT_SSH_PUBLIC_KEYFILE.md CURLOPT_SSLCERT.md CURLOPT_SSLCERTTYPE.md CURLOPT_SSLCERT_BLOB.md CURLOPT_SSLENGINE.md CURLOPT_SSLENGINE_DEFAULT.md CURLOPT_SSLKEY.md CURLOPT_SSLKEYTYPE.md CURLOPT_SSLKEY_BLOB.md CURLOPT_SSLVERSION.md CURLOPT_SSL_CIPHER_LIST.md CURLOPT_SSL_CTX_DATA.md CURLOPT_SSL_CTX_FUNCTION.md CURLOPT_SSL_EC_CURVES.md CURLOPT_SSL_ENABLE_ALPN.md CURLOPT_SSL_ENABLE_NPN.md CURLOPT_SSL_FALSESTART.md CURLOPT_SSL_OPTIONS.md CURLOPT_SSL_SESSIONID_CACHE.md CURLOPT_SSL_SIGNATURE_ALGORITHMS.md CURLOPT_SSL_VERIFYHOST.md CURLOPT_SSL_VERIFYPEER.md CURLOPT_SSL_VERIFYSTATUS.md CURLOPT_STDERR.md CURLOPT_STREAM_DEPENDS.md CURLOPT_STREAM_DEPENDS_E.md CURLOPT_STREAM_WEIGHT.md CURLOPT_SUPPRESS_CONNECT_HEADERS.md CURLOPT_TCP_FASTOPEN.md CURLOPT_TCP_KEEPALIVE.md CURLOPT_TCP_KEEPCNT.md CURLOPT_TCP_KEEPIDLE.md CURLOPT_TCP_KEEPINTVL.md CURLOPT_TCP_NODELAY.md CURLOPT_TELNETOPTIONS.md CURLOPT_TFTP_BLKSIZE.md CURLOPT_TFTP_NO_OPTIONS.md CURLOPT_TIMECONDITION.md CURLOPT_TIMEOUT.md CURLOPT_TIMEOUT_MS.md CURLOPT_TIMEVALUE.md CURLOPT_TIMEVALUE_LARGE.md CURLOPT_TLS13_CIPHERS.md CURLOPT_TLSAUTH_PASSWORD.md CURLOPT_TLSAUTH_TYPE.md CURLOPT_TLSAUTH_USERNAME.md CURLOPT_TRAILERDATA.md CURLOPT_TRAILERFUNCTION.md CURLOPT_TRANSFERTEXT.md CURLOPT_TRANSFER_ENCODING.md CURLOPT_UNIX_SOCKET_PATH.md CURLOPT_UNRESTRICTED_AUTH.md CURLOPT_UPKEEP_INTERVAL_MS.md CURLOPT_UPLOAD.md CURLOPT_UPLOAD_BUFFERSIZE.md CURLOPT_UPLOAD_FLAGS.md CURLOPT_URL.md CURLOPT_USERAGENT.md CURLOPT_USERNAME.md CURLOPT_USERPWD.md CURLOPT_USE_SSL.md CURLOPT_VERBOSE.md CURLOPT_WILDCARDMATCH.md CURLOPT_WRITEDATA.md CURLOPT_WRITEFUNCTION.md CURLOPT_WS_OPTIONS.md CURLOPT_XFERINFODATA.md CURLOPT_XFERINFOFUNCTION.md CURLOPT_XOAUTH2_BEARER.md CURLSHOPT_LOCKFUNC.md CURLSHOPT_SHARE.md CURLSHOPT_UNLOCKFUNC.md CURLSHOPT_UNSHARE.md CURLSHOPT_USERDATA.md Makefile.am Makefile.inc
.gitignore ABI.md CMakeLists.txt Makefile.am Makefile.inc curl_easy_cleanup.md curl_easy_duphandle.md curl_easy_escape.md curl_easy_getinfo.md curl_easy_header.md curl_easy_init.md curl_easy_nextheader.md curl_easy_option_by_id.md curl_easy_option_by_name.md curl_easy_option_next.md curl_easy_pause.md curl_easy_perform.md curl_easy_recv.md curl_easy_reset.md curl_easy_send.md curl_easy_setopt.md curl_easy_ssls_export.md curl_easy_ssls_import.md curl_easy_strerror.md curl_easy_unescape.md curl_easy_upkeep.md curl_escape.md curl_formadd.md curl_formfree.md curl_formget.md curl_free.md curl_getdate.md curl_getenv.md curl_global_cleanup.md curl_global_init.md curl_global_init_mem.md curl_global_sslset.md curl_global_trace.md curl_mime_addpart.md curl_mime_data.md curl_mime_data_cb.md curl_mime_encoder.md curl_mime_filedata.md curl_mime_filename.md curl_mime_free.md curl_mime_headers.md curl_mime_init.md curl_mime_name.md curl_mime_subparts.md curl_mime_type.md curl_mprintf.md curl_multi_add_handle.md curl_multi_assign.md curl_multi_cleanup.md curl_multi_fdset.md curl_multi_get_handles.md curl_multi_get_offt.md curl_multi_info_read.md curl_multi_init.md curl_multi_notify_disable.md curl_multi_notify_enable.md curl_multi_perform.md curl_multi_poll.md curl_multi_remove_handle.md curl_multi_setopt.md curl_multi_socket.md curl_multi_socket_action.md curl_multi_socket_all.md curl_multi_strerror.md curl_multi_timeout.md curl_multi_wait.md curl_multi_waitfds.md curl_multi_wakeup.md curl_pushheader_byname.md curl_pushheader_bynum.md curl_share_cleanup.md curl_share_init.md curl_share_setopt.md curl_share_strerror.md curl_slist_append.md curl_slist_free_all.md curl_strequal.md curl_strnequal.md curl_unescape.md curl_url.md curl_url_cleanup.md curl_url_dup.md curl_url_get.md curl_url_set.md curl_url_strerror.md curl_version.md curl_version_info.md curl_ws_meta.md curl_ws_recv.md curl_ws_send.md curl_ws_start_frame.md libcurl-easy.md libcurl-env-dbg.md libcurl-env.md libcurl-errors.md libcurl-multi.md libcurl-security.md libcurl-share.md libcurl-thread.md libcurl-tutorial.md libcurl-url.md libcurl-ws.md libcurl.m4 libcurl.md mksymbolsmanpage.pl symbols-in-versions symbols.pl
tests CI.md FILEFORMAT.md HTTP.md TEST-SUITE.md
.gitignore ALTSVC.md BINDINGS.md BUG-BOUNTY.md BUGS.md CIPHERS-TLS12.md CIPHERS.md CMakeLists.txt CODE_OF_CONDUCT.md CODE_REVIEW.md CONTRIBUTE.md CURL-DISABLE.md CURLDOWN.md DEPRECATE.md DISTROS.md EARLY-RELEASE.md ECH.md EXPERIMENTAL.md FAQ.md FEATURES.md GOVERNANCE.md HELP-US.md HISTORY.md HSTS.md HTTP-COOKIES.md HTTP3.md HTTPSRR.md INFRASTRUCTURE.md INSTALL-CMAKE.md INSTALL.md INTERNALS.md IPFS.md KNOWN_BUGS.md KNOWN_RISKS.md MAIL-ETIQUETTE.md MANUAL.md Makefile.am README.md RELEASE-PROCEDURE.md ROADMAP.md RUSTLS.md SECURITY-ADVISORY.md SPONSORS.md SSL-PROBLEMS.md SSLCERTS.md THANKS THANKS-filter TODO.md TheArtOfHttpScripting.md URL-SYNTAX.md VERIFY.md VERSIONS.md VULN-DISCLOSURE-POLICY.md curl-config.md mk-ca-bundle.md options-in-versions runtests.md testcurl.md wcurl.md
include
curl Makefile.am curl.h curlver.h easy.h header.h mprintf.h multi.h options.h stdcheaders.h system.h typecheck-gcc.h urlapi.h websockets.h
Makefile.am README.md
lib
curlx base64.c base64.h basename.c basename.h dynbuf.c dynbuf.h fopen.c fopen.h inet_ntop.c inet_ntop.h inet_pton.c inet_pton.h multibyte.c multibyte.h nonblock.c nonblock.h snprintf.c snprintf.h strcopy.c strcopy.h strdup.c strdup.h strerr.c strerr.h strparse.c strparse.h timediff.c timediff.h timeval.c timeval.h version_win32.c version_win32.h wait.c wait.h warnless.c warnless.h winapi.c winapi.h
vauth cleartext.c cram.c digest.c digest.h digest_sspi.c gsasl.c krb5_gssapi.c krb5_sspi.c ntlm.c ntlm_sspi.c oauth2.c spnego_gssapi.c spnego_sspi.c vauth.c vauth.h
vquic curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.h
vssh libssh.c libssh2.c ssh.h vssh.c vssh.h
vtls apple.c apple.h cipher_suite.c cipher_suite.h gtls.c gtls.h hostcheck.c hostcheck.h keylog.c keylog.h mbedtls.c mbedtls.h openssl.c openssl.h rustls.c rustls.h schannel.c schannel.h schannel_int.h schannel_verify.c vtls.c vtls.h vtls_int.h vtls_scache.c vtls_scache.h vtls_spack.c vtls_spack.h wolfssl.c wolfssl.h x509asn1.c x509asn1.h
.gitignore CMakeLists.txt Makefile.am Makefile.inc Makefile.soname altsvc.c altsvc.h amigaos.c amigaos.h arpa_telnet.h asyn-ares.c asyn-base.c asyn-thrdd.c asyn.h bufq.c bufq.h bufref.c bufref.h cf-dns.c cf-dns.h cf-h1-proxy.c cf-h1-proxy.h cf-h2-proxy.c cf-h2-proxy.h cf-haproxy.c cf-haproxy.h cf-https-connect.c cf-https-connect.h cf-ip-happy.c cf-ip-happy.h cf-socket.c cf-socket.h cfilters.c cfilters.h config-mac.h config-os400.h config-riscos.h config-win32.h conncache.c conncache.h connect.c connect.h content_encoding.c content_encoding.h cookie.c cookie.h creds.c creds.h cshutdn.c cshutdn.h curl_addrinfo.c curl_addrinfo.h curl_config-cmake.h.in curl_ctype.h curl_endian.c curl_endian.h curl_fnmatch.c curl_fnmatch.h curl_fopen.c curl_fopen.h curl_get_line.c curl_get_line.h curl_gethostname.c curl_gethostname.h curl_gssapi.c curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memrchr.c curl_memrchr.h curl_ntlm_core.c curl_ntlm_core.h curl_printf.h curl_range.c curl_range.h curl_sasl.c curl_sasl.h curl_setup.h curl_sha256.h curl_sha512_256.c curl_sha512_256.h curl_share.c curl_share.h curl_sspi.c curl_sspi.h curl_threads.c curl_threads.h curl_trc.c curl_trc.h cw-out.c cw-out.h cw-pause.c cw-pause.h dict.c dict.h dllmain.c dnscache.c dnscache.h doh.c doh.h dynhds.c dynhds.h easy.c easy_lock.h easygetopt.c easyif.h easyoptions.c easyoptions.h escape.c escape.h fake_addrinfo.c fake_addrinfo.h file.c file.h fileinfo.c fileinfo.h formdata.c formdata.h ftp-int.h ftp.c ftp.h ftplistparser.c ftplistparser.h functypes.h getenv.c getinfo.c getinfo.h gopher.c gopher.h hash.c hash.h headers.c headers.h hmac.c hostip.c hostip.h hostip4.c hostip6.c hsts.c hsts.h http.c http.h http1.c http1.h http2.c http2.h http_aws_sigv4.c http_aws_sigv4.h http_chunks.c http_chunks.h http_digest.c http_digest.h http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h http_proxy.c http_proxy.h httpsrr.c httpsrr.h idn.c idn.h if2ip.c if2ip.h imap.c imap.h ldap.c libcurl.def libcurl.rc libcurl.vers.in llist.c llist.h macos.c macos.h md4.c md5.c memdebug.c mime.c mime.h mprintf.c mqtt.c mqtt.h multi.c multi_ev.c multi_ev.h multi_ntfy.c multi_ntfy.h multihandle.h multiif.h netrc.c netrc.h noproxy.c noproxy.h openldap.c optiontable.pl parsedate.c parsedate.h peer.c peer.h pingpong.c pingpong.h pop3.c pop3.h progress.c progress.h protocol.c protocol.h psl.c psl.h rand.c rand.h ratelimit.c ratelimit.h request.c request.h rtsp.c rtsp.h select.c select.h sendf.c sendf.h setopt.c setopt.h setup-os400.h setup-vms.h setup-win32.h sha256.c sigpipe.h slist.c slist.h smb.c smb.h smtp.c smtp.h sockaddr.h socketpair.c socketpair.h socks.c socks.h socks_gssapi.c socks_sspi.c splay.c splay.h strcase.c strcase.h strequal.c strerror.c strerror.h system_win32.c system_win32.h telnet.c telnet.h tftp.c tftp.h thrdpool.c thrdpool.h thrdqueue.c thrdqueue.h transfer.c transfer.h uint-bset.c uint-bset.h uint-hash.c uint-hash.h uint-spbset.c uint-spbset.h uint-table.c uint-table.h url.c url.h urlapi-int.h urlapi.c urldata.h version.c ws.c ws.h
m4 .gitignore curl-amissl.m4 curl-apple-sectrust.m4 curl-compilers.m4 curl-confopts.m4 curl-functions.m4 curl-gnutls.m4 curl-mbedtls.m4 curl-openssl.m4 curl-override.m4 curl-reentrant.m4 curl-rustls.m4 curl-schannel.m4 curl-sysconfig.m4 curl-wolfssl.m4 xc-am-iface.m4 xc-cc-check.m4 xc-lt-iface.m4 xc-val-flgs.m4 zz40-xc-ovr.m4 zz50-xc-ovr.m4
projects
OS400
rpg-examples HEADERAPI HTTPPOST INMEMORY SIMPLE1 SIMPLE2 SMTPSRCMBR
.checksrc README.OS400 ccsidcurl.c ccsidcurl.h config400.default curl.cmd curl.inc.in curlcl.c curlmain.c initscript.sh make-docs.sh make-include.sh make-lib.sh make-src.sh make-tests.sh makefile.sh os400sys.c os400sys.h
Windows
tmpl .gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filters
.gitignore README.md generate.bat
vms Makefile.am backup_gnv_curl_src.com build_curl-config_script.com build_gnv_curl.com build_gnv_curl_pcsi_desc.com build_gnv_curl_pcsi_text.com build_gnv_curl_release_notes.com build_libcurl_pc.com build_vms.com clean_gnv_curl.com compare_curl_source.com config_h.com curl_crtl_init.c curl_gnv_build_steps.txt curl_release_note_start.txt curl_startup.com curlmsg.h curlmsg.msg curlmsg.sdl curlmsg_vms.h generate_config_vms_h_curl.com generate_vax_transfer.com gnv_conftest.c_first gnv_curl_configure.sh gnv_libcurl_symbols.opt gnv_link_curl.com macro32_exactcase.patch make_gnv_curl_install.sh make_pcsi_curl_kit_name.com pcsi_gnv_curl_file_list.txt pcsi_product_gnv_curl.com readme report_openssl_version.c setup_gnv_curl_build.com stage_curl_install.com vms_eco_level.h
Makefile.am README.md
scripts .checksrc CMakeLists.txt Makefile.am badwords badwords-all badwords.txt cd2cd cd2nroff cdall checksrc-all.pl checksrc.pl cmakelint.sh completion.pl contributors.sh contrithanks.sh coverage.sh delta dmaketgz extract-unit-protos firefox-db2pem.sh installcheck.sh maketgz managen mdlinkcheck mk-ca-bundle.pl mk-unity.pl nroff2cd perlcheck.sh pythonlint.sh randdisable release-notes.pl release-tools.sh schemetable.c singleuse.pl spacecheck.pl top-complexity top-length verify-release wcurl
src
toolx tool_time.c tool_time.h
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc config2setopts.c config2setopts.h curl.rc curlinfo.c mk-file-embed.pl mkhelp.pl slist_wc.c slist_wc.h terminal.c terminal.h tool_cb_dbg.c tool_cb_dbg.h tool_cb_hdr.c tool_cb_hdr.h tool_cb_prg.c tool_cb_prg.h tool_cb_rea.c tool_cb_rea.h tool_cb_see.c tool_cb_see.h tool_cb_soc.c tool_cb_soc.h tool_cb_wrt.c tool_cb_wrt.h tool_cfgable.c tool_cfgable.h tool_dirhie.c tool_dirhie.h tool_doswin.c tool_doswin.h tool_easysrc.c tool_easysrc.h tool_filetime.c tool_filetime.h tool_findfile.c tool_findfile.h tool_formparse.c tool_formparse.h tool_getparam.c tool_getparam.h tool_getpass.c tool_getpass.h tool_help.c tool_help.h tool_helpers.c tool_helpers.h tool_hugehelp.h tool_ipfs.c tool_ipfs.h tool_libinfo.c tool_libinfo.h tool_listhelp.c tool_main.c tool_main.h tool_msgs.c tool_msgs.h tool_operate.c tool_operate.h tool_operhlp.c tool_operhlp.h tool_paramhlp.c tool_paramhlp.h tool_parsecfg.c tool_parsecfg.h tool_progress.c tool_progress.h tool_sdecls.h tool_setopt.c tool_setopt.h tool_setup.h tool_ssls.c tool_ssls.h tool_stderr.c tool_stderr.h tool_urlglob.c tool_urlglob.h tool_util.c tool_util.h tool_version.h tool_vms.c tool_vms.h tool_writeout.c tool_writeout.h tool_writeout_json.c tool_writeout_json.h tool_xattr.c tool_xattr.h var.c var.h
tests
certs .gitignore CMakeLists.txt Makefile.am Makefile.inc genserv.pl srp-verifier-conf srp-verifier-db test-ca.cnf test-ca.prm test-client-cert.prm test-client-eku-only.prm test-localhost-san-first.prm test-localhost-san-last.prm test-localhost.nn.prm test-localhost.prm test-localhost0h.prm
cmake CMakeLists.txt test.c test.cpp test.sh
data .gitignore DISABLED Makefile.am data-xml1 data1400.c data1401.c data1402.c data1403.c data1404.c data1405.c data1406.c data1407.c data1420.c data1461.txt data1463.txt data1465.c data1481.c data1705-1.md data1705-2.md data1705-3.md data1705-4.md data1705-stdout.1 data1706-1.md data1706-2.md data1706-3.md data1706-4.md data1706-stdout.txt data320.html test1 test10 test100 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 test1008 test1009 test101 test1010 test1011 test1012 test1013 test1014 test1015 test1016 test1017 test1018 test1019 test102 test1020 test1021 test1022 test1023 test1024 test1025 test1026 test1027 test1028 test1029 test103 test1030 test1031 test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 test104 test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 test1048 test1049 test105 test1050 test1051 test1052 test1053 test1054 test1055 test1056 test1057 test1058 test1059 test106 test1060 test1061 test1062 test1063 test1064 test1065 test1066 test1067 test1068 test1069 test107 test1070 test1071 test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 test108 test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 test1088 test1089 test109 test1090 test1091 test1092 test1093 test1094 test1095 test1096 test1097 test1098 test1099 test11 test110 test1100 test1101 test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 test111 test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 test112 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 test1128 test1129 test113 test1130 test1131 test1132 test1133 test1134 test1135 test1136 test1137 test1138 test1139 test114 test1140 test1141 test1142 test1143 test1144 test1145 test1146 test1147 test1148 test1149 test115 test1150 test1151 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 test116 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 test1168 test1169 test117 test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 test1178 test1179 test118 test1180 test1181 test1182 test1183 test1184 test1185 test1186 test1187 test1188 test1189 test119 test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 test1199 test12 test120 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 test1208 test1209 test121 test1210 test1211 test1212 test1213 test1214 test1215 test1216 test1217 test1218 test1219 test122 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 test1228 test1229 test123 test1230 test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 test124 test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 test1248 test1249 test125 test1250 test1251 test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 test126 test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 test1268 test1269 test127 test1270 test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 test1279 test128 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 test1288 test1289 test129 test1290 test1291 test1292 test1293 test1294 test1295 test1296 test1297 test1298 test1299 test13 test130 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 test1309 test131 test1310 test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 test132 test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 test133 test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 test134 test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 test1348 test1349 test135 test1350 test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 test136 test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 test137 test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 test138 test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 test1388 test1389 test139 test1390 test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 test14 test140 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 test141 test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 test1418 test1419 test142 test1420 test1421 test1422 test1423 test1424 test1425 test1426 test1427 test1428 test1429 test143 test1430 test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 test144 test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 test145 test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 test146 test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 test1468 test1469 test147 test1470 test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 test1479 test148 test1480 test1481 test1482 test1483 test1484 test1485 test1486 test1487 test1488 test1489 test149 test1490 test1491 test1492 test1493 test1494 test1495 test1496 test1497 test1498 test1499 test15 test150 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 test1508 test1509 test151 test1510 test1511 test1512 test1513 test1514 test1515 test1516 test1517 test1518 test1519 test152 test1520 test1521 test1522 test1523 test1524 test1525 test1526 test1527 test1528 test1529 test153 test1530 test1531 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 test154 test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 test1548 test1549 test155 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 test1558 test1559 test156 test1560 test1561 test1562 test1563 test1564 test1565 test1566 test1567 test1568 test1569 test157 test1570 test1571 test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 test158 test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 test1589 test159 test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 test1598 test1599 test16 test160 test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 test1608 test1609 test161 test1610 test1611 test1612 test1613 test1614 test1615 test1616 test1617 test1618 test1619 test162 test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 test163 test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 test1638 test1639 test164 test1640 test1641 test1642 test1643 test1644 test1645 test165 test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 test1658 test1659 test166 test1660 test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 test1669 test167 test1670 test1671 test1672 test1673 test1674 test1675 test1676 test168 test1680 test1681 test1682 test1683 test1684 test1685 test169 test17 test170 test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 test1708 test1709 test171 test1710 test1711 test1712 test1713 test1714 test1715 test172 test1720 test1721 test173 test174 test175 test176 test177 test178 test179 test18 test180 test1800 test1801 test1802 test181 test182 test183 test184 test1847 test1848 test1849 test185 test1850 test1851 test186 test187 test188 test189 test19 test190 test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 test1908 test1909 test191 test1910 test1911 test1912 test1913 test1914 test1915 test1916 test1917 test1918 test1919 test192 test1920 test1921 test193 test1933 test1934 test1935 test1936 test1937 test1938 test1939 test194 test1940 test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 test195 test1955 test1956 test1957 test1958 test1959 test196 test1960 test1964 test1965 test1966 test197 test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 test1978 test1979 test198 test1980 test1981 test1982 test1983 test1984 test199 test2 test20 test200 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 test2008 test2009 test201 test2010 test2011 test2012 test2013 test2014 test202 test2023 test2024 test2025 test2026 test2027 test2028 test2029 test203 test2030 test2031 test2032 test2033 test2034 test2035 test2037 test2038 test2039 test204 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 test2048 test2049 test205 test2050 test2051 test2052 test2053 test2054 test2055 test2056 test2057 test2058 test2059 test206 test2060 test2061 test2062 test2063 test2064 test2065 test2066 test2067 test2068 test2069 test207 test2070 test2071 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 test208 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 test2088 test2089 test209 test2090 test2091 test2092 test21 test210 test2100 test2101 test2102 test2103 test2104 test211 test212 test213 test214 test215 test216 test217 test218 test219 test22 test220 test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 test221 test222 test223 test224 test225 test226 test227 test228 test229 test23 test230 test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 test2309 test231 test232 test233 test234 test235 test236 test237 test238 test239 test24 test240 test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 test2408 test2409 test241 test2410 test2411 test242 test243 test244 test245 test246 test247 test248 test249 test25 test250 test2500 test2501 test2502 test2503 test2504 test2505 test2506 test251 test252 test253 test254 test255 test256 test257 test258 test259 test26 test260 test2600 test2601 test2602 test2603 test2604 test2605 test261 test262 test263 test264 test265 test266 test267 test268 test269 test27 test270 test2700 test2701 test2702 test2703 test2704 test2705 test2706 test2707 test2708 test2709 test271 test2710 test2711 test2712 test2713 test2714 test2715 test2716 test2717 test2718 test2719 test272 test2720 test2721 test2722 test2723 test273 test274 test275 test276 test277 test278 test279 test28 test280 test281 test282 test283 test284 test285 test286 test287 test288 test289 test29 test290 test291 test292 test293 test294 test295 test296 test297 test298 test299 test3 test30 test300 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 test3008 test3009 test301 test3010 test3011 test3012 test3013 test3014 test3015 test3016 test3017 test3018 test3019 test302 test3020 test3021 test3022 test3023 test3024 test3025 test3026 test3027 test3028 test3029 test303 test3030 test3031 test3032 test3033 test3034 test3035 test3036 test304 test305 test306 test307 test308 test309 test31 test310 test3100 test3101 test3102 test3103 test3104 test3105 test3106 test311 test312 test313 test314 test315 test316 test317 test318 test319 test32 test320 test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 test3209 test321 test3210 test3211 test3212 test3213 test3214 test3215 test3216 test3217 test3218 test3219 test322 test3220 test323 test324 test325 test326 test327 test328 test329 test33 test330 test3300 test3301 test3302 test331 test332 test333 test334 test335 test336 test337 test338 test339 test34 test340 test341 test342 test343 test344 test345 test346 test347 test348 test349 test35 test350 test351 test352 test353 test354 test355 test356 test357 test358 test359 test36 test360 test361 test362 test363 test364 test365 test366 test367 test368 test369 test37 test370 test371 test372 test373 test374 test375 test376 test378 test379 test38 test380 test381 test383 test384 test385 test386 test387 test388 test389 test39 test390 test391 test392 test393 test394 test395 test396 test397 test398 test399 test4 test40 test400 test4000 test4001 test401 test402 test403 test404 test405 test406 test407 test408 test409 test41 test410 test411 test412 test413 test414 test415 test416 test417 test418 test419 test42 test420 test421 test422 test423 test424 test425 test426 test427 test428 test429 test43 test430 test431 test432 test433 test434 test435 test436 test437 test438 test439 test44 test440 test441 test442 test443 test444 test445 test446 test447 test448 test449 test45 test450 test451 test452 test453 test454 test455 test456 test457 test458 test459 test46 test460 test461 test462 test463 test467 test468 test469 test47 test470 test471 test472 test473 test474 test475 test476 test477 test478 test479 test48 test480 test481 test482 test483 test484 test485 test486 test487 test488 test489 test49 test490 test491 test492 test493 test494 test495 test496 test497 test498 test499 test5 test50 test500 test501 test502 test503 test504 test505 test506 test507 test508 test509 test51 test510 test511 test512 test513 test514 test515 test516 test517 test518 test519 test52 test520 test521 test522 test523 test524 test525 test526 test527 test528 test529 test53 test530 test531 test532 test533 test534 test535 test536 test537 test538 test539 test54 test540 test541 test542 test543 test544 test545 test546 test547 test548 test549 test55 test550 test551 test552 test553 test554 test555 test556 test557 test558 test559 test56 test560 test561 test562 test563 test564 test565 test566 test567 test568 test569 test57 test570 test571 test572 test573 test574 test575 test576 test577 test578 test579 test58 test580 test581 test582 test583 test584 test585 test586 test587 test588 test589 test59 test590 test591 test592 test593 test594 test595 test596 test597 test598 test599 test6 test60 test600 test601 test602 test603 test604 test605 test606 test607 test608 test609 test61 test610 test611 test612 test613 test614 test615 test616 test617 test618 test619 test62 test620 test621 test622 test623 test624 test625 test626 test627 test628 test629 test63 test630 test631 test632 test633 test634 test635 test636 test637 test638 test639 test64 test640 test641 test642 test643 test644 test645 test646 test647 test648 test649 test65 test650 test651 test652 test653 test654 test655 test656 test658 test659 test66 test660 test661 test662 test663 test664 test665 test666 test667 test668 test669 test67 test670 test671 test672 test673 test674 test675 test676 test677 test678 test679 test68 test680 test681 test682 test683 test684 test685 test686 test687 test688 test689 test69 test690 test691 test692 test693 test694 test695 test696 test697 test698 test699 test7 test70 test700 test701 test702 test703 test704 test705 test706 test707 test708 test709 test71 test710 test711 test712 test713 test714 test715 test716 test717 test718 test719 test72 test720 test721 test722 test723 test724 test725 test726 test727 test728 test729 test73 test730 test731 test732 test733 test734 test735 test736 test737 test738 test739 test74 test740 test741 test742 test743 test744 test745 test746 test747 test748 test749 test75 test750 test751 test752 test753 test754 test755 test756 test757 test758 test759 test76 test760 test761 test762 test763 test764 test765 test766 test767 test768 test769 test77 test770 test771 test772 test773 test774 test775 test776 test777 test778 test779 test78 test780 test781 test782 test783 test784 test785 test786 test787 test788 test789 test79 test790 test791 test792 test793 test794 test795 test796 test797 test798 test799 test8 test80 test800 test801 test802 test803 test804 test805 test806 test807 test808 test809 test81 test810 test811 test812 test813 test814 test815 test816 test817 test818 test819 test82 test820 test821 test822 test823 test824 test825 test826 test827 test828 test829 test83 test830 test831 test832 test833 test834 test835 test836 test837 test838 test839 test84 test840 test841 test842 test843 test844 test845 test846 test847 test848 test849 test85 test850 test851 test852 test853 test854 test855 test856 test857 test858 test859 test86 test860 test861 test862 test863 test864 test865 test866 test867 test868 test869 test87 test870 test871 test872 test873 test874 test875 test876 test877 test878 test879 test88 test880 test881 test882 test883 test884 test885 test886 test887 test888 test889 test89 test890 test891 test892 test893 test894 test895 test896 test897 test898 test899 test9 test90 test900 test901 test902 test903 test904 test905 test906 test907 test908 test909 test91 test910 test911 test912 test913 test914 test915 test916 test917 test918 test919 test92 test920 test921 test922 test923 test924 test925 test926 test927 test928 test929 test93 test930 test931 test932 test933 test934 test935 test936 test937 test938 test939 test94 test940 test941 test942 test943 test944 test945 test946 test947 test948 test949 test95 test950 test951 test952 test953 test954 test955 test956 test957 test958 test959 test96 test960 test961 test962 test963 test964 test965 test966 test967 test968 test969 test97 test970 test971 test972 test973 test974 test975 test976 test977 test978 test979 test98 test980 test981 test982 test983 test984 test985 test986 test987 test988 test989 test99 test990 test991 test992 test993 test994 test995 test996 test997 test998 test999
http
testenv
mod_curltest .gitignore mod_curltest.c
__init__.py caddy.py certs.py client.py curl.py dante.py dnsd.py env.py httpd.py nghttpx.py ports.py sshd.py vsftpd.py ws_echo_server.py
.gitignore CMakeLists.txt Makefile.am config.ini.in conftest.py requirements.txt scorecard.py test_01_basic.py test_02_download.py test_03_goaway.py test_04_stuttered.py test_05_errors.py test_06_eyeballs.py test_07_upload.py test_08_caddy.py test_09_push.py test_10_proxy.py test_11_unix.py test_12_reuse.py test_13_proxy_auth.py test_14_auth.py test_15_tracing.py test_16_info.py test_17_ssl_use.py test_18_methods.py test_19_shutdown.py test_20_websockets.py test_21_resolve.py test_22_httpsrr.py test_30_vsftpd.py test_31_vsftpds.py test_32_ftps_vsftpd.py test_40_socks.py test_50_scp.py test_51_sftp.py
libtest .gitignore CMakeLists.txt Makefile.am Makefile.inc cli_ftp_upload.c cli_h2_pausing.c cli_h2_serverpush.c cli_h2_upgrade_extreme.c cli_hx_download.c cli_hx_upload.c cli_tls_session_reuse.c cli_upload_pausing.c cli_ws_data.c cli_ws_pingpong.c first.c first.h lib1156.c lib1301.c lib1308.c lib1485.c lib1500.c lib1501.c lib1502.c lib1506.c lib1507.c lib1508.c lib1509.c lib1510.c lib1511.c lib1512.c lib1513.c lib1514.c lib1515.c lib1517.c lib1518.c lib1520.c lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c lib1545.c lib1549.c lib1550.c lib1551.c lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c lib1559.c lib1560.c lib1564.c lib1565.c lib1567.c lib1568.c lib1569.c lib1571.c lib1576.c lib1582.c lib1587.c lib1588.c lib1589.c lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c lib1598.c lib1599.c lib1662.c lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c lib1933.c lib1934.c lib1935.c lib1936.c lib1937.c lib1938.c lib1939.c lib1940.c lib1945.c lib1947.c lib1948.c lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c lib1964.c lib1965.c lib1970.c lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c lib2023.c lib2032.c lib2082.c lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c lib2402.c lib2404.c lib2405.c lib2502.c lib2504.c lib2505.c lib2506.c lib2700.c lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c lib3207.c lib3208.c lib500.c lib501.c lib502.c lib503.c lib504.c lib505.c lib506.c lib507.c lib508.c lib509.c lib510.c lib511.c lib512.c lib513.c lib514.c lib515.c lib516.c lib517.c lib518.c lib519.c lib520.c lib521.c lib523.c lib524.c lib525.c lib526.c lib530.c lib533.c lib536.c lib537.c lib539.c lib540.c lib541.c lib542.c lib543.c lib544.c lib547.c lib549.c lib552.c lib553.c lib554.c lib555.c lib556.c lib557.c lib558.c lib559.c lib560.c lib562.c lib564.c lib566.c lib567.c lib568.c lib569.c lib570.c lib571.c lib572.c lib573.c lib574.c lib575.c lib576.c lib578.c lib579.c lib582.c lib583.c lib586.c lib589.c lib590.c lib591.c lib597.c lib598.c lib599.c lib643.c lib650.c lib651.c lib652.c lib653.c lib654.c lib655.c lib658.c lib659.c lib661.c lib666.c lib667.c lib668.c lib670.c lib674.c lib676.c lib677.c lib678.c lib694.c lib695.c lib751.c lib753.c lib757.c lib758.c lib766.c memptr.c mk-lib1521.pl test1013.pl test1022.pl test307.pl test610.pl test613.pl testtrace.c testtrace.h testutil.c testutil.h unitcheck.h
server .checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc dnsd.c first.c first.h getpart.c mqttd.c resolve.c rtspd.c sockfilt.c socksd.c sws.c tftpd.c util.c
tunit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.c
unit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md unit1300.c unit1302.c unit1303.c unit1304.c unit1305.c unit1307.c unit1309.c unit1323.c unit1330.c unit1395.c unit1396.c unit1397.c unit1398.c unit1399.c unit1600.c unit1601.c unit1602.c unit1603.c unit1605.c unit1606.c unit1607.c unit1608.c unit1609.c unit1610.c unit1611.c unit1612.c unit1614.c unit1615.c unit1616.c unit1620.c unit1625.c unit1626.c unit1627.c unit1636.c unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c unit1666.c unit1667.c unit1668.c unit1669.c unit1674.c unit1675.c unit1676.c unit1979.c unit1980.c unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c unit3200.c unit3205.c unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c unit3219.c unit3300.c unit3301.c unit3302.c
.gitignore CMakeLists.txt Makefile.am allversions.pm appveyor.pm azure.pm config.in configurehelp.pm.in devtest.pl dictserver.py directories.pm ech_combos.py ech_tests.sh ftpserver.pl getpart.pm globalconfig.pm http-server.pl http2-server.pl http3-server.pl memanalyze.pl memanalyzer.pm negtelnetserver.py nghttpx.conf pathhelp.pm processhelp.pm requirements.txt rtspserver.pl runner.pm runtests.pl secureserver.pl serverhelp.pm servers.pm smbserver.py sshhelp.pm sshserver.pl test1119.pl test1135.pl test1139.pl test1140.pl test1165.pl test1167.pl test1173.pl test1175.pl test1177.pl test1222.pl test1275.pl test1276.pl test1477.pl test1486.pl test1488.pl test1544.pl test1707.pl test745.pl test971.pl testcurl.pl testutil.pm tftpserver.pl util.py valgrind.pm valgrind.supp
.clang-tidy.yml .dir-locals.el .editorconfig .git-blame-ignore-revs .gitattributes .gitignore .mailmap CHANGES.md CMakeLists.txt COPYING Dockerfile GIT-INFO.md Makefile.am README README.md RELEASE-NOTES REUSE.toml SECURITY.md acinclude.m4 appveyor.sh appveyor.yml configure.ac curl-config.in libcurl.pc.in renovate.json
examples .env config.ini crypto_test.lua env_test.lua fs_example.lua http_server.lua https_test.lua ini_example.lua json.lua log.lua path_fs_example.lua process_example.lua request_download.lua request_test.lua run_all.lua sqlite_example.lua sqlite_http_template.lua stash_test.lua template_test.lua timer.lua websocket.lua
iniparser
.github
ISSUE_TEMPLATE config.yml
workflows disable-pull-requests.yml trigger-gitlab-ci.yml
cmake JoinPaths.cmake config.cmake.in pc.in
example iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.ini
src dictionary.c dictionary.h iniparser.c iniparser.h
test
ressources
bad_ini ends_well.ini twisted-errors.ini twisted-ofkey.ini twisted-ofval.ini
good_ini empty.ini spaced.ini spaced2.ini twisted.ini
gruezi.ini old.ini quotes.ini utf8.ini
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.h
.cmake-format.py .gitignore .gitlab-ci.yml .gitmessage .travis.yml AUTHORS CMakeLists.txt FAQ-en.md FAQ-zhcn.md INSTALL LICENSE README.md compile_commands.json
jinjac
example CMakeLists.txt example.c
jinjac_test_app CMakeLists.txt jinjac_test_app.c
libjinjac
include jinjac.h
src CMakeLists.txt ast.c ast.h block_statement.c block_statement.h buffer.c buffer.h buildin.c buildin.h common.h convert.c convert.h flex_decl.h jfunction.c jfunction.h jinja_expression.l jinja_expression.y jinjac_parse.c jinjac_parse.h jinjac_stream.c jinjac_stream.h jlist.c jlist.h jobject.c jobject.h parameter.c parameter.h str_obj.c str_obj.h trace.c trace.h
CMakeLists.txt
test .gitignore CMakeLists.txt autotest.rb test_01.expected test_01.jinja test_01b.expected test_01b.jinja test_01c.expected test_01c.jinja test_01d.expected test_01d.jinja test_02.expected test_02.jinja test_03.expected test_03.jinja test_04.expected test_04.jinja test_05.expected test_05.jinja test_06.expected test_06.jinja test_07.expected test_07.jinja test_08.expected test_08.jinja test_08b.expected test_08b.jinja test_09.expected test_09.jinja test_10.expected test_10.jinja test_11.expected test_11.jinja test_12.expected test_12.jinja test_13.expected test_13.jinja test_14.expected test_14.jinja test_15.expected test_15.jinja test_16.expected test_16.jinja test_17.expected test_17.jinja test_18.expected test_18.jinja test_18b.expected test_18b.jinja test_18c.expected test_18c.jinja test_19.expected test_19.jinja test_19b.expected test_19b.jinja test_19c.expected test_19c.jinja test_19d.expected test_19d.jinja test_19e.expected test_19e.jinja test_19f.expected test_19f.jinja test_20.expected test_20.jinja test_21.expected test_21.jinja test_22.expected test_22.jinja test_22a.expected test_22a.jinja test_22b.expected test_22b.jinja test_23.expected test_23.jinja test_24.expected test_24.jinja
.gitignore CMakeLists.txt LICENSE.txt README.md build_coverage.sh build_debug.sh build_release.sh cppcheck_analysis.sh
libev Changes LICENSE Makefile Makefile.am Makefile.in README Symbols.ev Symbols.event aclocal.m4 autogen.sh compile config.guess config.h config.h.in config.status config.sub configure configure.ac depcomp ev++.h ev.3 ev.c ev.h ev.pod ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_vars.h ev_win32.c ev_wrap.h event.c event.h install-sh libev.m4 libtool ltmain.sh missing mkinstalldirs stamp-h1
luajit
doc
img contact.png
bluequad-print.css bluequad.css contact.html ext_buffer.html ext_c_api.html ext_ffi.html ext_ffi_api.html ext_ffi_semantics.html ext_ffi_tutorial.html ext_jit.html ext_profiler.html extensions.html install.html luajit.html running.html
dynasm dasm_arm.h dasm_arm.lua dasm_arm64.h dasm_arm64.lua dasm_mips.h dasm_mips.lua dasm_mips64.lua dasm_ppc.h dasm_ppc.lua dasm_proto.h dasm_x64.lua dasm_x86.h dasm_x86.lua dynasm.lua
etc luajit.1 luajit.pc
src
host .gitignore README buildvm.c buildvm.h buildvm_asm.c buildvm_fold.c buildvm_lib.c buildvm_libbc.h buildvm_peobj.c genlibbc.lua genminilua.lua genversion.lua minilua.c
jit .gitignore bc.lua bcsave.lua dis_arm.lua dis_arm64.lua dis_arm64be.lua dis_mips.lua dis_mips64.lua dis_mips64el.lua dis_mips64r6.lua dis_mips64r6el.lua dis_mipsel.lua dis_ppc.lua dis_x64.lua dis_x86.lua dump.lua p.lua v.lua zone.lua
.gitignore Makefile Makefile.dep lauxlib.h lib_aux.c lib_base.c lib_bit.c lib_buffer.c lib_debug.c lib_ffi.c lib_init.c lib_io.c lib_jit.c lib_math.c lib_os.c lib_package.c lib_string.c lib_table.c lj_alloc.c lj_alloc.h lj_api.c lj_arch.h lj_asm.c lj_asm.h lj_asm_arm.h lj_asm_arm64.h lj_asm_mips.h lj_asm_ppc.h lj_asm_x86.h lj_assert.c lj_bc.c lj_bc.h lj_bcdump.h lj_bcread.c lj_bcwrite.c lj_buf.c lj_buf.h lj_carith.c lj_carith.h lj_ccall.c lj_ccall.h lj_ccallback.c lj_ccallback.h lj_cconv.c lj_cconv.h lj_cdata.c lj_cdata.h lj_char.c lj_char.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_crecord.c lj_crecord.h lj_ctype.c lj_ctype.h lj_debug.c lj_debug.h lj_def.h lj_dispatch.c lj_dispatch.h lj_emit_arm.h lj_emit_arm64.h lj_emit_mips.h lj_emit_ppc.h lj_emit_x86.h lj_err.c lj_err.h lj_errmsg.h lj_ff.h lj_ffrecord.c lj_ffrecord.h lj_frame.h lj_func.c lj_func.h lj_gc.c lj_gc.h lj_gdbjit.c lj_gdbjit.h lj_ir.c lj_ir.h lj_ircall.h lj_iropt.h lj_jit.h lj_lex.c lj_lex.h lj_lib.c lj_lib.h lj_load.c lj_mcode.c lj_mcode.h lj_meta.c lj_meta.h lj_obj.c lj_obj.h lj_opt_dce.c lj_opt_fold.c lj_opt_loop.c lj_opt_mem.c lj_opt_narrow.c lj_opt_sink.c lj_opt_split.c lj_parse.c lj_parse.h lj_prng.c lj_prng.h lj_profile.c lj_profile.h lj_record.c lj_record.h lj_serialize.c lj_serialize.h lj_snap.c lj_snap.h lj_state.c lj_state.h lj_str.c lj_str.h lj_strfmt.c lj_strfmt.h lj_strfmt_num.c lj_strscan.c lj_strscan.h lj_tab.c lj_tab.h lj_target.h lj_target_arm.h lj_target_arm64.h lj_target_mips.h lj_target_ppc.h lj_target_x86.h lj_trace.c lj_trace.h lj_traceerr.h lj_udata.c lj_udata.h lj_vm.h lj_vmevent.c lj_vmevent.h lj_vmmath.c ljamalg.c lua.h lua.hpp luaconf.h luajit.c luajit_rolling.h lualib.h msvcbuild.bat nxbuild.bat ps4build.bat ps5build.bat psvitabuild.bat vm_arm.dasc vm_arm64.dasc vm_mips.dasc vm_mips64.dasc vm_ppc.dasc vm_x64.dasc vm_x86.dasc xb1build.bat xedkbuild.bat
.gitattributes .gitignore .relver COPYRIGHT Makefile README
sqlite shell.c sqlite3.c sqlite3.h sqlite3ext.h
wolfssl
.github
ISSUE_TEMPLATE bug_report.yaml other.yaml
actions
install-apt-deps action.yml
scripts
zephyr-4.x external_libc.conf zephyr-test.sh
openssl-ech.sh tls-anvil-test.sh
workflows
disabled haproxy.yml hitch.yml hostap.yml
hostap-files
configs
07c9f183ea744ac04585fb6dd10220c75a5e2e74 hostapd.config tests wpa_supplicant.config
b607d2723e927a3446d89aed813f1aa6068186bb hostapd.config tests wpa_supplicant.config
hostap_2_10 extra.patch hostapd.config tests wpa_supplicant.config
Makefile README dbus-wpa_supplicant.conf
ada.yml arduino.yml async-examples.yml async.yml atecc608-sim.yml bind.yml cmake-autoconf.yml cmake.yml codespell.yml coverity-scan-fixes.yml cryptocb-only.yml curl.yml cyrus-sasl.yml disable-pk-algs.yml docker-Espressif.yml docker-OpenWrt.yml emnet-nonblock.yml fil-c.yml freertos-mem-track.yml gencertbuf.yml grpc.yml haproxy.yml hostap-vm.yml intelasm-c-fallback.yml ipmitool.yml jwt-cpp.yml krb5.yml libspdm.yml libssh2.yml libvncserver.yml linuxkm.yml macos-apple-native-cert-validation.yml mbedtls.sh mbedtls.yml membrowse-comment.yml membrowse-onboard.yml membrowse-report.yml memcached.sh memcached.yml mono.yml mosquitto.yml msmtp.yml msys2.yml multi-arch.yml multi-compiler.yml net-snmp.yml nginx.yml no-malloc.yml no-tls.yml nss.sh nss.yml ntp.yml ocsp.yml openldap.yml openssh.yml openssl-ech.yml opensslcoexist.yml openvpn.yml os-check.yml packaging.yml pam-ipmi.yml pq-all.yml pr-commit-check.yml psk.yml puf.yml python.yml rng-tools.yml rust-wrapper.yml se050-sim.yml smallStackSize.yml socat.yml softhsm.yml sssd.yml stm32-sim.yml stsafe-a120-sim.yml stunnel.yml symbol-prefixes.yml threadx.yml tls-anvil.yml trackmemory.yml watcomc.yml win-csharp-test.yml wolfCrypt-Wconversion.yml wolfboot-integration.yml wolfsm.yml xcode.yml zephyr-4.x.yml zephyr.yml
PULL_REQUEST_TEMPLATE.md SECURITY.md membrowse-targets.json
Docker
OpenWrt Dockerfile README.md runTests.sh
packaging
debian Dockerfile
fedora Dockerfile
wolfCLU Dockerfile README.md
yocto Dockerfile buildAndPush.sh
Dockerfile Dockerfile.cross-compiler README.md buildAndPush.sh include.am run.sh
IDE
ARDUINO
sketches
wolfssl_client README.md
wolfssl_server README.md
wolfssl_version README.md
README.md
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.h
AURIX Cpu0_Main.c README.md include.am user_settings.h wolf_main.c
Android Android.bp README.md include.am user_settings.h
CRYPTOCELL README.md include.am main.c user_settings.h
CSBENCH include.am user_settings.h
ECLIPSE
DEOS
deos_wolfssl .options
README.md deos_malloc.c include.am tls_wolfssl.c tls_wolfssl.h user_settings.h
MICRIUM README.md client_wolfssl.c client_wolfssl.h include.am server_wolfssl.c server_wolfssl.h user_settings.h wolfsslRunTests.c
RTTHREAD README.md include.am user_settings.h wolfssl_test.c
SIFIVE README.md include.am
Espressif
ESP-IDF
examples
template
VisualGDB wolfssl_template_IDF_v5.1_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_benchmark
VisualGDB wolfssl_benchmark_IDF_v4.4_ESP32.sln wolfssl_benchmark_IDF_v4.4_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32.sln wolfssl_benchmark_IDF_v5_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32C3.sln wolfssl_benchmark_IDF_v5_ESP32C3.vgdbproj wolfssl_benchmark_IDF_v5_ESP32S3.sln wolfssl_benchmark_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_client
VisualGDB README.md wolfssl_client_IDF_v5_ESP32.sln wolfssl_client_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include client-tls.h main.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild client-tls.c component.mk main.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbproj
wolfssl_server
VisualGDB README.md wolfssl_server_IDF_v5_ESP32.sln wolfssl_server_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h server-tls.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild component.mk main.c server-tls.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbproj
wolfssl_test
VisualGDB wolfssl_test-IDF_v5_ESP32.sln wolfssl_test-IDF_v5_ESP32.vgdbproj wolfssl_test-IDF_v5_ESP32C3.sln wolfssl_test-IDF_v5_ESP32C3.vgdbproj wolfssl_test-IDF_v5_ESP32C6.sln wolfssl_test-IDF_v5_ESP32C6.vgdbproj wolfssl_test_IDF_v5_ESP32S3.sln wolfssl_test_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32 sdkconfig.defaults.esp32c3 sdkconfig.defaults.esp32c6 sdkconfig.defaults.esp32h2 sdkconfig.defaults.esp32s2 sdkconfig.defaults.esp32s3 sdkconfig.defaults.esp8266 testAll.sh testMonitor.sh wolfssl_test_ESP8266.sln wolfssl_test_ESP8266.vgdbproj
wolfssl_test_idf
VisualGDB VisualGDB_wolfssl_test_idf.sln VisualGDB_wolfssl_test_idf.vgdbproj
main CMakeLists.txt Kconfig.projbuild component.mk main.c main_wip.c.ex time_helper.c time_helper.h
CMakeLists.txt Kconfig.projbuild README.md component.mk sdkconfig.defaults
README.md
libs CMakeLists.txt README.md component.mk tigard.cfg
test CMakeLists.txt README.md component.mk test_wolfssl.c
README.md README_32se.md UPDATE.md compileAllExamples.sh dummy_config_h dummy_test_paths.h setup.sh setup_win.bat user_settings.h
README.md include.am
GCC-ARM
Header user_settings.h
Source armtarget.c benchmark_main.c test_main.c tls_client.c tls_server.c wolf_main.c
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ld
Gaisler-BCC README.md include.am
HEXAGON
DSP Makefile wolfssl_dsp.idl
Makefile README.md build.sh ecc-verify-benchmark.c ecc-verify.c include.am user_settings.h
HEXIWEAR
wolfSSL_HW .cwGeneratedFileSetLog user_settings.h
IAR-EWARM
Projects
benchmark benchmark-main.c current_time.c wolfCrypt-benchmark.ewd wolfCrypt-benchmark.ewp
common minimum-startup.c wolfssl.icf
lib wolfSSL-Lib.ewd wolfSSL-Lib.ewp
test test-main.c wolfCrypt-test.ewd wolfCrypt-test.ewp
user_settings.h wolfssl.eww
embOS
SAMV71_XULT
embOS_SAMV71_XULT_Linker_Script samv71q21_wolfssl.icf
embOS_SAMV71_XULT_user_settings user_settings.h user_settings_simple_example.h user_settings_verbose_example.h
embOS_wolfcrypt_benchmark_SAMV71_XULT
Application runBenchmarks.c
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewp
embOS_wolfcrypt_lib_SAMV71_XULT README_wolfcrypt_lib wolfcrypt_lib.ewd wolfcrypt_lib.ewp
embOS_wolfcrypt_test_SAMV71_XULT
Application runWolfcryptTests.c
README_wolfcrypt_test wolfcrypt_test.ewd wolfcrypt_test.ewp
README_SAMV71
custom_port
custom_port_Linker_Script samv71q21_wolfssl.icf
custom_port_user_settings user_settings.h
wolfcrypt_benchmark_custom_port
Application runBenchmarks.c
wolfcrypt_test_custom_port
Application runWolfcryptTests.c
README_custom_port
extract_trial_here README_extract_trial_here
README
.gitignore README
IAR-MSP430 Makefile README.md include.am main.c user_settings.h
INTIME-RTOS Makefile README.md include.am libwolfssl.c libwolfssl.vcxproj user_settings.h wolfExamples.c wolfExamples.h wolfExamples.sln wolfExamples.vcxproj wolfssl-lib.sln wolfssl-lib.vcxproj
Infineon README.md include.am user_settings.h
KDS
config user_settings.h
include.am
LINUX-SGX README.md build.sh clean.sh include.am sgx_t_static.mk
LPCXPRESSO
lib_wolfssl lpc_18xx_port.c user_settings.h
wolf_example
src lpc_18xx_startup.c wolfssl_example.c
readme.txt
README.md
M68K
benchmark Makefile main.cpp
testwolfcrypt Makefile main.cpp
Makefile README.md include.am user_settings.h
MCUEXPRESSO
RT1170 fsl_caam_c.patch fsl_caam_h.patch user_settings.h
benchmark
source run_benchmark.c
wolfssl liblinks.xml
README.md include.am user_settings.h wolfcrypt_test.c
MDK-ARM
LPC43xx time-LCP43xx.c
MDK-ARM
wolfSSL Retarget.c cert_data.c cert_data.h config-BARE-METAL.h config-FS.h config-RTX-TCP-FS.h config-WOLFLIB.h main.c shell.c time-CortexM3-4.c time-dummy.c wolfssl_MDK_ARM.c wolfssl_MDK_ARM.h
STM32F2xx_StdPeriph_Lib time-STM32F2xx.c
MDK5-ARM
Conf user_settings.h
Inc wolfssl_MDK_ARM.h
Projects
CryptBenchmark Abstract.txt CryptBenchmark.sct CryptBenchmark.uvoptx CryptBenchmark.uvprojx main.c
CryptTest Abstract.txt CryptTest.sct CryptTest.uvoptx CryptTest.uvprojx main.c
EchoClient Abstract.txt EchoClient.uvoptx EchoClient.uvprojx main.c wolfssl-link.sct
EchoServer Abstract.txt EchoServer.uvoptx EchoServer.uvprojx main.c wolfssl-link.sct
SimpleClient Abstract.txt SimpleClient.uvoptx SimpleClient.uvprojx main.c wolfssl-link.sct
SimpleServer Abstract.txt SimpleServer.uvoptx SimpleServer.uvprojx main.c wolfssl-link.sct
wolfSSL-Full Abstract.txt main.c shell.c time-CortexM3-4.c wolfsslFull.uvoptx wolfsslFull.uvprojx
wolfSSL-Lib Abstract.txt wolfSSL-Lib.uvoptx wolfSSL-Lib.uvprojx
Src ssl-dummy.c
README.md include.am
MPLABX16
wolfcrypt_test.X
nbproject
private configurations.xml private.xml
configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
README.md include.am main.c user_settings.h
MQX Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.h
MSVS-2019-AZSPHERE
client client.c client.h
server server.c server.h
shared util.h
wolfssl_new_azsphere
HardwareDefinitions
avnet_mt3620_sk
inc
hw template_appliance.h
template_appliance.json
mt3620_rdb
inc
hw template_appliance.h
template_appliance.json
seeed_mt3620_mdb
inc
hw template_appliance.h
template_appliance.json
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.c
README.md include.am user_settings.h
MYSQL CMakeLists_wolfCrypt.txt CMakeLists_wolfSSL.txt do.sh
NDS README.md
NETOS Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.c
OPENSTM32 README.md
PlatformIO
examples
wolfssl_benchmark
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspace
wolfssl_test
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_test.code-workspace
README.md wolfssl_platformio.code-workspace
README.md include.am
QNX
CAAM-DRIVER Makefile
example-client Makefile client-tls.c
example-cmac Makefile cmac-test.c
example-server Makefile server-tls.c
testwolfcrypt Makefile
wolfssl Makefile user_settings.h
README.md include.am
RISCV
SIFIVE-HIFIVE1 Makefile README.md include.am main.c user_settings.h
SIFIVE-UNLEASHED README.md include.am
include.am
ROWLEY-CROSSWORKS-ARM Kinetis_FlashPlacement.xml README.md arm_startup.c benchmark_main.c hw.h include.am kinetis_hw.c retarget.c test_main.c user_settings.h wolfssl.hzp wolfssl_ltc.hzp
Renesas
cs+
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
t4_demo README_en.txt README_jp.txt t4_demo.mtpj wolf_client.c wolf_demo.h wolf_main.c wolf_server.c
test test.mtpj test_main.c
wolfssl_lib wolfssl_lib.mtpj
README include.am
e2studio
DK-S7G2
benchmark-template
src app_entry.c
example_server-template
src app_entry.c
wolfcrypttest-template
src app_entry.c
wolfssl-template-project configuration.xml
README.md include.am user_settings.h
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
tools generate_rsa_keypair.sh genhexbuf.pl rsa_pss_sign.sh
wolfssl
src .gitkeep
wolfcrypt
src .gitkeep
README include.am
RA6M3
benchmark-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
client-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
common
ra6m3g README.md
src freertos_tcp_port.c
user_settings.h util.h
server-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
test-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl
src .gitkeep
wolfcrypt .gitkeep
README.md README_APRA6M_en.md README_APRA6M_jp.md include.am
RA6M3G README.md
RA6M4
common user_settings.h wolfssl_demo.h
test
key_data key_data.h key_data_sce.c
src
SEGGER_RTT myprint.c
common .gitignore
test_main.c wolf_client.c wolfssl_sce_unit_test.c
test_RA6M4Debug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
README.md include.am
RX65N
GR-ROSE
common strings.h unistd.h user_settings.h wolfssl_dummy.c
smc smc.scfg
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
test.rcpc test_HardwareDebug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
README_EN.md README_JP.md include.am
RSK
resource section.esi
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h
InstructionManualForExample_RSK+RX65N-2MB_EN.pdf InstructionManualForExample_RSK+RX65N-2MB_JP.pdf README_EN.md README_JP.md include.am
RX72N
EnvisionKit
Simple
common sectioninfo.esi wolfssl_dummy.c
test
src
client simple_tcp_client.c simple_tls_tsip_client.c
server simple_tcp_server.c simple_tls_server.c
test_main.c wolfssl_simple_demo.h
test.rcpc test.scfg test_HardwareDebug.launch
wolfssl wolfssl.rcpc
README_EN.md README_JP.md
resource section.esi
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.c
InstructionManualForExample_RX72N_EnvisonKit_EN.pdf InstructionManualForExample_RX72N_EnvisonKit_JP.pdf README_EN.md README_JP.md include.am
RZN2L
common user_settings.h wolfssl_demo.h
test
src
serial_io app_print.c
test wolf_client.c wolf_server.c wolfssl_rsip_unit_test.c
wolfCrypt .gitignore
wolfSSL .gitignore
local_system_init.c rzn2l_tst_thread_entry.c wolfssl_dummy.c
README.md include.am
SK-S7G2
common user_settings.h
wolfssl_lib configuration.xml
.gitignore README.md include.am
STARCORE README.txt include.am starcore_test.c user_settings.h
STM32Cube README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.h
SimplicityStudio README.md include.am test_wolf.c user_settings.h
TRUESTUDIO
wolfssl user_settings.h
README include.am
VS-ARM README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VS-AZURE-SPHERE
client app_manifest.json client.c client.h client.vcxproj
server app_manifest.json server.c server.h server.vcxproj
shared util.h
wolfcrypt_test app_manifest.json wolfcrypt_test.vcxproj
README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VisualDSP include.am user_settings.h wolf_tasks.c
WICED-STUDIO README include.am user_settings.h
WIN README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxproj
WIN-SGX ReadMe.txt include.am wolfSSL_SGX.edl wolfSSL_SGX.sln wolfSSL_SGX.vcxproj
WIN-SRTP-KDF-140-3 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WIN10 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WINCE README.md include.am user_settings.h user_settings.h.140-2-deprecated
WORKBENCH README.md include.am
XCODE
Benchmark
wolfBench
Assets.xcassets
AppIcon.appiconset Contents.json
Base.lproj LaunchScreen.storyboard Main.storyboard
AppDelegate.h AppDelegate.m Info.plist ViewController.h ViewController.m main.m
wolfBench.xcodeproj project.pbxproj
include.am
wolfssl-FIPS.xcodeproj project.pbxproj
wolfssl.xcodeproj project.pbxproj
wolfssl_testsuite.xcodeproj project.pbxproj
README.md build-for-i386.sh include.am user_settings.h
XCODE-FIPSv2
macOS-C++
Intel user_settings.h
M1 user_settings.h
include.am user_settings.h
XCODE-FIPSv5 README include.am user_settings.h
XCODE-FIPSv6 README include.am user_settings.h
XilinxSDK
2018_2 lscript.ld
2019_2
wolfCrypt_example
src lscript.ld
wolfCrypt_example_system wolfCrypt_example_system.sprj
2022_1
wolfCrypt_FreeRTOS_example wolfCrypt_FreeRTOS_example.prj
wolfCrypt_FreeRTOS_example_system wolfCrypt_FreeRTOS_example_system.sprj
wolfCrypt_example wolfCrypt_example.prj
wolfCrypt_example_system wolfCrypt_example_system.sprj
.gitignore
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.c
apple-universal
wolfssl-multiplatform
wolfssl-multiplatform
Assets.xcassets
AccentColor.colorset Contents.json
AppIcon.appiconset Contents.json
Contents.json
ContentView.swift simple_client_example.c simple_client_example.h wolfssl-multiplatform-Bridging-Header.h wolfssl_multiplatform.entitlements wolfssl_multiplatformApp.swift wolfssl_test_driver.c wolfssl_test_driver.h
wolfssl-multiplatform.xcodeproj project.pbxproj
.gitignore README.md build-wolfssl-framework.sh include.am
iotsafe Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.h
iotsafe-raspberrypi Makefile README.md client-tls13.c include.am main.c
mynewt README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.sh
zephyr README.md include.am
include.am
RTOS
nuttx
wolfssl .gitignore Kconfig Make.defs Makefile README.md setup-wolfssl.sh user_settings.h
include.am
bsdkm Makefile README.md bsdkm_wc_port.h include.am wolfkmod.c wolfkmod_aes.c x86_vecreg.c
certs
1024 ca-cert.der ca-cert.pem ca-key.der ca-key.pem client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der dh1024.der dh1024.pem dsa-pub-1024.pem dsa1024.der dsa1024.pem include.am rsa1024.der server-cert.der server-cert.pem server-key.der server-key.pem
3072 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
4096 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
acert
rsa_pss acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem
acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem include.am
aia ca-issuers-cert.pem multi-aia-cert.pem overflow-aia-cert.pem
crl
extra-crls ca-int-cert-revoked.pem claim-root.pem crl_critical_entry.pem crlnum_57oct.pem crlnum_64oct.pem general-server-crl.pem large_crlnum.pem large_crlnum2.pem
hash_der 0fdb2da4.r0
hash_pem 0fdb2da4.r0
bad_time_fmt.pem ca-int-ecc.pem ca-int.pem ca-int2-ecc.pem ca-int2.pem caEcc384Crl.pem caEccCrl.der caEccCrl.pem cliCrl.pem client-int-ecc.pem client-int.pem crl.der crl.pem crl.revoked crl2.der crl2.pem crl_reason.pem crl_rsapss.pem eccCliCRL.pem eccSrvCRL.pem gencrls.sh include.am server-goodaltCrl.pem server-goodaltwildCrl.pem server-goodcnCrl.pem server-goodcnwildCrl.pem server-int-ecc.pem server-int.pem wolfssl.cnf
dilithium bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.am
ecc bp256r1-key.der bp256r1-key.pem ca-secp256k1-cert.pem ca-secp256k1-key.pem client-bp256r1-cert.der client-bp256r1-cert.pem client-secp256k1-cert.der client-secp256k1-cert.pem genecc.sh include.am secp256k1-key.der secp256k1-key.pem secp256k1-param.pem secp256k1-privkey.der secp256k1-privkey.pem server-bp256r1-cert.der server-bp256r1-cert.pem server-secp256k1-cert.der server-secp256k1-cert.pem server2-secp256k1-cert.der server2-secp256k1-cert.pem wolfssl.cnf wolfssl_384.cnf
ed25519 ca-ed25519-key.der ca-ed25519-key.pem ca-ed25519-priv.der ca-ed25519-priv.pem ca-ed25519.der ca-ed25519.pem client-ed25519-key.der client-ed25519-key.pem client-ed25519-priv.der client-ed25519-priv.pem client-ed25519.der client-ed25519.pem eddsa-ed25519.der eddsa-ed25519.pem gen-ed25519-certs.sh gen-ed25519-keys.sh gen-ed25519.sh include.am root-ed25519-key.der root-ed25519-key.pem root-ed25519-priv.der root-ed25519-priv.pem root-ed25519.der root-ed25519.pem server-ed25519-cert.pem server-ed25519-key.der server-ed25519-key.pem server-ed25519-priv.der server-ed25519-priv.pem server-ed25519.der server-ed25519.pem
ed448 ca-ed448-key.der ca-ed448-key.pem ca-ed448-priv.der ca-ed448-priv.pem ca-ed448.der ca-ed448.pem client-ed448-key.der client-ed448-key.pem client-ed448-priv.der client-ed448-priv.pem client-ed448.der client-ed448.pem gen-ed448-certs.sh gen-ed448-keys.sh include.am root-ed448-key.der root-ed448-key.pem root-ed448-priv.der root-ed448-priv.pem root-ed448.der root-ed448.pem server-ed448-cert.pem server-ed448-key.der server-ed448-key.pem server-ed448-priv.der server-ed448-priv.pem server-ed448.der server-ed448.pem
external DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.am
falcon bench_falcon_level1_key.der bench_falcon_level5_key.der include.am
intermediate
ca_false_intermediate gentestcert.sh int_ca.key server.key test_ca.key test_ca.pem test_int_not_cacert.pem test_sign_bynoca_srv.pem wolfssl_base.conf wolfssl_srv.conf
ca-ecc-bad-aki.der ca-ecc-bad-aki.pem ca-int-cert.der ca-int-cert.pem ca-int-ecc-cert.der ca-int-ecc-cert.pem ca-int-ecc-key.der ca-int-ecc-key.pem ca-int-key.der ca-int-key.pem ca-int2-cert.der ca-int2-cert.pem ca-int2-ecc-cert.der ca-int2-ecc-cert.pem ca-int2-ecc-key.der ca-int2-ecc-key.pem ca-int2-key.der ca-int2-key.pem client-chain-alt-ecc.pem client-chain-alt.pem client-chain-ecc.der client-chain-ecc.pem client-chain.der client-chain.pem client-int-cert.der client-int-cert.pem client-int-ecc-cert.der client-int-ecc-cert.pem genintcerts.sh include.am server-chain-alt-ecc.pem server-chain-alt.pem server-chain-ecc.der server-chain-ecc.pem server-chain-short.pem server-chain.der server-chain.pem server-int-cert.der server-int-cert.pem server-int-ecc-cert.der server-int-ecc-cert.pem
lms bc_hss_L2_H5_W8_root.der bc_hss_L3_H5_W4_root.der bc_lms_chain_ca.der bc_lms_chain_leaf.der bc_lms_native_bc_root.der bc_lms_sha256_h10_w8_root.der bc_lms_sha256_h5_w4_root.der include.am
mldsa README.txt include.am mldsa44-cert.der mldsa44-cert.pem mldsa44-key.pem mldsa44_bare-priv.der mldsa44_bare-seed.der mldsa44_oqskeypair.der mldsa44_priv-only.der mldsa44_pub-spki.der mldsa44_seed-only.der mldsa44_seed-priv.der mldsa65-cert.der mldsa65-cert.pem mldsa65-key.pem mldsa65_bare-priv.der mldsa65_bare-seed.der mldsa65_oqskeypair.der mldsa65_priv-only.der mldsa65_pub-spki.der mldsa65_seed-only.der mldsa65_seed-priv.der mldsa87-cert.der mldsa87-cert.pem mldsa87-key.pem mldsa87_bare-priv.der mldsa87_bare-seed.der mldsa87_oqskeypair.der mldsa87_priv-only.der mldsa87_pub-spki.der mldsa87_seed-only.der mldsa87_seed-priv.der
ocsp imposter-root-ca-cert.der imposter-root-ca-cert.pem imposter-root-ca-key.der imposter-root-ca-key.pem include.am index-ca-and-intermediate-cas.txt index-ca-and-intermediate-cas.txt.attr index-intermediate1-ca-issued-certs.txt index-intermediate1-ca-issued-certs.txt.attr index-intermediate2-ca-issued-certs.txt index-intermediate2-ca-issued-certs.txt.attr index-intermediate3-ca-issued-certs.txt index-intermediate3-ca-issued-certs.txt.attr intermediate1-ca-cert.der intermediate1-ca-cert.pem intermediate1-ca-key.der intermediate1-ca-key.pem intermediate2-ca-cert.der intermediate2-ca-cert.pem intermediate2-ca-key.der intermediate2-ca-key.pem intermediate3-ca-cert.der intermediate3-ca-cert.pem intermediate3-ca-key.der intermediate3-ca-key.pem ocsp-responder-cert.der ocsp-responder-cert.pem ocsp-responder-key.der ocsp-responder-key.pem openssl.cnf renewcerts-for-test.sh renewcerts.sh root-ca-cert.der root-ca-cert.pem root-ca-crl.pem root-ca-key.der root-ca-key.pem server1-cert.der server1-cert.pem server1-chain-noroot.pem server1-key.der server1-key.pem server2-cert.der server2-cert.pem server2-key.der server2-key.pem server3-cert.der server3-cert.pem server3-key.der server3-key.pem server4-cert.der server4-cert.pem server4-key.der server4-key.pem server5-cert.der server5-cert.pem server5-key.der server5-key.pem test-leaf-response.der test-multi-response.der test-response-nointern.der test-response-rsapss.der test-response.der
p521 ca-p521-key.der ca-p521-key.pem ca-p521-priv.der ca-p521-priv.pem ca-p521.der ca-p521.pem client-p521-key.der client-p521-key.pem client-p521-priv.der client-p521-priv.pem client-p521.der client-p521.pem gen-p521-certs.sh gen-p521-keys.sh include.am root-p521-key.der root-p521-key.pem root-p521-priv.der root-p521-priv.pem root-p521.der root-p521.pem server-p521-cert.pem server-p521-key.der server-p521-key.pem server-p521-priv.der server-p521-priv.pem server-p521.der server-p521.pem
renewcerts wolfssl.cnf
rpk client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.der
rsapss ca-3072-rsapss-key.der ca-3072-rsapss-key.pem ca-3072-rsapss-priv.der ca-3072-rsapss-priv.pem ca-3072-rsapss.der ca-3072-rsapss.pem ca-rsapss-key.der ca-rsapss-key.pem ca-rsapss-priv.der ca-rsapss-priv.pem ca-rsapss.der ca-rsapss.pem client-3072-rsapss-key.der client-3072-rsapss-key.pem client-3072-rsapss-priv.der client-3072-rsapss-priv.pem client-3072-rsapss.der client-3072-rsapss.pem client-rsapss-key.der client-rsapss-key.pem client-rsapss-priv.der client-rsapss-priv.pem client-rsapss.der client-rsapss.pem gen-rsapss-keys.sh include.am renew-rsapss-certs.sh root-3072-rsapss-key.der root-3072-rsapss-key.pem root-3072-rsapss-priv.der root-3072-rsapss-priv.pem root-3072-rsapss.der root-3072-rsapss.pem root-rsapss-key.der root-rsapss-key.pem root-rsapss-priv.der root-rsapss-priv.pem root-rsapss.der root-rsapss.pem server-3072-rsapss-cert.pem server-3072-rsapss-key.der server-3072-rsapss-key.pem server-3072-rsapss-priv.der server-3072-rsapss-priv.pem server-3072-rsapss.der server-3072-rsapss.pem server-mix-rsapss-cert.pem server-rsapss-cert.pem server-rsapss-key.der server-rsapss-key.pem server-rsapss-priv.der server-rsapss-priv.pem server-rsapss.der server-rsapss.pem
sia timestamping-sia-cert.pem
slhdsa bench_slhdsa_sha2_128f_key.der bench_slhdsa_sha2_128s_key.der bench_slhdsa_sha2_192f_key.der bench_slhdsa_sha2_192s_key.der bench_slhdsa_sha2_256f_key.der bench_slhdsa_sha2_256s_key.der bench_slhdsa_shake128f_key.der bench_slhdsa_shake128s_key.der bench_slhdsa_shake192f_key.der bench_slhdsa_shake192s_key.der bench_slhdsa_shake256f_key.der bench_slhdsa_shake256s_key.der client-mldsa44-priv.pem client-mldsa44-sha2.der client-mldsa44-sha2.pem client-mldsa44-shake.der client-mldsa44-shake.pem gen-slhdsa-mldsa-certs.sh include.am root-slhdsa-sha2-128s-priv.der root-slhdsa-sha2-128s-priv.pem root-slhdsa-sha2-128s.der root-slhdsa-sha2-128s.pem root-slhdsa-shake-128s-priv.der root-slhdsa-shake-128s-priv.pem root-slhdsa-shake-128s.der root-slhdsa-shake-128s.pem server-mldsa44-priv.pem server-mldsa44-sha2.der server-mldsa44-sha2.pem server-mldsa44-shake.der server-mldsa44-shake.pem
sm2 ca-sm2-key.der ca-sm2-key.pem ca-sm2-priv.der ca-sm2-priv.pem ca-sm2.der ca-sm2.pem client-sm2-key.der client-sm2-key.pem client-sm2-priv.der client-sm2-priv.pem client-sm2.der client-sm2.pem fix_sm2_spki.py gen-sm2-certs.sh gen-sm2-keys.sh include.am root-sm2-key.der root-sm2-key.pem root-sm2-priv.der root-sm2-priv.pem root-sm2.der root-sm2.pem self-sm2-cert.pem self-sm2-key.pem self-sm2-priv.pem server-sm2-cert.der server-sm2-cert.pem server-sm2-key.der server-sm2-key.pem server-sm2-priv.der server-sm2-priv.pem server-sm2.der server-sm2.pem
statickeys dh-ffdhe2048-params.pem dh-ffdhe2048-pub.der dh-ffdhe2048-pub.pem dh-ffdhe2048.der dh-ffdhe2048.pem ecc-secp256r1.der ecc-secp256r1.pem gen-static.sh include.am x25519-pub.der x25519-pub.pem x25519.der x25519.pem
test
expired expired-ca.der expired-ca.pem expired-cert.der expired-cert.pem
catalog.txt cert-bad-neg-int.der cert-bad-oid.der cert-bad-utf8.der cert-ext-ia.cfg cert-ext-ia.der cert-ext-ia.pem cert-ext-joi.cfg cert-ext-joi.der cert-ext-joi.pem cert-ext-mnc.der cert-ext-multiple.cfg cert-ext-multiple.der cert-ext-multiple.pem cert-ext-nc-combined.der cert-ext-nc-combined.pem cert-ext-nc.cfg cert-ext-nc.der cert-ext-nc.pem cert-ext-ncdns.der cert-ext-ncdns.pem cert-ext-ncip.der cert-ext-ncip.pem cert-ext-ncmixed.der cert-ext-ncmulti.der cert-ext-ncmulti.pem cert-ext-ncrid.der cert-ext-ncrid.pem cert-ext-nct.cfg cert-ext-nct.der cert-ext-nct.pem cert-ext-ndir-exc.cfg cert-ext-ndir-exc.der cert-ext-ndir-exc.pem cert-ext-ndir.cfg cert-ext-ndir.der cert-ext-ndir.pem cert-ext-ns.der cert-over-max-altnames.cfg cert-over-max-altnames.der cert-over-max-altnames.pem cert-over-max-nc.cfg cert-over-max-nc.der cert-over-max-nc.pem client-ecc-cert-ski.hex cn-ip-literal.der cn-ip-wildcard.der crit-cert.pem crit-key.pem dh1024.der dh1024.pem dh512.der dh512.pem digsigku.pem encrypteddata.msg gen-badsig.sh gen-ext-certs.sh gen-testcerts.sh include.am kari-keyid-cms.msg ktri-keyid-cms.msg ossl-trusted-cert.pem server-badaltname.der server-badaltname.pem server-badaltnull.der server-badaltnull.pem server-badcn.der server-badcn.pem server-badcnnull.der server-badcnnull.pem server-cert-ecc-badsig.der server-cert-ecc-badsig.pem server-cert-rsa-badsig.der server-cert-rsa-badsig.pem server-duplicate-policy.pem server-garbage.der server-garbage.pem server-goodalt.der server-goodalt.pem server-goodaltwild.der server-goodaltwild.pem server-goodcn.der server-goodcn.pem server-goodcnwild.der server-goodcnwild.pem server-localhost.der server-localhost.pem smime-test-canon.p7s smime-test-multipart-badsig.p7s smime-test-multipart.p7s smime-test.p7s
test-pathlen assemble-chains.sh chainA-ICA1-key.pem chainA-ICA1-pathlen0.pem chainA-assembled.pem chainA-entity-key.pem chainA-entity.pem chainB-ICA1-key.pem chainB-ICA1-pathlen0.pem chainB-ICA2-key.pem chainB-ICA2-pathlen1.pem chainB-assembled.pem chainB-entity-key.pem chainB-entity.pem chainC-ICA1-key.pem chainC-ICA1-pathlen1.pem chainC-assembled.pem chainC-entity-key.pem chainC-entity.pem chainD-ICA1-key.pem chainD-ICA1-pathlen127.pem chainD-assembled.pem chainD-entity-key.pem chainD-entity.pem chainE-ICA1-key.pem chainE-ICA1-pathlen128.pem chainE-assembled.pem chainE-entity-key.pem chainE-entity.pem chainF-ICA1-key.pem chainF-ICA1-pathlen1.pem chainF-ICA2-key.pem chainF-ICA2-pathlen0.pem chainF-assembled.pem chainF-entity-key.pem chainF-entity.pem chainG-ICA1-key.pem chainG-ICA1-pathlen0.pem chainG-ICA2-key.pem chainG-ICA2-pathlen1.pem chainG-ICA3-key.pem chainG-ICA3-pathlen99.pem chainG-ICA4-key.pem chainG-ICA4-pathlen5.pem chainG-ICA5-key.pem chainG-ICA5-pathlen20.pem chainG-ICA6-key.pem chainG-ICA6-pathlen10.pem chainG-ICA7-key.pem chainG-ICA7-pathlen100.pem chainG-assembled.pem chainG-entity-key.pem chainG-entity.pem chainH-ICA1-key.pem chainH-ICA1-pathlen0.pem chainH-ICA2-key.pem chainH-ICA2-pathlen2.pem chainH-ICA3-key.pem chainH-ICA3-pathlen2.pem chainH-ICA4-key.pem chainH-ICA4-pathlen2.pem chainH-assembled.pem chainH-entity-key.pem chainH-entity.pem chainI-ICA1-key.pem chainI-ICA1-no_pathlen.pem chainI-ICA2-key.pem chainI-ICA2-no_pathlen.pem chainI-ICA3-key.pem chainI-ICA3-pathlen2.pem chainI-assembled.pem chainI-entity-key.pem chainI-entity.pem chainJ-ICA1-key.pem chainJ-ICA1-no_pathlen.pem chainJ-ICA2-key.pem chainJ-ICA2-no_pathlen.pem chainJ-ICA3-key.pem chainJ-ICA3-no_pathlen.pem chainJ-ICA4-key.pem chainJ-ICA4-pathlen2.pem chainJ-assembled.pem chainJ-entity-key.pem chainJ-entity.pem include.am refreshkeys.sh
test-serial0 ee_normal.pem ee_serial0.pem generate_certs.sh include.am intermediate_serial0.pem root_serial0.pem root_serial0_key.pem selfsigned_nonca_serial0.pem
xmss bc_xmss_chain_ca.der bc_xmss_chain_leaf.der bc_xmss_sha2_10_256_root.der bc_xmss_sha2_16_256_root.der bc_xmssmt_sha2_20_2_256_root.der bc_xmssmt_sha2_20_4_256_root.der bc_xmssmt_sha2_40_8_256_root.der include.am
ca-cert-chain.der ca-cert.der ca-cert.pem ca-ecc-cert.der ca-ecc-cert.pem ca-ecc-key.der ca-ecc-key.pem ca-ecc384-cert.der ca-ecc384-cert.pem ca-ecc384-key.der ca-ecc384-key.pem ca-key-pkcs8-attribute.der ca-key.der ca-key.pem check_dates.sh client-absolute-urn.pem client-ca-cert.der client-ca-cert.pem client-ca.pem client-cert-ext.der client-cert-ext.pem client-cert.der client-cert.pem client-crl-dist.der client-crl-dist.pem client-ecc-ca-cert.der client-ecc-ca-cert.pem client-ecc-cert.der client-ecc-cert.pem client-ecc384-cert.der client-ecc384-cert.pem client-ecc384-key.der client-ecc384-key.pem client-key.der client-key.pem client-keyEnc.pem client-keyPub.der client-keyPub.pem client-relative-uri.pem client-uri-cert.pem csr.attr.der csr.dsa.der csr.dsa.pem csr.ext.der csr.signed.der dh-priv-2048.der dh-priv-2048.pem dh-pub-2048.der dh-pub-2048.pem dh-pubkey-2048.der dh2048.der dh2048.pem dh3072.der dh3072.pem dh4096.der dh4096.pem dsa-pubkey-2048.der dsa2048.der dsa2048.pem dsa3072.der dsaparams.der dsaparams.pem ecc-client-key.der ecc-client-key.pem ecc-client-keyPub.der ecc-client-keyPub.pem ecc-key-comp.pem ecc-keyPkcs8.der ecc-keyPkcs8.pem ecc-keyPkcs8Enc.der ecc-keyPkcs8Enc.pem ecc-keyPub.der ecc-keyPub.pem ecc-params.der ecc-params.pem ecc-privOnlyCert.pem ecc-privOnlyKey.pem ecc-privkey.der ecc-privkey.pem ecc-privkeyPkcs8.der ecc-privkeyPkcs8.pem ecc-rsa-server.p12 empty-issuer-cert.pem entity-no-ca-bool-cert.pem entity-no-ca-bool-key.pem fpki-cert.der fpki-certpol-cert.der gen_revoked.sh include.am renewcerts.sh rid-cert.der rsa-pub-2048.pem rsa2048.der rsa3072.der server-cert-chain.der server-cert.der server-cert.pem server-ecc-comp.der server-ecc-comp.pem server-ecc-rsa.der server-ecc-rsa.pem server-ecc-self.der server-ecc-self.pem server-ecc.der server-ecc.pem server-ecc384-cert.der server-ecc384-cert.pem server-ecc384-key.der server-ecc384-key.pem server-key.der server-key.pem server-keyEnc.pem server-keyPkcs8.der server-keyPkcs8.pem server-keyPkcs8Enc.der server-keyPkcs8Enc.pem server-keyPkcs8Enc12.pem server-keyPkcs8Enc2.pem server-keyPub.der server-keyPub.pem server-revoked-cert.pem server-revoked-key.pem taoCert.txt test-ber-exp02-05-2022.p7b test-degenerate.p7b test-multiple-recipients.p7b test-servercert-rc2.p12 test-servercert.p12 test-stream-dec.p7b test-stream-sign.p7b wolfssl-website-ca.pem x942dh2048.der x942dh2048.pem
cmake
consumer CMakeLists.txt README.md main.c
modules FindARIA.cmake FindOQS.cmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.in
debian
source format
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.in
doc
dox_comments
header_files aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h puf.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wc_she.h wc_slhdsa.h wolfio.h
header_files-ja aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wolfio.h
formats
html
html_changes
search search.css search.js
customdoxygen.css doxygen.css menu.js menudata.js tabs.css
Doxyfile footer.html header.html mainpage.dox
pdf Doxyfile header.tex
images wolfssl_logo.png
QUIC.md README.txt README_DOXYGEN check_api.sh generate_documentation.sh include.am
examples
asn1 asn1.c dumpasn1.cfg gen_oid_names.rb include.am oid_names.h
async Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.h
benchmark include.am tls_bench.c tls_bench.h
client client.c client.h client.sln client.vcproj client.vcxproj include.am
configs README.md include.am user_settings_EBSnet.h user_settings_all.h user_settings_arduino.h user_settings_baremetal.h user_settings_ca.h user_settings_curve25519nonblock.h user_settings_dtls13.h user_settings_eccnonblock.h user_settings_espressif.h user_settings_fipsv2.h user_settings_fipsv5.h user_settings_min_ecc.h user_settings_openssl_compat.h user_settings_pkcs7.h user_settings_platformio.h user_settings_pq.h user_settings_rsa_only.h user_settings_stm32.h user_settings_template.h user_settings_tls12.h user_settings_tls13.h user_settings_wolfboot_keytools.h user_settings_wolfssh.h user_settings_wolftpm.h
crypto_policies
default wolfssl.txt
future wolfssl.txt
legacy wolfssl.txt
echoclient echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quit
echoserver echoserver.c echoserver.h echoserver.sln echoserver.vcproj echoserver.vcxproj include.am
ocsp_responder include.am ocsp_responder.c ocsp_responder.h
pem include.am pem.c
sctp include.am sctp-client-dtls.c sctp-client.c sctp-server-dtls.c sctp-server.c
server include.am server.c server.h server.sln server.vcproj server.vcxproj
README.md include.am
linuxkm
patches
5.10.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch
5.10.236 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch
5.14.0-570.58.1.el9_6 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v14-570v58v1-el9_6.patch
5.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch
5.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch
5.17-ubuntu-jammy-tegra WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17-ubuntu-jammy-tegra.patch
6.1.73 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch
6.12 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch
6.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch
7.0 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-7v0.patch
regen-patches.sh
Kbuild Makefile README.md get_thread_size.c include.am linuxkm-fips-hash-wrapper.sh linuxkm-fips-hash.c linuxkm_memory.c linuxkm_memory.h linuxkm_wc_port.h lkcapi_aes_glue.c lkcapi_dh_glue.c lkcapi_ecdh_glue.c lkcapi_ecdsa_glue.c lkcapi_glue.c lkcapi_rsa_glue.c lkcapi_sha_glue.c module_exports.c.template module_hooks.c pie_redirect_table.c wolfcrypt.lds x86_vector_register_glue.c
m4 ax_add_am_macro.m4 ax_am_jobserver.m4 ax_am_macros.m4 ax_append_compile_flags.m4 ax_append_flag.m4 ax_append_link_flags.m4 ax_append_to_file.m4 ax_atomic.m4 ax_bsdkm.m4 ax_check_compile_flag.m4 ax_check_link_flag.m4 ax_compiler_version.m4 ax_count_cpus.m4 ax_create_generic_config.m4 ax_debug.m4 ax_file_escapes.m4 ax_harden_compiler_flags.m4 ax_linuxkm.m4 ax_print_to_file.m4 ax_pthread.m4 ax_require_defined.m4 ax_tls.m4 ax_vcs_checkout.m4 hexversion.m4 lib_socket_nsl.m4 visibility.m4
mcapi
wolfcrypt_mcapi.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
zlib.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README crypto.c crypto.h include.am mcapi_test.c user_settings.h
mplabx
wolfcrypt_benchmark.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README benchmark_main.c include.am test_main.c user_settings.h
mqx
util_lib
Sources include.am util.c util.h
wolfcrypt_benchmark
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfcrypt_test
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfssl include.am
wolfssl_client
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfssl_client_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
README
rpm include.am spec.in
scripts
bench bench_functions.sh
aria-cmake-build-test.sh asn1_oid_sum.pl benchmark.test benchmark_compare.sh cleanup_testfiles.sh crl-gen-openssl.test crl-revoked.test dertoc.pl dtls.test dtlscid.test external.test google.test include.am makedistsmall.sh memtest.sh ocsp-responder-openssl-interop.test ocsp-stapling-with-ca-as-responder.test ocsp-stapling-with-wolfssl-responder.test ocsp-stapling.test ocsp-stapling2.test ocsp-stapling_tls13multi.test ocsp.test openssl.test openssl_srtp.test pem.test ping.test pkcallbacks.test psk.test resume.test rsapss.test sniffer-gen.sh sniffer-ipv6.pcap sniffer-static-rsa.pcap sniffer-testsuite.test sniffer-tls12-keylog.out sniffer-tls12-keylog.pcap sniffer-tls12-keylog.sslkeylog sniffer-tls13-dh-resume.pcap sniffer-tls13-dh.pcap sniffer-tls13-ecc-resume.pcap sniffer-tls13-ecc.pcap sniffer-tls13-hrr.pcap sniffer-tls13-keylog.out sniffer-tls13-keylog.pcap sniffer-tls13-keylog.sslkeylog sniffer-tls13-x25519-resume.pcap sniffer-tls13-x25519.pcap stm32l4-v4_0_1_build.sh tls13.test trusted_peer.test unit.test.in user_settings_asm.sh
src bio.c conf.c crl.c dtls.c dtls13.c include.am internal.c keys.c ocsp.c pk.c pk_ec.c pk_rsa.c quic.c sniffer.c ssl.c ssl_api_cert.c ssl_api_crl_ocsp.c ssl_api_pk.c ssl_asn1.c ssl_bn.c ssl_certman.c ssl_crypto.c ssl_ech.c ssl_load.c ssl_misc.c ssl_p7p12.c ssl_sess.c ssl_sk.c tls.c tls13.c wolfio.c x509.c x509_str.c
sslSniffer
sslSnifferTest README_WIN.md include.am snifftest.c sslSniffTest.vcproj sslSniffTest.vcxproj
README.md sslSniffer.vcproj sslSniffer.vcxproj
support gen-debug-trace-error-codes.sh include.am wolfssl.pc.in
tests
api api.h api_decl.h create_ocsp_test_blobs.py include.am test_aes.c test_aes.h test_arc4.c test_arc4.h test_ascon.c test_ascon.h test_ascon_kats.h test_asn.c test_asn.h test_blake2.c test_blake2.h test_camellia.c test_camellia.h test_certman.c test_certman.h test_chacha.c test_chacha.h test_chacha20_poly1305.c test_chacha20_poly1305.h test_cmac.c test_cmac.h test_curve25519.c test_curve25519.h test_curve448.c test_curve448.h test_des3.c test_des3.h test_dh.c test_dh.h test_digest.h test_dsa.c test_dsa.h test_dtls.c test_dtls.h test_ecc.c test_ecc.h test_ed25519.c test_ed25519.h test_ed448.c test_ed448.h test_evp.c test_evp.h test_evp_cipher.c test_evp_cipher.h test_evp_digest.c test_evp_digest.h test_evp_pkey.c test_evp_pkey.h test_hash.c test_hash.h test_hmac.c test_hmac.h test_md2.c test_md2.h test_md4.c test_md4.h test_md5.c test_md5.h test_mldsa.c test_mldsa.h test_mlkem.c test_mlkem.h test_ocsp.c test_ocsp.h test_ocsp_test_blobs.h test_ossl_asn1.c test_ossl_asn1.h test_ossl_bio.c test_ossl_bio.h test_ossl_bn.c test_ossl_bn.h test_ossl_cipher.c test_ossl_cipher.h test_ossl_dgst.c test_ossl_dgst.h test_ossl_dh.c test_ossl_dh.h test_ossl_dsa.c test_ossl_dsa.h test_ossl_ec.c test_ossl_ec.h test_ossl_ecx.c test_ossl_ecx.h test_ossl_mac.c test_ossl_mac.h test_ossl_obj.c test_ossl_obj.h test_ossl_p7p12.c test_ossl_p7p12.h test_ossl_pem.c test_ossl_pem.h test_ossl_rand.c test_ossl_rand.h test_ossl_rsa.c test_ossl_rsa.h test_ossl_sk.c test_ossl_sk.h test_ossl_x509.c test_ossl_x509.h test_ossl_x509_acert.c test_ossl_x509_acert.h test_ossl_x509_crypto.c test_ossl_x509_crypto.h test_ossl_x509_ext.c test_ossl_x509_ext.h test_ossl_x509_info.c test_ossl_x509_info.h test_ossl_x509_io.c test_ossl_x509_io.h test_ossl_x509_lu.c test_ossl_x509_lu.h test_ossl_x509_name.c test_ossl_x509_name.h test_ossl_x509_pk.c test_ossl_x509_pk.h test_ossl_x509_str.c test_ossl_x509_str.h test_ossl_x509_vp.c test_ossl_x509_vp.h test_pkcs12.c test_pkcs12.h test_pkcs7.c test_pkcs7.h test_poly1305.c test_poly1305.h test_random.c test_random.h test_rc2.c test_rc2.h test_ripemd.c test_ripemd.h test_rsa.c test_rsa.h test_sha.c test_sha.h test_sha256.c test_sha256.h test_sha3.c test_sha3.h test_sha512.c test_sha512.h test_she.c test_she.h test_signature.c test_signature.h test_slhdsa.c test_slhdsa.h test_sm2.c test_sm2.h test_sm3.c test_sm3.h test_sm4.c test_sm4.h test_tls.c test_tls.h test_tls13.c test_tls13.h test_tls_ext.c test_tls_ext.h test_wc_encrypt.c test_wc_encrypt.h test_wolfmath.c test_wolfmath.h test_x509.c test_x509.h
emnet
IP IP.h
Makefile emnet_nonblock_test.c emnet_shim.c
freertos-mem-track-repro FreeRTOS.h repro.c run.sh semphr.h task.h user_settings.h
swdev .gitignore Makefile README.md swdev.c swdev.h swdev_loader.c swdev_loader.h user_settings.h
CONF_FILES_README.md NCONF_test.cnf README TXT_DB.txt api.c include.am quic.c srp.c suites.c test-altchains.conf test-chains.conf test-dhprime.conf test-dtls-downgrade.conf test-dtls-fails-cipher.conf test-dtls-fails.conf test-dtls-group.conf test-dtls-mtu.conf test-dtls-reneg-client.conf test-dtls-reneg-server.conf test-dtls-resume.conf test-dtls-sha2.conf test-dtls-srtp-fails.conf test-dtls-srtp.conf test-dtls.conf test-dtls13-cid.conf test-dtls13-downgrade-fails.conf test-dtls13-downgrade.conf test-dtls13-pq-hybrid-extra-frag.conf test-dtls13-pq-hybrid-extra.conf test-dtls13-pq-hybrid-frag.conf test-dtls13-pq-standalone-frag.conf test-dtls13-pq-standalone.conf test-dtls13-psk.conf test-dtls13.conf test-ecc-cust-curves.conf test-ed25519.conf test-ed448.conf test-enckeys.conf test-fails.conf test-maxfrag-dtls.conf test-maxfrag.conf test-p521.conf test-psk-no-id-sha2.conf test-psk-no-id.conf test-psk.conf test-rsapss.conf test-sctp-sha2.conf test-sctp.conf test-sha2.conf test-sig.conf test-sm2.conf test-tls-downgrade.conf test-tls13-down.conf test-tls13-ecc.conf test-tls13-pq-hybrid-extra.conf test-tls13-pq-hybrid.conf test-tls13-pq-standalone.conf test-tls13-psk-certs.conf test-tls13-psk.conf test-tls13-slhdsa-fail.conf test-tls13-slhdsa-sha2.conf test-tls13-slhdsa-shake.conf test-tls13.conf test-trustpeer.conf test.conf unit.c unit.h utils.c utils.h w64wrapper.c
testsuite include.am testsuite.c testsuite.sln testsuite.vcproj testsuite.vcxproj utils.c utils.h
tirtos
packages
ti
net
wolfssl
tests
EK_TM4C1294XL
wolfcrypt
benchmark TM4C1294NC.icf benchmark.cfg main.c package.bld.hide package.xdc
test TM4C1294NC.icf main.c package.bld.hide package.xdc test.cfg
package.bld package.xdc package.xs
.gitignore README include.am products.mak wolfssl.bld wolfssl.mak
wolfcrypt
benchmark README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.am
src
port
Espressif
esp_crt_bundle README.md cacrt_all.pem cacrt_deprecated.pem cacrt_local.pem esp_crt_bundle.c gen_crt_bundle.py pio_install_cryptography.py
README.md esp32_aes.c esp32_mp.c esp32_sha.c esp32_util.c esp_sdk_mem_lib.c esp_sdk_time_lib.c esp_sdk_wifi_lib.c
Renesas README.md renesas_common.c renesas_fspsm_aes.c renesas_fspsm_rsa.c renesas_fspsm_sha.c renesas_fspsm_util.c renesas_rx64_hw_sha.c renesas_rx64_hw_util.c renesas_tsip_aes.c renesas_tsip_rsa.c renesas_tsip_sha.c renesas_tsip_util.c
af_alg afalg_aes.c afalg_hash.c wc_afalg.c
aria aria-crypt.c aria-cryptocb.c
arm armv8-32-aes-asm.S armv8-32-aes-asm_c.c armv8-32-chacha-asm.S armv8-32-chacha-asm_c.c armv8-32-curve25519.S armv8-32-curve25519_c.c armv8-32-mlkem-asm.S armv8-32-mlkem-asm_c.c armv8-32-poly1305-asm.S armv8-32-poly1305-asm_c.c armv8-32-sha256-asm.S armv8-32-sha256-asm_c.c armv8-32-sha3-asm.S armv8-32-sha3-asm_c.c armv8-32-sha512-asm.S armv8-32-sha512-asm_c.c armv8-aes-asm.S armv8-aes-asm_c.c armv8-aes.c armv8-chacha-asm.S armv8-chacha-asm_c.c armv8-curve25519.S armv8-curve25519_c.c armv8-mlkem-asm.S armv8-mlkem-asm_c.c armv8-poly1305-asm.S armv8-poly1305-asm_c.c armv8-sha256-asm.S armv8-sha256-asm_c.c armv8-sha256.c armv8-sha3-asm.S armv8-sha3-asm_c.c armv8-sha512-asm.S armv8-sha512-asm_c.c armv8-sha512.c cryptoCell.c cryptoCellHash.c thumb2-aes-asm.S thumb2-aes-asm_c.c thumb2-chacha-asm.S thumb2-chacha-asm_c.c thumb2-curve25519.S thumb2-curve25519_c.c thumb2-mlkem-asm.S thumb2-mlkem-asm_c.c thumb2-poly1305-asm.S thumb2-poly1305-asm_c.c thumb2-sha256-asm.S thumb2-sha256-asm_c.c thumb2-sha3-asm.S thumb2-sha3-asm_c.c thumb2-sha512-asm.S thumb2-sha512-asm_c.c
atmel README.md atmel.c
autosar README.md cryif.c crypto.c csm.c include.am test.c
caam README.md caam_aes.c caam_doc.pdf caam_driver.c caam_error.c caam_integrity.c caam_qnx.c caam_sha.c wolfcaam_aes.c wolfcaam_cmac.c wolfcaam_ecdsa.c wolfcaam_fsl_nxp.c wolfcaam_hash.c wolfcaam_hmac.c wolfcaam_init.c wolfcaam_qnx.c wolfcaam_rsa.c wolfcaam_seco.c wolfcaam_x25519.c
cavium README.md README_Octeon.md cavium_nitrox.c cavium_octeon_sync.c
cuda README.md aes-cuda.cu
cypress README.md psoc6_crypto.c
devcrypto README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.c
intel README.md quickassist.c quickassist_mem.c quickassist_sync.c
iotsafe iotsafe.c
kcapi README.md kcapi_aes.c kcapi_dh.c kcapi_ecc.c kcapi_hash.c kcapi_hmac.c kcapi_rsa.c
liboqs liboqs.c
maxim README.md max3266x.c maxq10xx.c
mynewt mynewt_port.c
nxp README.md README_SE050.md casper_port.c dcp_port.c hashcrypt_port.c ksdk_port.c se050_port.c
pic32 pic32mz-crypt.c
ppc32 ppc32-sha256-asm.S ppc32-sha256-asm_c.c ppc32-sha256-asm_cr.c
psa README.md psa.c psa_aes.c psa_hash.c psa_pkcbs.c
riscv riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.c
rpi_pico README.md pico.c
silabs README.md silabs_aes.c silabs_ecc.c silabs_hash.c silabs_random.c
st README.md STM32MP13.md STM32MP25.md stm32.c stsafe.c
ti ti-aes.c ti-ccm.c ti-des3.c ti-hash.c
tropicsquare README.md tropic01.c
xilinx xil-aesgcm.c xil-sha3.c xil-versal-glue.c xil-versal-trng.c
nrf51.c
ASN_TEMPLATE.md aes.c aes_asm.S aes_asm.asm aes_gcm_asm.S aes_gcm_asm.asm aes_gcm_x86_asm.S aes_xts_asm.S aes_xts_asm.asm arc4.c ascon.c asm.c asn.c asn_orig.c async.c blake2b.c blake2s.c camellia.c chacha.c chacha20_poly1305.c chacha_asm.S chacha_asm.asm cmac.c coding.c compress.c cpuid.c cryptocb.c curve25519.c curve448.c des3.c dh.c dilithium.c dsa.c ecc.c ecc_fp.c eccsi.c ed25519.c ed448.c error.c evp.c evp_pk.c falcon.c fe_448.c fe_low_mem.c fe_operations.c fe_x25519_128.h fe_x25519_asm.S fp_mont_small.i fp_mul_comba_12.i fp_mul_comba_17.i fp_mul_comba_20.i fp_mul_comba_24.i fp_mul_comba_28.i fp_mul_comba_3.i fp_mul_comba_32.i fp_mul_comba_4.i fp_mul_comba_48.i fp_mul_comba_6.i fp_mul_comba_64.i fp_mul_comba_7.i fp_mul_comba_8.i fp_mul_comba_9.i fp_mul_comba_small_set.i fp_sqr_comba_12.i fp_sqr_comba_17.i fp_sqr_comba_20.i fp_sqr_comba_24.i fp_sqr_comba_28.i fp_sqr_comba_3.i fp_sqr_comba_32.i fp_sqr_comba_4.i fp_sqr_comba_48.i fp_sqr_comba_6.i fp_sqr_comba_64.i fp_sqr_comba_7.i fp_sqr_comba_8.i fp_sqr_comba_9.i fp_sqr_comba_small_set.i ge_448.c ge_low_mem.c ge_operations.c hash.c hmac.c hpke.c include.am integer.c kdf.c logging.c md2.c md4.c md5.c memory.c misc.c pkcs12.c pkcs7.c poly1305.c poly1305_asm.S poly1305_asm.asm puf.c pwdbased.c random.c rc2.c ripemd.c rng_bank.c rsa.c sakke.c sha.c sha256.c sha256_asm.S sha3.c sha3_asm.S sha512.c sha512_asm.S signature.c siphash.c sm2.c sm3.c sm3_asm.S sm4.c sp_arm32.c sp_arm64.c sp_armthumb.c sp_c32.c sp_c64.c sp_cortexm.c sp_dsp32.c sp_int.c sp_sm2_arm32.c sp_sm2_arm64.c sp_sm2_armthumb.c sp_sm2_c32.c sp_sm2_c64.c sp_sm2_cortexm.c sp_sm2_x86_64.c sp_sm2_x86_64_asm.S sp_x86_64.c sp_x86_64_asm.S sp_x86_64_asm.asm srp.c tfm.c wc_dsp.c wc_encrypt.c wc_lms.c wc_lms_impl.c wc_mldsa_asm.S wc_mlkem.c wc_mlkem_asm.S wc_mlkem_poly.c wc_pkcs11.c wc_port.c wc_she.c wc_slhdsa.c wc_xmss.c wc_xmss_impl.c wolfentropy.c wolfevent.c wolfmath.c
test README.md include.am test-VS2022.sln test-VS2022.vcxproj test-VS2022.vcxproj.user test.c test.h test.sln test.vcproj test_paths.h.in
wolfssl
openssl aes.h asn1.h asn1t.h bio.h bn.h buffer.h camellia.h cmac.h cms.h compat_types.h conf.h crypto.h des.h dh.h dsa.h ec.h ec25519.h ec448.h ecdh.h ecdsa.h ed25519.h ed448.h engine.h err.h evp.h fips_rand.h hmac.h include.am kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pkcs12.h pkcs7.h rand.h rc4.h ripemd.h rsa.h safestack.h sha.h sha3.h srp.h ssl.h ssl23.h stack.h tls1.h txt_db.h ui.h x509.h x509_vfy.h x509v3.h
wolfcrypt
port
Espressif esp-sdk-lib.h esp32-crypt.h esp_crt_bundle.h
Renesas renesas-fspsm-crypt.h renesas-fspsm-types.h renesas-rx64-hw-crypt.h renesas-tsip-crypt.h renesas_cmn.h renesas_fspsm_internal.h renesas_sync.h renesas_tsip_internal.h renesas_tsip_types.h
af_alg afalg_hash.h wc_afalg.h
aria aria-crypt.h aria-cryptocb.h
arm cryptoCell.h
atmel atmel.h
autosar CryIf.h Crypto.h Csm.h StandardTypes.h
caam caam_driver.h caam_error.h caam_qnx.h wolfcaam.h wolfcaam_aes.h wolfcaam_cmac.h wolfcaam_ecdsa.h wolfcaam_fsl_nxp.h wolfcaam_hash.h wolfcaam_qnx.h wolfcaam_rsa.h wolfcaam_seco.h wolfcaam_sha.h wolfcaam_x25519.h
cavium cavium_nitrox.h cavium_octeon_sync.h
cypress psoc6_crypto.h
devcrypto wc_devcrypto.h
intel quickassist.h quickassist_mem.h quickassist_sync.h
iotsafe iotsafe.h
kcapi kcapi_dh.h kcapi_ecc.h kcapi_hash.h kcapi_hmac.h kcapi_rsa.h wc_kcapi.h
liboqs liboqs.h
maxim max3266x-cryptocb.h max3266x.h maxq10xx.h
nxp casper_port.h dcp_port.h hashcrypt_port.h ksdk_port.h se050_port.h
pic32 pic32mz-crypt.h
psa psa.h
riscv riscv-64-asm.h
rpi_pico pico.h
silabs silabs_aes.h silabs_ecc.h silabs_hash.h silabs_random.h
st stm32.h stsafe.h
ti ti-ccm.h ti-hash.h
tropicsquare tropic01.h
xilinx xil-sha3.h xil-versal-glue.h xil-versal-trng.h
nrf51.h
aes.h arc4.h ascon.h asn.h asn_public.h async.h blake2-impl.h blake2-int.h blake2.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cpuid.h cryptocb.h curve25519.h curve448.h des3.h dh.h dilithium.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h falcon.h fe_448.h fe_operations.h fips_test.h ge_448.h ge_operations.h hash.h hmac.h hpke.h include.am integer.h kdf.h libwolfssl_sources.h libwolfssl_sources_asm.h logging.h md2.h md4.h md5.h mem_track.h memory.h misc.h mpi_class.h mpi_superclass.h oid_sum.h pkcs11.h pkcs12.h pkcs7.h poly1305.h puf.h pwdbased.h random.h rc2.h ripemd.h rng_bank.h rsa.h sakke.h selftest.h settings.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h sm2.h sm3.h sm4.h sp.h sp_int.h srp.h tfm.h types.h visibility.h wc_encrypt.h wc_lms.h wc_mlkem.h wc_pkcs11.h wc_port.h wc_she.h wc_slhdsa.h wc_xmss.h wolfentropy.h wolfevent.h wolfmath.h
callbacks.h certs_test.h certs_test_sm.h crl.h error-ssl.h include.am internal.h ocsp.h options.h.in quic.h sniffer.h sniffer_error.h sniffer_error.rc ssl.h test.h version.h version.h.in wolfio.h
wrapper
Ada
examples
src aes_verify_main.adb rsa_verify_main.adb sha256_main.adb spark_sockets.adb spark_sockets.ads spark_terminal.adb spark_terminal.ads tls_client.adb tls_client.ads tls_client_main.adb tls_server.adb tls_server.ads tls_server_main.adb
.gitignore alire.toml examples.gpr
tests
src
support test_support.adb test_support.ads tests_root_suite.adb tests_root_suite.ads
aes_bindings_tests.adb aes_bindings_tests.ads rsa_verify_bindings_tests.adb rsa_verify_bindings_tests.ads sha256_bindings_tests.adb sha256_bindings_tests.ads tests.adb
.gitignore README.md alire.toml tests.gpr valgrind.supp
.gitignore README.md ada_binding.c alire.toml default.gpr include.am restricted.adc user_settings.h wolfssl-full_runtime.adb wolfssl-full_runtime.ads wolfssl.adb wolfssl.ads wolfssl.gpr
CSharp
wolfCrypt-Test
Properties AssemblyInfo.cs
App.config wolfCrypt-Test.cs wolfCrypt-Test.csproj
wolfSSL-DTLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-PSK-Server.cs wolfSSL-DTLS-PSK-Server.csproj
wolfSSL-DTLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-Server.cs wolfSSL-DTLS-Server.csproj
wolfSSL-Example-IOCallbacks
Properties AssemblyInfo.cs
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csproj
wolfSSL-TLS-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Client.cs wolfSSL-TLS-Client.csproj
wolfSSL-TLS-PSK-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Client.cs wolfSSL-TLS-PSK-Client.csproj
wolfSSL-TLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Server.cs wolfSSL-TLS-PSK-Server.csproj
wolfSSL-TLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Server.cs wolfSSL-TLS-Server.csproj
wolfSSL-TLS-ServerThreaded
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csproj
wolfSSL_CSharp
Properties AssemblyInfo.cs Resources.Designer.cs Resources.resx
X509.cs wolfCrypt.cs wolfSSL.cs wolfSSL_CSharp.csproj
README.md include.am user_settings.h wolfSSL_CSharp.sln wolfssl.vcxproj
python README.md
rust
wolfssl-wolfcrypt
src aes.rs blake2.rs chacha20_poly1305.rs cmac.rs cmac_mac.rs curve25519.rs dh.rs dilithium.rs ecc.rs ecdsa.rs ed25519.rs ed448.rs fips.rs hkdf.rs hmac.rs hmac_mac.rs kdf.rs lib.rs lms.rs mlkem.rs mlkem_kem.rs pbkdf2_password_hash.rs prf.rs random.rs rsa.rs rsa_pkcs1v15.rs sha.rs sha_digest.rs sys.rs
tests
common mod.rs
test_aes.rs test_blake2.rs test_chacha20_poly1305.rs test_cmac.rs test_cmac_mac.rs test_curve25519.rs test_dh.rs test_dilithium.rs test_ecc.rs test_ecdsa.rs test_ed25519.rs test_ed448.rs test_hkdf.rs test_hmac.rs test_hmac_mac.rs test_kdf.rs test_lms.rs test_mlkem.rs test_mlkem_kem.rs test_pbkdf2_password_hash.rs test_prf.rs test_random.rs test_rsa.rs test_rsa_pkcs1v15.rs test_sha.rs test_sha_digest.rs test_wolfcrypt.rs
CHANGELOG.md Cargo.lock Cargo.toml Makefile README.md build.rs headers.h
Makefile README.md include.am
include.am
zephyr
samples
wolfssl_benchmark
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_test
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_sock
boards native_sim.conf
src tls_sock.c
CMakeLists.txt README install_sample.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_thread
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
src tls_threaded.c
CMakeLists.txt README install_sample.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl options.h
CMakeLists.txt Kconfig Kconfig.tls-generic README.md include.am module.yml user_settings-no-malloc.h user_settings.h zephyr_init.c
.codespellexcludelines .cyignore .editorconfig .gitignore .wolfssl_known_macro_extras AUTHORS CMakeLists.txt CMakePresets.json CMakeSettings.json COPYING ChangeLog.md INSTALL LICENSING LPCExpresso.cproject LPCExpresso.project Makefile.am README README-async.md README.md SCRIPTS-LIST SECURITY-POLICY.md SECURITY-REPORT-TEMPLATE.md Vagrantfile autogen.sh commit-tests.sh configure.ac fips-check.sh fips-hash.sh gencertbuf.pl input pull_to_vagrant.sh quit resource.h stamp-h.in valgrind-bash.supp valgrind-error.sh wnr-example.conf wolfssl-VS2022.vcxproj wolfssl.rc wolfssl.vcproj wolfssl.vcxproj wolfssl64.sln
.clangd .gitignore DOCS.md Makefile README.md assert.c core.c crypto.c env.c fs.c http.c ini.c json.c log.c luna.h main.c makext.mk path.c process.c request.c sqlite.c stash.c template.c util.c
wolfssl/src/x509.c raw
    1/* x509.c
    2 *
    3 * Copyright (C) 2006-2026 wolfSSL Inc.
    4 *
    5 * This file is part of wolfSSL.
    6 *
    7 * wolfSSL is free software; you can redistribute it and/or modify
    8 * it under the terms of the GNU General Public License as published by
    9 * the Free Software Foundation; either version 3 of the License, or
   10 * (at your option) any later version.
   11 *
   12 * wolfSSL is distributed in the hope that it will be useful,
   13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15 * GNU General Public License for more details.
   16 *
   17 * You should have received a copy of the GNU General Public License
   18 * along with this program; if not, write to the Free Software
   19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
   20 */
   21
   22#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
   23
   24#if !defined(WOLFSSL_X509_INCLUDED)
   25    #ifndef WOLFSSL_IGNORE_FILE_WARN
   26        #warning x509.c does not need to be compiled separately from ssl.c
   27    #endif
   28#else
   29
   30#ifndef WOLFCRYPT_ONLY
   31
   32#ifndef NO_CERTS
   33
   34#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
   35    #include <wolfssl/openssl/x509v3.h>
   36#endif
   37#ifdef OPENSSL_EXTRA
   38    #include <wolfssl/wolfio.h>
   39#endif
   40
   41/* 16 times MAX_X509_SIZE should be more than enough to read any X509
   42 * certificate file */
   43#define MAX_BIO_READ_BUFFER (MAX_X509_SIZE * 16)
   44
   45#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
   46unsigned int wolfSSL_X509_get_extension_flags(WOLFSSL_X509* x509)
   47{
   48    unsigned int flags = 0;
   49
   50    WOLFSSL_ENTER("wolfSSL_X509_get_extension_flags");
   51
   52    if (x509 != NULL) {
   53        if (x509->keyUsageSet) {
   54            flags |= WOLFSSL_EXFLAG_KUSAGE;
   55        }
   56        if (x509->extKeyUsageSrc != NULL) {
   57            flags |= WOLFSSL_EXFLAG_XKUSAGE;
   58        }
   59    }
   60
   61    WOLFSSL_LEAVE("wolfSSL_X509_get_extension_flags", flags);
   62
   63    return flags;
   64}
   65
   66unsigned int wolfSSL_X509_get_key_usage(WOLFSSL_X509* x509)
   67{
   68    unsigned int ret = 0;
   69
   70    WOLFSSL_ENTER("wolfSSL_X509_get_key_usage");
   71
   72    if (x509 == NULL) {
   73        WOLFSSL_MSG("x509 is NULL");
   74    }
   75    else {
   76        if (x509->keyUsageSet) {
   77            ret = wolfSSL_X509_get_keyUsage(x509);
   78        }
   79        else {
   80            ret = (unsigned int)-1;
   81        }
   82    }
   83
   84    WOLFSSL_LEAVE("wolfSSL_X509_get_key_usage", ret);
   85
   86    return ret;
   87}
   88
   89unsigned int wolfSSL_X509_get_extended_key_usage(WOLFSSL_X509* x509)
   90{
   91    int ret = 0;
   92
   93    WOLFSSL_ENTER("wolfSSL_X509_get_extended_key_usage");
   94
   95    if (x509 != NULL) {
   96        if (x509->extKeyUsage & EXTKEYUSE_OCSP_SIGN)
   97            ret |= WOLFSSL_XKU_OCSP_SIGN;
   98        if (x509->extKeyUsage & EXTKEYUSE_TIMESTAMP)
   99            ret |= WOLFSSL_XKU_TIMESTAMP;
  100        if (x509->extKeyUsage & EXTKEYUSE_EMAILPROT)
  101            ret |= WOLFSSL_XKU_SMIME;
  102        if (x509->extKeyUsage & EXTKEYUSE_CODESIGN)
  103            ret |= WOLFSSL_XKU_CODE_SIGN;
  104        if (x509->extKeyUsage & EXTKEYUSE_CLIENT_AUTH)
  105            ret |= WOLFSSL_XKU_SSL_CLIENT;
  106        if (x509->extKeyUsage & EXTKEYUSE_SERVER_AUTH)
  107            ret |= WOLFSSL_XKU_SSL_SERVER;
  108        if (x509->extKeyUsage & EXTKEYUSE_ANY)
  109            ret |= WOLFSSL_XKU_ANYEKU;
  110    }
  111
  112    WOLFSSL_LEAVE("wolfSSL_X509_get_extended_key_usage", ret);
  113
  114    return (unsigned int)ret;
  115}
  116
  117/* Returns the number of X509V3 extensions in X509 object, or 0 on failure */
  118int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
  119{
  120    int extCount = 0;
  121    int length = 0;
  122    int outSz = 0;
  123    const byte* rawCert;
  124    int sz = 0;
  125    word32 idx = 0;
  126    const byte* input;
  127    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
  128
  129    WOLFSSL_ENTER("wolfSSL_X509_get_ext_count");
  130    if (passedCert == NULL) {
  131        WOLFSSL_MSG("\tNot passed a certificate");
  132        return WOLFSSL_FAILURE;
  133    }
  134
  135    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)passedCert, &outSz);
  136    if (rawCert == NULL) {
  137        WOLFSSL_MSG("\tpassedCert has no internal DerBuffer set.");
  138        return WOLFSSL_FAILURE;
  139    }
  140
  141#ifdef WOLFSSL_SMALL_STACK
  142    cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL, DYNAMIC_TYPE_DCERT);
  143    if (cert == NULL) {
  144        WOLFSSL_MSG("out of memory");
  145        return WOLFSSL_FAILURE;
  146    }
  147#endif
  148
  149    InitDecodedCert(cert, rawCert, (word32)outSz, 0);
  150
  151    if (ParseCert(cert,
  152#ifdef WOLFSSL_CERT_REQ
  153            passedCert->isCSR ? CERTREQ_TYPE :
  154#endif
  155                    CA_TYPE,
  156            NO_VERIFY, NULL) < 0) {
  157        WOLFSSL_MSG("\tCertificate parsing failed");
  158        goto out;
  159    }
  160
  161    input = cert->extensions;
  162    sz = cert->extensionsSz;
  163
  164    if (input == NULL || sz == 0) {
  165        WOLFSSL_MSG("\tsz or input NULL error");
  166        goto out;
  167    }
  168
  169#ifdef WOLFSSL_CERT_REQ
  170    if (!passedCert->isCSR)
  171#endif
  172    {
  173        if (input[idx++] != ASN_EXTENSIONS) {
  174            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
  175            goto out;
  176        }
  177
  178        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
  179            WOLFSSL_MSG("\tfail: invalid length");
  180            goto out;
  181        }
  182    }
  183
  184    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
  185        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
  186        goto out;
  187    }
  188
  189    while (idx < (word32)sz) {
  190        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
  191            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
  192            FreeDecodedCert(cert);
  193            return WOLFSSL_FAILURE;
  194        }
  195        idx += length;
  196        extCount++;
  197    }
  198
  199out:
  200
  201    FreeDecodedCert(cert);
  202    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  203    return extCount;
  204}
  205
  206/* Creates and returns pointer to a new X509_EXTENSION object in memory */
  207WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void)
  208{
  209    WOLFSSL_X509_EXTENSION* newExt;
  210
  211    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_new");
  212
  213    newExt = (WOLFSSL_X509_EXTENSION*)XMALLOC(sizeof(WOLFSSL_X509_EXTENSION),
  214              NULL, DYNAMIC_TYPE_X509_EXT);
  215    if (newExt == NULL)
  216        return NULL;
  217    XMEMSET(newExt, 0, sizeof(WOLFSSL_X509_EXTENSION));
  218
  219    return newExt;
  220}
  221
  222
  223/* Clear out and free internal pointers of ASN.1 STRING object.
  224 *
  225 * @param [in] asn1  ASN.1 STRING object.
  226 */
  227static void wolfSSL_ASN1_STRING_clear(WOLFSSL_ASN1_STRING* asn1)
  228{
  229    /* Check we have an object to free. */
  230    if (asn1 != NULL) {
  231        /* Dispose of dynamic data. */
  232        if ((asn1->length > 0) && asn1->isDynamic) {
  233            XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
  234        }
  235        XMEMSET(asn1, 0, sizeof(WOLFSSL_ASN1_STRING));
  236    }
  237}
  238
  239
  240void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* x)
  241{
  242    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_free");
  243    if (x == NULL)
  244        return;
  245
  246    if (x->obj != NULL) {
  247        wolfSSL_ASN1_OBJECT_free(x->obj);
  248    }
  249
  250    wolfSSL_ASN1_STRING_clear(&x->value);
  251    wolfSSL_sk_pop_free(x->ext_sk, NULL);
  252
  253    XFREE(x, NULL, DYNAMIC_TYPE_X509_EXT);
  254}
  255
  256WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(WOLFSSL_X509_EXTENSION* src)
  257{
  258    WOLFSSL_X509_EXTENSION* ret = NULL;
  259    int err = 0;
  260
  261    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_dup");
  262
  263    if (src == NULL) {
  264        err = 1;
  265    }
  266
  267    if (err == 0) {
  268        ret = wolfSSL_X509_EXTENSION_new();
  269        if (ret == NULL) {
  270            err = 1;
  271        }
  272    }
  273    if (err == 0 && src->obj != NULL) {
  274        ret->obj = wolfSSL_ASN1_OBJECT_dup(src->obj);
  275        if (ret->obj == NULL) {
  276            err = 1;
  277        }
  278    }
  279    if (err == 0) {
  280        ret->crit = src->crit;
  281        if (wolfSSL_ASN1_STRING_copy(&ret->value, &src->value) !=
  282                WOLFSSL_SUCCESS) {
  283            err = 1;
  284        }
  285    }
  286
  287    if (err == 1 && ret != NULL) {
  288        wolfSSL_X509_EXTENSION_free(ret);
  289        ret = NULL;
  290    }
  291
  292    return ret;
  293}
  294
  295WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_create_by_OBJ(
  296    WOLFSSL_X509_EXTENSION* ex, WOLFSSL_ASN1_OBJECT *obj, int crit,
  297    WOLFSSL_ASN1_STRING *data)
  298{
  299    int err = 0;
  300    WOLFSSL_X509_EXTENSION *ret = ex;
  301
  302    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_create_by_OBJ");
  303
  304    if ((obj == NULL) || (data == NULL)) {
  305       return NULL;
  306    }
  307
  308    if (ret == NULL) {
  309        ret = wolfSSL_X509_EXTENSION_new();
  310        if (ret == NULL) {
  311            err = 1;
  312        }
  313    }
  314    else {
  315        /* Prevent potential memory leaks and dangling pointers. */
  316        wolfSSL_ASN1_OBJECT_free(ret->obj);
  317        ret->obj = NULL;
  318        wolfSSL_ASN1_STRING_clear(&ret->value);
  319    }
  320
  321    if (err == 0) {
  322        ret->crit = crit;
  323        ret->obj = wolfSSL_ASN1_OBJECT_dup(obj);
  324        if (ret->obj == NULL) {
  325            err = 1;
  326        }
  327    }
  328
  329    if (err == 0) {
  330        if (wolfSSL_ASN1_STRING_copy(&ret->value, data) != WOLFSSL_SUCCESS) {
  331            err = 1;
  332        }
  333    }
  334
  335    if (err == 1) {
  336        if (ret != ex) {
  337            wolfSSL_X509_EXTENSION_free(ret);
  338        }
  339        ret = NULL;
  340    }
  341    return ret;
  342}
  343
  344/* Creates and returns a new WOLFSSL_X509_EXTENSION stack. */
  345WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void)
  346{
  347    WOLFSSL_STACK* sk;
  348    WOLFSSL_ENTER("wolfSSL_sk_new_x509_ext");
  349
  350    sk = wolfSSL_sk_new_null();
  351    if (sk) {
  352        sk->type = STACK_TYPE_X509_EXT;
  353    }
  354    return sk;
  355}
  356
  357/* This function does NOT return 1 on success. It returns 0 on fail, and the
  358 * number of items in the stack upon success. This is for compatibility with
  359 * OpenSSL. */
  360int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,
  361    WOLFSSL_X509_EXTENSION* ext)
  362{
  363    WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_push");
  364
  365    return wolfSSL_sk_push(sk, ext);
  366}
  367
  368static WOLFSSL_STACK* generateExtStack(const WOLFSSL_X509 *x)
  369{
  370    int numOfExt, i;
  371    WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
  372    WOLFSSL_STACK* ret;
  373    WOLFSSL_STACK* tmp;
  374
  375    if (!x509) {
  376        WOLFSSL_MSG("Bad parameter");
  377        return NULL;
  378    }
  379
  380    /* Save x509->ext_sk */
  381    tmp = x509->ext_sk;
  382    x509->ext_sk = NULL;
  383    numOfExt = wolfSSL_X509_get_ext_count(x509);
  384
  385    for (i = 0; i < numOfExt; i++) {
  386        /* Build the extension stack */
  387        (void)wolfSSL_X509_set_ext(x509, i);
  388    }
  389
  390    /* Restore */
  391    ret = x509->ext_sk;
  392    x509->ext_sk = tmp;
  393    return ret;
  394}
  395
  396/**
  397 * @param x Certificate to extract extensions from
  398 * @return STACK_OF(X509_EXTENSION)*
  399 */
  400const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x)
  401{
  402    int numOfExt;
  403    WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
  404    WOLFSSL_ENTER("wolfSSL_X509_get0_extensions");
  405
  406    if (!x509) {
  407        WOLFSSL_MSG("Bad parameter");
  408        return NULL;
  409    }
  410
  411    numOfExt = wolfSSL_X509_get_ext_count(x509);
  412
  413    if (numOfExt != wolfSSL_sk_num(x509->ext_sk_full)) {
  414        wolfSSL_sk_pop_free(x509->ext_sk_full, NULL);
  415        x509->ext_sk_full = generateExtStack(x);
  416    }
  417
  418    return x509->ext_sk_full;
  419}
  420
  421/**
  422 * Caller is responsible for freeing the returned stack.
  423 */
  424const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x)
  425{
  426    return generateExtStack(x);
  427}
  428
  429/* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509.
  430 *
  431 * x509   : The X509 structure to look for the extension.
  432 * loc    : Location of the extension. If the extension is found at the given
  433 * location, a new X509_EXTENSION structure is populated with extension-specific
  434 * data based on the extension type.
  435
  436 * Returns NULL on error or pointer to X509_EXTENSION structure containing the
  437 * extension. The returned X509_EXTENSION should not be free'd by caller.
  438 * The returned X509_EXTENSION is pushed onto a stack inside the x509 argument.
  439 * This is later free'd when x509 is free'd.
  440 *
  441 * NOTE: for unknown extension NIDs, a X509_EXTENSION is populated with the
  442 * extension oid as the ASN1_OBJECT (QT compatibility)
  443 */
  444WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x509, int loc)
  445{
  446    WOLFSSL_X509_EXTENSION* ext = NULL;
  447    WOLFSSL_ENTER("wolfSSL_X509_get_ext");
  448    if (x509 == NULL)
  449        return NULL;
  450
  451   ext = wolfSSL_X509_set_ext((WOLFSSL_X509*) x509, loc);
  452   return ext;
  453}
  454
  455int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x,
  456        const WOLFSSL_ASN1_OBJECT *obj, int lastpos)
  457{
  458    const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION) *sk;
  459
  460    if (!x || !obj) {
  461        WOLFSSL_MSG("Bad parameter");
  462        return WOLFSSL_FATAL_ERROR;
  463    }
  464
  465    sk = wolfSSL_X509_get0_extensions(x);
  466    if (!sk) {
  467        WOLFSSL_MSG("No extensions");
  468        return WOLFSSL_FATAL_ERROR;
  469    }
  470    lastpos++;
  471    if (lastpos < 0)
  472        lastpos = 0;
  473    for (; lastpos < wolfSSL_sk_num(sk); lastpos++) {
  474        const WOLFSSL_X509_EXTENSION *ext =
  475            wolfSSL_sk_X509_EXTENSION_value(sk, lastpos);
  476        if (ext == NULL)
  477            continue;
  478        if (wolfSSL_OBJ_cmp(ext->obj, obj) == 0)
  479            return lastpos;
  480    }
  481    return WOLFSSL_FATAL_ERROR;
  482}
  483
  484
  485int wolfSSL_X509_OBJECT_set1_X509(WOLFSSL_X509_OBJECT *a, WOLFSSL_X509 *obj)
  486{
  487    WOLFSSL_STUB("wolfSSL_X509_OBJECT_set1_X509");
  488    (void)a;
  489    (void)obj;
  490    return 0;
  491}
  492
  493int wolfSSL_X509_OBJECT_set1_X509_CRL(WOLFSSL_X509_OBJECT *a,
  494    WOLFSSL_X509_CRL *obj)
  495{
  496    WOLFSSL_STUB("wolfSSL_X509_OBJECT_set1_X509_CRL");
  497    (void)a;
  498    (void)obj;
  499    return 0;
  500}
  501
  502#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
  503
  504#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
  505    defined(WOLFSSL_WPAS_SMALL)
  506/* Set a general name from the DNS entry data.
  507 *
  508 * @param [in]      dns  DNS entry.
  509 * @param [in, out] gn   General name to place data in.
  510 * @return  1 on success.
  511 * @return  0 on failure.
  512 */
  513static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns,
  514    WOLFSSL_GENERAL_NAME* gn)
  515{
  516    int ret = 0;
  517    WOLFSSL_ASN1_OBJECT* obj = NULL;
  518    WOLFSSL_ASN1_TYPE* type = NULL;
  519    WOLFSSL_ASN1_STRING* str = NULL;
  520    byte tag = 0;
  521    unsigned char* p = (unsigned char *)dns->name;
  522    long len = dns->len;
  523
  524#ifdef WOLFSSL_FPKI
  525    if (dns->oidSum != 0) {
  526        /* UPN OID: 1.3.6.1.4.1.311.20.2.3 */
  527        static const unsigned char upn_oid[] = {
  528            0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03
  529        };
  530        /* FASCN OID: 2.16.840.1.101.3.6.6 */
  531        static const unsigned char fascn_oid[] = {
  532            0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x06, 0x06
  533        };
  534        const unsigned char* oid;
  535        word32 oidSz;
  536
  537        if ((oid = OidFromId(dns->oidSum, oidCertAltNameType, &oidSz)) ==
  538                NULL) {
  539            if (dns->oidSum == UPN_OID) {
  540                oid = upn_oid;
  541                oidSz = (word32)sizeof(upn_oid);
  542            }
  543            else if (dns->oidSum == FASCN_OID) {
  544                oid = fascn_oid;
  545                oidSz = (word32)sizeof(fascn_oid);
  546            }
  547            else {
  548                goto err;
  549            }
  550        }
  551        if ((obj = wolfSSL_c2i_ASN1_OBJECT(NULL, &oid, oidSz)) == NULL) {
  552            goto err;
  553        }
  554
  555        tag = WOLFSSL_V_ASN1_UTF8STRING;
  556    }
  557    else
  558#endif
  559    {
  560        word32 idx = 0;
  561        int nameLen;
  562
  563        /* Create an object id for general name from DER encoding. */
  564        obj = wolfSSL_d2i_ASN1_OBJECT(NULL, (const unsigned char**)&p, len);
  565        if (obj == NULL)
  566            goto err;
  567        /* Pointer moved on and now update length of remaining data. */
  568        len -= (long)((size_t)p - (size_t)dns->name);
  569
  570        /* Next is "value      [0] EXPLICIT ANY DEFINED BY type-id" */
  571        if (GetASNHeader(p, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0,
  572                &idx, &nameLen, (word32)len) < 0)
  573            goto err;
  574        p += idx;
  575        len -= idx;
  576
  577        /* Set the tag to object so that it gets output in raw form */
  578        tag = WOLFSSL_V_ASN1_SEQUENCE;
  579    }
  580
  581    /* Create a WOLFSSL_ASN1_STRING from the DER. */
  582    str = wolfSSL_ASN1_STRING_type_new(tag);
  583    if (str == NULL) {
  584        goto err;
  585    }
  586    wolfSSL_ASN1_STRING_set(str, p, (int)len);
  587
  588    /* Wrap string in a WOLFSSL_ASN1_TYPE. */
  589    type = wolfSSL_ASN1_TYPE_new();
  590    if (type == NULL)
  591        goto err;
  592    wolfSSL_ASN1_TYPE_set(type, tag, str);
  593    str = NULL; /* type now owns str */
  594
  595    if (wolfSSL_GENERAL_NAME_set_type(gn, WOLFSSL_GEN_OTHERNAME)
  596            != WOLFSSL_SUCCESS) {
  597        goto err;
  598    }
  599
  600    /* Store the object and string in general name. */
  601    gn->d.otherName->type_id = obj;
  602    gn->d.otherName->value = type;
  603    type = NULL; /* gn->d.otherName owns type */
  604
  605    ret = 1;
  606err:
  607    if (ret != 1) {
  608        wolfSSL_ASN1_OBJECT_free(obj);
  609        wolfSSL_ASN1_TYPE_free(type);
  610        wolfSSL_ASN1_STRING_free(str);
  611    }
  612    return ret;
  613}
  614#endif /* OPENSSL_ALL || WOLFSSL_WPAS_SMALL */
  615
  616#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
  617static int DNS_to_GENERAL_NAME(WOLFSSL_GENERAL_NAME* gn, DNS_entry* dns)
  618{
  619    switch (dns->type) {
  620        case WOLFSSL_GEN_OTHERNAME:
  621            /* Sets gn->type internally */
  622            if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
  623                WOLFSSL_MSG("OTHERNAME set failed");
  624                return WOLFSSL_FAILURE;
  625            }
  626            break;
  627
  628        case WOLFSSL_GEN_EMAIL:
  629        case WOLFSSL_GEN_DNS:
  630        case WOLFSSL_GEN_URI:
  631        case WOLFSSL_GEN_IPADD:
  632        case WOLFSSL_GEN_IA5:
  633            gn->type = dns->type;
  634            gn->d.ia5->length = dns->len;
  635            if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
  636                    gn->d.ia5->length) != WOLFSSL_SUCCESS) {
  637                WOLFSSL_MSG("ASN1_STRING_set failed");
  638                return WOLFSSL_FAILURE;
  639            }
  640            break;
  641
  642
  643        case WOLFSSL_GEN_DIRNAME:
  644            gn->type = dns->type;
  645            /* wolfSSL_GENERAL_NAME_new() mallocs this by default */
  646            wolfSSL_ASN1_STRING_free(gn->d.ia5);
  647            gn->d.ia5 = NULL;
  648
  649            gn->d.dirn = wolfSSL_X509_NAME_new();;
  650            /* @TODO extract dir name info from DNS_entry */
  651            break;
  652
  653        case WOLFSSL_GEN_RID:
  654            /* registeredID is parsed into altNames unconditionally so
  655             * ConfirmNameConstraints can enforce RID name constraints
  656             * (RFC 5280 Sec. 4.2.1.10). The body uses only the raw OID
  657             * bytes carried in dns->name/dns->len and constructs a
  658             * proper ASN1_OBJECT, so this case is independent of
  659             * WOLFSSL_RID_ALT_NAME (which only gates the human-readable
  660             * ridString form). */
  661            gn->type = dns->type;
  662            /* wolfSSL_GENERAL_NAME_new() mallocs this by default */
  663            wolfSSL_ASN1_STRING_free(gn->d.ia5);
  664            gn->d.ia5 = NULL;
  665
  666            gn->d.registeredID = wolfSSL_ASN1_OBJECT_new();
  667            if (gn->d.registeredID == NULL) {
  668                return WOLFSSL_FAILURE;
  669            }
  670            {
  671                /* Store DER-encoded OID (tag + length + content) in obj */
  672                word32 derSz = 1 + SetLength(dns->len, NULL) + dns->len;
  673                byte* der = (byte*)XMALLOC(derSz,
  674                    gn->d.registeredID->heap, DYNAMIC_TYPE_ASN1);
  675                if (der == NULL) {
  676                    return WOLFSSL_FAILURE;
  677                }
  678                {
  679                    word32 idx = 0;
  680                    der[idx++] = ASN_OBJECT_ID;
  681                    idx += SetLength(dns->len, der + idx);
  682                    XMEMCPY(der + idx, dns->name, dns->len);
  683                }
  684                gn->d.registeredID->obj = der;
  685                gn->d.registeredID->objSz = derSz;
  686            }
  687            gn->d.registeredID->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
  688            gn->d.registeredID->grp = oidCertExtType;
  689            break;
  690
  691        case WOLFSSL_GEN_X400:
  692            /* Unsupported: fall through */
  693        case WOLFSSL_GEN_EDIPARTY:
  694            /* Unsupported: fall through */
  695        default:
  696            WOLFSSL_MSG("Unsupported type conversion");
  697            return WOLFSSL_FAILURE;
  698    }
  699    return WOLFSSL_SUCCESS;
  700}
  701
  702
  703static int wolfssl_x509_alt_names_to_gn(WOLFSSL_X509* x509,
  704    WOLFSSL_X509_EXTENSION* ext)
  705{
  706    int ret = 0;
  707    WOLFSSL_GENERAL_NAME* gn = NULL;
  708    DNS_entry* dns = NULL;
  709    WOLFSSL_STACK* sk;
  710
  711    sk = (WOLFSSL_GENERAL_NAMES*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAMES), NULL,
  712        DYNAMIC_TYPE_ASN1);
  713    if (sk == NULL) {
  714        goto err;
  715    }
  716    XMEMSET(sk, 0, sizeof(WOLFSSL_GENERAL_NAMES));
  717    sk->type = STACK_TYPE_GEN_NAME;
  718
  719    if (x509->subjAltNameSet && x509->altNames != NULL) {
  720        /* alt names are DNS_entry structs */
  721        dns = x509->altNames;
  722        /* Currently only support GEN_DNS type */
  723        while (dns != NULL) {
  724            gn = wolfSSL_GENERAL_NAME_new();
  725            if (gn == NULL) {
  726                WOLFSSL_MSG("Error creating GENERAL_NAME");
  727                wolfSSL_sk_pop_free(sk, NULL);
  728                goto err;
  729            }
  730
  731            if (DNS_to_GENERAL_NAME(gn, dns) != WOLFSSL_SUCCESS) {
  732                wolfSSL_GENERAL_NAME_free(gn);
  733                wolfSSL_sk_pop_free(sk, NULL);
  734                goto err;
  735            }
  736
  737            if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) <= 0) {
  738                WOLFSSL_MSG("Error pushing onto stack");
  739                wolfSSL_GENERAL_NAME_free(gn);
  740                wolfSSL_sk_pop_free(sk, NULL);
  741                goto err;
  742            }
  743
  744            dns = dns->next;
  745        }
  746    }
  747    ext->ext_sk = sk;
  748    ext->crit = x509->subjAltNameCrit;
  749
  750    ret = 1;
  751err:
  752    return ret;
  753}
  754
  755/* Pushes a new X509_EXTENSION* ext onto the stack inside WOLFSSL_X509* x509.
  756 * This is currently a helper function for wolfSSL_X509_get_ext
  757 * Caller does not free the returned WOLFSSL_X509_EXTENSION*
  758 */
  759WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
  760{
  761    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
  762    int objSz = 0, isSet = 0;
  763    const byte* rawCert;
  764    const byte* input;
  765    byte* oidBuf;
  766    word32 oid, idx = 0, tmpIdx = 0, nid;
  767    WOLFSSL_X509_EXTENSION* ext = NULL;
  768    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
  769
  770    WOLFSSL_ENTER("wolfSSL_X509_set_ext");
  771
  772    if (x509 == NULL) {
  773        WOLFSSL_MSG("\tNot passed a certificate");
  774        return NULL;
  775    }
  776
  777    if (loc < 0 || (loc > wolfSSL_X509_get_ext_count(x509))) {
  778        WOLFSSL_MSG("\tBad location argument");
  779        return NULL;
  780    }
  781
  782    ext = wolfSSL_X509_EXTENSION_new();
  783    if (ext == NULL) {
  784        WOLFSSL_MSG("\tX509_EXTENSION_new() failed");
  785        return NULL;
  786    }
  787
  788    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
  789    if (rawCert == NULL) {
  790        WOLFSSL_MSG("\tX509_get_der() failed");
  791        wolfSSL_X509_EXTENSION_free(ext);
  792        return NULL;
  793    }
  794
  795#ifdef WOLFSSL_SMALL_STACK
  796    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
  797    if (cert == NULL) {
  798        WOLFSSL_MSG("Failed to allocate memory for DecodedCert");
  799        wolfSSL_X509_EXTENSION_free(ext);
  800        return NULL;
  801    }
  802#endif
  803
  804    InitDecodedCert(cert, rawCert, (word32)outSz, 0);
  805
  806    if (ParseCert(cert,
  807#ifdef WOLFSSL_CERT_REQ
  808            x509->isCSR ? CERTREQ_TYPE :
  809#endif
  810                    CA_TYPE,
  811            NO_VERIFY, NULL) < 0) {
  812        WOLFSSL_MSG("\tCertificate parsing failed");
  813        wolfSSL_X509_EXTENSION_free(ext);
  814        FreeDecodedCert(cert);
  815        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  816        return NULL;
  817    }
  818
  819    input = cert->extensions;
  820    sz = cert->extensionsSz;
  821
  822    if (input == NULL || sz == 0) {
  823        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
  824        wolfSSL_X509_EXTENSION_free(ext);
  825        FreeDecodedCert(cert);
  826        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  827        return NULL;
  828    }
  829
  830#ifdef WOLFSSL_CERT_REQ
  831    if (!x509->isCSR)
  832#endif
  833    {
  834        if (input[idx++] != ASN_EXTENSIONS) {
  835            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
  836            wolfSSL_X509_EXTENSION_free(ext);
  837            FreeDecodedCert(cert);
  838            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  839            return NULL;
  840        }
  841
  842        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
  843            WOLFSSL_MSG("\tfail: invalid length");
  844            wolfSSL_X509_EXTENSION_free(ext);
  845            FreeDecodedCert(cert);
  846            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  847            return NULL;
  848        }
  849    }
  850
  851    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
  852        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
  853        wolfSSL_X509_EXTENSION_free(ext);
  854        FreeDecodedCert(cert);
  855        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  856        return NULL;
  857    }
  858
  859    while (idx < (word32)sz) {
  860        oid = 0;
  861
  862        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
  863            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
  864            wolfSSL_X509_EXTENSION_free(ext);
  865            FreeDecodedCert(cert);
  866            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  867            return NULL;
  868        }
  869
  870        tmpIdx = idx;
  871        ret = GetObjectId(input, &idx, &oid, oidCertExtType, (word32)sz);
  872        if (ret < 0) {
  873            WOLFSSL_MSG("\tfail: OBJECT ID");
  874            wolfSSL_X509_EXTENSION_free(ext);
  875            FreeDecodedCert(cert);
  876            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  877            return NULL;
  878        }
  879        idx = tmpIdx;
  880        nid = (word32)oid2nid(oid, oidCertExtType);
  881
  882        /* Continue while loop until extCount == loc or idx > sz */
  883        if (extCount != loc) {
  884            idx += length;
  885            extCount++;
  886            continue;
  887        }
  888        /* extCount == loc. Now get the extension. */
  889        /* Check if extension has been set */
  890        isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509, (int)nid);
  891
  892        if (wolfSSL_OBJ_nid2ln((int)nid) != NULL) {
  893            /* This is NOT an unknown OID. */
  894            ext->obj = wolfSSL_OBJ_nid2obj((int)nid);
  895            if (ext->obj == NULL) {
  896                WOLFSSL_MSG("\tfail: Invalid OBJECT");
  897                wolfSSL_X509_EXTENSION_free(ext);
  898                FreeDecodedCert(cert);
  899                WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  900                return NULL;
  901            }
  902        }
  903
  904        if (ext->obj) {
  905            ext->obj->nid = (int)nid;
  906        }
  907
  908        switch (oid) {
  909            case BASIC_CA_OID:
  910            {
  911                WOLFSSL_ASN1_INTEGER* a;
  912                word32 dataIdx = idx;
  913                word32 dummyOid;
  914                int dataLen = 0;
  915
  916                if (!isSet)
  917                    break;
  918
  919                /* Set pathlength */
  920                a = wolfSSL_ASN1_INTEGER_new();
  921
  922                /* Set the data */
  923                ret = GetObjectId(input, &dataIdx, &dummyOid, oidCertExtType,
  924                        (word32)sz) == 0;
  925                if (ret && dataIdx < (word32)sz) {
  926                    /* Skip the critical information */
  927                    if (input[dataIdx] == ASN_BOOLEAN) {
  928                        dataIdx++;
  929                        ret = GetLength(input, &dataIdx, &dataLen, sz) >= 0;
  930                        dataIdx += dataLen;
  931                    }
  932                }
  933                if (ret) {
  934                    ret = GetOctetString(input, &dataIdx, &dataLen,
  935                            (word32)sz) > 0;
  936                }
  937                if (ret) {
  938                    ret = wolfSSL_ASN1_STRING_set(&ext->value, input + dataIdx,
  939                            dataLen) == 1;
  940                }
  941
  942                if (a == NULL || !ret) {
  943                    wolfSSL_X509_EXTENSION_free(ext);
  944                    FreeDecodedCert(cert);
  945                    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  946                    return NULL;
  947                }
  948                a->length = (int)x509->pathLength;
  949
  950                /* Save ASN1_INTEGER in x509 extension */
  951                ext->obj->pathlen = a;
  952
  953                ext->obj->ca = x509->isCa;
  954                break;
  955            }
  956
  957            case AUTH_INFO_OID:
  958            {
  959                WOLFSSL_STACK* sk;
  960
  961                if (!isSet)
  962                    break;
  963
  964                /* Create a stack to hold both the caIssuer and ocsp objects
  965                    in X509_EXTENSION structure */
  966                sk = wolfSSL_sk_new_asn1_obj();
  967                if (sk == NULL) {
  968                    WOLFSSL_MSG("Failed to malloc stack");
  969                    wolfSSL_X509_EXTENSION_free(ext);
  970                    FreeDecodedCert(cert);
  971                    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  972                    return NULL;
  973                }
  974
  975                /* Add CaIssuers object to stack */
  976                if (x509->authInfoCaIssuer != NULL &&
  977                    x509->authInfoCaIssuerSz > 0)
  978                {
  979                    WOLFSSL_ASN1_OBJECT* obj;
  980                    obj = wolfSSL_ASN1_OBJECT_new();
  981                    if (obj == NULL) {
  982                        WOLFSSL_MSG("Error creating ASN1 object");
  983                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
  984                        wolfSSL_X509_EXTENSION_free(ext);
  985                        FreeDecodedCert(cert);
  986                        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
  987                        return NULL;
  988                    }
  989                    obj->obj = (byte*)x509->authInfoCaIssuer;
  990                    obj->objSz = (unsigned int)x509->authInfoCaIssuerSz;
  991                    obj->grp = oidCertAuthInfoType;
  992                    obj->nid = WC_NID_ad_ca_issuers;
  993
  994                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj) > 0
  995                            ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
  996                    if (ret != WOLFSSL_SUCCESS) {
  997                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
  998                        wolfSSL_ASN1_OBJECT_free(obj);
  999                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 1000                        wolfSSL_X509_EXTENSION_free(ext);
 1001                        FreeDecodedCert(cert);
 1002                        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1003                        return NULL;
 1004                    }
 1005                }
 1006
 1007                /* Add OCSP object to stack */
 1008                if (x509->authInfo != NULL &&
 1009                    x509->authInfoSz > 0)
 1010                {
 1011                    WOLFSSL_ASN1_OBJECT* obj;
 1012                    obj = wolfSSL_ASN1_OBJECT_new();
 1013                    if (obj == NULL) {
 1014                        WOLFSSL_MSG("Error creating ASN1 object");
 1015                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 1016                        wolfSSL_X509_EXTENSION_free(ext);
 1017                        FreeDecodedCert(cert);
 1018                        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1019                        return NULL;
 1020                    }
 1021                    obj->obj = x509->authInfo;
 1022                    obj->objSz = (unsigned int)x509->authInfoSz;
 1023                    obj->grp = oidCertAuthInfoType;
 1024                    obj->nid = WC_NID_ad_OCSP;
 1025
 1026                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj) > 0
 1027                            ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 1028                    if (ret != WOLFSSL_SUCCESS) {
 1029                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
 1030                        wolfSSL_ASN1_OBJECT_free(obj);
 1031                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 1032                        wolfSSL_X509_EXTENSION_free(ext);
 1033                        FreeDecodedCert(cert);
 1034                        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1035                        return NULL;
 1036                    }
 1037                }
 1038                ext->ext_sk = sk;
 1039                break;
 1040            }
 1041
 1042            case ALT_NAMES_OID:
 1043                if (!isSet)
 1044                    break;
 1045                if (!wolfssl_x509_alt_names_to_gn(x509, ext)) {
 1046                    wolfSSL_X509_EXTENSION_free(ext);
 1047                    FreeDecodedCert(cert);
 1048                    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1049                    return NULL;
 1050                }
 1051                break;
 1052        }
 1053
 1054        /* The ASN1_OBJECT in the extension is set in the same way
 1055         * for recognized and for unrecognized extension types, as
 1056         * the full OCTET STRING */
 1057
 1058        /* Get OID from input */
 1059        if (GetASNObjectId(input, &idx, &length, (word32)sz) != 0) {
 1060            WOLFSSL_MSG("Failed to Get ASN Object Id");
 1061            wolfSSL_X509_EXTENSION_free(ext);
 1062            FreeDecodedCert(cert);
 1063            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1064            return NULL;
 1065        }
 1066        oidBuf = (byte*)XMALLOC(length+1+MAX_LENGTH_SZ, NULL,
 1067                            DYNAMIC_TYPE_TMP_BUFFER);
 1068        if (oidBuf == NULL) {
 1069            WOLFSSL_MSG("Failed to malloc tmp buffer");
 1070            wolfSSL_X509_EXTENSION_free(ext);
 1071            FreeDecodedCert(cert);
 1072            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1073            return NULL;
 1074        }
 1075        oidBuf[0] = ASN_OBJECT_ID;
 1076        objSz++;
 1077        objSz += SetLength(length, oidBuf + 1);
 1078        objSz += length;
 1079
 1080        /* Set object size and reallocate space in object buffer */
 1081        if (ext->obj == NULL) {
 1082            ext->obj = wolfSSL_ASN1_OBJECT_new();
 1083            if (ext->obj == NULL) {
 1084                XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 1085                wolfSSL_X509_EXTENSION_free(ext);
 1086                FreeDecodedCert(cert);
 1087                WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1088                return NULL;
 1089            }
 1090        }
 1091
 1092        if (((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
 1093            (ext->obj->obj == NULL)) {
 1094            byte* tmp;
 1095        #ifdef WOLFSSL_NO_REALLOC
 1096            tmp = (byte*)XMALLOC(objSz, NULL, DYNAMIC_TYPE_ASN1);
 1097            if (tmp != NULL && ext->obj->obj != NULL) {
 1098                XMEMCPY(tmp, ext->obj->obj, ext->obj->objSz);
 1099                XFREE((byte*)ext->obj->obj, NULL, DYNAMIC_TYPE_ASN1);
 1100            }
 1101            else if (tmp == NULL) {
 1102                XFREE((byte*)ext->obj->obj, NULL, DYNAMIC_TYPE_ASN1);
 1103            }
 1104            ext->obj->obj = tmp;
 1105        #else
 1106            tmp = (byte*)XREALLOC((byte*)ext->obj->obj, objSz, NULL,
 1107                                  DYNAMIC_TYPE_ASN1);
 1108            if (tmp == NULL)
 1109                XFREE((byte*)ext->obj->obj, NULL, DYNAMIC_TYPE_ASN1);
 1110            ext->obj->obj = tmp;
 1111        #endif
 1112            if (ext->obj->obj == NULL) {
 1113                wolfSSL_X509_EXTENSION_free(ext);
 1114                FreeDecodedCert(cert);
 1115                XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 1116                WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1117                return NULL;
 1118            }
 1119            ext->obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
 1120        }
 1121        else {
 1122            ext->obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
 1123        }
 1124        ext->obj->objSz = (unsigned int)objSz;
 1125
 1126        /* Get OID from input and copy to ASN1_OBJECT buffer */
 1127        XMEMCPY(oidBuf+2, input+idx, length);
 1128        XMEMCPY((byte*)ext->obj->obj, oidBuf, ext->obj->objSz);
 1129        XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 1130        oidBuf = NULL;
 1131        ext->obj->grp = oidCertExtType;
 1132        ext->crit = 0;
 1133
 1134        tmpIdx = idx + length;
 1135
 1136        /* Get CRITICAL. If not present, defaults to false.
 1137         * It present, must be a valid TRUE */
 1138        if ((tmpIdx < (word32)sz) &&
 1139            (input[tmpIdx] == ASN_BOOLEAN))
 1140        {
 1141            if (((tmpIdx + 2) >= (word32)sz) ||
 1142                /* Check bool length */
 1143                (input[tmpIdx+1] != 1) ||
 1144                /* Assert true if CRITICAL present */
 1145                (input[tmpIdx+2] != 0xff))
 1146            {
 1147                WOLFSSL_MSG("Error decoding unknown extension data");
 1148                wolfSSL_ASN1_OBJECT_free(ext->obj);
 1149                wolfSSL_X509_EXTENSION_free(ext);
 1150                FreeDecodedCert(cert);
 1151                WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1152                return NULL;
 1153            }
 1154
 1155            ext->crit = 1;
 1156            tmpIdx += 3;
 1157        }
 1158
 1159        /* Get extension data and copy as ASN1_STRING */
 1160        if ((tmpIdx >= (word32)sz) ||
 1161            (input[tmpIdx] != ASN_OCTET_STRING))
 1162        {
 1163            WOLFSSL_MSG("Error decoding unknown extension data");
 1164            wolfSSL_ASN1_OBJECT_free(ext->obj);
 1165            wolfSSL_X509_EXTENSION_free(ext);
 1166            FreeDecodedCert(cert);
 1167            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1168            return NULL;
 1169        }
 1170
 1171        tmpIdx++;
 1172
 1173        if (GetLength(input, &tmpIdx, &length, (word32)sz) <= 0) {
 1174            WOLFSSL_MSG("Error: Invalid Input Length.");
 1175            wolfSSL_ASN1_OBJECT_free(ext->obj);
 1176            wolfSSL_X509_EXTENSION_free(ext);
 1177            FreeDecodedCert(cert);
 1178            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1179            return NULL;
 1180        }
 1181        ext->value.data = (char*)XMALLOC(length, NULL,
 1182            DYNAMIC_TYPE_ASN1);
 1183        ext->value.isDynamic = 1;
 1184        if (ext->value.data == NULL) {
 1185            WOLFSSL_MSG("Failed to malloc ASN1_STRING data");
 1186            wolfSSL_X509_EXTENSION_free(ext);
 1187            FreeDecodedCert(cert);
 1188            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1189            return NULL;
 1190        }
 1191        XMEMCPY(ext->value.data,input+tmpIdx,length);
 1192        ext->value.length = length;
 1193
 1194        break; /* Got the Extension. Now exit while loop. */
 1195
 1196    } /* while(idx < sz) */
 1197
 1198    /* Store the new extension in a stack inside x509
 1199     * The extensions on the stack are free'd internally when FreeX509 is called
 1200     */
 1201    if (x509->ext_sk == NULL)
 1202        x509->ext_sk = wolfSSL_sk_new_x509_ext();
 1203    if (wolfSSL_sk_insert(x509->ext_sk, ext, -1) <= 0) {
 1204        wolfSSL_X509_EXTENSION_free(ext);
 1205        ext = NULL;
 1206    }
 1207
 1208    FreeDecodedCert(cert);
 1209    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 1210    return ext;
 1211}
 1212
 1213/**
 1214 * @param str String to copy
 1215 * @param buf Output buffer. If this contains a pointer then it is free'd
 1216 *            with the DYNAMIC_TYPE_X509_EXT hint.
 1217 * @param len Output length
 1218 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
 1219 */
 1220static int asn1_string_copy_to_buffer(WOLFSSL_ASN1_STRING* str, byte** buf,
 1221        word32* len, void* heap)
 1222{
 1223    if (str->data && str->length > 0) {
 1224        if (*buf)
 1225            XFREE(*buf, heap, DYNAMIC_TYPE_X509_EXT);
 1226        *len = 0;
 1227        *buf = (byte*)XMALLOC(str->length, heap, DYNAMIC_TYPE_X509_EXT);
 1228        if (!*buf) {
 1229            WOLFSSL_MSG("malloc error");
 1230            return WOLFSSL_FAILURE;
 1231        }
 1232        *len = (word32)str->length;
 1233        XMEMCPY(*buf, str->data, str->length);
 1234    }
 1235
 1236    (void)heap;
 1237    return WOLFSSL_SUCCESS;
 1238}
 1239
 1240int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext,
 1241    int loc)
 1242{
 1243    int nid;
 1244
 1245    WOLFSSL_ENTER("wolfSSL_X509_add_ext");
 1246
 1247    if (!x509 || !ext || loc >= 0) {
 1248        WOLFSSL_MSG("Bad parameter");
 1249        return WOLFSSL_FAILURE;
 1250    }
 1251    nid = (ext->obj != NULL) ? ext->obj->type : ext->value.nid;
 1252
 1253    switch (nid) {
 1254    case WC_NID_authority_key_identifier:
 1255        if (x509->authKeyIdSrc != NULL) {
 1256            /* If authKeyId points into authKeyIdSrc then free it and
 1257             * revert to old functionality */
 1258            XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
 1259            x509->authKeyIdSrc = NULL;
 1260            x509->authKeyId = NULL;
 1261        }
 1262        if (asn1_string_copy_to_buffer(&ext->value, &x509->authKeyId,
 1263                &x509->authKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
 1264            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
 1265            return WOLFSSL_FAILURE;
 1266        }
 1267        x509->authKeyIdCrit = (byte)ext->crit;
 1268        break;
 1269    case WC_NID_subject_key_identifier:
 1270        if (asn1_string_copy_to_buffer(&ext->value, &x509->subjKeyId,
 1271                &x509->subjKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
 1272            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
 1273            return WOLFSSL_FAILURE;
 1274        }
 1275        x509->subjKeyIdCrit = (byte)ext->crit;
 1276        break;
 1277    case WC_NID_subject_alt_name:
 1278    {
 1279        WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk;
 1280        while (gns) {
 1281            WOLFSSL_GENERAL_NAME* gn = gns->data.gn;
 1282            if ((gn != NULL) && (gn->type == ASN_OTHER_TYPE)) {
 1283                char *buf = NULL;
 1284                int ret = 0;
 1285                word32 len = 0;
 1286
 1287                len = SetOthername(gn->d.otherName, NULL);
 1288                if (len == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
 1289                    return WOLFSSL_FAILURE;
 1290                }
 1291
 1292                buf = (char*)XMALLOC(len, x509->heap, DYNAMIC_TYPE_X509_EXT);
 1293                if (buf == NULL) {
 1294                    WOLFSSL_MSG("Couldn't allocate memory for othername");
 1295                    return WOLFSSL_FAILURE;
 1296                }
 1297
 1298                /* SetOthername() cannot fail; already passed above. */
 1299                SetOthername(gn->d.otherName, (byte*)buf);
 1300
 1301                ret = wolfSSL_X509_add_altname_ex(x509, buf, len,
 1302                                                  ASN_OTHER_TYPE);
 1303                XFREE(buf, x509->heap, DYNAMIC_TYPE_X509_EXT);
 1304                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
 1305                     WOLFSSL_MSG("wolfSSL_X509_add_altname_ex() failed");
 1306                     return WOLFSSL_FAILURE;
 1307                }
 1308            }
 1309            else if (!gn || !gn->d.ia5 ||
 1310                wolfSSL_X509_add_altname_ex(x509, gn->d.ia5->data,
 1311                    gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) {
 1312                WOLFSSL_MSG("Subject alternative name missing extension");
 1313                return WOLFSSL_FAILURE;
 1314            }
 1315            gns = gns->next;
 1316        }
 1317        x509->subjAltNameSet = 1;
 1318        x509->subjAltNameCrit = (byte)ext->crit;
 1319        break;
 1320    }
 1321    case WC_NID_key_usage:
 1322        if (ext && ext->value.data) {
 1323            if (ext->value.length == sizeof(word16)) {
 1324                /* if ext->value is already word16, set directly */
 1325                word16 ku;
 1326                XMEMCPY(&ku, ext->value.data, sizeof(word16));
 1327                x509->keyUsage = ku;
 1328#ifdef BIG_ENDIAN_ORDER
 1329                x509->keyUsage = rotlFixed16(x509->keyUsage, 8U);
 1330#endif
 1331                x509->keyUsageCrit = (byte)ext->crit;
 1332                x509->keyUsageSet = 1;
 1333            }
 1334            else if (ext->value.length > 0) {
 1335                /* ext->value is comma-delimited string, convert to word16 */
 1336                if (ParseKeyUsageStr(ext->value.data, &x509->keyUsage,
 1337                                     x509->heap) != 0) {
 1338                    return WOLFSSL_FAILURE;
 1339                }
 1340                x509->keyUsageCrit = (byte)ext->crit;
 1341                x509->keyUsageSet = 1;
 1342            }
 1343            else {
 1344                return WOLFSSL_FAILURE;
 1345            }
 1346        }
 1347        break;
 1348    case WC_NID_ext_key_usage:
 1349        if (ext && ext->value.data) {
 1350            if (ext->value.length == sizeof(byte)) {
 1351                /* if ext->value is already 1 byte, set directly */
 1352                x509->extKeyUsage = *(byte*)ext->value.data;
 1353                x509->extKeyUsageCrit = (byte)ext->crit;
 1354            }
 1355            else if (ext->value.length > 0) {
 1356                /* ext->value is comma-delimited string, convert to word16 */
 1357                if (ParseExtKeyUsageStr(ext->value.data, &x509->extKeyUsage,
 1358                                        x509->heap) != 0) {
 1359                    return WOLFSSL_FAILURE;
 1360                }
 1361                x509->extKeyUsageCrit = (byte)ext->crit;
 1362            }
 1363            else {
 1364                return WOLFSSL_FAILURE;
 1365            }
 1366        }
 1367        break;
 1368    case WC_NID_basic_constraints:
 1369        if (ext->obj) {
 1370            x509->isCa = (byte)ext->obj->ca;
 1371            x509->basicConstCrit = (byte)ext->crit;
 1372            if (ext->obj->pathlen) {
 1373                x509->pathLength = (word32)ext->obj->pathlen->length;
 1374                x509->basicConstPlSet = 1;
 1375                x509->pathLengthSet = 1;
 1376            }
 1377            x509->basicConstSet = 1;
 1378        }
 1379        break;
 1380    default:
 1381#ifdef WOLFSSL_CUSTOM_OID
 1382    {
 1383        char *oid = NULL;
 1384        byte *val = NULL;
 1385        int err = 0;
 1386
 1387        if ((ext->obj == NULL) || (ext->value.length == 0)) {
 1388            WOLFSSL_MSG("Extension has insufficient information.");
 1389            return WOLFSSL_FAILURE;
 1390        }
 1391
 1392        if ((x509->customExtCount < 0) ||
 1393            (x509->customExtCount >= NUM_CUSTOM_EXT)) {
 1394            WOLFSSL_MSG("Bad value for customExtCount.");
 1395            return WOLFSSL_FAILURE;
 1396        }
 1397
 1398        /* This is a viable custom extension. */
 1399        oid = (char*)XMALLOC(MAX_OID_STRING_SZ, x509->heap,
 1400            DYNAMIC_TYPE_X509_EXT);
 1401        val = (byte*)XMALLOC(ext->value.length, x509->heap,
 1402            DYNAMIC_TYPE_X509_EXT);
 1403        if ((oid == NULL) || (val == NULL)) {
 1404            WOLFSSL_MSG("Memory allocation failure.\n");
 1405            err = 1;
 1406        }
 1407
 1408        if (err == 0) {
 1409            XMEMCPY(val, ext->value.data, ext->value.length);
 1410            if (wolfSSL_OBJ_obj2txt(oid, MAX_OID_STRING_SZ, ext->obj, 1) < 0) {
 1411                err = 1;
 1412            }
 1413        }
 1414
 1415        if (err == 1) {
 1416            XFREE(val, x509->heap, DYNAMIC_TYPE_X509_EXT);
 1417            XFREE(oid, x509->heap, DYNAMIC_TYPE_X509_EXT);
 1418            return WOLFSSL_FAILURE;
 1419        }
 1420
 1421        /* ext->crit is WOLFSSL_ASN1_BOOLEAN */
 1422        if (ext->crit != 0 && ext->crit != -1) {
 1423            XFREE(val, x509->heap, DYNAMIC_TYPE_X509_EXT);
 1424            XFREE(oid, x509->heap, DYNAMIC_TYPE_X509_EXT);
 1425            return WOLFSSL_FAILURE;
 1426        }
 1427
 1428        /* x509->custom_exts now owns the buffers and they must be managed. */
 1429        x509->custom_exts[x509->customExtCount].oid = oid;
 1430        x509->custom_exts[x509->customExtCount].crit = (byte)ext->crit;
 1431        x509->custom_exts[x509->customExtCount].val = val;
 1432        x509->custom_exts[x509->customExtCount].valSz = ext->value.length;
 1433        x509->customExtCount++;
 1434        break;
 1435    }
 1436#else
 1437        WOLFSSL_MSG("Unsupported extension to add");
 1438        return WOLFSSL_FAILURE;
 1439#endif /* WOLFSSL_CUSTOM_OID */
 1440    } /* switch (nid) */
 1441
 1442    return WOLFSSL_SUCCESS;
 1443}
 1444
 1445/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
 1446static WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data_internal(
 1447    WOLFSSL_X509_EXTENSION* ext)
 1448{
 1449    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_data_internal");
 1450    if (ext == NULL)
 1451        return NULL;
 1452
 1453    return &ext->value;
 1454}
 1455
 1456
 1457#ifndef NO_BIO
 1458
 1459#ifndef MAX_INDENT
 1460    #define MAX_INDENT 40
 1461#endif
 1462
 1463
 1464/* Return 0 on success and 1 on failure. Copies ext data to bio, using indent
 1465 *  to pad the output. flag is ignored. */
 1466int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext,
 1467        unsigned long flag, int indent)
 1468{
 1469    WOLFSSL_ASN1_OBJECT* obj;
 1470    WOLFSSL_ASN1_STRING* str;
 1471    int nid;
 1472    int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 1473    char tmp[CTC_NAME_SIZE*2 + 1];
 1474    const int tmpSz = sizeof(tmp);
 1475    int tmpLen = 0;
 1476    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_print");
 1477
 1478    if (indent < 0) indent = 0;
 1479    if (indent > MAX_INDENT) indent = MAX_INDENT;
 1480
 1481    if ((out == NULL) || (ext == NULL)) {
 1482        WOLFSSL_MSG("NULL parameter error");
 1483        return rc;
 1484    }
 1485
 1486    obj = wolfSSL_X509_EXTENSION_get_object(ext);
 1487    if (obj == NULL) {
 1488        WOLFSSL_MSG("Error getting ASN1_OBJECT from X509_EXTENSION");
 1489        return rc;
 1490    }
 1491
 1492    str = wolfSSL_X509_EXTENSION_get_data_internal(ext);
 1493    if (str == NULL) {
 1494        WOLFSSL_MSG("Error getting ASN1_STRING from X509_EXTENSION");
 1495        return rc;
 1496    }
 1497
 1498    /* Print extension based on the type */
 1499    nid = wolfSSL_OBJ_obj2nid(obj);
 1500    switch (nid) {
 1501        case BASIC_CA_OID:
 1502        {
 1503            char isCa[] = "TRUE";
 1504            char notCa[] = "FALSE";
 1505            if ((tmpLen = XSNPRINTF(tmp, tmpSz, "%*sCA:%s", indent, "",
 1506                                     obj->ca ? isCa : notCa))
 1507                >= tmpSz)
 1508                return rc;
 1509            break;
 1510        }
 1511        case ALT_NAMES_OID:
 1512        {
 1513            WOLFSSL_STACK* sk;
 1514            char* val;
 1515            int valLen;
 1516            int len;
 1517
 1518            sk = ext->ext_sk;
 1519            while (sk != NULL) {
 1520                if (sk->type == STACK_TYPE_GEN_NAME && sk->data.gn) {
 1521                    /* str is GENERAL_NAME for subject alternative name ext */
 1522                    str = sk->data.gn->d.ia5;
 1523                    len = str->length + 2; /* + 2 for NULL char and "," */
 1524                    if (len > tmpSz) {
 1525                        WOLFSSL_MSG("len greater than buffer size");
 1526                        return rc;
 1527                    }
 1528
 1529                    val = (char*)XMALLOC(len + indent, NULL,
 1530                                                       DYNAMIC_TYPE_TMP_BUFFER);
 1531                    if (val == NULL) {
 1532                        WOLFSSL_MSG("Memory error");
 1533                        return rc;
 1534                    }
 1535                    valLen = XSNPRINTF(val, (size_t)len, "%*s%s", indent, "",
 1536                            str->strData);
 1537                    if ((valLen < 0) || (valLen >= len)
 1538                            || ((tmpLen + valLen) >= tmpSz)) {
 1539                        XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 1540                        return rc;
 1541                    }
 1542                    XMEMCPY(tmp + tmpLen, val, valLen);
 1543                    tmpLen += valLen;
 1544                    XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 1545                }
 1546                sk = sk->next;
 1547            }
 1548            break;
 1549        }
 1550        case AUTH_KEY_OID:
 1551        case SUBJ_KEY_OID:
 1552        {
 1553            char* asn1str;
 1554            asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str);
 1555            tmpLen = XSNPRINTF(tmp, tmpSz, "%*s%s", indent, "", asn1str);
 1556            XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 1557            if (tmpLen >= tmpSz)
 1558                tmpLen = tmpSz - 1;
 1559            break;
 1560        }
 1561        case AUTH_INFO_OID:
 1562        case CERT_POLICY_OID:
 1563        case CRL_DIST_OID:
 1564        case KEY_USAGE_OID:
 1565            WOLFSSL_MSG("X509V3_EXT_print not yet implemented for ext type");
 1566            break;
 1567
 1568        default:
 1569            if ((tmpLen = XSNPRINTF(
 1570                     tmp, tmpSz, "%*s%s", indent, "", str->strData))
 1571                >= tmpSz)
 1572                return rc;
 1573    }
 1574
 1575    if (wolfSSL_BIO_write(out, tmp, tmpLen) == tmpLen) {
 1576        rc = WOLFSSL_SUCCESS;
 1577    }
 1578    (void) flag;
 1579
 1580    return rc;
 1581}
 1582#endif /* !NO_BIO */
 1583
 1584#ifndef NO_WOLFSSL_STUB
 1585int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx,
 1586        const char *section, WOLFSSL_X509 *cert)
 1587{
 1588    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_add_nconf");
 1589    WOLFSSL_STUB("wolfSSL_X509V3_EXT_add_nconf");
 1590    (void)conf;
 1591    (void)ctx;
 1592    (void)section;
 1593    (void)cert;
 1594    return WOLFSSL_SUCCESS;
 1595}
 1596#endif
 1597
 1598/* Find extension by NID in a stack of extensions.
 1599 *
 1600 * @param sk Stack of extensions
 1601 * @param nid ID to search for
 1602 * @param lastpos Start search from this position (not inclusive, -1 means start from beginning)
 1603 * @return Index of matching extension or -1 on error/not found
 1604 */
 1605int wolfSSL_X509v3_get_ext_by_NID(const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
 1606                                 int nid, int lastpos)
 1607{
 1608    int i;
 1609    WOLFSSL_ENTER("wolfSSL_X509v3_get_ext_by_NID");
 1610
 1611    if (sk == NULL) {
 1612        WOLFSSL_MSG("Stack pointer is NULL");
 1613        return WOLFSSL_FATAL_ERROR;
 1614    }
 1615
 1616    if (lastpos < -1 || lastpos >= wolfSSL_sk_num(sk)) {
 1617        WOLFSSL_MSG("Invalid position argument");
 1618        return WOLFSSL_FATAL_ERROR;
 1619    }
 1620
 1621    for (i = lastpos + 1; i < wolfSSL_sk_num(sk); i++) {
 1622        WOLFSSL_X509_EXTENSION* ext = wolfSSL_sk_X509_EXTENSION_value(sk, i);
 1623        if (ext && ext->obj) {
 1624            if (wolfSSL_OBJ_obj2nid(ext->obj) == nid)
 1625                return i;
 1626        }
 1627    }
 1628
 1629    /* Not found */
 1630    return -1;
 1631}
 1632
 1633/* Get extension from a stack of extensions by location.
 1634 *
 1635 * @param sk Stack of extensions
 1636 * @param loc Index of extension to retrieve
 1637 * @return Pointer to extension or NULL on error
 1638 */
 1639WOLFSSL_X509_EXTENSION* wolfSSL_X509v3_get_ext(
 1640    const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int loc)
 1641{
 1642    WOLFSSL_ENTER("wolfSSL_X509v3_get_ext");
 1643
 1644    if (sk == NULL) {
 1645        WOLFSSL_MSG("Stack pointer is NULL");
 1646        return NULL;
 1647    }
 1648
 1649    if (loc < 0 || loc >= wolfSSL_sk_num(sk)) {
 1650        WOLFSSL_MSG("Invalid location argument");
 1651        return NULL;
 1652    }
 1653
 1654    return wolfSSL_sk_X509_EXTENSION_value(sk, loc);
 1655}
 1656
 1657/* Returns crit flag in X509_EXTENSION object */
 1658int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex)
 1659{
 1660    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_critical");
 1661    if (ex == NULL)
 1662        return BAD_FUNC_ARG;
 1663    return ex->crit;
 1664}
 1665
 1666/* Sets if the extension is critical
 1667 * returns WOLFSSL_SUCCESS on success
 1668 */
 1669int wolfSSL_X509_EXTENSION_set_critical(WOLFSSL_X509_EXTENSION* ex, int crit)
 1670{
 1671    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_critical");
 1672    if (ex == NULL)
 1673        return WOLFSSL_FAILURE;
 1674    ex->crit = crit;
 1675    return WOLFSSL_SUCCESS;
 1676}
 1677
 1678/* Creates v3_ext_method for a given X509v3 extension
 1679 *
 1680 * ex   : The X509_EXTENSION used to create v3_ext_method. If the extension is
 1681 * not NULL, get the NID of the extension object and populate the
 1682 * extension type-specific X509V3_EXT_* function(s) in v3_ext_method.
 1683 *
 1684 * Returns NULL on error or pointer to the v3_ext_method populated with
 1685 * extension type-specific X509V3_EXT_* function(s).
 1686 *
 1687 * NOTE: WC_NID_subject_key_identifier is currently the only extension
 1688 * implementing the X509V3_EXT_* functions, as it is the only type called
 1689 * directly by QT. The other extension types return a pointer to a
 1690 * v3_ext_method struct that contains only the NID.
 1691 */
 1692#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
 1693const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
 1694#else
 1695WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
 1696#endif
 1697{
 1698    int nid;
 1699    WOLFSSL_v3_ext_method method;
 1700
 1701    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_get");
 1702    if ((ex == NULL) || (ex->obj == NULL)) {
 1703        WOLFSSL_MSG("Passed an invalid X509_EXTENSION*");
 1704        return NULL;
 1705    }
 1706    /* Initialize method to 0 */
 1707    XMEMSET(&method, 0, sizeof(struct WOLFSSL_v3_ext_method));
 1708
 1709    nid = ex->obj->nid;
 1710    if (nid <= 0) {
 1711        WOLFSSL_MSG("Failed to get nid from passed extension object");
 1712        return NULL;
 1713    }
 1714    switch (nid) {
 1715        case WC_NID_basic_constraints:
 1716            break;
 1717        case WC_NID_subject_key_identifier:
 1718            method.i2s = (WOLFSSL_X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
 1719            break;
 1720        case WC_NID_subject_alt_name:
 1721            WOLFSSL_MSG("i2v function not yet implemented for Subject "
 1722                        "Alternative Name");
 1723            break;
 1724        case WC_NID_key_usage:
 1725            WOLFSSL_MSG("i2v function not yet implemented for Key Usage");
 1726            break;
 1727        case WC_NID_authority_key_identifier:
 1728            WOLFSSL_MSG("i2v function not yet implemented for Auth Key Id");
 1729            break;
 1730        case WC_NID_info_access:
 1731            WOLFSSL_MSG("i2v function not yet implemented for Info Access");
 1732            break;
 1733        case WC_NID_ext_key_usage:
 1734            WOLFSSL_MSG("i2v function not yet implemented for Ext Key Usage");
 1735            break;
 1736        case WC_NID_certificate_policies:
 1737            WOLFSSL_MSG("r2i function not yet implemented for Cert Policies");
 1738            break;
 1739        case WC_NID_crl_distribution_points:
 1740            WOLFSSL_MSG("r2i function not yet implemented for CRL Dist Points");
 1741            break;
 1742        default:
 1743            /* If extension type is unknown, return NULL -- QT makes call to
 1744                X509_EXTENSION_get_data() if there is no v3_ext_method */
 1745            WOLFSSL_MSG("X509V3_EXT_get(): Unknown extension type found");
 1746            return NULL;
 1747    }
 1748
 1749    method.ext_nid = nid;
 1750    ex->ext_method = method;
 1751
 1752#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
 1753    return (const WOLFSSL_v3_ext_method*)&ex->ext_method;
 1754#else
 1755    return (WOLFSSL_v3_ext_method*)&ex->ext_method;
 1756#endif
 1757}
 1758
 1759/* Create an Authority Info Access (AIA) from the contents of the extension.
 1760 *
 1761 * AIA is a stack of Access Descriptions.
 1762 *
 1763 * RFC 5280: 4.2.2.1
 1764 *
 1765 * @param [in] ext  X509v3 extension.
 1766 * @return  Stack of Access Descriptions as an AIA on success.
 1767 * @return  NULL on error.
 1768 */
 1769static WOLFSSL_AUTHORITY_INFO_ACCESS* wolfssl_x509v3_ext_aia_d2i(
 1770    WOLFSSL_X509_EXTENSION* ext)
 1771{
 1772    int err = 0;
 1773    int ret;
 1774    WOLFSSL_AUTHORITY_INFO_ACCESS* aia = NULL;
 1775    WOLFSSL_STACK* sk;
 1776    WOLFSSL_ACCESS_DESCRIPTION* ad = NULL;
 1777
 1778    /* Get the type specific data of this extension. */
 1779    sk = ext->ext_sk;
 1780    if (sk == NULL) {
 1781        WOLFSSL_MSG("ACCESS_DESCRIPTION stack NULL");
 1782        err = 1;
 1783    }
 1784
 1785    if (!err) {
 1786        /* AUTHORITY_INFO_ACCESS is a stack of ACCESS_DESCRIPTION entries. */
 1787        aia = wolfSSL_sk_new_null();
 1788        if (aia == NULL) {
 1789            WOLFSSL_MSG("Failed to malloc AUTHORITY_INFO_ACCESS");
 1790            err = 1;
 1791        }
 1792    }
 1793    if (!err) {
 1794        /* AIA is a stack of Access Descriptions. */
 1795        aia->type = STACK_TYPE_ACCESS_DESCRIPTION;
 1796    }
 1797
 1798    while ((!err) && (sk != NULL)) {
 1799        WOLFSSL_ASN1_OBJECT* aiaEntry;
 1800
 1801        /* Looking for objects in extension's data. */
 1802        if (sk->type != STACK_TYPE_OBJ) {
 1803            sk = sk->next;
 1804            continue;
 1805        }
 1806
 1807        /* Get ASN.1 Object from the stack entry's data. */
 1808        aiaEntry = sk->data.obj;
 1809
 1810        /* ACCESS_DESCRIPTION has two members: method and location.
 1811         *  method: ASN1_OBJECT as either AIA_OCSP_OID or AIA_CA_ISSUER_OID
 1812         *  location: GENERAL_NAME structure containing the URI.
 1813         */
 1814
 1815        /* Allocate a new Access Description. */
 1816        ad = (WOLFSSL_ACCESS_DESCRIPTION*)XMALLOC(
 1817            sizeof(WOLFSSL_ACCESS_DESCRIPTION), NULL, DYNAMIC_TYPE_X509_EXT);
 1818        if (ad == NULL) {
 1819            WOLFSSL_MSG("Failed to malloc ACCESS_DESCRIPTION");
 1820            err = 1;
 1821            break;
 1822        }
 1823        XMEMSET(ad, 0, sizeof(WOLFSSL_ACCESS_DESCRIPTION));
 1824
 1825        /* Create new ASN1_OBJECT from NID. */
 1826        ad->method = wolfSSL_OBJ_nid2obj(aiaEntry->nid);
 1827        if (ad->method == NULL) {
 1828            WOLFSSL_MSG("OBJ_nid2obj() failed");
 1829            err = 1;
 1830            break;
 1831        }
 1832
 1833        /* Allocate memory for GENERAL NAME. */
 1834        ad->location = wolfSSL_GENERAL_NAME_new();
 1835        if (ad->location == NULL) {
 1836            WOLFSSL_MSG("Failed to malloc GENERAL_NAME");
 1837            err = 1;
 1838            break;
 1839        }
 1840
 1841        /* Set the type of general name to URI (only type supported). */
 1842        ret = wolfSSL_GENERAL_NAME_set_type(ad->location, WOLFSSL_GEN_URI);
 1843        if (ret != WOLFSSL_SUCCESS) {
 1844            err = 1;
 1845            break;
 1846        }
 1847
 1848        /* Set the URI into GENERAL_NAME. */
 1849        ret = wolfSSL_ASN1_STRING_set(ad->location->d.uniformResourceIdentifier,
 1850            aiaEntry->obj, aiaEntry->objSz);
 1851        if (ret != WOLFSSL_SUCCESS) {
 1852            WOLFSSL_MSG("ASN1_STRING_set() failed");
 1853            err = 1;
 1854            break;
 1855        }
 1856        /* Push onto AUTHORITY_INFO_ACCESS stack. */
 1857        ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad) > 0
 1858                ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 1859        if (ret != WOLFSSL_SUCCESS) {
 1860            WOLFSSL_MSG("Error pushing ASN1 AD onto stack");
 1861            err = 1;
 1862            break;
 1863        }
 1864        /* Set to NULL so that it doesn't get freed now it is in AIA stack. */
 1865        ad = NULL;
 1866
 1867        sk = sk->next;
 1868    }
 1869
 1870    if (err) {
 1871        /* Dispose of Access Description if not put in stack. */
 1872        if (ad != NULL) {
 1873            wolfSSL_ASN1_OBJECT_free(ad->method);
 1874            wolfSSL_GENERAL_NAME_free(ad->location);
 1875            XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
 1876        }
 1877        /* Dispose of incomplete Access Description stack. */
 1878        wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
 1879        aia = NULL;
 1880    }
 1881    return aia;
 1882}
 1883
 1884/* Parses and returns an x509v3 extension internal structure.
 1885 *
 1886 * ext   : The X509_EXTENSION for parsing internal structure. If extension is
 1887 * not NULL, get the NID of the extension object and create a new
 1888 * extension-specific internal structure based on the extension type.
 1889 *
 1890 * Returns NULL on error or if NID is not found, otherwise returns a pointer to
 1891 * the extension type-specific X509_EXTENSION internal structure.
 1892 * Return is expected to be free'd by caller.
 1893 */
 1894void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
 1895{
 1896    const WOLFSSL_v3_ext_method* method;
 1897    int ret;
 1898    WOLFSSL_ASN1_OBJECT* object;
 1899    WOLFSSL_BASIC_CONSTRAINTS* bc;
 1900    WOLFSSL_AUTHORITY_KEYID* akey;
 1901    WOLFSSL_ASN1_STRING* asn1String = NULL, *newString = NULL;
 1902    WOLFSSL_STACK* sk;
 1903    void *data = NULL;
 1904    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
 1905
 1906    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_d2i");
 1907
 1908    if (ext == NULL) {
 1909        WOLFSSL_MSG("Bad function Argument");
 1910        return NULL;
 1911    }
 1912
 1913    object = wolfSSL_X509_EXTENSION_get_object(ext);
 1914    if (object == NULL) {
 1915        WOLFSSL_MSG("X509_EXTENSION_get_object failed");
 1916        return NULL;
 1917    }
 1918    /* extract extension info */
 1919    method = wolfSSL_X509V3_EXT_get(ext);
 1920    if (method == NULL) {
 1921        WOLFSSL_MSG("wolfSSL_X509V3_EXT_get error");
 1922        return NULL;
 1923    }
 1924
 1925#ifdef WOLFSSL_SMALL_STACK
 1926    cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL,
 1927            DYNAMIC_TYPE_X509_EXT);
 1928    if (cert == NULL) {
 1929        WOLFSSL_MSG("\tout of memory");
 1930        return NULL;
 1931    }
 1932#endif
 1933
 1934    InitDecodedCert(cert, NULL, 0, NULL);
 1935
 1936    if ((object->type != WC_NID_basic_constraints) &&
 1937        (object->type != WC_NID_subject_alt_name) &&
 1938        (object->type != WC_NID_info_access)) {
 1939
 1940        asn1String = wolfSSL_X509_EXTENSION_get_data_internal(ext);
 1941        if (asn1String == NULL) {
 1942            WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
 1943            goto out;
 1944        }
 1945
 1946        ret = DecodeExtensionType((const byte*)asn1String->data,
 1947                asn1String->length, object->type, (byte)ext->crit, cert, NULL);
 1948        if (ret != 0) {
 1949            WOLFSSL_MSG("DecodeExtensionType() failed");
 1950            goto out;
 1951        }
 1952    }
 1953
 1954    /* Return pointer to proper internal structure based on NID */
 1955    switch (object->type) {
 1956        /* basicConstraints */
 1957        case WC_NID_basic_constraints:
 1958            WOLFSSL_MSG("basicConstraints");
 1959            /* Allocate new BASIC_CONSTRAINTS structure */
 1960            bc = wolfSSL_BASIC_CONSTRAINTS_new();
 1961            if (bc == NULL) {
 1962                WOLFSSL_MSG("Failed to malloc basic constraints");
 1963                break;
 1964            }
 1965            /* Copy pathlen and CA into BASIC_CONSTRAINTS from object */
 1966            bc->ca = object->ca;
 1967            if (object->pathlen != NULL && object->pathlen->length > 0) {
 1968                bc->pathlen = wolfSSL_ASN1_INTEGER_dup(object->pathlen);
 1969                if (bc->pathlen == NULL) {
 1970                    WOLFSSL_MSG("Failed to duplicate ASN1_INTEGER");
 1971                    wolfSSL_BASIC_CONSTRAINTS_free(bc);
 1972                    break;
 1973                }
 1974            }
 1975            else
 1976                bc->pathlen = NULL;
 1977
 1978            data = bc;
 1979            break;
 1980
 1981        /* subjectKeyIdentifier */
 1982        case WC_NID_subject_key_identifier:
 1983        {
 1984            WOLFSSL_MSG("subjectKeyIdentifier");
 1985
 1986            newString = wolfSSL_ASN1_STRING_new();
 1987            if (newString == NULL) {
 1988                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
 1989                break;
 1990            }
 1991            ret = wolfSSL_ASN1_STRING_set(newString, cert->extSubjKeyId,
 1992                                          cert->extSubjKeyIdSz);
 1993            if (ret != WOLFSSL_SUCCESS) {
 1994                WOLFSSL_MSG("ASN1_STRING_set() failed");
 1995                wolfSSL_ASN1_STRING_free(newString);
 1996                break;
 1997            };
 1998
 1999            newString->type = asn1String->type;
 2000            data = newString;
 2001            break;
 2002        }
 2003
 2004        /* authorityKeyIdentifier */
 2005        case WC_NID_authority_key_identifier:
 2006        {
 2007            WOLFSSL_MSG("AuthorityKeyIdentifier");
 2008
 2009            akey = (WOLFSSL_AUTHORITY_KEYID*)
 2010                    XMALLOC(sizeof(WOLFSSL_AUTHORITY_KEYID), NULL,
 2011                    DYNAMIC_TYPE_X509_EXT);
 2012            if (akey == NULL) {
 2013                WOLFSSL_MSG("Failed to malloc authority key id");
 2014                break;
 2015            }
 2016
 2017            XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
 2018
 2019            akey->keyid = wolfSSL_ASN1_STRING_new();
 2020            if (akey->keyid == NULL) {
 2021                WOLFSSL_MSG("ASN1_STRING_new() failed");
 2022                wolfSSL_AUTHORITY_KEYID_free(akey);
 2023                break;
 2024            }
 2025
 2026            ret = wolfSSL_ASN1_STRING_set(akey->keyid, cert->extAuthKeyId,
 2027                                          cert->extAuthKeyIdSz);
 2028            if (ret != WOLFSSL_SUCCESS) {
 2029                WOLFSSL_MSG("ASN1_STRING_set() failed");
 2030                wolfSSL_AUTHORITY_KEYID_free(akey);
 2031                break;
 2032            };
 2033            akey->keyid->type   = asn1String->type;
 2034
 2035            /* For now, set issuer and serial to NULL. This may need to be
 2036                updated for future use */
 2037            akey->issuer = NULL;
 2038            akey->serial = NULL;
 2039
 2040            data = akey;
 2041            break;
 2042        }
 2043
 2044        /* keyUsage */
 2045        case WC_NID_key_usage:
 2046        {
 2047            WOLFSSL_MSG("keyUsage");
 2048
 2049            /* This may need to be updated for future use. The i2v method for
 2050                keyUsage is not currently set. For now, return the ASN1_STRING
 2051                representation of KeyUsage bit string */
 2052            newString = wolfSSL_ASN1_STRING_new();
 2053            if (newString == NULL) {
 2054                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
 2055                break;
 2056            }
 2057            ret = wolfSSL_ASN1_STRING_set(newString, (byte*)&cert->extKeyUsage,
 2058                                                                sizeof(word16));
 2059            if (ret != WOLFSSL_SUCCESS) {
 2060                WOLFSSL_MSG("ASN1_STRING_set() failed");
 2061                wolfSSL_ASN1_STRING_free(newString);
 2062                break;
 2063            };
 2064            newString->type = asn1String->type;
 2065            data = newString;
 2066            break;
 2067        }
 2068
 2069        /* extKeyUsage */
 2070        case WC_NID_ext_key_usage:
 2071            WOLFSSL_MSG("extKeyUsage not supported yet");
 2072            break;
 2073
 2074        /* certificatePolicies */
 2075        case WC_NID_certificate_policies:
 2076            WOLFSSL_MSG("certificatePolicies not supported yet");
 2077            break;
 2078
 2079        /* cRLDistributionPoints */
 2080        case WC_NID_crl_distribution_points:
 2081            WOLFSSL_MSG("cRLDistributionPoints not supported yet");
 2082            break;
 2083
 2084        case WC_NID_subject_alt_name:
 2085            if (ext->ext_sk == NULL) {
 2086                WOLFSSL_MSG("Subject alt name stack NULL");
 2087                break;
 2088            }
 2089            sk = wolfSSL_sk_dup(ext->ext_sk);
 2090            if (sk == NULL) {
 2091                WOLFSSL_MSG("Failed to duplicate subject alt names stack.");
 2092                break;
 2093            }
 2094            data = sk;
 2095            break;
 2096
 2097        /* authorityInfoAccess */
 2098        case WC_NID_info_access:
 2099            WOLFSSL_MSG("AuthorityInfoAccess");
 2100            data = wolfssl_x509v3_ext_aia_d2i(ext);
 2101            break;
 2102
 2103        default:
 2104            WOLFSSL_MSG("Extension NID not in table, returning NULL");
 2105            break;
 2106    }
 2107
 2108out:
 2109
 2110    FreeDecodedCert(cert);
 2111    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_X509_EXT);
 2112
 2113    return data;
 2114}
 2115
 2116/* Looks for the extension matching the passed in nid
 2117 *
 2118 * x509 : certificate to get parse through for extension.
 2119 * nid : Extension OID to be found.
 2120 * lastPos : Start search from extension after lastPos.
 2121 *           Set to -1 to search from index 0.
 2122 * return >= 0 If successful the extension index is returned.
 2123 * return WOLFSSL_FATAL_ERROR If extension is not found or error is encountered.
 2124 */
 2125int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
 2126{
 2127    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
 2128    int isSet = 0, found = 0, loc;
 2129    const byte* rawCert;
 2130    const byte* input;
 2131    word32 oid, idx = 0, tmpIdx = 0, foundNID;
 2132    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
 2133
 2134    WOLFSSL_ENTER("wolfSSL_X509_get_ext_by_NID");
 2135
 2136    if (x509 == NULL) {
 2137        WOLFSSL_MSG("\tNot passed a certificate");
 2138        return WOLFSSL_FATAL_ERROR;
 2139    }
 2140
 2141    if (lastPos < -1 || (lastPos > (wolfSSL_X509_get_ext_count(x509) - 1))) {
 2142        WOLFSSL_MSG("\tBad location argument");
 2143        return WOLFSSL_FATAL_ERROR;
 2144    }
 2145
 2146    loc = lastPos + 1;
 2147
 2148    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
 2149    if (rawCert == NULL) {
 2150        WOLFSSL_MSG("\tX509_get_der() failed");
 2151        return WOLFSSL_FATAL_ERROR;
 2152    }
 2153
 2154#ifdef WOLFSSL_SMALL_STACK
 2155    cert = (DecodedCert *)XMALLOC(sizeof(*cert), x509->heap,
 2156                                  DYNAMIC_TYPE_DCERT);
 2157    if (cert == NULL) {
 2158        WOLFSSL_MSG("\tout of memory");
 2159        return WOLFSSL_FATAL_ERROR;
 2160    }
 2161#endif
 2162
 2163    InitDecodedCert( cert, rawCert, (word32)outSz, 0);
 2164
 2165    if (ParseCert(cert,
 2166#ifdef WOLFSSL_CERT_REQ
 2167            x509->isCSR ? CERTREQ_TYPE :
 2168#endif
 2169            CA_TYPE,
 2170            NO_VERIFY, NULL) < 0) {
 2171        WOLFSSL_MSG("\tCertificate parsing failed");
 2172        goto out;
 2173    }
 2174
 2175    input = cert->extensions;
 2176    sz = cert->extensionsSz;
 2177
 2178    if (input == NULL || sz == 0) {
 2179        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
 2180        goto out;
 2181    }
 2182
 2183#ifdef WOLFSSL_CERT_REQ
 2184    if (!x509->isCSR)
 2185#endif
 2186    {
 2187        if (input[idx++] != ASN_EXTENSIONS) {
 2188            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
 2189            goto out;
 2190        }
 2191
 2192        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
 2193            WOLFSSL_MSG("\tfail: invalid length");
 2194            goto out;
 2195        }
 2196    }
 2197
 2198    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
 2199        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
 2200        goto out;
 2201    }
 2202
 2203    while (idx < (word32)sz) {
 2204        oid = 0;
 2205
 2206        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
 2207            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
 2208            goto out;
 2209        }
 2210
 2211        tmpIdx = idx;
 2212        ret = GetObjectId(input, &idx, &oid, oidCertExtType, (word32)sz);
 2213        if (ret < 0) {
 2214            WOLFSSL_MSG("\tfail: OBJECT ID");
 2215            goto out;
 2216        }
 2217        idx = tmpIdx;
 2218        foundNID = (word32)oid2nid(oid, oidCertExtType);
 2219
 2220        if (extCount >= loc) {
 2221            /* extCount >= loc. Now check if extension has been set */
 2222            isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509,
 2223                (int)foundNID);
 2224            if (isSet && ((word32)nid == foundNID)) {
 2225                found = 1;
 2226                break;
 2227            }
 2228        }
 2229
 2230        idx += length;
 2231        extCount++;
 2232    } /* while(idx < sz) */
 2233
 2234out:
 2235
 2236    FreeDecodedCert(cert);
 2237    WC_FREE_VAR_EX(cert, x509->heap, DYNAMIC_TYPE_DCERT);
 2238
 2239    return found ? extCount : WOLFSSL_FATAL_ERROR;
 2240}
 2241
 2242#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
 2243
 2244#if defined(OPENSSL_EXTRA) && !defined(IGNORE_NAME_CONSTRAINTS)
 2245/*
 2246 * Convert a Base_entry linked list to a STACK of GENERAL_SUBTREE.
 2247 *
 2248 * Base_entry stores name constraint data from DecodedCert. This function
 2249 * converts it to GENERAL_SUBTREE format.
 2250 *
 2251 * Supported types: ASN_DNS_TYPE, ASN_RFC822_TYPE, ASN_DIR_TYPE, ASN_IP_TYPE,
 2252 *                  ASN_URI_TYPE
 2253 *
 2254 * Returns 0 on success, negative on error.
 2255 */
 2256static int ConvertBaseEntryToSubtreeStack(Base_entry* list, WOLFSSL_STACK* sk,
 2257                                          void* heap)
 2258{
 2259    Base_entry* entry = list;
 2260    WOLFSSL_GENERAL_SUBTREE* subtree = NULL;
 2261    WOLFSSL_GENERAL_NAME* gn = NULL;
 2262    (void)heap;
 2263
 2264    while (entry != NULL) {
 2265
 2266        if (entry->type != ASN_DNS_TYPE && entry->type != ASN_RFC822_TYPE &&
 2267            entry->type != ASN_DIR_TYPE && entry->type != ASN_IP_TYPE &&
 2268            entry->type != ASN_URI_TYPE) {
 2269            entry = entry->next;
 2270            continue;
 2271        }
 2272
 2273        /* Allocate subtree and general name */
 2274        subtree = (WOLFSSL_GENERAL_SUBTREE*)XMALLOC(
 2275            sizeof(WOLFSSL_GENERAL_SUBTREE), heap, DYNAMIC_TYPE_OPENSSL);
 2276        if (subtree == NULL) {
 2277            WOLFSSL_MSG("Failed to allocate GENERAL_SUBTREE");
 2278            return MEMORY_E;
 2279        }
 2280        XMEMSET(subtree, 0, sizeof(WOLFSSL_GENERAL_SUBTREE));
 2281
 2282        gn = wolfSSL_GENERAL_NAME_new();
 2283        if (gn == NULL) {
 2284            WOLFSSL_MSG("Failed to allocate GENERAL_NAME");
 2285            XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
 2286            return MEMORY_E;
 2287        }
 2288
 2289        /* Free default ia5 string allocated by GENERAL_NAME_new */
 2290        wolfSSL_ASN1_STRING_free(gn->d.ia5);
 2291        gn->d.ia5 = NULL;
 2292
 2293        switch (entry->type) {
 2294            case ASN_DNS_TYPE:
 2295            case ASN_RFC822_TYPE:
 2296            case ASN_URI_TYPE:
 2297            {
 2298                if (entry->type == ASN_DNS_TYPE) {
 2299                    gn->type = WOLFSSL_GEN_DNS;
 2300                }
 2301                else if (entry->type == ASN_RFC822_TYPE) {
 2302                    gn->type = WOLFSSL_GEN_EMAIL;
 2303                }
 2304                else {
 2305                    gn->type = WOLFSSL_GEN_URI;
 2306                }
 2307                gn->d.ia5 = wolfSSL_ASN1_STRING_new();
 2308                if (gn->d.ia5 == NULL) {
 2309                    WOLFSSL_MSG("Failed to allocate ASN1_STRING");
 2310                    wolfSSL_GENERAL_NAME_free(gn);
 2311                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
 2312                    return MEMORY_E;
 2313                }
 2314                if (wolfSSL_ASN1_STRING_set(gn->d.ia5, entry->name,
 2315                        entry->nameSz) != WOLFSSL_SUCCESS) {
 2316                    WOLFSSL_MSG("Failed to set ASN1_STRING");
 2317                    wolfSSL_GENERAL_NAME_free(gn);
 2318                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
 2319                    return MEMORY_E;
 2320                }
 2321                gn->d.ia5->type = WOLFSSL_V_ASN1_IA5STRING;
 2322                break;
 2323            }
 2324
 2325            case ASN_DIR_TYPE:
 2326            {
 2327                byte* seqBuf = NULL;
 2328                unsigned char* p = NULL;
 2329                int seqLen = 0;
 2330
 2331                /* Wrap in SEQUENCE and parse as X509_NAME */
 2332                gn->type = WOLFSSL_GEN_DIRNAME;
 2333                seqBuf = (byte*)XMALLOC((word32)entry->nameSz + MAX_SEQ_SZ,
 2334                                        heap, DYNAMIC_TYPE_TMP_BUFFER);
 2335                if (seqBuf == NULL) {
 2336                    WOLFSSL_MSG("Failed to allocate sequence buffer");
 2337                    wolfSSL_GENERAL_NAME_free(gn);
 2338                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
 2339                    return MEMORY_E;
 2340                }
 2341
 2342                seqLen = SetSequence(entry->nameSz, seqBuf);
 2343                XMEMCPY(seqBuf + seqLen, entry->name, entry->nameSz);
 2344
 2345                p = seqBuf;
 2346                gn->d.directoryName = wolfSSL_d2i_X509_NAME(NULL, &p,
 2347                    (long)entry->nameSz + seqLen);
 2348                XFREE(seqBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
 2349
 2350                if (gn->d.directoryName == NULL) {
 2351                    WOLFSSL_MSG("Failed to parse directoryName");
 2352                    wolfSSL_GENERAL_NAME_free(gn);
 2353                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
 2354                    return ASN_PARSE_E;
 2355                }
 2356                break;
 2357            }
 2358
 2359            case ASN_IP_TYPE:
 2360            {
 2361                /* For IP address, store raw bytes as OCTET_STRING. */
 2362                gn->type = WOLFSSL_GEN_IPADD;
 2363                gn->d.iPAddress = wolfSSL_ASN1_STRING_new();
 2364                if (gn->d.iPAddress == NULL) {
 2365                    WOLFSSL_MSG("Failed to allocate ASN1_STRING for IP");
 2366                    wolfSSL_GENERAL_NAME_free(gn);
 2367                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
 2368                    return MEMORY_E;
 2369                }
 2370                if (wolfSSL_ASN1_STRING_set(gn->d.iPAddress, entry->name,
 2371                        entry->nameSz) != WOLFSSL_SUCCESS) {
 2372                    WOLFSSL_MSG("Failed to set IP ASN1_STRING");
 2373                    wolfSSL_GENERAL_NAME_free(gn);
 2374                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
 2375                    return MEMORY_E;
 2376                }
 2377                gn->d.iPAddress->type = WOLFSSL_V_ASN1_OCTET_STRING;
 2378                break;
 2379            }
 2380        }
 2381
 2382        subtree->base = gn;
 2383
 2384        if (wolfSSL_sk_push(sk, subtree) <= 0) {
 2385            WOLFSSL_MSG("Failed to push subtree onto stack");
 2386            wolfSSL_GENERAL_NAME_free(gn);
 2387            XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
 2388            return MEMORY_E;
 2389        }
 2390        entry = entry->next;
 2391    }
 2392
 2393    return 0;
 2394}
 2395#endif /* OPENSSL_EXTRA && !IGNORE_NAME_CONSTRAINTS */
 2396
 2397#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
 2398/* Looks for the extension matching the passed in nid
 2399 *
 2400 * c   : if not null then is set to status value -2 if multiple occurrences
 2401 *       of the extension are found, -1 if not found, 0 if found and not
 2402 *       critical, and 1 if found and critical.
 2403 * nid : Extension OID to be found.
 2404 * idx : if NULL return first extension found match, otherwise start search at
 2405 *       idx location and set idx to the location of extension returned.
 2406 * returns NULL or a pointer to an WOLFSSL_ASN1_BIT_STRING (for KEY_USAGE_OID)
 2407 * or WOLFSSL_STACK (for other)
 2408 * holding extension structure
 2409 *
 2410 * NOTE code for decoding extensions is in asn.c DecodeCertExtensions --
 2411 * use already decoded extension in this function to avoid decoding twice.
 2412 * Currently we do not make use of idx since getting pre decoded extensions.
 2413 */
 2414void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
 2415    int* idx)
 2416{
 2417    void* ret = NULL;
 2418    WOLFSSL_STACK* sk = NULL;
 2419    WOLFSSL_ASN1_OBJECT* obj = NULL;
 2420    WOLFSSL_GENERAL_NAME* gn = NULL;
 2421#ifdef OPENSSL_EXTRA
 2422    WOLFSSL_DIST_POINT* dp = NULL;
 2423#endif
 2424    WOLFSSL_BASIC_CONSTRAINTS* bc = NULL;
 2425
 2426    WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i");
 2427
 2428    if (x509 == NULL) {
 2429        return NULL;
 2430    }
 2431
 2432    if (c != NULL) {
 2433        *c = -1; /* default to not found */
 2434    }
 2435
 2436    switch (nid) {
 2437        case BASIC_CA_OID:
 2438            if (x509->basicConstSet) {
 2439                WOLFSSL_ASN1_INTEGER* a;
 2440
 2441                bc = wolfSSL_BASIC_CONSTRAINTS_new();
 2442                if (!bc) {
 2443                    WOLFSSL_MSG("wolfSSL_BASIC_CONSTRAINTS_new error");
 2444                    return NULL;
 2445                }
 2446
 2447                a = wolfSSL_ASN1_INTEGER_new();
 2448                if (!a) {
 2449                    WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
 2450                    wolfSSL_BASIC_CONSTRAINTS_free(bc);
 2451                    return NULL;
 2452                }
 2453                a->length = (int)x509->pathLength;
 2454
 2455#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
 2456        defined(WOLFSSL_APACHE_HTTPD)
 2457                bc->ca = x509->isCa;
 2458#endif
 2459                bc->pathlen = a;
 2460                if (c != NULL) {
 2461                    *c = x509->basicConstCrit;
 2462                }
 2463            }
 2464            else {
 2465                WOLFSSL_MSG("No Basic Constraint set");
 2466            }
 2467            return bc;
 2468
 2469        case ALT_NAMES_OID:
 2470        {
 2471            DNS_entry* dns = NULL;
 2472
 2473            if (x509->subjAltNameSet && x509->altNames != NULL) {
 2474                /* Malloc GENERAL_NAME stack */
 2475                sk = wolfSSL_sk_new_null();
 2476                if (sk == NULL)
 2477                    return NULL;
 2478                sk->type = STACK_TYPE_GEN_NAME;
 2479
 2480                /* alt names are DNS_entry structs */
 2481                if (c != NULL) {
 2482                    if (x509->altNames->next != NULL) {
 2483                        *c = -2; /* more then one found */
 2484                    }
 2485                    else {
 2486                        *c = x509->subjAltNameCrit;
 2487                    }
 2488                }
 2489
 2490                dns = x509->altNames;
 2491                /* Currently only support GEN_DNS type */
 2492                while (dns != NULL) {
 2493                    gn = wolfSSL_GENERAL_NAME_new();
 2494                    if (gn == NULL) {
 2495                        WOLFSSL_MSG("Error creating GENERAL_NAME");
 2496                        goto err;
 2497                    }
 2498
 2499                    switch (dns->type) {
 2500                        case ASN_DIR_TYPE:
 2501                            gn->type = dns->type;
 2502                            {
 2503                                int localIdx = 0;
 2504                                unsigned char* n = (unsigned char*)XMALLOC(
 2505                                        dns->len + MAX_SEQ_SZ, x509->heap,
 2506                                        DYNAMIC_TYPE_TMP_BUFFER);
 2507                                if (n == NULL) {
 2508                                    goto err;
 2509                                }
 2510
 2511                                localIdx += SetSequence(dns->len, n);
 2512                                XMEMCPY(n + localIdx, dns->name, dns->len);
 2513                                gn->d.dirn =  wolfSSL_d2i_X509_NAME(NULL, &n,
 2514                                        dns->len + localIdx);
 2515                                XFREE(n, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
 2516                                if (gn->d.dirn == NULL) {
 2517                                    WOLFSSL_MSG("Convert altDirName to X509 "
 2518                                            "NAME failed");
 2519                                    goto err;
 2520                                }
 2521                            }
 2522                            break;
 2523
 2524                        case ASN_OTHER_TYPE:
 2525                            /* gn->type set internally */
 2526                            if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
 2527                                goto err;
 2528                            }
 2529                            break;
 2530
 2531                        case ASN_IP_TYPE:
 2532                            gn->type = dns->type;
 2533                            if (wolfSSL_ASN1_STRING_set(gn->d.iPAddress,
 2534                                    dns->name, dns->len) != WOLFSSL_SUCCESS) {
 2535                                WOLFSSL_MSG("ASN1_STRING_set failed");
 2536                                goto err;
 2537                            }
 2538                            gn->d.iPAddress->type = WOLFSSL_V_ASN1_OCTET_STRING;
 2539                            break;
 2540
 2541                        case ASN_RID_TYPE:
 2542                            /* Always handle registeredID: the union
 2543                             * member d.registeredID is populated from
 2544                             * raw OID body bytes. WOLFSSL_RID_ALT_NAME
 2545                             * only gates the human-readable ridString,
 2546                             * which this path does not need. */
 2547                            gn->type = dns->type;
 2548                            /* Free ia5 before using union for registeredID */
 2549                            wolfSSL_ASN1_STRING_free(gn->d.ia5);
 2550                            gn->d.ia5 = NULL;
 2551
 2552                            gn->d.registeredID = wolfSSL_ASN1_OBJECT_new();
 2553                            if (gn->d.registeredID == NULL) {
 2554                                goto err;
 2555                            }
 2556                            {
 2557                                /* Store DER-encoded OID (tag+length+content) */
 2558                                word32 derSz = 1 + SetLength(dns->len, NULL)
 2559                                               + dns->len;
 2560                                byte* der = (byte*)XMALLOC(derSz,
 2561                                    gn->d.registeredID->heap,
 2562                                    DYNAMIC_TYPE_ASN1);
 2563                                if (der == NULL) {
 2564                                    goto err;
 2565                                }
 2566                                {
 2567                                    word32 derIdx = 0;
 2568                                    der[derIdx++] = ASN_OBJECT_ID;
 2569                                    derIdx += SetLength(dns->len, der + derIdx);
 2570                                    XMEMCPY(der + derIdx, dns->name, dns->len);
 2571                                }
 2572                                gn->d.registeredID->obj = der;
 2573                                gn->d.registeredID->objSz = derSz;
 2574                            }
 2575                            gn->d.registeredID->dynamic |=
 2576                                WOLFSSL_ASN1_DYNAMIC_DATA;
 2577                            gn->d.registeredID->grp = oidCertExtType;
 2578                            break;
 2579
 2580                        default:
 2581                            gn->type = dns->type;
 2582                            if (wolfSSL_ASN1_STRING_set(gn->d.dNSName,
 2583                                    dns->name, dns->len) != WOLFSSL_SUCCESS) {
 2584                                WOLFSSL_MSG("ASN1_STRING_set failed");
 2585                                goto err;
 2586                            }
 2587                            gn->d.dNSName->type = WOLFSSL_V_ASN1_IA5STRING;
 2588                    }
 2589
 2590                    dns = dns->next;
 2591                    /* Using wolfSSL_sk_insert to maintain backwards
 2592                     * compatibility with earlier versions of _push API that
 2593                     * pushed items to the start of the list instead of the
 2594                     * end. */
 2595                    if (wolfSSL_sk_insert(sk, gn, 0) <= 0) {
 2596                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
 2597                        goto err;
 2598                    }
 2599                    /* null so that it doesn't get pushed again after switch */
 2600                    gn = NULL;
 2601                }
 2602            }
 2603            else {
 2604                WOLFSSL_MSG("No Alt Names set");
 2605            }
 2606
 2607            break;
 2608        }
 2609
 2610        case CRL_DIST_OID:
 2611    #if defined(OPENSSL_EXTRA)
 2612            if (x509->CRLdistSet && x509->CRLInfo != NULL) {
 2613                if (c != NULL) {
 2614                    *c = x509->CRLdistCrit;
 2615                }
 2616
 2617                sk = wolfSSL_sk_new_null();
 2618                if (sk == NULL) {
 2619                    return NULL;
 2620                }
 2621                sk->type = STACK_TYPE_DIST_POINT;
 2622
 2623                gn = wolfSSL_GENERAL_NAME_new();
 2624                if (gn == NULL) {
 2625                    WOLFSSL_MSG("Error creating GENERAL_NAME");
 2626                    goto err;
 2627                }
 2628
 2629                if (wolfSSL_GENERAL_NAME_set_type(gn, WOLFSSL_GEN_URI) !=
 2630                        WOLFSSL_SUCCESS) {
 2631                    WOLFSSL_MSG("Error setting GENERAL_NAME type");
 2632                    goto err;
 2633                }
 2634
 2635                if (wolfSSL_ASN1_STRING_set(gn->d.uniformResourceIdentifier,
 2636                        x509->CRLInfo, x509->CRLInfoSz) != WOLFSSL_SUCCESS) {
 2637                    WOLFSSL_MSG("ASN1_STRING_set failed");
 2638                    goto err;
 2639                }
 2640
 2641                /* wolfSSL only decodes one dist point */
 2642                dp = wolfSSL_DIST_POINT_new();
 2643                if (dp == NULL) {
 2644                    WOLFSSL_MSG("Error creating DIST_POINT");
 2645                    goto err;
 2646                }
 2647
 2648                /* push GENERAL_NAME onto fullname stack */
 2649                if (wolfSSL_sk_GENERAL_NAME_push(dp->distpoint->name.fullname,
 2650                                                 gn) <= 0) {
 2651                    WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
 2652                    goto err;
 2653                }
 2654
 2655                /* push DIST_POINT onto stack */
 2656                if (wolfSSL_sk_DIST_POINT_push(sk, dp) <= 0) {
 2657                    WOLFSSL_MSG("Error pushing DIST_POINT onto stack");
 2658                    goto err;
 2659                }
 2660
 2661                gn = NULL;
 2662                dp = NULL;
 2663
 2664            }
 2665            else {
 2666                WOLFSSL_MSG("No CRL dist set");
 2667            }
 2668    #endif /* OPENSSL_EXTRA */
 2669            break;
 2670
 2671        case AUTH_INFO_OID:
 2672            if (x509->authInfoSet && x509->authInfo != NULL) {
 2673                if (c != NULL) {
 2674                    *c = x509->authInfoCrit;
 2675                }
 2676                obj = wolfSSL_ASN1_OBJECT_new();
 2677                if (obj == NULL) {
 2678                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
 2679                    return NULL;
 2680                }
 2681                obj->type  = AUTH_INFO_OID;
 2682                obj->grp   = oidCertExtType;
 2683                obj->obj   = x509->authInfo;
 2684                obj->objSz = (unsigned int)x509->authInfoSz;
 2685            }
 2686            else {
 2687                WOLFSSL_MSG("No Auth Info set");
 2688            }
 2689            break;
 2690
 2691        case AUTH_KEY_OID:
 2692            if (x509->authKeyIdSet) {
 2693                WOLFSSL_AUTHORITY_KEYID* akey = wolfSSL_AUTHORITY_KEYID_new();
 2694                if (!akey) {
 2695                    WOLFSSL_MSG(
 2696                        "Issue creating WOLFSSL_AUTHORITY_KEYID struct");
 2697                    return NULL;
 2698                }
 2699
 2700                if (c != NULL) {
 2701                    *c = x509->authKeyIdCrit;
 2702                }
 2703                obj = wolfSSL_ASN1_OBJECT_new();
 2704                if (obj == NULL) {
 2705                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
 2706                    wolfSSL_AUTHORITY_KEYID_free(akey);
 2707                    return NULL;
 2708                }
 2709                obj->type  = AUTH_KEY_OID;
 2710                obj->grp   = oidCertExtType;
 2711                obj->obj   = x509->authKeyId;
 2712                obj->objSz = x509->authKeyIdSz;
 2713                akey->issuer = obj;
 2714                return akey;
 2715            }
 2716            else {
 2717                WOLFSSL_MSG("No Auth Key set");
 2718            }
 2719            break;
 2720
 2721        case SUBJ_KEY_OID:
 2722            if (x509->subjKeyIdSet) {
 2723                if (c != NULL) {
 2724                    *c = x509->subjKeyIdCrit;
 2725                }
 2726                obj = wolfSSL_ASN1_OBJECT_new();
 2727                if (obj == NULL) {
 2728                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
 2729                    return NULL;
 2730                }
 2731                obj->type  = SUBJ_KEY_OID;
 2732                obj->grp   = oidCertExtType;
 2733                obj->obj   = x509->subjKeyId;
 2734                obj->objSz = x509->subjKeyIdSz;
 2735            }
 2736            else {
 2737                WOLFSSL_MSG("No Subject Key set");
 2738            }
 2739            break;
 2740
 2741        case CERT_POLICY_OID:
 2742        {
 2743        #ifdef WOLFSSL_CERT_EXT
 2744            int i;
 2745
 2746            if (x509->certPoliciesNb > 0) {
 2747                if (c != NULL) {
 2748                    if (x509->certPoliciesNb > 1) {
 2749                        *c = -2;
 2750                    }
 2751                    else {
 2752                        *c = 0;
 2753                    }
 2754                }
 2755
 2756                sk = wolfSSL_sk_new_asn1_obj();
 2757                if (sk == NULL) {
 2758                    return NULL;
 2759                }
 2760
 2761                for (i = 0; i < x509->certPoliciesNb - 1; i++) {
 2762                    obj = wolfSSL_ASN1_OBJECT_new();
 2763                    if (obj == NULL) {
 2764                        WOLFSSL_MSG(
 2765                            "Issue creating WOLFSSL_ASN1_OBJECT struct");
 2766                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 2767                        return NULL;
 2768                    }
 2769                    obj->type  = CERT_POLICY_OID;
 2770                    obj->grp   = oidCertExtType;
 2771                    obj->obj   = (byte*)(x509->certPolicies[i]);
 2772                    obj->objSz = MAX_CERTPOL_SZ;
 2773                    if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
 2774                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
 2775                        wolfSSL_ASN1_OBJECT_free(obj);
 2776                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 2777                        sk = NULL;
 2778                    }
 2779                }
 2780
 2781                obj = wolfSSL_ASN1_OBJECT_new();
 2782                if (obj == NULL) {
 2783                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
 2784                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 2785                    return NULL;
 2786                }
 2787                obj->type  = CERT_POLICY_OID;
 2788                obj->grp   = oidCertExtType;
 2789                obj->obj   = (byte*)(x509->certPolicies[i]);
 2790                obj->objSz = MAX_CERTPOL_SZ;
 2791
 2792                if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
 2793                    WOLFSSL_MSG("Error pushing ASN1 object onto stack");
 2794                    wolfSSL_ASN1_OBJECT_free(obj);
 2795                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 2796                    sk = NULL;
 2797                }
 2798
 2799                obj = NULL;
 2800            }
 2801            else {
 2802                WOLFSSL_MSG("No Cert Policy set");
 2803            }
 2804        #endif /* WOLFSSL_CERT_EXT */
 2805        #ifdef WOLFSSL_SEP
 2806            if (x509->certPolicySet) {
 2807                if (c != NULL) {
 2808                    *c = x509->certPolicyCrit;
 2809                }
 2810                obj = wolfSSL_ASN1_OBJECT_new();
 2811                if (obj == NULL) {
 2812                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
 2813                    return NULL;
 2814                }
 2815                obj->type  = CERT_POLICY_OID;
 2816                obj->grp   = oidCertExtType;
 2817            }
 2818            else {
 2819                WOLFSSL_MSG("No Cert Policy set");
 2820            }
 2821        #endif
 2822            break;
 2823        }
 2824        case KEY_USAGE_OID:
 2825        {
 2826            WOLFSSL_ASN1_STRING* asn1str = NULL;
 2827            if (x509->keyUsageSet) {
 2828                if (c != NULL) {
 2829                    *c = x509->keyUsageCrit;
 2830                }
 2831
 2832                asn1str = wolfSSL_ASN1_STRING_new();
 2833                if (asn1str == NULL) {
 2834                    WOLFSSL_MSG("Failed to malloc ASN1_STRING");
 2835                    return NULL;
 2836                }
 2837
 2838                if (wolfSSL_ASN1_STRING_set(asn1str, &x509->keyUsage,
 2839                        sizeof(word16)) != WOLFSSL_SUCCESS) {
 2840                    WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
 2841                    wolfSSL_ASN1_STRING_free(asn1str);
 2842                    return NULL;
 2843                }
 2844
 2845                asn1str->type = KEY_USAGE_OID;
 2846            }
 2847            else {
 2848                WOLFSSL_MSG("No Key Usage set");
 2849            }
 2850            /* don't add stack of and return bit string directly */
 2851            return asn1str;
 2852        }
 2853        case INHIBIT_ANY_OID:
 2854            WOLFSSL_MSG("INHIBIT ANY extension not supported");
 2855            break;
 2856
 2857        case EXT_KEY_USAGE_OID:
 2858            if (x509->extKeyUsageSrc != NULL) {
 2859                const byte* ekuSrc = x509->extKeyUsageSrc;
 2860                word32 i;
 2861
 2862                sk = wolfSSL_sk_new_asn1_obj();
 2863                if (sk == NULL) {
 2864                    WOLFSSL_MSG("Issue creating stack");
 2865                    return NULL;
 2866                }
 2867
 2868                for (i = 0; i < x509->extKeyUsageCount; i++) {
 2869                    long ekuSrcLen = (long)(x509->extKeyUsageSz -
 2870                            (word32)(ekuSrc - x509->extKeyUsageSrc));
 2871                    WOLFSSL_ASN1_OBJECT* ekuObj = wolfSSL_d2i_ASN1_OBJECT(NULL,
 2872                            &ekuSrc, ekuSrcLen);
 2873                    if (ekuObj == NULL) {
 2874                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 2875                        WOLFSSL_MSG("d2i obj error");
 2876                        return NULL;
 2877                    }
 2878                    ekuObj->type  = EXT_KEY_USAGE_OID;
 2879                    ekuObj->grp   = oidCertExtType;
 2880                    /* Push to end to maintain order */
 2881                    if (wolfSSL_sk_insert(sk, ekuObj, -1) <= 0) {
 2882                        wolfSSL_ASN1_OBJECT_free(ekuObj);
 2883                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 2884                        WOLFSSL_MSG("d2i obj error");
 2885                        return NULL;
 2886                    }
 2887                }
 2888
 2889                if ((word32)(ekuSrc - x509->extKeyUsageSrc)
 2890                        != x509->extKeyUsageSz ||
 2891                        i != x509->extKeyUsageCount) {
 2892                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
 2893                    WOLFSSL_MSG("incorrect eku count or buffer not exhausted");
 2894                    return NULL;
 2895                }
 2896
 2897                if (c != NULL) {
 2898                    if (x509->extKeyUsageCount > 1) {
 2899                        *c = -2;
 2900                    }
 2901                    else {
 2902                        *c = x509->extKeyUsageCrit;
 2903                    }
 2904                }
 2905            }
 2906            else {
 2907                WOLFSSL_MSG("No Extended Key Usage set");
 2908            }
 2909            break;
 2910
 2911    #if defined(OPENSSL_EXTRA) && !defined(IGNORE_NAME_CONSTRAINTS)
 2912        case NAME_CONS_OID:
 2913        {
 2914            WOLFSSL_NAME_CONSTRAINTS* nc = NULL;
 2915
 2916            /* Check if name constraints exist in stored X509 */
 2917            if (x509->permittedNames == NULL && x509->excludedNames == NULL) {
 2918                WOLFSSL_MSG("No Name Constraints set");
 2919                break;
 2920            }
 2921
 2922            if (c != NULL) {
 2923                *c = x509->nameConstraintCrit;
 2924            }
 2925
 2926            nc = (WOLFSSL_NAME_CONSTRAINTS*)XMALLOC(
 2927                sizeof(WOLFSSL_NAME_CONSTRAINTS), x509->heap,
 2928                DYNAMIC_TYPE_OPENSSL);
 2929            if (nc == NULL) {
 2930                WOLFSSL_MSG("Failed to allocate NAME_CONSTRAINTS");
 2931                break;
 2932            }
 2933            XMEMSET(nc, 0, sizeof(WOLFSSL_NAME_CONSTRAINTS));
 2934
 2935            /* Convert permitted names */
 2936            if (x509->permittedNames != NULL) {
 2937                nc->permittedSubtrees = wolfSSL_sk_new_null();
 2938                if (nc->permittedSubtrees == NULL) {
 2939                    WOLFSSL_MSG("Failed to allocate permitted stack");
 2940                    wolfSSL_NAME_CONSTRAINTS_free(nc);
 2941                    break;
 2942                }
 2943                nc->permittedSubtrees->type = STACK_TYPE_GENERAL_SUBTREE;
 2944
 2945                if (ConvertBaseEntryToSubtreeStack(x509->permittedNames,
 2946                        nc->permittedSubtrees, x509->heap) != 0) {
 2947                    WOLFSSL_MSG("Failed to convert permitted names");
 2948                    wolfSSL_NAME_CONSTRAINTS_free(nc);
 2949                    break;
 2950                }
 2951            }
 2952
 2953            /* Convert excluded names */
 2954            if (x509->excludedNames != NULL) {
 2955                nc->excludedSubtrees = wolfSSL_sk_new_null();
 2956                if (nc->excludedSubtrees == NULL) {
 2957                    WOLFSSL_MSG("Failed to allocate excluded stack");
 2958                    wolfSSL_NAME_CONSTRAINTS_free(nc);
 2959                    break;
 2960                }
 2961                nc->excludedSubtrees->type = STACK_TYPE_GENERAL_SUBTREE;
 2962
 2963                if (ConvertBaseEntryToSubtreeStack(x509->excludedNames,
 2964                        nc->excludedSubtrees, x509->heap) != 0) {
 2965                    WOLFSSL_MSG("Failed to convert excluded names");
 2966                    wolfSSL_NAME_CONSTRAINTS_free(nc);
 2967                    break;
 2968                }
 2969            }
 2970
 2971            return nc;
 2972        }
 2973    #endif /* OPENSSL_EXTRA && !IGNORE_NAME_CONSTRAINTS */
 2974
 2975        case PRIV_KEY_USAGE_PERIOD_OID:
 2976            WOLFSSL_MSG("Private Key Usage Period extension not supported");
 2977            break;
 2978
 2979        case SUBJ_INFO_ACC_OID:
 2980            WOLFSSL_MSG("Subject Info Access extension not supported");
 2981            break;
 2982
 2983        case POLICY_MAP_OID:
 2984            WOLFSSL_MSG("Policy Map extension not supported");
 2985            break;
 2986
 2987        case POLICY_CONST_OID:
 2988            WOLFSSL_MSG("Policy Constraint extension not supported");
 2989            break;
 2990
 2991        case ISSUE_ALT_NAMES_OID:
 2992            WOLFSSL_MSG("Issue Alt Names extension not supported");
 2993            break;
 2994
 2995        case TLS_FEATURE_OID:
 2996            WOLFSSL_MSG("TLS Feature extension not supported");
 2997            break;
 2998
 2999        default:
 3000            WOLFSSL_MSG("Unsupported/Unknown extension OID");
 3001    }
 3002
 3003    /* make sure stack of is allocated */
 3004    if ((obj || gn) && sk == NULL) {
 3005        sk = wolfSSL_sk_new_asn1_obj();
 3006        if (sk == NULL) {
 3007            goto err;
 3008        }
 3009    }
 3010    if (obj) {
 3011        if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
 3012            WOLFSSL_MSG("Error pushing ASN1_OBJECT object onto "
 3013                        "stack.");
 3014            goto err;
 3015        }
 3016    }
 3017
 3018    ret = sk;
 3019
 3020    (void)idx;
 3021
 3022    return ret;
 3023
 3024err:
 3025    if (obj) {
 3026        wolfSSL_ASN1_OBJECT_free(obj);
 3027    }
 3028    if (gn) {
 3029        wolfSSL_GENERAL_NAME_free(gn);
 3030    }
 3031    #ifdef OPENSSL_EXTRA
 3032    if (dp) {
 3033        wolfSSL_DIST_POINT_free(dp);
 3034    }
 3035    #endif
 3036    if (sk) {
 3037        wolfSSL_sk_pop_free(sk, NULL);
 3038    }
 3039    return NULL;
 3040}
 3041#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
 3042
 3043#ifdef OPENSSL_EXTRA
 3044int wolfSSL_X509_add_altname_ex(WOLFSSL_X509* x509, const char* name,
 3045        word32 nameSz, int type)
 3046{
 3047    DNS_entry* newAltName = NULL;
 3048    char* nameCopy = NULL;
 3049
 3050    if (x509 == NULL)
 3051        return WOLFSSL_FAILURE;
 3052
 3053    if ((name == NULL) || (nameSz == 0))
 3054        return WOLFSSL_SUCCESS;
 3055
 3056    newAltName = AltNameNew(x509->heap);
 3057    if (newAltName == NULL)
 3058        return WOLFSSL_FAILURE;
 3059
 3060    nameCopy = (char*)XMALLOC(nameSz + 1, x509->heap, DYNAMIC_TYPE_ALTNAME);
 3061    if (nameCopy == NULL) {
 3062        XFREE(newAltName, x509->heap, DYNAMIC_TYPE_ALTNAME);
 3063        return WOLFSSL_FAILURE;
 3064    }
 3065
 3066    XMEMCPY(nameCopy, name, nameSz);
 3067
 3068    nameCopy[nameSz] = '\0';
 3069
 3070    newAltName->next = x509->altNames;
 3071    newAltName->type = type;
 3072    newAltName->len = (int)nameSz;
 3073    newAltName->name = nameCopy;
 3074    newAltName->nameStored = 1;
 3075    x509->altNames = newAltName;
 3076
 3077    return WOLFSSL_SUCCESS;
 3078}
 3079
 3080int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
 3081{
 3082    word32 nameSz;
 3083
 3084    if (name == NULL)
 3085        return WOLFSSL_SUCCESS;
 3086
 3087    nameSz = (word32)XSTRLEN(name);
 3088    if (nameSz == 0)
 3089        return WOLFSSL_SUCCESS;
 3090
 3091    if (type == ASN_IP_TYPE) {
 3092#ifdef WOLFSSL_IP_ALT_NAME
 3093        byte ip4[4];
 3094        byte ip6[16];
 3095        int ptonRet;
 3096
 3097        /* Check if this is an ip4 address */
 3098    #ifdef FREESCALE_MQX
 3099        ptonRet = XINET_PTON(WOLFSSL_IP4, name, ip4, sizeof(ip4));
 3100        if (ptonRet == RTCS_OK) {
 3101    #else
 3102        ptonRet = XINET_PTON(WOLFSSL_IP4, name, ip4);
 3103        if (ptonRet == 1) {
 3104    #endif
 3105            return wolfSSL_X509_add_altname_ex(x509, (const char*)ip4, 4,
 3106                type);
 3107        }
 3108
 3109        /* Check for ip6 */
 3110    #ifdef FREESCALE_MQX
 3111        ptonRet = XINET_PTON(WOLFSSL_IP6, name, ip6, sizeof(ip6));
 3112        if (ptonRet == RTCS_OK) {
 3113    #else
 3114        ptonRet = XINET_PTON(WOLFSSL_IP6, name, ip6);
 3115        if (ptonRet == 1) {
 3116    #endif
 3117            return wolfSSL_X509_add_altname_ex(x509, (const char*)ip6, 16,
 3118                type);
 3119        }
 3120
 3121        WOLFSSL_MSG("IP address parse failed");
 3122        return WOLFSSL_FAILURE;
 3123#else
 3124        WOLFSSL_MSG("WOLFSSL_IP_ALT_NAME not enabled");
 3125        return WOLFSSL_FAILURE;
 3126#endif
 3127    }
 3128
 3129    return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type);
 3130}
 3131
 3132#ifndef NO_WOLFSSL_STUB
 3133WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc)
 3134{
 3135    WOLFSSL_STUB("wolfSSL_X509_delete_ext");
 3136    (void)x509;
 3137    (void)loc;
 3138    return NULL;
 3139}
 3140
 3141/* currently LHASH is not implemented (and not needed for Apache port) */
 3142WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid(
 3143        WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid,
 3144        char* value)
 3145{
 3146    WOLFSSL_STUB("wolfSSL_X509V3_EXT_conf_nid");
 3147
 3148    if (conf != NULL) {
 3149        WOLFSSL_MSG("Handling LHASH not implemented yet");
 3150        return NULL;
 3151    }
 3152
 3153    (void)conf;
 3154    (void)ctx;
 3155    (void)nid;
 3156    (void)value;
 3157    return NULL;
 3158}
 3159
 3160void wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX* ctx)
 3161{
 3162    WOLFSSL_STUB("wolfSSL_X509V3_set_ctx_nodb");
 3163    (void)ctx;
 3164}
 3165#endif /* !NO_WOLFSSL_STUB */
 3166
 3167#ifdef OPENSSL_EXTRA
 3168static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value)
 3169{
 3170    WOLFSSL_X509_EXTENSION* ext;
 3171
 3172    ext = wolfSSL_X509_EXTENSION_new();
 3173    if (ext == NULL) {
 3174        WOLFSSL_MSG("memory error");
 3175        return NULL;
 3176    }
 3177    ext->value.nid = nid;
 3178
 3179    switch (nid) {
 3180        case WC_NID_subject_key_identifier:
 3181        case WC_NID_authority_key_identifier:
 3182            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
 3183                    != WOLFSSL_SUCCESS) {
 3184                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
 3185                goto err_cleanup;
 3186            }
 3187            ext->value.type = CTC_UTF8;
 3188            break;
 3189        case WC_NID_subject_alt_name:
 3190        {
 3191            WOLFSSL_GENERAL_NAMES* gns;
 3192            WOLFSSL_GENERAL_NAME* gn;
 3193
 3194            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
 3195                    != WOLFSSL_SUCCESS) {
 3196                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
 3197                goto err_cleanup;
 3198            }
 3199            ext->value.type = ASN_DNS_TYPE;
 3200
 3201            /* add stack of general names */
 3202            gns = wolfSSL_sk_new_null();
 3203            if (gns == NULL) {
 3204                WOLFSSL_MSG("wolfSSL_sk_new_null error");
 3205                goto err_cleanup;
 3206            }
 3207            ext->ext_sk = gns; /* wolfSSL_X509_EXTENSION_free will handle
 3208                                * free'ing gns */
 3209            gns->type = STACK_TYPE_GEN_NAME;
 3210            gn = wolfSSL_GENERAL_NAME_new();
 3211            if (gn == NULL) {
 3212                WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
 3213                goto err_cleanup;
 3214            }
 3215            if (wolfSSL_sk_GENERAL_NAME_push(gns, gn) <= 0) {
 3216                WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
 3217                wolfSSL_GENERAL_NAME_free(gn);
 3218                goto err_cleanup;
 3219            }
 3220            if (wolfSSL_ASN1_STRING_set(gn->d.ia5, value, -1)
 3221                    != WOLFSSL_SUCCESS) {
 3222                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
 3223                goto err_cleanup;
 3224            }
 3225            gn->type = ASN_DNS_TYPE;
 3226            break;
 3227        }
 3228        case WC_NID_key_usage:
 3229            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
 3230                    != WOLFSSL_SUCCESS) {
 3231                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
 3232                goto err_cleanup;
 3233            }
 3234            ext->value.type = KEY_USAGE_OID;
 3235            break;
 3236        case WC_NID_ext_key_usage:
 3237            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
 3238                    != WOLFSSL_SUCCESS) {
 3239                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
 3240                goto err_cleanup;
 3241            }
 3242            ext->value.type = EXT_KEY_USAGE_OID;
 3243            break;
 3244        default:
 3245            WOLFSSL_MSG("invalid or unsupported NID");
 3246            goto err_cleanup;
 3247    }
 3248    return ext;
 3249err_cleanup:
 3250    wolfSSL_X509_EXTENSION_free(ext);
 3251    return NULL;
 3252}
 3253
 3254/**
 3255 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
 3256 * @param conf  Not used
 3257 * @param ctx   Not used
 3258 * @param nid   Interprets the value parameter as the x509 extension that
 3259 *              corresponds to this NID.
 3260 * @param value A NULL terminated string that is taken as the value of the
 3261 *              newly created extension object.
 3262 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
 3263 */
 3264WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf_nid(WOLFSSL_CONF* conf,
 3265        WOLFSSL_X509V3_CTX *ctx, int nid, const char *value)
 3266{
 3267    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf_nid");
 3268
 3269    if (value == NULL) {
 3270        WOLFSSL_MSG("value NULL parameter");
 3271        return NULL;
 3272    }
 3273
 3274    if (conf != NULL || ctx != NULL) {
 3275        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf_nid does not handle either "
 3276                    "conf or ctx parameters");
 3277    }
 3278
 3279    return createExtFromStr(nid, value);
 3280}
 3281
 3282/**
 3283 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
 3284 * @param conf  Not used
 3285 * @param ctx   Not used
 3286 * @param sName The textual representation of the NID that the value parameter
 3287 *              should be interpreted as.
 3288 * @param value A NULL terminated string that is taken as the value of the
 3289 *              newly created extension object.
 3290 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
 3291 */
 3292WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf(WOLFSSL_CONF *conf,
 3293        WOLFSSL_X509V3_CTX *ctx, const char *sName, const char *value)
 3294{
 3295    const WOLFSSL_ObjectInfo* info = wolfssl_object_info;
 3296    size_t i;
 3297
 3298    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf");
 3299
 3300    if (value == NULL || sName == NULL) {
 3301        WOLFSSL_MSG("NULL parameter");
 3302        return NULL;
 3303    }
 3304
 3305    if (conf != NULL || ctx != NULL) {
 3306        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf does not handle either "
 3307                    "conf or ctx parameters");
 3308    }
 3309
 3310    for (i = 0; i < wolfssl_object_info_sz; i++, info++) {
 3311        if (XSTRCMP(info->sName, sName) == 0)
 3312            return createExtFromStr(info->nid, value);
 3313    }
 3314
 3315    WOLFSSL_MSG("value didn't match any known NID");
 3316    return NULL;
 3317}
 3318
 3319static void wolfSSL_X509V3_EXT_METHOD_populate(WOLFSSL_v3_ext_method *method,
 3320                                               int nid)
 3321{
 3322    if (!method)
 3323        return;
 3324
 3325    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_METHOD_populate");
 3326    switch (nid) {
 3327    case WC_NID_subject_key_identifier:
 3328        method->i2s = (WOLFSSL_X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
 3329        FALL_THROUGH;
 3330    case WC_NID_authority_key_identifier:
 3331    case WC_NID_key_usage:
 3332    case WC_NID_certificate_policies:
 3333    case WC_NID_policy_mappings:
 3334    case WC_NID_subject_alt_name:
 3335    case WC_NID_issuer_alt_name:
 3336    case WC_NID_basic_constraints:
 3337    case WC_NID_name_constraints:
 3338    case WC_NID_policy_constraints:
 3339    case WC_NID_ext_key_usage:
 3340    case WC_NID_crl_distribution_points:
 3341    case WC_NID_inhibit_any_policy:
 3342    case WC_NID_info_access:
 3343        WOLFSSL_MSG("Nothing to populate for current NID");
 3344        break;
 3345    default:
 3346        WOLFSSL_MSG("Unknown or unsupported NID");
 3347        break;
 3348    }
 3349
 3350    return;
 3351}
 3352
 3353/**
 3354 * @param nid One of the WC_NID_* constants defined in asn.h
 3355 * @param crit
 3356 * @param data This data is copied to the returned extension.
 3357 * @return
 3358 */
 3359WOLFSSL_X509_EXTENSION *wolfSSL_X509V3_EXT_i2d(int nid, int crit,
 3360                                               void *data)
 3361{
 3362    WOLFSSL_X509_EXTENSION *ext = NULL;
 3363    WOLFSSL_ASN1_STRING* asn1str = NULL;
 3364
 3365    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_i2d");
 3366
 3367    if (!data) {
 3368        return NULL;
 3369    }
 3370
 3371    if (!(ext = wolfSSL_X509_EXTENSION_new())) {
 3372        return NULL;
 3373    }
 3374
 3375    wolfSSL_X509V3_EXT_METHOD_populate(&ext->ext_method, nid);
 3376
 3377    switch (nid) {
 3378    case WC_NID_subject_key_identifier:
 3379        /* WOLFSSL_ASN1_STRING */
 3380    case WC_NID_key_usage:
 3381        /* WOLFSSL_ASN1_STRING */
 3382    {
 3383        asn1str = (WOLFSSL_ASN1_STRING*)data;
 3384        ext->value = *asn1str;
 3385        if (asn1str->isDynamic) {
 3386            ext->value.data = (char*)XMALLOC(asn1str->length, NULL,
 3387                                             DYNAMIC_TYPE_OPENSSL);
 3388            if (!ext->value.data) {
 3389                WOLFSSL_MSG("malloc failed");
 3390                /* Zero so that no existing memory is freed */
 3391                XMEMSET(&ext->value, 0, sizeof(WOLFSSL_ASN1_STRING));
 3392                goto err_cleanup;
 3393            }
 3394            XMEMCPY(ext->value.data, asn1str->data, asn1str->length);
 3395        }
 3396        else {
 3397            ext->value.data = ext->value.strData;
 3398        }
 3399
 3400        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
 3401            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
 3402            goto err_cleanup;
 3403        }
 3404
 3405        break;
 3406    }
 3407    case WC_NID_subject_alt_name:
 3408        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
 3409    case WC_NID_issuer_alt_name:
 3410        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
 3411    case WC_NID_ext_key_usage:
 3412        /* typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE */
 3413    case WC_NID_info_access:
 3414        /* typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS */
 3415    {
 3416        WOLFSSL_STACK* sk = (WOLFSSL_STACK*)data;
 3417
 3418        if (ext->ext_sk) {
 3419            wolfSSL_sk_pop_free(ext->ext_sk, NULL);
 3420        }
 3421
 3422        if (!(ext->ext_sk = wolfSSL_sk_dup(sk))) {
 3423            WOLFSSL_MSG("wolfSSL_sk_dup failed");
 3424            goto err_cleanup;
 3425        }
 3426
 3427        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
 3428            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
 3429            goto err_cleanup;
 3430        }
 3431
 3432        break;
 3433    }
 3434    case WC_NID_basic_constraints:
 3435    {
 3436        /* WOLFSSL_BASIC_CONSTRAINTS */
 3437        WOLFSSL_BASIC_CONSTRAINTS* bc = (WOLFSSL_BASIC_CONSTRAINTS*)data;
 3438
 3439        if (!(ext->obj = wolfSSL_ASN1_OBJECT_new())) {
 3440            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
 3441            goto err_cleanup;
 3442        }
 3443
 3444        ext->obj->ca = bc->ca;
 3445        if (bc->pathlen) {
 3446            ext->obj->pathlen = wolfSSL_ASN1_INTEGER_dup(bc->pathlen);
 3447            if (!ext->obj->pathlen) {
 3448                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_dup failed");
 3449                goto err_cleanup;
 3450            }
 3451        }
 3452        break;
 3453    }
 3454    case WC_NID_authority_key_identifier:
 3455    {
 3456        /* AUTHORITY_KEYID */
 3457        WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)data;
 3458
 3459        if (akey->keyid) {
 3460            if (wolfSSL_ASN1_STRING_set(&ext->value, akey->keyid->data,
 3461                                    akey->keyid->length) != WOLFSSL_SUCCESS) {
 3462                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
 3463                goto err_cleanup;
 3464            }
 3465            ext->value.type = akey->keyid->type;
 3466
 3467            if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
 3468                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
 3469                goto err_cleanup;
 3470            }
 3471
 3472        }
 3473        else if (akey->issuer) {
 3474            ext->obj = wolfSSL_ASN1_OBJECT_dup(akey->issuer);
 3475            if (!ext->obj) {
 3476                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup failed");
 3477                goto err_cleanup;
 3478            }
 3479        }
 3480        else {
 3481            WOLFSSL_MSG("WC_NID_authority_key_identifier empty data");
 3482            goto err_cleanup;
 3483        }
 3484        break;
 3485    }
 3486    case WC_NID_inhibit_any_policy:
 3487        /* ASN1_INTEGER */
 3488    case WC_NID_certificate_policies:
 3489        /* STACK_OF(POLICYINFO) */
 3490    case WC_NID_policy_mappings:
 3491        /* STACK_OF(POLICY_MAPPING) */
 3492    case WC_NID_name_constraints:
 3493        /* NAME_CONSTRAINTS */
 3494    case WC_NID_policy_constraints:
 3495        /* POLICY_CONSTRAINTS */
 3496    case WC_NID_crl_distribution_points:
 3497        /* typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS */
 3498    default:
 3499        WOLFSSL_MSG("Unknown or unsupported NID");
 3500        break;
 3501    }
 3502
 3503    ext->crit = crit;
 3504
 3505    return ext;
 3506err_cleanup:
 3507    if (ext) {
 3508        wolfSSL_X509_EXTENSION_free(ext);
 3509    }
 3510    return NULL;
 3511}
 3512
 3513/* Returns pointer to ASN1_OBJECT from an X509_EXTENSION object */
 3514WOLFSSL_ASN1_OBJECT* wolfSSL_X509_EXTENSION_get_object(
 3515    WOLFSSL_X509_EXTENSION* ext)
 3516{
 3517    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_object");
 3518    if (ext == NULL)
 3519        return NULL;
 3520    return ext->obj;
 3521}
 3522
 3523
 3524/**
 3525 * duplicates the 'obj' input and sets it into the 'ext' structure
 3526 * returns WOLFSSL_SUCCESS on success
 3527 */
 3528int wolfSSL_X509_EXTENSION_set_object(WOLFSSL_X509_EXTENSION* ext,
 3529        const WOLFSSL_ASN1_OBJECT* obj)
 3530{
 3531    WOLFSSL_ASN1_OBJECT *current;
 3532
 3533    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_object");
 3534    if (ext == NULL)
 3535        return WOLFSSL_FAILURE;
 3536
 3537    current = wolfSSL_X509_EXTENSION_get_object(ext);
 3538    if (current != NULL) {
 3539        wolfSSL_ASN1_OBJECT_free(current);
 3540    }
 3541    ext->obj = wolfSSL_ASN1_OBJECT_dup((WOLFSSL_ASN1_OBJECT*)obj);
 3542    return WOLFSSL_SUCCESS;
 3543}
 3544#endif /* OPENSSL_ALL */
 3545
 3546#ifdef WOLFSSL_OLD_EXTDATA_FMT
 3547/*
 3548 * Replace the current string in 'asn1str', which is the full X.509
 3549 * extension octet string with some data specific for the extension
 3550 * type. The extension is the one given in 'oid'.
 3551 * Return 0 in case of success, or a negative error code.
 3552 */
 3553static int wolfSSL_ASN1_STRING_into_old_ext_fmt(WOLFSSL_ASN1_STRING *asn1str,
 3554                                                word32 oid)
 3555{
 3556    switch (oid)
 3557    {
 3558        case AUTH_INFO_OID:
 3559            wolfSSL_ASN1_STRING_clear(asn1str);
 3560            asn1str->data = NULL;
 3561            asn1str->length = 0;
 3562            return 0;
 3563
 3564        case AUTH_KEY_OID:
 3565        {
 3566            int ret = 0;
 3567            const byte *extAuthKeyId = NULL;
 3568            word32 extAuthKeyIdSz = 0;
 3569            char *data = NULL;
 3570
 3571            ret = DecodeAuthKeyId((const byte *)asn1str->data, asn1str->length,
 3572                    &extAuthKeyId, &extAuthKeyIdSz, NULL, NULL, NULL, NULL);
 3573
 3574            if (ret != 0)
 3575                return ret;
 3576
 3577            data = (char*)XMALLOC((size_t)(extAuthKeyIdSz), NULL,
 3578                                  DYNAMIC_TYPE_OPENSSL);
 3579            if (data == NULL)
 3580                return MEMORY_ERROR;
 3581
 3582            XMEMCPY(data, extAuthKeyId, (size_t)extAuthKeyIdSz);
 3583            wolfSSL_ASN1_STRING_set(asn1str, data, extAuthKeyIdSz);
 3584            XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
 3585            return 0;
 3586        }
 3587
 3588        case SUBJ_KEY_OID:
 3589        {
 3590            int ret = 0;
 3591            const byte *extSubjKeyId = NULL;
 3592            word32 extSubjKeyIdSz = 0;
 3593            char *data = NULL;
 3594
 3595            ret = DecodeSubjKeyId((const byte *)asn1str->data, asn1str->length,
 3596                    &extSubjKeyId, &extSubjKeyIdSz);
 3597            if (ret != 0)
 3598                return ret;
 3599
 3600            data = (char*)XMALLOC((size_t)(extSubjKeyIdSz), NULL,
 3601                                  DYNAMIC_TYPE_OPENSSL);
 3602            if (data == NULL)
 3603                return MEMORY_ERROR;
 3604
 3605            XMEMCPY(data, extSubjKeyId, (size_t)extSubjKeyIdSz);
 3606            wolfSSL_ASN1_STRING_set(asn1str, data, extSubjKeyIdSz);
 3607            XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
 3608            return 0;
 3609        }
 3610
 3611        case CERT_POLICY_OID:
 3612            wolfSSL_ASN1_STRING_clear(asn1str);
 3613            asn1str->data = NULL;
 3614            asn1str->length = 0;
 3615            return 0;
 3616
 3617        case KEY_USAGE_OID:
 3618        {
 3619            int ret = 0;
 3620            word16 extKeyUsage = 0;
 3621
 3622            ret = DecodeKeyUsage((const byte *)asn1str->data, asn1str->length,
 3623                    &extKeyUsage);
 3624            if (ret != 0)
 3625                return ret;
 3626
 3627            wolfSSL_ASN1_STRING_set(asn1str, (byte*)&extKeyUsage,
 3628                                    sizeof(extKeyUsage));
 3629            return 0;
 3630        }
 3631
 3632        case EXT_KEY_USAGE_OID:
 3633        {
 3634            int ret = 0;
 3635            const byte *extExtKeyUsageSrc = NULL;
 3636            word32 extExtKeyUsageSz = 0;
 3637            word32 extExtKeyUsageCount = 0;
 3638            byte extExtKeyUsage = 0;
 3639            byte extExtKeyUsageSsh = 0;
 3640            char *data = NULL;
 3641
 3642            ret = DecodeExtKeyUsage((const byte*)asn1str->data, asn1str->length,
 3643                    &extExtKeyUsageSrc, &extExtKeyUsageSz, &extExtKeyUsageCount,
 3644                    &extExtKeyUsage, &extExtKeyUsageSsh);
 3645            if (ret != 0)
 3646                return ret;
 3647
 3648            data = (char*)XMALLOC((size_t)(extExtKeyUsageSz), NULL,
 3649                                  DYNAMIC_TYPE_OPENSSL);
 3650            if (data == NULL)
 3651                return MEMORY_ERROR;
 3652
 3653            XMEMCPY(data, extExtKeyUsageSrc, (size_t)extExtKeyUsageSz);
 3654            wolfSSL_ASN1_STRING_set(asn1str, data, extExtKeyUsageSz);
 3655            XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
 3656            return 0;
 3657        }
 3658
 3659        case CRL_DIST_OID:
 3660            wolfSSL_ASN1_STRING_clear(asn1str);
 3661            asn1str->data = NULL;
 3662            asn1str->length = 0;
 3663            return 0;
 3664
 3665        default:
 3666            /* Do nothing, it is already set */
 3667            return 0;
 3668    }
 3669}
 3670#endif /* WOLFSSL_OLD_EXTDATA_FMT */
 3671
 3672/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
 3673WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(
 3674    WOLFSSL_X509_EXTENSION* ext)
 3675{
 3676    WOLFSSL_ASN1_STRING *ret;
 3677
 3678    ret =  wolfSSL_X509_EXTENSION_get_data_internal(ext);
 3679
 3680#ifdef WOLFSSL_OLD_EXTDATA_FMT
 3681    if (ret)
 3682    {
 3683        int error;
 3684        error = wolfSSL_ASN1_STRING_into_old_ext_fmt (ret, ext->obj->type);
 3685        if (error != 0)
 3686        {
 3687            WOLFSSL_MSG("Error calling wolfSSL_ASN1_STRING_into_old_ext_fmt");
 3688            return NULL;
 3689        }
 3690    }
 3691#endif
 3692
 3693    return ret;
 3694}
 3695
 3696
 3697/**
 3698 * Creates a duplicate of input 'data' and sets it into 'ext' structure
 3699 * returns WOLFSSL_SUCCESS on success
 3700 */
 3701int wolfSSL_X509_EXTENSION_set_data(WOLFSSL_X509_EXTENSION* ext,
 3702        WOLFSSL_ASN1_STRING* data)
 3703{
 3704    WOLFSSL_ASN1_STRING* current;
 3705
 3706    if (ext == NULL || data == NULL)
 3707        return WOLFSSL_FAILURE;
 3708
 3709    current = wolfSSL_X509_EXTENSION_get_data_internal(ext);
 3710    if (current->length > 0 && current->data != NULL && current->isDynamic) {
 3711        XFREE(current->data, NULL, DYNAMIC_TYPE_OPENSSL);
 3712    }
 3713
 3714    return wolfSSL_ASN1_STRING_copy(&ext->value, data);
 3715}
 3716
 3717#if !defined(NO_PWDBASED)
 3718int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest,
 3719        unsigned char* buf, unsigned int* len)
 3720{
 3721    int ret;
 3722
 3723    WOLFSSL_ENTER("wolfSSL_X509_digest");
 3724
 3725    if (x509 == NULL || digest == NULL) {
 3726        WOLFSSL_MSG("Null argument found");
 3727        return WOLFSSL_FAILURE;
 3728    }
 3729
 3730    if (x509->derCert == NULL) {
 3731        WOLFSSL_MSG("No DER certificate stored in X509");
 3732        return WOLFSSL_FAILURE;
 3733    }
 3734
 3735    ret = wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf,
 3736                              len, digest, NULL);
 3737    WOLFSSL_LEAVE("wolfSSL_X509_digest", ret);
 3738    return ret;
 3739}
 3740
 3741int wolfSSL_X509_pubkey_digest(const WOLFSSL_X509 *x509,
 3742        const WOLFSSL_EVP_MD *digest, unsigned char* buf, unsigned int* len)
 3743{
 3744    int ret;
 3745
 3746    WOLFSSL_ENTER("wolfSSL_X509_pubkey_digest");
 3747
 3748    if (x509 == NULL || digest == NULL) {
 3749        WOLFSSL_MSG("Null argument found");
 3750        return WOLFSSL_FAILURE;
 3751    }
 3752
 3753    if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
 3754        WOLFSSL_MSG("No DER public key stored in X509");
 3755        return WOLFSSL_FAILURE;
 3756    }
 3757
 3758    ret = wolfSSL_EVP_Digest(x509->pubKey.buffer, x509->pubKey.length, buf,
 3759                              len, digest, NULL);
 3760    WOLFSSL_LEAVE("wolfSSL_X509_pubkey_digest", ret);
 3761    return ret;
 3762}
 3763#endif
 3764
 3765#endif /* OPENSSL_EXTRA */
 3766
 3767#ifdef OPENSSL_EXTRA
 3768
 3769    #ifndef NO_WOLFSSL_STUB
 3770    const char* wolfSSL_X509_get_default_cert_file_env(void)
 3771    {
 3772        WOLFSSL_STUB("X509_get_default_cert_file_env");
 3773        return "";
 3774    }
 3775
 3776    const char* wolfSSL_X509_get_default_cert_file(void)
 3777    {
 3778        WOLFSSL_STUB("X509_get_default_cert_file");
 3779        return "";
 3780    }
 3781
 3782    const char* wolfSSL_X509_get_default_cert_dir_env(void)
 3783    {
 3784        WOLFSSL_STUB("X509_get_default_cert_dir_env");
 3785        return "";
 3786    }
 3787
 3788    const char* wolfSSL_X509_get_default_cert_dir(void)
 3789    {
 3790        WOLFSSL_STUB("X509_get_default_cert_dir");
 3791        return "";
 3792    }
 3793    #endif
 3794
 3795#endif /* OPENSSL_EXTRA */
 3796
 3797#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
 3798    defined(KEEP_OUR_CERT) || \
 3799    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
 3800
 3801/* user externally called free X509, if dynamic go ahead with free, otherwise
 3802 * don't */
 3803static void ExternalFreeX509(WOLFSSL_X509* x509)
 3804{
 3805#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
 3806    int doFree = 0;
 3807#endif
 3808
 3809    WOLFSSL_ENTER("ExternalFreeX509");
 3810    if (x509) {
 3811#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
 3812        wolfSSL_CRYPTO_cleanup_ex_data(&x509->ex_data);
 3813#endif
 3814        if (x509->dynamicMemory) {
 3815        #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
 3816            int ret;
 3817            wolfSSL_RefDec(&x509->ref, &doFree, &ret);
 3818            if (ret != 0) {
 3819                WOLFSSL_MSG("Couldn't lock x509 mutex");
 3820            }
 3821            if (doFree)
 3822        #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
 3823            {
 3824                FreeX509(x509);
 3825                XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
 3826            }
 3827        }
 3828        else {
 3829            WOLFSSL_MSG("free called on non dynamic object, not freeing");
 3830        }
 3831    }
 3832}
 3833
 3834/* Frees an external WOLFSSL_X509 structure */
 3835WOLFSSL_ABI
 3836void wolfSSL_X509_free(WOLFSSL_X509* x509)
 3837{
 3838    WOLFSSL_ENTER("wolfSSL_X509_free");
 3839    ExternalFreeX509(x509);
 3840}
 3841#endif
 3842
 3843#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
 3844    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
 3845
 3846/* copy name into in buffer, at most sz bytes, if buffer is null will
 3847   malloc buffer, call responsible for freeing                     */
 3848WOLFSSL_ABI
 3849char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
 3850{
 3851    int copySz;
 3852
 3853    WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
 3854
 3855    if (name == NULL) {
 3856        WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
 3857        return NULL;
 3858    }
 3859
 3860    if (name->sz == 0)
 3861        return in;
 3862
 3863    if (!in) {
 3864    #ifdef WOLFSSL_STATIC_MEMORY
 3865        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
 3866        return NULL;
 3867    #else
 3868        in = (char*)XMALLOC(name->sz, NULL, DYNAMIC_TYPE_OPENSSL);
 3869        if (!in)
 3870            return in;
 3871        copySz = name->sz;
 3872    #endif
 3873    }
 3874    else {
 3875        copySz = (int)min((word32)sz, (word32)name->sz);
 3876        if (copySz <= 0)
 3877            return in;
 3878    }
 3879
 3880    XMEMCPY(in, name->name, copySz - 1);
 3881    in[copySz - 1] = 0;
 3882
 3883    return in;
 3884}
 3885
 3886#ifdef OPENSSL_EXTRA
 3887/* Given an X509_NAME, convert it to canonical form and then hash
 3888 * with the provided hash type. Returns the first 4 bytes of the hash
 3889 * as unsigned long on success, and 0 otherwise. */
 3890static unsigned long X509NameHash(WOLFSSL_X509_NAME* name,
 3891    enum wc_HashType hashType)
 3892{
 3893    unsigned long  hash = 0;
 3894    unsigned char* canonName = NULL;
 3895    byte           digest[WC_MAX_DIGEST_SIZE];
 3896    int            size = 0;
 3897    int            rc;
 3898
 3899    WOLFSSL_ENTER("X509NameHash");
 3900
 3901    if (name == NULL) {
 3902        WOLFSSL_ERROR_MSG("WOLFSSL_X509_NAME pointer was NULL");
 3903        return 0;
 3904    }
 3905
 3906    if (name->sz == 0) {
 3907        WOLFSSL_ERROR_MSG("Nothing to hash in WOLFSSL_X509_NAME");
 3908        return 0;
 3909    }
 3910
 3911    size = wolfSSL_i2d_X509_NAME_canon(name, &canonName);
 3912
 3913    if (size <= 0 || canonName == NULL) {
 3914        WOLFSSL_ERROR_MSG("wolfSSL_i2d_X509_NAME_canon error");
 3915        return 0;
 3916    }
 3917
 3918    rc = wc_Hash(hashType, (const byte*)canonName, (word32)size, digest,
 3919        sizeof(digest));
 3920
 3921    if (rc == 0) {
 3922        hash = (((unsigned long)digest[3] << 24) |
 3923                ((unsigned long)digest[2] << 16) |
 3924                ((unsigned long)digest[1] <<  8) |
 3925                ((unsigned long)digest[0]));
 3926    }
 3927    else if (rc == WC_NO_ERR_TRACE(HASH_TYPE_E)) {
 3928        WOLFSSL_ERROR_MSG("Hash function not compiled in");
 3929    }
 3930    else {
 3931        WOLFSSL_ERROR_MSG("Error hashing name");
 3932    }
 3933
 3934    XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL);
 3935    return hash;
 3936}
 3937
 3938unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name)
 3939{
 3940    return X509NameHash(name, WC_HASH_TYPE_SHA);
 3941}
 3942
 3943/******************************************************************************
 3944* wolfSSL_X509_subject_name_hash
 3945* wolfSSL_X509_issuer_name_hash
 3946* Compute the hash digest of the subject / issuer name.
 3947* These functions prefer SHA-1 (if available) for compatibility. Otherwise
 3948* they use SHA-256.
 3949*
 3950* RETURNS:
 3951* The first 4 bytes of SHA-1 (or SHA-256) hash in little endian order as
 3952* unsigned long.
 3953* Otherwise, returns zero.
 3954*
 3955* Note:
 3956* Returns the same hash value as OpenSSL's X509_X_name_hash() API
 3957* if SHA-1 support is compiled in. SHA-256 will be used if SHA-1 is
 3958* not available.
 3959*/
 3960unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
 3961{
 3962    if (x509 == NULL) {
 3963        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
 3964        return 0;
 3965    }
 3966
 3967    #ifndef NO_SHA
 3968    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject, WC_HASH_TYPE_SHA);
 3969    #elif !defined(NO_SHA256)
 3970    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject,
 3971                        WC_HASH_TYPE_SHA256);
 3972    #else
 3973    WOLFSSL_ERROR_MSG("Hash function not compiled in");
 3974    return 0;
 3975    #endif
 3976}
 3977
 3978unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509)
 3979{
 3980    if (x509 == NULL) {
 3981        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
 3982        return 0;
 3983    }
 3984
 3985    #ifndef NO_SHA
 3986    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer, WC_HASH_TYPE_SHA);
 3987    #elif !defined(NO_SHA256)
 3988    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer,
 3989                        WC_HASH_TYPE_SHA256);
 3990    #else
 3991    WOLFSSL_ERROR_MSG("Hash function not compiled in");
 3992    return 0;
 3993    #endif
 3994}
 3995#endif /* OPENSSL_EXTRA */
 3996
 3997#if defined(OPENSSL_EXTRA) && defined(XSNPRINTF)
 3998/* Copies X509 subject name into a buffer, with comma-separated name entries
 3999 *   (matching OpenSSL v1.0.0 format)
 4000 * Example Output for Issuer:
 4001 *
 4002 * C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting,
 4003 *  CN=www.wolfssl.com, emailAddress=info@wolfssl.com
 4004 */
 4005char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
 4006{
 4007    int count, i;
 4008    int totalLen = 0;
 4009    char tmpBuf[256];
 4010    WOLFSSL_ENTER("wolfSSL_X509_get_name_oneline");
 4011
 4012    if (name == NULL) {
 4013        WOLFSSL_MSG("wolfSSL_X509_get_name_oneline failed");
 4014        return NULL;
 4015    }
 4016    #ifdef WOLFSSL_STATIC_MEMORY
 4017    if (!in) {
 4018        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
 4019        return NULL;
 4020    }
 4021    #endif
 4022
 4023    /* Loop through X509 name entries and copy new format to buffer */
 4024    count = wolfSSL_X509_NAME_entry_count(name);
 4025    for (i = 0; i < count; i++) {
 4026        WOLFSSL_X509_NAME_ENTRY* entry;
 4027        int nameSz;
 4028        int strSz;
 4029        int strLen;
 4030        char *str;
 4031        const int tmpBufSz = sizeof(tmpBuf);
 4032        char buf[80];
 4033        const char* sn;
 4034
 4035        /* Get name entry and size */
 4036        entry = wolfSSL_X509_NAME_get_entry(name, i);
 4037        if (entry == NULL) {
 4038            WOLFSSL_MSG("wolfSSL_X509_NAME_get_entry failed");
 4039            return NULL;
 4040        }
 4041        nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, entry->nid, buf,
 4042                                                                   sizeof(buf));
 4043        if (nameSz < 0) {
 4044            WOLFSSL_MSG("wolfSSL_X509_NAME_get_text_by_NID failed");
 4045            return NULL;
 4046        }
 4047
 4048        /* Get short name */
 4049        sn = wolfSSL_OBJ_nid2sn(entry->nid);
 4050        if (sn == NULL) {
 4051            WOLFSSL_MSG("OBJ_nid2sn failed");
 4052            return NULL;
 4053        }
 4054
 4055        /* Copy sn and name text to buffer
 4056         * Add extra strSz for '=', ',', ' ' and '\0' characters in XSNPRINTF.
 4057         */
 4058        if (i != count - 1) {
 4059            strSz = (int)XSTRLEN(sn) + nameSz + 4;
 4060            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 4061            if (str == NULL) {
 4062                WOLFSSL_MSG("Memory error");
 4063                return NULL;
 4064            }
 4065            strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s, ", sn, buf);
 4066            if ((strLen  < 0) || (strLen  >= strSz)) {
 4067                WOLFSSL_MSG("buffer overrun");
 4068                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 4069                return NULL;
 4070            }
 4071        }
 4072        else {
 4073            /* Copy last name entry
 4074            * Add extra strSz for '=' and '\0' characters in XSNPRINTF.
 4075            */
 4076            strSz = (int)XSTRLEN(sn) + nameSz + 2;
 4077            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 4078            if (str == NULL) {
 4079                WOLFSSL_MSG("Memory error");
 4080                return NULL;
 4081            }
 4082            strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s", sn, buf);
 4083            if ((strLen  < 0) || (strLen  >= strSz)) {
 4084                WOLFSSL_MSG("buffer overrun");
 4085                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 4086                return NULL;
 4087            }
 4088        }
 4089        /* Copy string to tmpBuf */
 4090        if (totalLen + strLen > tmpBufSz) {
 4091            WOLFSSL_MSG("buffer overrun");
 4092            XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 4093            return NULL;
 4094        }
 4095        XMEMCPY(tmpBuf + totalLen, str, strLen);
 4096        totalLen += strLen;
 4097        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 4098    }
 4099
 4100    /* Allocate space based on total string size if no buffer was provided */
 4101    if (!in) {
 4102        in = (char*)XMALLOC(totalLen+1, NULL, DYNAMIC_TYPE_OPENSSL);
 4103        if (in == NULL) {
 4104            WOLFSSL_MSG("Memory error");
 4105            return in;
 4106        }
 4107    }
 4108    else {
 4109        if (totalLen + 1 > sz) {
 4110            WOLFSSL_MSG("buffer overrun");
 4111            return NULL;
 4112        }
 4113    }
 4114
 4115    XMEMCPY(in, tmpBuf, totalLen); /* cppcheck-suppress uninitvar */
 4116    in[totalLen] = '\0';
 4117
 4118    return in;
 4119}
 4120#endif
 4121
 4122
 4123/* Wraps wolfSSL_X509_d2i
 4124 *
 4125 * returns a WOLFSSL_X509 structure pointer on success and NULL on fail
 4126 */
 4127WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
 4128        int len)
 4129{
 4130    WOLFSSL_X509* newX509 = NULL;
 4131    WOLFSSL_ENTER("wolfSSL_d2i_X509");
 4132
 4133    if (in == NULL) {
 4134        WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
 4135        return NULL;
 4136    }
 4137
 4138    newX509 = wolfSSL_X509_d2i(x509, *in, len);
 4139    if (newX509 != NULL) {
 4140        *in += newX509->derCert->length;
 4141    }
 4142    return newX509;
 4143}
 4144
 4145static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
 4146                                  const byte* in, int len, int req, void* heap)
 4147{
 4148    WOLFSSL_X509 *newX509 = NULL;
 4149    int type = req ? CERTREQ_TYPE : CERT_TYPE;
 4150
 4151    WOLFSSL_ENTER("wolfSSL_X509_d2i");
 4152
 4153    if (in != NULL && len != 0
 4154    #ifndef WOLFSSL_CERT_REQ
 4155            && req == 0
 4156    #else
 4157            && (req == 0 || req == 1)
 4158    #endif
 4159            ) {
 4160        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
 4161
 4162        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
 4163            return NULL);
 4164
 4165        InitDecodedCert(cert, (byte*)in, (word32)len, heap);
 4166    #ifdef WOLFSSL_CERT_REQ
 4167        cert->isCSR = (byte)req;
 4168    #endif
 4169        if (ParseCertRelative(cert, type, 0, NULL, NULL) == 0) {
 4170            newX509 = wolfSSL_X509_new_ex(heap);
 4171            if (newX509 != NULL) {
 4172                if (CopyDecodedToX509(newX509, cert) != 0) {
 4173                    wolfSSL_X509_free(newX509);
 4174                    newX509 = NULL;
 4175                }
 4176            }
 4177        }
 4178        FreeDecodedCert(cert);
 4179        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 4180    }
 4181
 4182    if (x509 != NULL)
 4183        *x509 = newX509;
 4184
 4185    return newX509;
 4186}
 4187
 4188int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
 4189{
 4190    int isCA = 0;
 4191
 4192    WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
 4193
 4194    if (x509 != NULL)
 4195        isCA = x509->isCa;
 4196
 4197    WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
 4198
 4199    return isCA;
 4200}
 4201
 4202WOLFSSL_X509* wolfSSL_X509_d2i_ex(WOLFSSL_X509** x509, const byte* in, int len,
 4203    void* heap)
 4204{
 4205    return d2i_X509orX509REQ(x509, in, len, 0, heap);
 4206}
 4207
 4208WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
 4209{
 4210    return wolfSSL_X509_d2i_ex(x509, in, len, NULL);
 4211}
 4212
 4213#ifdef WOLFSSL_CERT_REQ
 4214WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509,
 4215        const unsigned char* in, int len)
 4216{
 4217    return d2i_X509orX509REQ(x509, in, len, 1, NULL);
 4218}
 4219
 4220WOLFSSL_X509* wolfSSL_d2i_X509_REQ_INFO(WOLFSSL_X509** req,
 4221        const unsigned char** in, int len)
 4222{
 4223    WOLFSSL_X509* ret = NULL;
 4224    WOLFSSL_ENTER("wolfSSL_d2i_X509_REQ_INFO");
 4225
 4226    if (in == NULL) {
 4227        WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
 4228        return NULL;
 4229    }
 4230
 4231    ret = wolfSSL_X509_REQ_d2i(req, *in, len);
 4232    if (ret != NULL) {
 4233        *in += ret->derCert->length;
 4234    }
 4235    return ret;
 4236}
 4237#endif
 4238
 4239#endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
 4240          OPENSSL_EXTRA_X509_SMALL */
 4241
 4242#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
 4243/* returns the number of entries in the WOLFSSL_X509_NAME */
 4244int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
 4245{
 4246    int count = 0;
 4247
 4248    WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
 4249
 4250    if (name != NULL)
 4251        count = name->entrySz;
 4252
 4253    WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
 4254    return count;
 4255}
 4256#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
 4257
 4258#if defined(OPENSSL_EXTRA) || \
 4259    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT)
 4260
 4261/* return the next, if any, altname from the peer cert */
 4262WOLFSSL_ABI
 4263char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
 4264{
 4265    char* ret = NULL;
 4266    WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
 4267
 4268    /* don't have any to work with */
 4269    if (cert == NULL || cert->altNames == NULL)
 4270        return NULL;
 4271
 4272    /* already went through them */
 4273    if (cert->altNamesNext == NULL) {
 4274#ifdef WOLFSSL_MULTICIRCULATE_ALTNAMELIST
 4275        /* Reset altNames List to head
 4276         * so that caller can circulate the list again
 4277         */
 4278        cert->altNamesNext = cert->altNames;
 4279#endif
 4280        return NULL;
 4281    }
 4282
 4283    /* In default builds iPAddress entries hold raw 4/16 octet payloads
 4284     * and registeredID entries hold raw OID body bytes (no human-readable
 4285     * ipString/ridString), so returning them as a C string would truncate
 4286     * at any embedded NUL byte. Such entries are still parsed into
 4287     * altNames for name-constraint enforcement; skip them here so
 4288     * string-iteration callers see the same set of entries as before.
 4289     *
 4290     * With WOLFSSL_MULTICIRCULATE_ALTNAMELIST, a list consisting only of
 4291     * skipped entries collapses to "no entries" on the first pass and
 4292     * resets to head on the next call; the cycle shape matches the
 4293     * pre-fix behavior where such entries were never parsed. */
 4294#if !defined(WOLFSSL_IP_ALT_NAME) || !defined(WOLFSSL_RID_ALT_NAME)
 4295    while (cert->altNamesNext != NULL) {
 4296        int skip = 0;
 4297#ifndef WOLFSSL_IP_ALT_NAME
 4298        if (cert->altNamesNext->type == ASN_IP_TYPE)
 4299            skip = 1;
 4300#endif
 4301#ifndef WOLFSSL_RID_ALT_NAME
 4302        if (cert->altNamesNext->type == ASN_RID_TYPE)
 4303            skip = 1;
 4304#endif
 4305        if (!skip)
 4306            break;
 4307        cert->altNamesNext = cert->altNamesNext->next;
 4308    }
 4309    if (cert->altNamesNext == NULL)
 4310        return NULL;
 4311#endif /* !WOLFSSL_IP_ALT_NAME || !WOLFSSL_RID_ALT_NAME */
 4312
 4313    /* unsafe cast required for ABI compatibility. */
 4314    ret = (char *)(wc_ptr_t)cert->altNamesNext->name;
 4315#ifdef WOLFSSL_IP_ALT_NAME
 4316    /* return the IP address as a string */
 4317    if (cert->altNamesNext->type == ASN_IP_TYPE) {
 4318        ret = cert->altNamesNext->ipString;
 4319    }
 4320#endif
 4321#ifdef WOLFSSL_RID_ALT_NAME
 4322    /* return the registeredID as a string */
 4323    if (cert->altNamesNext->type == ASN_RID_TYPE) {
 4324        ret = cert->altNamesNext->ridString;
 4325    }
 4326#endif
 4327    cert->altNamesNext = cert->altNamesNext->next;
 4328
 4329    return ret;
 4330}
 4331
 4332int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
 4333                                                unsigned char* buf, int* bufSz)
 4334{
 4335    WOLFSSL_ENTER("wolfSSL_X509_get_signature");
 4336    if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->sig.length &&
 4337                buf != NULL))
 4338        return WOLFSSL_FATAL_ERROR;
 4339
 4340    if (buf != NULL)
 4341        XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
 4342    *bufSz = (int)x509->sig.length;
 4343
 4344    return WOLFSSL_SUCCESS;
 4345}
 4346
 4347
 4348/* Getter function that copies over the DER public key buffer to "buf" and
 4349    * sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed
 4350    * buffer size. "bufSz" passed in should initially be set by the user to be
 4351    * the size of "buf". This gets checked to make sure the buffer is large
 4352    * enough to hold the public key.
 4353    *
 4354    * Note: this is the X.509 form of key with "header" info.
 4355    * return WOLFSSL_SUCCESS on success
 4356    */
 4357int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509,
 4358                                            unsigned char* buf, int* bufSz)
 4359{
 4360    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
 4361    const byte*  der;
 4362    int length = 0;
 4363    int    ret = 0, derSz = 0;
 4364    int badDate = 0;
 4365    const byte* pubKeyX509 = NULL;
 4366    int   pubKeyX509Sz = 0;
 4367
 4368    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer");
 4369    if (x509 == NULL || bufSz == NULL) {
 4370        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BAD_FUNC_ARG);
 4371        return WOLFSSL_FATAL_ERROR;
 4372    }
 4373
 4374
 4375#ifdef WOLFSSL_SMALL_STACK
 4376    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
 4377                                    x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
 4378    if (cert == NULL) {
 4379        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", MEMORY_E);
 4380        return WOLFSSL_FATAL_ERROR;
 4381    }
 4382#endif
 4383
 4384    der = wolfSSL_X509_get_der(x509, &derSz);
 4385    if (der != NULL) {
 4386        InitDecodedCert(cert, der, (word32)derSz, NULL);
 4387        ret = wc_GetPubX509(cert, 0, &badDate);
 4388        if (ret >= 0) {
 4389            word32 idx = cert->srcIdx;
 4390            pubKeyX509 = cert->source + cert->srcIdx;
 4391            ret = GetSequence(cert->source, &cert->srcIdx, &length,
 4392                    cert->maxIdx);
 4393            pubKeyX509Sz = length + (cert->srcIdx - idx);
 4394        }
 4395        FreeDecodedCert(cert);
 4396    }
 4397    WC_FREE_VAR_EX(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
 4398
 4399    if (ret < 0) {
 4400        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", ret);
 4401        return WOLFSSL_FATAL_ERROR;
 4402    }
 4403
 4404    if (buf != NULL && pubKeyX509 != NULL) {
 4405        if (pubKeyX509Sz > *bufSz) {
 4406            WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BUFFER_E);
 4407            return WOLFSSL_FATAL_ERROR;
 4408        }
 4409        XMEMCPY(buf, pubKeyX509, pubKeyX509Sz);
 4410    }
 4411    *bufSz = pubKeyX509Sz;
 4412
 4413    return WOLFSSL_SUCCESS;
 4414}
 4415
 4416
 4417/* Getter function for the public key OID value
 4418    * return public key OID stored in WOLFSSL_X509 structure */
 4419int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509)
 4420{
 4421    if (x509 == NULL)
 4422        return WOLFSSL_FAILURE;
 4423    return x509->pubKeyOID;
 4424}
 4425
 4426#endif /* OPENSSL_EXTRA || KEEP_OUR_CERT || KEEP_PEER_CERT || SESSION_CERTS */
 4427
 4428#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
 4429    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
 4430
 4431/* write X509 serial number in unsigned binary to buffer
 4432    buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
 4433    return WOLFSSL_SUCCESS on success */
 4434int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
 4435                                    byte* in, int* inOutSz)
 4436{
 4437    WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
 4438    if (x509 == NULL || inOutSz == NULL) {
 4439        WOLFSSL_MSG("Null argument passed in");
 4440        return BAD_FUNC_ARG;
 4441    }
 4442
 4443    if (in != NULL) {
 4444        if (*inOutSz < x509->serialSz) {
 4445            WOLFSSL_MSG("Serial buffer too small");
 4446            return BUFFER_E;
 4447        }
 4448        XMEMCPY(in, x509->serial, x509->serialSz);
 4449    }
 4450    *inOutSz = x509->serialSz;
 4451
 4452    return WOLFSSL_SUCCESS;
 4453}
 4454
 4455/* not an openssl compatibility function - getting for derCert */
 4456const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
 4457{
 4458    WOLFSSL_ENTER("wolfSSL_X509_get_der");
 4459
 4460    if (x509 == NULL || x509->derCert == NULL || outSz == NULL)
 4461        return NULL;
 4462
 4463    *outSz = (int)x509->derCert->length;
 4464    return x509->derCert->buffer;
 4465}
 4466
 4467#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_OUR_CERT ||
 4468        * KEEP_PEER_CERT || SESSION_CERTS */
 4469
 4470#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) || \
 4471    defined(OPENSSL_ALL) || defined(KEEP_OUR_CERT) || \
 4472    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
 4473
 4474/* used by JSSE (not a standard compatibility function) */
 4475WOLFSSL_ABI
 4476const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
 4477{
 4478    WOLFSSL_ENTER("wolfSSL_X509_notBefore");
 4479
 4480    if (x509 == NULL) {
 4481        return NULL;
 4482    }
 4483
 4484    if (x509->notBefore.length < 0 ||
 4485            x509->notBefore.length > (int)sizeof(x509->notBeforeData) - 2) {
 4486        return NULL;
 4487    }
 4488
 4489    XMEMSET(x509->notBeforeData, 0, sizeof(x509->notBeforeData));
 4490    x509->notBeforeData[0] = (byte)x509->notBefore.type;
 4491    x509->notBeforeData[1] = (byte)x509->notBefore.length;
 4492    XMEMCPY(&x509->notBeforeData[2], x509->notBefore.data,
 4493        x509->notBefore.length);
 4494
 4495    return x509->notBeforeData;
 4496}
 4497
 4498/* used by JSSE (not a standard compatibility function) */
 4499WOLFSSL_ABI
 4500const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
 4501{
 4502    WOLFSSL_ENTER("wolfSSL_X509_notAfter");
 4503
 4504    if (x509 == NULL) {
 4505        return NULL;
 4506    }
 4507
 4508    if (x509->notAfter.length < 0 ||
 4509            x509->notAfter.length > (int)sizeof(x509->notAfterData) - 2) {
 4510        return NULL;
 4511    }
 4512
 4513    XMEMSET(x509->notAfterData, 0, sizeof(x509->notAfterData));
 4514    x509->notAfterData[0] = (byte)x509->notAfter.type;
 4515    x509->notAfterData[1] = (byte)x509->notAfter.length;
 4516    XMEMCPY(&x509->notAfterData[2], x509->notAfter.data, x509->notAfter.length);
 4517
 4518    return x509->notAfterData;
 4519}
 4520
 4521int wolfSSL_X509_version(WOLFSSL_X509* x509)
 4522{
 4523    WOLFSSL_ENTER("wolfSSL_X509_version");
 4524
 4525    if (x509 == NULL)
 4526        return 0;
 4527
 4528    return x509->version;
 4529}
 4530#endif
 4531
 4532#ifdef OPENSSL_EXTRA
 4533
 4534/* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate
 4535    *
 4536    * outSz : gets set to the size of the buffer
 4537    * returns a pointer to the internal buffer at the location of TBS on
 4538    *         on success and NULL on failure.
 4539    */
 4540const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz)
 4541{
 4542    int sz = 0, len;
 4543    unsigned int idx = 0, tmpIdx;
 4544    const unsigned char* der = NULL;
 4545    const unsigned char* tbs = NULL;
 4546
 4547    if (x509 == NULL || outSz == NULL) {
 4548        return NULL;
 4549    }
 4550
 4551    der = wolfSSL_X509_get_der(x509, &sz);
 4552    if (der == NULL) {
 4553        return NULL;
 4554    }
 4555
 4556    if (GetSequence(der, &idx, &len, (word32)sz) < 0) {
 4557        return NULL;
 4558    }
 4559    tbs = der + idx;
 4560    tmpIdx = idx;
 4561    if (GetSequence(der, &idx, &len, (word32)sz) < 0) {
 4562        return NULL;
 4563    }
 4564    *outSz = len + (idx - tmpIdx);
 4565    return tbs;
 4566}
 4567
 4568#ifdef WOLFSSL_SEP
 4569
 4570/* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
 4571   malloc buffer, call responsible for freeing. Actual size returned in
 4572   *inOutSz. Requires inOutSz be non-null */
 4573byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
 4574{
 4575    int copySz;
 4576
 4577    WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
 4578    if (x509 == NULL) return NULL;
 4579    if (inOutSz == NULL) return NULL;
 4580    if (!x509->deviceTypeSz) return in;
 4581
 4582    copySz = min(*inOutSz, x509->deviceTypeSz);
 4583
 4584    if (!in) {
 4585    #ifdef WOLFSSL_STATIC_MEMORY
 4586        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
 4587        return NULL;
 4588    #else
 4589        in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
 4590        if (!in) return in;
 4591        copySz = x509->deviceTypeSz;
 4592    #endif
 4593    }
 4594
 4595    XMEMCPY(in, x509->deviceType, copySz);
 4596    *inOutSz = copySz;
 4597
 4598    return in;
 4599}
 4600
 4601
 4602byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
 4603{
 4604    int copySz;
 4605
 4606    WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
 4607    if (x509 == NULL) return NULL;
 4608    if (inOutSz == NULL) return NULL;
 4609    if (!x509->hwTypeSz) return in;
 4610
 4611    copySz = min(*inOutSz, x509->hwTypeSz);
 4612
 4613    if (!in) {
 4614    #ifdef WOLFSSL_STATIC_MEMORY
 4615        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
 4616        return NULL;
 4617    #else
 4618        in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
 4619        if (!in) return in;
 4620        copySz = x509->hwTypeSz;
 4621    #endif
 4622    }
 4623
 4624    XMEMCPY(in, x509->hwType, copySz);
 4625    *inOutSz = copySz;
 4626
 4627    return in;
 4628}
 4629
 4630
 4631byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
 4632                                        int* inOutSz)
 4633{
 4634    int copySz;
 4635
 4636    WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
 4637    if (x509 == NULL) return NULL;
 4638    if (inOutSz == NULL) return NULL;
 4639    if (!x509->hwTypeSz) return in;
 4640
 4641    copySz = min(*inOutSz, x509->hwSerialNumSz);
 4642
 4643    if (!in) {
 4644    #ifdef WOLFSSL_STATIC_MEMORY
 4645        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
 4646        return NULL;
 4647    #else
 4648        in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
 4649        if (!in) return in;
 4650        copySz = x509->hwSerialNumSz;
 4651    #endif
 4652    }
 4653
 4654    XMEMCPY(in, x509->hwSerialNum, copySz);
 4655    *inOutSz = copySz;
 4656
 4657    return in;
 4658}
 4659
 4660#endif /* WOLFSSL_SEP */
 4661#endif /* OPENSSL_EXTRA */
 4662
 4663/* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
 4664#if defined(OPENSSL_EXTRA)
 4665
 4666WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509)
 4667{
 4668    WOLFSSL_ENTER("wolfSSL_X509_get_notBefore");
 4669
 4670    if (x509 == NULL)
 4671        return NULL;
 4672
 4673    return (WOLFSSL_ASN1_TIME*)&x509->notBefore;
 4674}
 4675
 4676
 4677WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509)
 4678{
 4679    WOLFSSL_ENTER("wolfSSL_X509_get_notAfter");
 4680
 4681    if (x509 == NULL)
 4682        return NULL;
 4683
 4684    return (WOLFSSL_ASN1_TIME*)&x509->notAfter;
 4685}
 4686
 4687
 4688/* return number of elements on success 0 on fail */
 4689int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
 4690    WOLFSSL_X509* x509)
 4691{
 4692    WOLFSSL_ENTER("wolfSSL_sk_X509_push");
 4693
 4694    if (sk == NULL || x509 == NULL) {
 4695        return WOLFSSL_FAILURE;
 4696    }
 4697
 4698    return wolfSSL_sk_push(sk, x509);
 4699}
 4700
 4701
 4702/* Return and remove the last x509 pushed on stack */
 4703WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
 4704{
 4705    return (WOLFSSL_X509*)wolfSSL_sk_pop(sk);
 4706}
 4707
 4708/* Getter function for WOLFSSL_X509 pointer
 4709 *
 4710 * sk is the stack to retrieve pointer from
 4711 * i  is the index value in stack
 4712 *
 4713 * returns a pointer to a WOLFSSL_X509 structure on success and NULL on
 4714 *         fail
 4715 */
 4716WOLFSSL_X509* wolfSSL_sk_X509_value(WOLF_STACK_OF(WOLFSSL_X509)* sk, int i)
 4717{
 4718    WOLFSSL_ENTER("wolfSSL_sk_X509_value");
 4719
 4720    for (; sk != NULL && i > 0; i--)
 4721        sk = sk->next;
 4722
 4723    if (i != 0 || sk == NULL)
 4724        return NULL;
 4725    return sk->data.x509;
 4726}
 4727
 4728
 4729/* Return and remove the first x509 pushed on stack */
 4730WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk)
 4731{
 4732    return (WOLFSSL_X509*)wolfSSL_sk_pop_node(sk, 0);
 4733}
 4734
 4735#endif /* OPENSSL_EXTRA */
 4736
 4737#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
 4738/* Free's all nodes in X509 stack. This is different then wolfSSL_sk_X509_free
 4739 * in that it free's the underlying objects pushed to the stack.
 4740 *
 4741 * sk  stack to free nodes in
 4742 * f   X509 free function
 4743 */
 4744void wolfSSL_sk_X509_pop_free(WOLF_STACK_OF(WOLFSSL_X509)* sk,
 4745    void (*f) (WOLFSSL_X509*))
 4746{
 4747    WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
 4748    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
 4749}
 4750
 4751
 4752/* free just the stack structure */
 4753void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk)
 4754{
 4755    wolfSSL_sk_free(sk);
 4756}
 4757
 4758#ifdef HAVE_CRL
 4759WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void)
 4760{
 4761    WOLFSSL_STACK* s = wolfSSL_sk_new_node(NULL);
 4762    if (s != NULL)
 4763        s->type = STACK_TYPE_X509_CRL;
 4764    return s;
 4765}
 4766
 4767WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new_null(void)
 4768{
 4769    WOLFSSL_STACK* s = wolfSSL_sk_new_null();
 4770    if (s != NULL)
 4771        s->type = STACK_TYPE_X509_CRL;
 4772    return s;
 4773}
 4774
 4775void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
 4776    void (*f) (WOLFSSL_X509_CRL*))
 4777{
 4778    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_pop_free");
 4779    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
 4780}
 4781
 4782void wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk)
 4783{
 4784    wolfSSL_sk_X509_CRL_pop_free(sk, NULL);
 4785}
 4786
 4787/* return number of elements on success 0 on fail */
 4788int wolfSSL_sk_X509_CRL_push(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
 4789    WOLFSSL_X509_CRL* crl)
 4790{
 4791    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_push");
 4792
 4793    if (sk == NULL || crl == NULL) {
 4794        return WOLFSSL_FAILURE;
 4795    }
 4796
 4797    return wolfSSL_sk_push(sk, crl);
 4798}
 4799
 4800WOLFSSL_X509_CRL* wolfSSL_sk_X509_CRL_value(WOLF_STACK_OF(WOLFSSL_X509)* sk,
 4801                                            int i)
 4802{
 4803    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_value");
 4804    if (sk)
 4805        return (WOLFSSL_X509_CRL*)wolfSSL_sk_value(sk, i);
 4806    return NULL;
 4807}
 4808
 4809int wolfSSL_sk_X509_CRL_num(WOLF_STACK_OF(WOLFSSL_X509)* sk)
 4810{
 4811    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_num");
 4812    if (sk)
 4813        return wolfSSL_sk_num(sk);
 4814    return 0;
 4815}
 4816#endif /* HAVE_CRL */
 4817
 4818#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
 4819
 4820#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT)
 4821/* return number of elements on success 0 on fail */
 4822int wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk,
 4823                                              WOLFSSL_ACCESS_DESCRIPTION* a)
 4824{
 4825    WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_push");
 4826
 4827    return wolfSSL_sk_push(sk, a);
 4828}
 4829
 4830/* Frees all nodes in ACCESS_DESCRIPTION stack
 4831*
 4832* sk stack of nodes to free
 4833* f  free function to use
 4834*/
 4835void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk,
 4836    void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
 4837{
 4838   WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_pop_free");
 4839   wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
 4840}
 4841
 4842void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk)
 4843{
 4844    wolfSSL_sk_free(sk);
 4845}
 4846
 4847
 4848/* AUTHORITY_INFO_ACCESS object is a stack of ACCESS_DESCRIPTION objects,
 4849 * to free the stack the WOLFSSL_ACCESS_DESCRIPTION stack free function is
 4850 * used */
 4851void wolfSSL_AUTHORITY_INFO_ACCESS_free(
 4852        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk)
 4853{
 4854    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
 4855    wolfSSL_sk_ACCESS_DESCRIPTION_free(sk);
 4856}
 4857
 4858void wolfSSL_AUTHORITY_INFO_ACCESS_pop_free(
 4859        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk,
 4860        void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
 4861{
 4862    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
 4863    wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, f);
 4864}
 4865
 4866
 4867void wolfSSL_ACCESS_DESCRIPTION_free(WOLFSSL_ACCESS_DESCRIPTION* a)
 4868{
 4869    WOLFSSL_ENTER("wolfSSL_ACCESS_DESCRIPTION_free");
 4870    if (a == NULL)
 4871        return;
 4872
 4873    if (a->method)
 4874        wolfSSL_ASN1_OBJECT_free(a->method);
 4875    if (a->location)
 4876        wolfSSL_GENERAL_NAME_free(a->location);
 4877    XFREE(a, NULL, DYNAMIC_TYPE_X509_EXT);
 4878
 4879    /* a = NULL, don't try to a or double free it */
 4880}
 4881#endif /* OPENSSL_EXTRA || WOLFSSL_QT */
 4882
 4883#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
 4884
 4885/* Creates and returns new GENERAL_NAME structure */
 4886WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void)
 4887{
 4888    WOLFSSL_GENERAL_NAME* gn;
 4889    WOLFSSL_ENTER("GENERAL_NAME_new");
 4890
 4891    gn = (WOLFSSL_GENERAL_NAME*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAME), NULL,
 4892                                                             DYNAMIC_TYPE_ASN1);
 4893    if (gn == NULL) {
 4894        return NULL;
 4895    }
 4896    XMEMSET(gn, 0, sizeof(WOLFSSL_GENERAL_NAME));
 4897
 4898    gn->d.ia5 = wolfSSL_ASN1_STRING_new();
 4899    if (gn->d.ia5 == NULL) {
 4900        WOLFSSL_MSG("Issue creating ASN1_STRING struct");
 4901        wolfSSL_GENERAL_NAME_free(gn);
 4902        return NULL;
 4903    }
 4904    gn->type = WOLFSSL_GEN_IA5;
 4905    return gn;
 4906}
 4907
 4908WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn)
 4909{
 4910    WOLFSSL_GENERAL_NAME* dupl = NULL;
 4911
 4912    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_dup");
 4913
 4914    if (!gn) {
 4915        WOLFSSL_MSG("Bad parameter");
 4916        return NULL;
 4917    }
 4918
 4919    if (!(dupl = wolfSSL_GENERAL_NAME_new())) {
 4920        WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
 4921        return NULL;
 4922    }
 4923
 4924    wolfSSL_ASN1_STRING_free(dupl->d.ia5);
 4925    dupl->d.ia5 = NULL;
 4926    switch (gn->type) {
 4927    /* WOLFSSL_ASN1_STRING types */
 4928    case WOLFSSL_GEN_DNS:
 4929        if (!(dupl->d.dNSName = wolfSSL_ASN1_STRING_dup(gn->d.dNSName))) {
 4930            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
 4931            goto error;
 4932        }
 4933        break;
 4934    case WOLFSSL_GEN_IPADD:
 4935        if (!(dupl->d.iPAddress = wolfSSL_ASN1_STRING_dup(gn->d.iPAddress))) {
 4936            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
 4937            goto error;
 4938        }
 4939        break;
 4940    case WOLFSSL_GEN_EMAIL:
 4941        if (!(dupl->d.rfc822Name = wolfSSL_ASN1_STRING_dup(gn->d.rfc822Name))) {
 4942            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
 4943            goto error;
 4944        }
 4945        break;
 4946    case WOLFSSL_GEN_URI:
 4947        if (!(dupl->d.uniformResourceIdentifier =
 4948                wolfSSL_ASN1_STRING_dup(gn->d.uniformResourceIdentifier))) {
 4949            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
 4950            goto error;
 4951        }
 4952        break;
 4953    case WOLFSSL_GEN_OTHERNAME:
 4954        if (gn->d.otherName->value->type != WOLFSSL_V_ASN1_UTF8STRING) {
 4955            WOLFSSL_MSG("Unsupported othername value type");
 4956            goto error;
 4957        }
 4958        dupl->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
 4959            sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
 4960        if (dupl->d.otherName == NULL) {
 4961            WOLFSSL_MSG("XMALLOC error");
 4962            goto error;
 4963        }
 4964        dupl->d.otherName->type_id = wolfSSL_ASN1_OBJECT_dup(
 4965            gn->d.otherName->type_id);
 4966        dupl->d.otherName->value = (WOLFSSL_ASN1_TYPE*)XMALLOC(
 4967            sizeof(WOLFSSL_ASN1_TYPE), NULL, DYNAMIC_TYPE_ASN1);
 4968        if (dupl->d.otherName->value != NULL) {
 4969            dupl->d.otherName->value->type = gn->d.otherName->value->type;
 4970            dupl->d.otherName->value->value.utf8string =
 4971                wolfSSL_ASN1_STRING_dup(
 4972                                      gn->d.otherName->value->value.utf8string);
 4973        }
 4974        if ((dupl->d.otherName->type_id == NULL) ||
 4975            (dupl->d.otherName->value == NULL) ||
 4976            (dupl->d.otherName->value->value.utf8string == NULL)) {
 4977            wolfSSL_ASN1_OBJECT_free(dupl->d.otherName->type_id);
 4978            wolfSSL_ASN1_TYPE_free(dupl->d.otherName->value);
 4979            XFREE(dupl->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
 4980            dupl->d.otherName = NULL;
 4981            WOLFSSL_MSG("error duping othername");
 4982            goto error;
 4983        }
 4984        break;
 4985    case WOLFSSL_GEN_X400:
 4986    case WOLFSSL_GEN_DIRNAME:
 4987    case WOLFSSL_GEN_EDIPARTY:
 4988    case WOLFSSL_GEN_RID:
 4989    default:
 4990        WOLFSSL_MSG("Unrecognized or unsupported GENERAL_NAME type");
 4991        goto error;
 4992    }
 4993    dupl->type = gn->type;
 4994
 4995    return dupl;
 4996error:
 4997    wolfSSL_GENERAL_NAME_free(dupl);
 4998    return NULL;
 4999}
 5000
 5001/* Set an Othername in a general name.
 5002 *
 5003 * @param [out] gen     Pointer to the GENERAL_NAME where the othername is set.
 5004 * @param [in]  oid     Object ID (ie UPN).
 5005 * @param [in]  name    The actual name.
 5006 * @return  WOLFSSL_FAILURE on invalid parameter or memory error,
 5007 *          WOLFSSL_SUCCESS otherwise.
 5008 */
 5009int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen,
 5010                                        WOLFSSL_ASN1_OBJECT* oid,
 5011                                        WOLFSSL_ASN1_TYPE* value)
 5012{
 5013    WOLFSSL_ASN1_OBJECT *x = NULL;
 5014
 5015    if ((gen == NULL) || (oid == NULL) || (value == NULL)) {
 5016        return WOLFSSL_FAILURE;
 5017    }
 5018
 5019    x = wolfSSL_ASN1_OBJECT_dup(oid);
 5020    if (x == NULL) {
 5021        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup() failed");
 5022        return WOLFSSL_FAILURE;
 5023    }
 5024
 5025    if (wolfSSL_GENERAL_NAME_set_type(gen, WOLFSSL_GEN_OTHERNAME)
 5026            != WOLFSSL_SUCCESS) {
 5027        wolfSSL_ASN1_OBJECT_free(x);
 5028        return WOLFSSL_FAILURE;
 5029    }
 5030
 5031    gen->d.otherName->type_id = x;
 5032    gen->d.otherName->value = value;
 5033    return WOLFSSL_SUCCESS;
 5034}
 5035
 5036/* return number of elements on success 0 on fail */
 5037int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk,
 5038                                 WOLFSSL_GENERAL_NAME* gn)
 5039{
 5040    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_push");
 5041
 5042    return wolfSSL_sk_push(sk, gn);
 5043}
 5044
 5045#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
 5046
 5047#ifdef OPENSSL_EXTRA
 5048
 5049/* Returns the general name at index i from the stack
 5050 *
 5051 * sk  stack to get general name from
 5052 * idx index to get
 5053 *
 5054 * return a pointer to the internal node of the stack
 5055 */
 5056WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int idx)
 5057{
 5058    return (WOLFSSL_GENERAL_NAME*)wolfSSL_sk_value(sk, idx);
 5059}
 5060
 5061/* Gets the number of nodes in the stack
 5062 *
 5063 * sk  stack to get the number of nodes from
 5064 *
 5065 * returns the number of nodes, -1 if no nodes
 5066 */
 5067int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk)
 5068{
 5069    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num");
 5070
 5071    return wolfSSL_sk_num(sk);
 5072}
 5073
 5074/* Allocates an empty GENERAL NAME stack */
 5075WOLFSSL_STACK* wolfSSL_sk_GENERAL_NAME_new(void *cmpFunc) {
 5076    WOLFSSL_STACK* sk = NULL;
 5077    (void)cmpFunc;
 5078    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_new");
 5079
 5080    sk = wolfSSL_sk_new_null();
 5081    if (sk != NULL) {
 5082        sk->type = STACK_TYPE_GEN_NAME;
 5083    }
 5084
 5085    return sk;
 5086}
 5087#endif /* OPENSSL_EXTRA */
 5088
 5089#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
 5090
 5091/* Frees all nodes in a GENERAL NAME stack
 5092 *
 5093 * sk stack of nodes to free
 5094 * f  free function to use, not called with wolfSSL
 5095 */
 5096void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk,
 5097        void (*f) (WOLFSSL_GENERAL_NAME*))
 5098{
 5099    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_pop_free");
 5100    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
 5101}
 5102
 5103void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk)
 5104{
 5105    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_free");
 5106    wolfSSL_sk_X509_pop_free(sk, NULL);
 5107}
 5108#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
 5109
 5110#ifdef OPENSSL_EXTRA
 5111static void wolfSSL_DIST_POINT_NAME_free(WOLFSSL_DIST_POINT_NAME* dpn)
 5112{
 5113    if (dpn != NULL) {
 5114        if (dpn->name.fullname != NULL) {
 5115            wolfSSL_sk_X509_pop_free(dpn->name.fullname, NULL);
 5116        }
 5117        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
 5118    }
 5119}
 5120
 5121
 5122/* returns new pointer on success and NULL on fail */
 5123static WOLFSSL_DIST_POINT_NAME* wolfSSL_DIST_POINT_NAME_new(void)
 5124{
 5125    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
 5126    WOLFSSL_GENERAL_NAMES* gns = NULL;
 5127
 5128    dpn = (WOLFSSL_DIST_POINT_NAME*)XMALLOC(sizeof(WOLFSSL_DIST_POINT_NAME),
 5129                                            NULL, DYNAMIC_TYPE_OPENSSL);
 5130    if (dpn == NULL) {
 5131        return NULL;
 5132    }
 5133    XMEMSET(dpn, 0, sizeof(WOLFSSL_DIST_POINT_NAME));
 5134
 5135    gns = wolfSSL_sk_new_null();
 5136    if (gns == NULL) {
 5137        WOLFSSL_MSG("wolfSSL_sk_new_null error");
 5138        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
 5139        return NULL;
 5140    }
 5141    gns->type = STACK_TYPE_GEN_NAME;
 5142
 5143    /* DIST_POINT_NAME type may be 0 or 1, indicating whether fullname or
 5144     * relativename is used. See: RFC 5280 section 4.2.1.13 */
 5145    dpn->name.fullname = gns;
 5146    dpn->type = 0;
 5147
 5148    return dpn;
 5149}
 5150
 5151
 5152/* Creates and returns new DIST_POINT structure */
 5153WOLFSSL_DIST_POINT* wolfSSL_DIST_POINT_new(void)
 5154{
 5155    WOLFSSL_DIST_POINT* dp = NULL;
 5156    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
 5157
 5158    WOLFSSL_ENTER("wolfSSL_DIST_POINT_new");
 5159
 5160    dp = (WOLFSSL_DIST_POINT*)XMALLOC(sizeof(WOLFSSL_DIST_POINT), NULL,
 5161                                      DYNAMIC_TYPE_OPENSSL);
 5162    if (dp == NULL) {
 5163        return NULL;
 5164    }
 5165    XMEMSET(dp, 0, sizeof(WOLFSSL_DIST_POINT));
 5166
 5167    dpn = wolfSSL_DIST_POINT_NAME_new();
 5168    if (dpn == NULL) {
 5169        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
 5170        return NULL;
 5171    }
 5172    dp->distpoint = dpn;
 5173
 5174    return dp;
 5175}
 5176
 5177
 5178/* Frees DIST_POINT objects.
 5179*/
 5180void wolfSSL_DIST_POINT_free(WOLFSSL_DIST_POINT* dp)
 5181{
 5182    WOLFSSL_ENTER("wolfSSL_DIST_POINT_free");
 5183    if (dp != NULL) {
 5184        wolfSSL_DIST_POINT_NAME_free(dp->distpoint);
 5185        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
 5186    }
 5187}
 5188
 5189void wolfSSL_DIST_POINTS_free(WOLFSSL_DIST_POINTS *dps)
 5190{
 5191    WOLFSSL_ENTER("wolfSSL_DIST_POINTS_free");
 5192
 5193    if (dps == NULL) {
 5194        return;
 5195    }
 5196
 5197    wolfSSL_sk_free(dps);
 5198}
 5199
 5200/* return number of elements on success 0 on fail */
 5201int wolfSSL_sk_DIST_POINT_push(WOLFSSL_DIST_POINTS* sk, WOLFSSL_DIST_POINT* dp)
 5202{
 5203    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_push");
 5204
 5205    if (sk == NULL || dp == NULL) {
 5206        return WOLFSSL_FAILURE;
 5207    }
 5208
 5209    return wolfSSL_sk_push(sk, dp);
 5210}
 5211
 5212/* Returns the CRL dist point at index i from the stack
 5213 *
 5214 * sk  stack to get general name from
 5215 * idx index to get
 5216 *
 5217 * return a pointer to the internal node of the stack
 5218 */
 5219WOLFSSL_DIST_POINT* wolfSSL_sk_DIST_POINT_value(WOLFSSL_STACK* sk, int idx)
 5220{
 5221    if (sk == NULL) {
 5222        return NULL;
 5223    }
 5224
 5225    return (WOLFSSL_DIST_POINT*)wolfSSL_sk_value(sk, idx);
 5226}
 5227
 5228/* Gets the number of nodes in the stack
 5229 *
 5230 * sk  stack to get the number of nodes from
 5231 *
 5232 * returns the number of nodes, -1 if no nodes
 5233 */
 5234int wolfSSL_sk_DIST_POINT_num(WOLFSSL_STACK* sk)
 5235{
 5236    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_num");
 5237
 5238    if (sk == NULL) {
 5239        return WOLFSSL_FATAL_ERROR;
 5240    }
 5241
 5242    return wolfSSL_sk_num(sk);
 5243}
 5244
 5245/* Frees all nodes in a DIST_POINT stack
 5246 *
 5247 * sk stack of nodes to free
 5248 * f  free function to use
 5249 */
 5250void wolfSSL_sk_DIST_POINT_pop_free(WOLFSSL_STACK* sk,
 5251        void (*f) (WOLFSSL_DIST_POINT*))
 5252{
 5253    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_pop_free");
 5254    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
 5255}
 5256
 5257void wolfSSL_sk_DIST_POINT_free(WOLFSSL_STACK* sk)
 5258{
 5259    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_free");
 5260    wolfSSL_sk_free(sk);
 5261}
 5262
 5263/* returns the number of nodes in stack on success and WOLFSSL_FATAL_ERROR
 5264 * on fail */
 5265int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk)
 5266{
 5267    if (sk == NULL) {
 5268        return WOLFSSL_FATAL_ERROR;
 5269    }
 5270
 5271    return (int)sk->num;
 5272}
 5273
 5274/* returns NULL on fail and pointer to internal data on success */
 5275WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value(
 5276        WOLFSSL_STACK* sk, int idx)
 5277{
 5278    WOLFSSL_STACK* ret;
 5279
 5280    if (sk == NULL) {
 5281        return NULL;
 5282    }
 5283
 5284    ret = wolfSSL_sk_get_node(sk, idx);
 5285    if (ret != NULL) {
 5286        return ret->data.access;
 5287    }
 5288    return NULL;
 5289}
 5290#endif /* OPENSSL_EXTRA */
 5291
 5292#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
 5293/* free's the internal type for the general name */
 5294static void wolfSSL_GENERAL_NAME_type_free(WOLFSSL_GENERAL_NAME* name)
 5295{
 5296    if (name != NULL) {
 5297        switch (name->type) {
 5298        case WOLFSSL_GEN_IA5:
 5299            wolfSSL_ASN1_STRING_free(name->d.ia5);
 5300            name->d.ia5 = NULL;
 5301            break;
 5302        case WOLFSSL_GEN_EMAIL:
 5303            wolfSSL_ASN1_STRING_free(name->d.rfc822Name);
 5304            name->d.rfc822Name = NULL;
 5305            break;
 5306        case WOLFSSL_GEN_DNS:
 5307            wolfSSL_ASN1_STRING_free(name->d.dNSName);
 5308            name->d.dNSName = NULL;
 5309            break;
 5310        case WOLFSSL_GEN_DIRNAME:
 5311            wolfSSL_X509_NAME_free(name->d.dirn);
 5312            name->d.dirn = NULL;
 5313            break;
 5314        case WOLFSSL_GEN_URI:
 5315            wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier);
 5316            name->d.uniformResourceIdentifier = NULL;
 5317            break;
 5318        case WOLFSSL_GEN_IPADD:
 5319            wolfSSL_ASN1_STRING_free(name->d.iPAddress);
 5320            name->d.iPAddress = NULL;
 5321            break;
 5322        case WOLFSSL_GEN_RID:
 5323            wolfSSL_ASN1_OBJECT_free(name->d.registeredID);
 5324            name->d.registeredID = NULL;
 5325            break;
 5326        case WOLFSSL_GEN_OTHERNAME:
 5327            if (name->d.otherName != NULL) {
 5328                wolfSSL_ASN1_OBJECT_free(name->d.otherName->type_id);
 5329                wolfSSL_ASN1_TYPE_free(name->d.otherName->value);
 5330                XFREE(name->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
 5331                name->d.otherName = NULL;
 5332            }
 5333            break;
 5334        case WOLFSSL_GEN_X400:
 5335            /* Unsupported: fall through */
 5336        case WOLFSSL_GEN_EDIPARTY:
 5337            /* Unsupported: fall through */
 5338        default:
 5339            WOLFSSL_MSG("wolfSSL_GENERAL_NAME_type_free: possible leak");
 5340            break;
 5341        }
 5342    }
 5343}
 5344
 5345/* sets the general name type and free's the existing one
 5346 * can fail with a memory error if malloc fails or bad arg error
 5347 * otherwise return WOLFSSL_SUCCESS */
 5348int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, int typ)
 5349{
 5350    int ret = WOLFSSL_SUCCESS;
 5351
 5352    if (name != NULL) {
 5353        wolfSSL_GENERAL_NAME_type_free(name);
 5354        name->type = typ;
 5355
 5356        switch (typ) {
 5357            case WOLFSSL_GEN_URI:
 5358                name->d.uniformResourceIdentifier = wolfSSL_ASN1_STRING_new();
 5359                if (name->d.uniformResourceIdentifier == NULL)
 5360                    ret = MEMORY_E;
 5361                break;
 5362            case WOLFSSL_GEN_OTHERNAME:
 5363                name->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
 5364                    sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
 5365                if (name->d.otherName == NULL) {
 5366                    ret = MEMORY_E;
 5367                }
 5368                else {
 5369                    XMEMSET(name->d.otherName, 0, sizeof(WOLFSSL_ASN1_OTHERNAME));
 5370                }
 5371                break;
 5372            default:
 5373                name->type = WOLFSSL_GEN_IA5;
 5374                name->d.ia5 = wolfSSL_ASN1_STRING_new();
 5375                if (name->d.ia5 == NULL)
 5376                    ret = MEMORY_E;
 5377        }
 5378    }
 5379    else {
 5380        ret = BAD_FUNC_ARG;
 5381    }
 5382
 5383    return ret;
 5384}
 5385
 5386/* Set the value in a general name. This is a compat layer API.
 5387 *
 5388 * @param [out] a       Pointer to the GENERAL_NAME where the othername is set.
 5389 * @param [in]  type    The type of this general name.
 5390 * @param [in]  value   The ASN.1 string that is the value.
 5391 * @return none
 5392 * @note the set0 indicates we take ownership so the user does NOT free value.
 5393 */
 5394void wolfSSL_GENERAL_NAME_set0_value(WOLFSSL_GENERAL_NAME *a, int type,
 5395                                     void *value)
 5396{
 5397    WOLFSSL_ASN1_STRING *val = (WOLFSSL_ASN1_STRING *)value;
 5398    if (a == NULL) {
 5399        WOLFSSL_MSG("a is NULL");
 5400        return;
 5401    }
 5402
 5403    if (val == NULL) {
 5404        WOLFSSL_MSG("value is NULL");
 5405        return;
 5406    }
 5407
 5408    if (type != WOLFSSL_GEN_DNS) {
 5409        WOLFSSL_MSG("Only WOLFSSL_GEN_DNS is supported");
 5410        return;
 5411    }
 5412
 5413    wolfSSL_GENERAL_NAME_type_free(a);
 5414    a->type = type;
 5415    /* Only when WOLFSSL_GEN_DNS. */
 5416    a->d.dNSName = val;
 5417}
 5418
 5419/* Frees GENERAL_NAME objects.
 5420*/
 5421void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name)
 5422{
 5423    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free");
 5424    if (name != NULL) {
 5425        wolfSSL_GENERAL_NAME_type_free(name);
 5426        XFREE(name, NULL, DYNAMIC_TYPE_OPENSSL);
 5427    }
 5428}
 5429#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL*/
 5430
 5431#ifdef OPENSSL_EXTRA
 5432void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens)
 5433{
 5434    WOLFSSL_ENTER("wolfSSL_GENERAL_NAMES_free");
 5435
 5436    if (gens == NULL) {
 5437        return;
 5438    }
 5439
 5440    wolfSSL_sk_GENERAL_NAME_free(gens);
 5441}
 5442
 5443void wolfSSL_EXTENDED_KEY_USAGE_free(WOLFSSL_STACK * sk)
 5444{
 5445    WOLFSSL_ENTER("wolfSSL_EXTENDED_KEY_USAGE_free");
 5446
 5447    if (sk == NULL) {
 5448        return;
 5449    }
 5450
 5451    wolfSSL_sk_X509_pop_free(sk, NULL);
 5452}
 5453
 5454#if !defined(IGNORE_NAME_CONSTRAINTS)
 5455/*
 5456 * Allocate and initialize an empty GENERAL_SUBTREE structure.
 5457 * Returns NULL on allocation failure.
 5458 */
 5459WOLFSSL_GENERAL_SUBTREE* wolfSSL_GENERAL_SUBTREE_new(void)
 5460{
 5461    WOLFSSL_GENERAL_SUBTREE* subtree;
 5462
 5463    WOLFSSL_ENTER("wolfSSL_GENERAL_SUBTREE_new");
 5464
 5465    subtree = (WOLFSSL_GENERAL_SUBTREE*)XMALLOC(sizeof(WOLFSSL_GENERAL_SUBTREE),
 5466                                                NULL, DYNAMIC_TYPE_OPENSSL);
 5467    if (subtree == NULL) {
 5468        WOLFSSL_MSG("Failed to allocate GENERAL_SUBTREE");
 5469        return NULL;
 5470    }
 5471    XMEMSET(subtree, 0, sizeof(WOLFSSL_GENERAL_SUBTREE));
 5472    return subtree;
 5473}
 5474
 5475/*
 5476 * Create an empty NAME_CONSTRAINTS structure.
 5477 * Returns NULL on allocation failure.
 5478 */
 5479WOLFSSL_NAME_CONSTRAINTS* wolfSSL_NAME_CONSTRAINTS_new(void)
 5480{
 5481    WOLFSSL_NAME_CONSTRAINTS* nc;
 5482
 5483    WOLFSSL_ENTER("wolfSSL_NAME_CONSTRAINTS_new");
 5484
 5485    nc = (WOLFSSL_NAME_CONSTRAINTS*)XMALLOC(sizeof(WOLFSSL_NAME_CONSTRAINTS),
 5486                                            NULL, DYNAMIC_TYPE_OPENSSL);
 5487    if (nc == NULL) {
 5488        WOLFSSL_MSG("Failed to allocate NAME_CONSTRAINTS");
 5489        return NULL;
 5490    }
 5491    XMEMSET(nc, 0, sizeof(WOLFSSL_NAME_CONSTRAINTS));
 5492    return nc;
 5493}
 5494
 5495/* Free a GENERAL_SUBTREE and its contents. */
 5496void wolfSSL_GENERAL_SUBTREE_free(WOLFSSL_GENERAL_SUBTREE* subtree)
 5497{
 5498    if (subtree == NULL) {
 5499        return;
 5500    }
 5501    wolfSSL_GENERAL_NAME_free(subtree->base);
 5502    XFREE(subtree, NULL, DYNAMIC_TYPE_OPENSSL);
 5503}
 5504
 5505/* Free a NAME_CONSTRAINTS structure and all its contents. */
 5506void wolfSSL_NAME_CONSTRAINTS_free(WOLFSSL_NAME_CONSTRAINTS* nc)
 5507{
 5508    WOLFSSL_ENTER("wolfSSL_NAME_CONSTRAINTS_free");
 5509
 5510    if (nc == NULL) {
 5511        return;
 5512    }
 5513
 5514    if (nc->permittedSubtrees != NULL) {
 5515        wolfSSL_sk_pop_free(nc->permittedSubtrees,
 5516            (wolfSSL_sk_freefunc)wolfSSL_GENERAL_SUBTREE_free);
 5517    }
 5518
 5519    if (nc->excludedSubtrees != NULL) {
 5520        wolfSSL_sk_pop_free(nc->excludedSubtrees,
 5521            (wolfSSL_sk_freefunc)wolfSSL_GENERAL_SUBTREE_free);
 5522    }
 5523
 5524    XFREE(nc, NULL, DYNAMIC_TYPE_OPENSSL);
 5525}
 5526
 5527/* Get number of items in GENERAL_SUBTREE stack. */
 5528int wolfSSL_sk_GENERAL_SUBTREE_num(const WOLFSSL_STACK* sk)
 5529{
 5530    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_SUBTREE_num");
 5531
 5532    return wolfSSL_sk_num(sk);
 5533}
 5534
 5535/* Get GENERAL_SUBTREE at index from stack. */
 5536WOLFSSL_GENERAL_SUBTREE* wolfSSL_sk_GENERAL_SUBTREE_value(
 5537    const WOLFSSL_STACK* sk, int idx)
 5538{
 5539    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_SUBTREE_value");
 5540
 5541    return (WOLFSSL_GENERAL_SUBTREE*)wolfSSL_sk_value(sk, idx);
 5542}
 5543
 5544/* Check IP address string matches constraint.
 5545 *
 5546 * name: IP address string (ex "192.168.1.50")
 5547 * nameSz: length of name string
 5548 * gn: GENERAL_NAME containing IP constraint (IP + mask bytes)
 5549 *
 5550 * Return 1 on match, otherwise 0
 5551 */
 5552static int MatchIpName(const char* name, int nameSz, WOLFSSL_GENERAL_NAME* gn)
 5553{
 5554    int ipLen = 0;
 5555    int constraintLen;
 5556    char ipStr[WOLFSSL_MAX_IPSTR];
 5557    unsigned char ipBytes[16]; /* Max 16 bytes for IPv6 */
 5558    const unsigned char* constraintData;
 5559
 5560    if (name == NULL || nameSz <= 0 || gn == NULL || gn->d.iPAddress == NULL) {
 5561        return 0;
 5562    }
 5563
 5564    constraintData = wolfSSL_ASN1_STRING_get0_data(gn->d.iPAddress);
 5565    constraintLen = wolfSSL_ASN1_STRING_length(gn->d.iPAddress);
 5566    if (constraintData == NULL || constraintLen <= 0) {
 5567        return 0;
 5568    }
 5569
 5570    /* Null-terminate IP string */
 5571    if (nameSz >= (int)sizeof(ipStr)) {
 5572        return 0;
 5573    }
 5574    XMEMCPY(ipStr, name, nameSz);
 5575    ipStr[nameSz] = '\0';
 5576
 5577    /* IPv4 constraint 8 bytes (IP + mask),
 5578     * IPv6 constraint 32 bytes (IP + mask) */
 5579    if (constraintLen == 8) {
 5580    #ifdef FREESCALE_MQX
 5581        if (XINET_PTON(WOLFSSL_IP4, ipStr, ipBytes, sizeof(ipBytes)) == RTCS_OK) {
 5582    #else
 5583        if (XINET_PTON(WOLFSSL_IP4, ipStr, ipBytes) == 1) {
 5584    #endif
 5585            ipLen = 4;
 5586        }
 5587    }
 5588    else if (constraintLen == 32) {
 5589    #ifdef FREESCALE_MQX
 5590        if (XINET_PTON(WOLFSSL_IP6, ipStr, ipBytes, sizeof(ipBytes)) == RTCS_OK) {
 5591    #else
 5592        if (XINET_PTON(WOLFSSL_IP6, ipStr, ipBytes) == 1) {
 5593    #endif
 5594            ipLen = 16;
 5595        }
 5596    }
 5597
 5598    if (ipLen == 0) {
 5599        return 0;
 5600    }
 5601
 5602    return wolfssl_local_MatchIpSubnet(ipBytes, ipLen,
 5603        constraintData, constraintLen);
 5604}
 5605
 5606/* Extract host from URI for name constraint matching.
 5607 * URI format: scheme://[userinfo@]host[:port][/path][?query][#fragment]
 5608 * IPv6 literals are enclosed in brackets: scheme://[ipv6addr]:port/path
 5609 * Returns pointer to host start and sets hostLen, or NULL on failure. */
 5610static const char* ExtractHostFromUri(const char* uri, int uriLen, int* hostLen)
 5611{
 5612    const char* hostStart;
 5613    const char* hostEnd;
 5614    const char* p;
 5615    const char* uriEnd;
 5616
 5617    if (uri == NULL || uriLen <= 0 || hostLen == NULL) {
 5618        return NULL;
 5619    }
 5620
 5621    uriEnd = uri + uriLen;
 5622
 5623    /* Find "://" to skip scheme */
 5624    hostStart = NULL;
 5625    for (p = uri; p < uriEnd - 2; p++) {
 5626        if (p[0] == ':' && p[1] == '/' && p[2] == '/') {
 5627            hostStart = p + 3;
 5628            break;
 5629        }
 5630    }
 5631    if (hostStart == NULL || hostStart >= uriEnd) {
 5632        return NULL;
 5633    }
 5634
 5635    /* Skip userinfo if present (look for @ before any /, ?, #)
 5636     * userinfo can contain ':' (ex: user:pass@host), don't stop at ':'
 5637     * For IPv6, also don't stop at '[' in userinfo */
 5638    for (p = hostStart; p < uriEnd; p++) {
 5639        if (*p == '@') {
 5640            hostStart = p + 1;
 5641            break;
 5642        }
 5643        if (*p == '/' || *p == '?' || *p == '#') {
 5644            /* No userinfo found */
 5645            break;
 5646        }
 5647        /* If '[' before '@', found IPv6 literal, not userinfo */
 5648        if (*p == '[') {
 5649            break;
 5650        }
 5651    }
 5652    if (hostStart >= uriEnd) {
 5653        return NULL;
 5654    }
 5655
 5656    /* Check for IPv6 literal */
 5657    if (*hostStart == '[') {
 5658        /* Find closing bracket, skip opening one */
 5659        hostStart++;
 5660        hostEnd = hostStart;
 5661        while (hostEnd < uriEnd && *hostEnd != ']') {
 5662            hostEnd++;
 5663        }
 5664        if (hostEnd >= uriEnd) {
 5665            /* No closing bracket found, malformed */
 5666            return NULL;
 5667        }
 5668        /* hostEnd points to closing bracket, extract content between */
 5669        *hostLen = (int)(hostEnd - hostStart);
 5670        if (*hostLen <= 0) {
 5671            return NULL;
 5672        }
 5673        return hostStart;
 5674    }
 5675
 5676    /* Regular hostname, find end */
 5677    hostEnd = hostStart;
 5678    while (hostEnd < uriEnd && *hostEnd != ':' && *hostEnd != '/' &&
 5679           *hostEnd != '?' && *hostEnd != '#') {
 5680        hostEnd++;
 5681    }
 5682
 5683    *hostLen = (int)(hostEnd - hostStart);
 5684    if (*hostLen <= 0) {
 5685        return NULL;
 5686    }
 5687
 5688    return hostStart;
 5689}
 5690
 5691/* Helper to check if name string matches a single GENERAL_NAME constraint.
 5692 * Returns 1 if matches, 0 if not. */
 5693static int MatchNameConstraint(int type, const char* name, int nameSz,
 5694    WOLFSSL_GENERAL_NAME* gn)
 5695{
 5696    const char* baseStr;
 5697    int baseLen;
 5698
 5699    if (gn == NULL || gn->type != type) {
 5700        return 0;
 5701    }
 5702
 5703    switch (type) {
 5704        case WOLFSSL_GEN_IPADD:
 5705            return MatchIpName(name, nameSz, gn);
 5706
 5707        case WOLFSSL_GEN_DNS:
 5708        case WOLFSSL_GEN_EMAIL:
 5709        case WOLFSSL_GEN_URI:
 5710            if (gn->d.ia5 == NULL) {
 5711                return 0;
 5712            }
 5713            baseStr = (const char*)wolfSSL_ASN1_STRING_get0_data(gn->d.ia5);
 5714            baseLen = wolfSSL_ASN1_STRING_length(gn->d.ia5);
 5715            if (baseStr == NULL || baseLen <= 0) {
 5716                return 0;
 5717            }
 5718
 5719            if (type == WOLFSSL_GEN_EMAIL) {
 5720                return wolfssl_local_MatchBaseName(ASN_RFC822_TYPE, name,
 5721                    nameSz, baseStr, baseLen);
 5722            }
 5723            else if (type == WOLFSSL_GEN_URI) {
 5724                const char* host;
 5725                int hostLen;
 5726
 5727                /* For URI, extract host and match against DNS-style */
 5728                host = ExtractHostFromUri(name, nameSz, &hostLen);
 5729                if (host == NULL) {
 5730                    return 0;
 5731                }
 5732                return wolfssl_local_MatchBaseName(ASN_DNS_TYPE, host, hostLen,
 5733                    baseStr, baseLen);
 5734            }
 5735            else {
 5736                /* WOLFSSL_GEN_DNS uses DNS-style matching */
 5737                return wolfssl_local_MatchBaseName(ASN_DNS_TYPE, name, nameSz,
 5738                    baseStr, baseLen);
 5739            }
 5740
 5741        default:
 5742            /* Unsupported type */
 5743            return 0;
 5744    }
 5745}
 5746
 5747/*
 5748 * Check if a name string satisfies given name constraints.
 5749 *
 5750 * nc: NAME_CONSTRAINTS struct containing permitted/excluded subtrees
 5751 * type: GeneralName type (WOLFSSL_GEN_DNS, WOLFSSL_GEN_EMAIL, etc.)
 5752 * name: The name string to check
 5753 * nameSz: Length of name string
 5754 *
 5755 * Returns 1 if name satisfies constraints (permitted and not excluded),
 5756 * otherwise 0 if name does not satisfy constraints or on error
 5757 *
 5758 * A name satisfies constraints if permitted subtrees exist for the type,
 5759 * name matches at least one, and name does not match any excluded subtree.
 5760 */
 5761int wolfSSL_NAME_CONSTRAINTS_check_name(WOLFSSL_NAME_CONSTRAINTS* nc,
 5762    int type, const char* name, int nameSz)
 5763{
 5764    int i, num;
 5765    int hasPermittedType = 0;
 5766    int matchedPermitted = 0;
 5767    WOLFSSL_GENERAL_SUBTREE* subtree;
 5768    WOLFSSL_GENERAL_NAME* gn;
 5769
 5770    WOLFSSL_ENTER("wolfSSL_NAME_CONSTRAINTS_check_name");
 5771
 5772    if (nc == NULL || name == NULL || nameSz <= 0) {
 5773        WOLFSSL_MSG("Bad argument to NAME_CONSTRAINTS_check_name");
 5774        return 0;
 5775    }
 5776
 5777    /* Check permitted subtrees */
 5778    if (nc->permittedSubtrees != NULL) {
 5779        num = wolfSSL_sk_GENERAL_SUBTREE_num(nc->permittedSubtrees);
 5780        for (i = 0; i < num; i++) {
 5781            subtree = wolfSSL_sk_GENERAL_SUBTREE_value(
 5782                nc->permittedSubtrees, i);
 5783            if (subtree == NULL || subtree->base == NULL) {
 5784                continue;
 5785            }
 5786
 5787            gn = subtree->base;
 5788            if (gn->type != type) {
 5789                continue;
 5790            }
 5791            hasPermittedType = 1;
 5792
 5793            if (MatchNameConstraint(type, name, nameSz, gn)) {
 5794                matchedPermitted = 1;
 5795                break;
 5796            }
 5797        }
 5798    }
 5799
 5800    /* If permitted constraints exist for this type but none matched, fail */
 5801    if (hasPermittedType && !matchedPermitted) {
 5802        WOLFSSL_MSG("Name not in permitted subtrees");
 5803        return 0;
 5804    }
 5805
 5806    /* Check excluded subtrees */
 5807    if (nc->excludedSubtrees != NULL) {
 5808        num = wolfSSL_sk_GENERAL_SUBTREE_num(nc->excludedSubtrees);
 5809        for (i = 0; i < num; i++) {
 5810            subtree = wolfSSL_sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
 5811            if (subtree == NULL || subtree->base == NULL) {
 5812                continue;
 5813            }
 5814
 5815            gn = subtree->base;
 5816            if (gn->type != type) {
 5817                continue;
 5818            }
 5819
 5820            if (MatchNameConstraint(type, name, nameSz, gn)) {
 5821                WOLFSSL_MSG("Name in excluded subtrees");
 5822                return 0;
 5823            }
 5824        }
 5825    }
 5826
 5827    return 1;
 5828}
 5829#endif /* !IGNORE_NAME_CONSTRAINTS */
 5830
 5831#if defined(OPENSSL_ALL) && !defined(NO_BIO)
 5832/* Outputs name string of the given WOLFSSL_GENERAL_NAME_OBJECT to WOLFSSL_BIO.
 5833 * Can handle following GENERAL_NAME_OBJECT types:
 5834 *  - GEN_OTHERNAME #
 5835 *  - GEN_EMAIL
 5836 *  - GEN_DNS
 5837 *  - GEN_X400  #
 5838 *  - GEN_DIRNAME
 5839 *  - GEN_EDIPARTY #
 5840 *  - GEN_URI
 5841 *  - GEN_RID
 5842 * The each name string to be output has "typename:namestring" format.
 5843 * For instance, email name string will be output as "email:info@wolfssl.com".
 5844 * However,some types above marked with "#" will be output with
 5845 * "typename:<unsupported>".
 5846 *
 5847 * Parameters:
 5848 *  - out: WOLFSSL_BIO object which is the output destination
 5849 *  - gen: WOLFSSL_GENERAL_NAME object to be output its name
 5850 *
 5851 * Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure.
 5852 */
 5853int wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO* out, WOLFSSL_GENERAL_NAME* gen)
 5854{
 5855    int ret, i;
 5856    unsigned int wd;
 5857    unsigned char* p;
 5858    (void)wd;
 5859    (void)p;
 5860    (void)i;
 5861    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_print");
 5862
 5863    if (out == NULL || gen == NULL)
 5864        return WOLFSSL_FAILURE;
 5865
 5866    ret = WOLFSSL_FAILURE;
 5867    switch (gen->type)
 5868    {
 5869    case GEN_OTHERNAME:
 5870        ret = wolfSSL_BIO_printf(out, "othername:<unsupported>");
 5871        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5872        break;
 5873
 5874    case GEN_EMAIL:
 5875        ret = wolfSSL_BIO_printf(out, "email:");
 5876        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5877        if (ret == WOLFSSL_SUCCESS)
 5878        {
 5879            ret = wolfSSL_ASN1_STRING_print(out, gen->d.rfc822Name);
 5880        }
 5881        break;
 5882
 5883    case GEN_DNS:
 5884        ret = wolfSSL_BIO_printf(out, "DNS:");
 5885        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5886        if (ret == WOLFSSL_SUCCESS) {
 5887            ret = wolfSSL_BIO_printf(out, "%s", gen->d.dNSName->strData);
 5888            ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5889        }
 5890        break;
 5891
 5892    case GEN_X400:
 5893        ret = wolfSSL_BIO_printf(out, "X400Name:<unsupported>");
 5894        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5895        break;
 5896
 5897    case GEN_DIRNAME:
 5898        ret = wolfSSL_BIO_printf(out, "DirName:");
 5899        if (ret == WOLFSSL_SUCCESS) {
 5900            ret = wolfSSL_X509_NAME_print_ex(out, gen->d.directoryName, 0,
 5901                                                         XN_FLAG_ONELINE);
 5902        }
 5903        break;
 5904
 5905    case GEN_EDIPARTY:
 5906        ret = wolfSSL_BIO_printf(out, "EdiPartyName:<unsupported>");
 5907        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5908        break;
 5909
 5910    case GEN_URI:
 5911        ret = wolfSSL_BIO_printf(out, "URI:");
 5912        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5913        if (ret == WOLFSSL_SUCCESS) {
 5914            ret = wolfSSL_ASN1_STRING_print(out,
 5915                                    gen->d.uniformResourceIdentifier);
 5916        }
 5917        break;
 5918
 5919    case GEN_IPADD:
 5920        ret = wolfSSL_BIO_printf(out, "IP Address");
 5921        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5922        if (ret == WOLFSSL_SUCCESS) {
 5923
 5924            if (!gen->d.iPAddress->length) {
 5925                ret = WOLFSSL_FAILURE;
 5926                break;
 5927            }
 5928            p = (unsigned char*)gen->d.iPAddress->strData;
 5929
 5930            if (gen->d.iPAddress->length == 4) {
 5931                ret = wolfSSL_BIO_printf(out, ":%d.%d.%d.%d",
 5932                                  p[0],p[1],p[2],p[3]);
 5933            }
 5934            else if (gen->d.iPAddress->length == 16) {
 5935
 5936                for (i = 0; i < 16 && ret == WOLFSSL_SUCCESS;) {
 5937                    wd = p[i] << 8 | p[i+1];
 5938
 5939                    i += 2;
 5940                    ret = wolfSSL_BIO_printf(out, ":%X", wd);
 5941                    ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5942                }
 5943            }
 5944            else {
 5945                ret = wolfSSL_BIO_printf(out, "<unsupported>");
 5946            }
 5947            ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5948        }
 5949        break;
 5950
 5951    case GEN_RID:
 5952        ret = wolfSSL_BIO_printf(out, "Registered ID:");
 5953        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 5954        if (ret == WOLFSSL_SUCCESS) {
 5955            ret = wolfSSL_i2a_ASN1_OBJECT(out, gen->d.registeredID);
 5956        }
 5957        break;
 5958
 5959    default:
 5960        /* unsupported type */
 5961        break;
 5962    }
 5963
 5964    if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
 5965        return WOLFSSL_FAILURE;
 5966    else
 5967        return WOLFSSL_SUCCESS;
 5968}
 5969#endif /* OPENSSL_ALL */
 5970
 5971WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void)
 5972{
 5973    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
 5974    if (sk) {
 5975        sk->type = STACK_TYPE_X509_EXT;
 5976    }
 5977
 5978    return (WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)*)sk;;
 5979}
 5980
 5981/* returns the number of nodes on the stack */
 5982int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
 5983{
 5984    if (sk != NULL) {
 5985        return (int)sk->num;
 5986    }
 5987    return WOLFSSL_FATAL_ERROR;
 5988}
 5989
 5990
 5991/* returns null on failure and pointer to internal value on success */
 5992WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value(
 5993        const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx)
 5994{
 5995    return (WOLFSSL_X509_EXTENSION*)wolfSSL_sk_value(sk, idx);
 5996}
 5997
 5998/* frees all of the nodes and the values in stack */
 5999void wolfSSL_sk_X509_EXTENSION_pop_free(
 6000        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
 6001        void (*f) (WOLFSSL_X509_EXTENSION*))
 6002{
 6003    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
 6004}
 6005
 6006void wolfSSL_sk_X509_EXTENSION_free(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
 6007{
 6008    wolfSSL_sk_pop_free(sk, NULL);
 6009}
 6010
 6011#endif /* OPENSSL_EXTRA */
 6012
 6013#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
 6014    !defined(NO_STDIO_FILESYSTEM)
 6015
 6016WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
 6017{
 6018    WOLFSSL_X509* newX509 = NULL;
 6019
 6020    WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
 6021
 6022    if (file != XBADFILE) {
 6023        byte* fileBuffer = NULL;
 6024        long sz = 0;
 6025
 6026        if (XFSEEK(file, 0, XSEEK_END) != 0)
 6027            return NULL;
 6028        sz = XFTELL(file);
 6029        if (XFSEEK(file, 0, XSEEK_SET) != 0)
 6030            return NULL;
 6031
 6032        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
 6033            WOLFSSL_MSG("X509_d2i file size error");
 6034            return NULL;
 6035        }
 6036
 6037        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
 6038        if (fileBuffer != NULL) {
 6039            int ret = (int)XFREAD(fileBuffer, 1, (size_t)sz, file);
 6040            if (ret == sz) {
 6041                newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
 6042            }
 6043            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
 6044        }
 6045    }
 6046
 6047    if (x509 != NULL)
 6048        *x509 = newX509;
 6049
 6050    return newX509;
 6051}
 6052
 6053#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
 6054
 6055#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
 6056    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
 6057
 6058#ifndef NO_FILESYSTEM
 6059WOLFSSL_ABI
 6060WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
 6061{
 6062#ifdef WOLFSSL_SMALL_STACK
 6063    byte  staticBuffer[1]; /* force heap usage */
 6064#else
 6065    byte  staticBuffer[FILE_BUFFER_SIZE];
 6066#endif
 6067    byte* fileBuffer = staticBuffer;
 6068    int   dynamic = 0;
 6069    int   ret;
 6070    long  sz = 0;
 6071    XFILE file;
 6072
 6073    WOLFSSL_X509* x509 = NULL;
 6074
 6075    /* Check the inputs */
 6076    if ((fname == NULL) ||
 6077        (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM))
 6078        return NULL;
 6079
 6080    file = XFOPEN(fname, "rb");
 6081    if (file == XBADFILE)
 6082        return NULL;
 6083
 6084    if (XFSEEK(file, 0, XSEEK_END) != 0) {
 6085        XFCLOSE(file);
 6086        return NULL;
 6087    }
 6088    sz = XFTELL(file);
 6089    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
 6090        XFCLOSE(file);
 6091        return NULL;
 6092    }
 6093
 6094    if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
 6095        WOLFSSL_MSG("X509_load_certificate_file size error");
 6096        XFCLOSE(file);
 6097        return NULL;
 6098    }
 6099
 6100    if (sz > (long)sizeof(staticBuffer)) {
 6101        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
 6102        if (fileBuffer == NULL) {
 6103            XFCLOSE(file);
 6104            return NULL;
 6105        }
 6106        dynamic = 1;
 6107    }
 6108
 6109    ret = (int)XFREAD(fileBuffer, 1, (size_t)sz, file);
 6110    if (ret != sz) {
 6111        XFCLOSE(file);
 6112        if (dynamic)
 6113            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
 6114        return NULL;
 6115    }
 6116
 6117    XFCLOSE(file);
 6118
 6119    x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format);
 6120
 6121    if (dynamic)
 6122        XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
 6123
 6124    return x509;
 6125}
 6126#endif /* !NO_FILESYSTEM */
 6127
 6128static WOLFSSL_X509* loadX509orX509REQFromBuffer(
 6129    const unsigned char* buf, int sz, int format, int type,
 6130    wc_pem_password_cb *cb, void *u)
 6131{
 6132
 6133    int ret = 0;
 6134    WOLFSSL_X509* x509 = NULL;
 6135    DerBuffer* der = NULL;
 6136
 6137    WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex");
 6138
 6139    if (format == WOLFSSL_FILETYPE_PEM) {
 6140        EncryptedInfo info;
 6141        XMEMSET(&info, 0, sizeof(EncryptedInfo));
 6142    #ifdef WOLFSSL_ENCRYPTED_KEYS
 6143        info.passwd_cb       = cb;
 6144        info.passwd_userdata = u;
 6145    #endif
 6146
 6147    #ifdef WOLFSSL_PEM_TO_DER
 6148        ret = PemToDer(buf, sz, type, &der, NULL, &info, NULL);
 6149        if (ret != 0) {
 6150            FreeDer(&der);
 6151        }
 6152    #else
 6153        ret = NOT_COMPILED_IN;
 6154    #endif
 6155    }
 6156    else {
 6157        ret = AllocDer(&der, (word32)sz, type, NULL);
 6158        if (ret == 0) {
 6159            XMEMCPY(der->buffer, buf, sz);
 6160        }
 6161    }
 6162
 6163    /* At this point we want `der` to have the certificate in DER format */
 6164    /* ready to be decoded. */
 6165    if (der != NULL && der->buffer != NULL) {
 6166        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
 6167        /* For TRUSTED_CERT_TYPE, the DER buffer contains the certificate
 6168         * followed by auxiliary trust info. ParseCertRelative expects CERT_TYPE
 6169         * and will parse only the certificate portion, ignoring the rest. */
 6170        int parseType = (type == TRUSTED_CERT_TYPE) ? CERT_TYPE : type;
 6171
 6172        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
 6173            ret=MEMORY_ERROR);
 6174        if (WC_VAR_OK(cert))
 6175        {
 6176            InitDecodedCert(cert, der->buffer, der->length, NULL);
 6177            ret = ParseCertRelative(cert, parseType, 0, NULL, NULL);
 6178            if (ret == 0) {
 6179                /* For TRUSTED_CERT_TYPE, truncate the DER buffer to exclude
 6180                 * auxiliary trust data. ParseCertRelative sets srcIdx to the
 6181                 * end of the certificate, so we adjust cert->maxIdx accordingly. */
 6182                if (type == TRUSTED_CERT_TYPE && cert->srcIdx < cert->maxIdx) {
 6183                    cert->maxIdx = cert->srcIdx;
 6184                }
 6185
 6186                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
 6187                                                             DYNAMIC_TYPE_X509);
 6188                if (x509 != NULL) {
 6189                    InitX509(x509, 1, NULL);
 6190                    ret = CopyDecodedToX509(x509, cert);
 6191                    if (ret != 0) {
 6192                        wolfSSL_X509_free(x509);
 6193                        x509 = NULL;
 6194                    }
 6195                }
 6196                else {
 6197                    ret = MEMORY_ERROR;
 6198                }
 6199            }
 6200
 6201            FreeDecodedCert(cert);
 6202            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
 6203        }
 6204
 6205        FreeDer(&der);
 6206    }
 6207
 6208    if (ret != 0) {
 6209        WOLFSSL_ERROR(ret);
 6210    }
 6211
 6212    /* unused parameter when built without WOLFSSL_ENCRYPTED_KEYS */
 6213    (void)cb;
 6214    (void)u;
 6215    return x509;
 6216}
 6217
 6218WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
 6219    const unsigned char* buf, int sz, int format)
 6220{
 6221    return loadX509orX509REQFromBuffer(buf, sz,
 6222            format, CERT_TYPE, NULL, NULL);
 6223}
 6224
 6225#ifdef WOLFSSL_CERT_REQ
 6226WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer(
 6227    const unsigned char* buf, int sz, int format)
 6228{
 6229    return loadX509orX509REQFromBuffer(buf, sz,
 6230            format, CERTREQ_TYPE, NULL, NULL);
 6231}
 6232#endif
 6233
 6234#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_PEER_CERT || \
 6235          SESSION_CERTS */
 6236
 6237#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(KEEP_PEER_CERT) || \
 6238    defined(SESSION_CERTS)
 6239/* Smaller subset of X509 compatibility functions. Avoid increasing the size of
 6240 * this subset and its memory usage */
 6241
 6242/* returns a pointer to a new WOLFSSL_X509 structure on success and NULL on
 6243 * fail
 6244 */
 6245WOLFSSL_X509* wolfSSL_X509_new_ex(void* heap)
 6246{
 6247    WOLFSSL_X509* x509;
 6248
 6249    x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
 6250            DYNAMIC_TYPE_X509);
 6251    if (x509 != NULL) {
 6252        InitX509(x509, 1, heap);
 6253    }
 6254
 6255    return x509;
 6256}
 6257
 6258WOLFSSL_X509* wolfSSL_X509_new(void)
 6259{
 6260    return wolfSSL_X509_new_ex(NULL);
 6261}
 6262
 6263WOLFSSL_ABI
 6264WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
 6265{
 6266    WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
 6267    if (cert)
 6268        return &cert->subject;
 6269    return NULL;
 6270}
 6271
 6272WOLFSSL_ABI
 6273WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
 6274{
 6275    WOLFSSL_ENTER("wolfSSL_X509_get_issuer_name");
 6276    if (cert)
 6277        return &cert->issuer;
 6278    return NULL;
 6279}
 6280
 6281
 6282int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
 6283{
 6284    int type = 0;
 6285
 6286    WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
 6287
 6288    if (x509 != NULL)
 6289        type = x509->sigOID;
 6290
 6291    return type;
 6292}
 6293
 6294#if defined(OPENSSL_EXTRA_X509_SMALL)
 6295
 6296int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
 6297{
 6298    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
 6299    if (!name)
 6300        return WOLFSSL_FATAL_ERROR;
 6301    return name->sz;
 6302}
 6303
 6304/* Searches for the first ENTRY of type NID
 6305 * idx is the location to start searching from, the value at when the entry was
 6306 *     found is stored into idx
 6307 * returns a pointer to the entry on success and null on fail */
 6308static WOLFSSL_X509_NAME_ENTRY* GetEntryByNID(WOLFSSL_X509_NAME* name, int nid,
 6309        int* idx)
 6310{
 6311    int i;
 6312    WOLFSSL_X509_NAME_ENTRY* ret = NULL;
 6313
 6314    for (i = *idx; i < MAX_NAME_ENTRIES; i++) {
 6315        if (name->entry[i].nid == nid) {
 6316            ret = &name->entry[i];
 6317            *idx = i;
 6318            break;
 6319        }
 6320    }
 6321    return ret;
 6322}
 6323
 6324
 6325/* Used to get a string from the WOLFSSL_X509_NAME structure that
 6326 * corresponds with the NID value passed in. This finds the first entry with
 6327 * matching NID value, if searching for the case where there is multiple
 6328 * entries with the same NID value than other functions should be used
 6329 * (i.e. wolfSSL_X509_NAME_get_index_by_NID, wolfSSL_X509_NAME_get_entry)
 6330 *
 6331 * name structure to get string from
 6332 * nid  NID value to search for
 6333 * buf  [out] buffer to hold results. If NULL then the buffer size minus the
 6334 *      null char is returned.
 6335 * len  size of "buf" passed in
 6336 *
 6337 * returns the length of string found, not including the NULL terminator.
 6338 *         It's possible the function could return a negative value in the
 6339 *         case that len is less than or equal to 0. A negative value is
 6340 *         considered an error case.
 6341 */
 6342int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
 6343                                      int nid, char* buf, int len)
 6344{
 6345    WOLFSSL_X509_NAME_ENTRY* e;
 6346    unsigned char *text = NULL;
 6347    int textSz = 0;
 6348    int idx    = 0;
 6349
 6350    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
 6351
 6352    if (name == NULL) {
 6353        WOLFSSL_MSG("NULL argument passed in");
 6354        return WOLFSSL_FATAL_ERROR;
 6355    }
 6356
 6357    e = GetEntryByNID(name, nid, &idx);
 6358    if (e == NULL) {
 6359        WOLFSSL_MSG("Entry type not found");
 6360        return WOLFSSL_FATAL_ERROR;
 6361    }
 6362    text   = wolfSSL_ASN1_STRING_data(e->value);
 6363    textSz = wolfSSL_ASN1_STRING_length(e->value);
 6364
 6365    if (text == NULL) {
 6366        WOLFSSL_MSG("Unable to get entry text");
 6367        return WOLFSSL_FATAL_ERROR;
 6368    }
 6369
 6370    /* if buf is NULL return size of buffer needed (minus null char) */
 6371    if (buf == NULL) {
 6372        WOLFSSL_MSG("Buffer is NULL, returning buffer size only");
 6373        return textSz;
 6374    }
 6375    if (len <= 0) {
 6376        return 0;
 6377    }
 6378
 6379    /* + 1 to account for null char */
 6380    textSz = (int)min((word32)textSz + 1, (word32)len);
 6381    if (textSz > 0) {
 6382        XMEMCPY(buf, text, textSz - 1);
 6383        buf[textSz - 1] = '\0';
 6384    }
 6385
 6386    WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
 6387    return (textSz - 1); /* do not include null character in size */
 6388}
 6389
 6390/* Creates a new WOLFSSL_EVP_PKEY structure that has the public key from x509
 6391 *
 6392 * returns a pointer to the created WOLFSSL_EVP_PKEY on success and NULL on fail
 6393 */
 6394WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
 6395{
 6396    WOLFSSL_EVP_PKEY* key = NULL;
 6397    int ret = 0;
 6398
 6399    (void)ret;
 6400
 6401    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey");
 6402    if (x509 != NULL) {
 6403        key = wolfSSL_EVP_PKEY_new_ex(x509->heap);
 6404        if (key != NULL) {
 6405            if (x509->pubKeyOID == RSAk) {
 6406                key->type = WC_EVP_PKEY_RSA;
 6407            }
 6408            else if (x509->pubKeyOID == DSAk) {
 6409                key->type = WC_EVP_PKEY_DSA;
 6410            }
 6411        #ifdef HAVE_DILITHIUM
 6412            else if (x509->pubKeyOID == ML_DSA_LEVEL2k ||
 6413                     x509->pubKeyOID == ML_DSA_LEVEL3k ||
 6414                     x509->pubKeyOID == ML_DSA_LEVEL5k) {
 6415                key->type = WC_EVP_PKEY_DILITHIUM;
 6416            }
 6417        #endif
 6418            else {
 6419                key->type = WC_EVP_PKEY_EC;
 6420            }
 6421            key->save_type = 0;
 6422            key->pkey.ptr = (char*)XMALLOC(
 6423                        x509->pubKey.length, x509->heap,
 6424                                                       DYNAMIC_TYPE_PUBLIC_KEY);
 6425            if (key->pkey.ptr == NULL) {
 6426                wolfSSL_EVP_PKEY_free(key);
 6427                return NULL;
 6428            }
 6429            XMEMCPY(key->pkey.ptr, x509->pubKey.buffer, x509->pubKey.length);
 6430            key->pkey_sz = (int)x509->pubKey.length;
 6431
 6432            #ifdef HAVE_ECC
 6433                key->pkey_curve = (int)x509->pkCurveOID;
 6434            #endif /* HAVE_ECC */
 6435
 6436            /* decode RSA key */
 6437            #ifndef NO_RSA
 6438            if (key->type == WC_EVP_PKEY_RSA) {
 6439                key->ownRsa = 1;
 6440                key->rsa = wolfSSL_RSA_new();
 6441                if (key->rsa == NULL) {
 6442                    wolfSSL_EVP_PKEY_free(key);
 6443                    return NULL;
 6444                }
 6445
 6446                if (wolfSSL_RSA_LoadDer_ex(key->rsa,
 6447                            (const unsigned char*)key->pkey.ptr, key->pkey_sz,
 6448                            WOLFSSL_RSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
 6449                    wolfSSL_EVP_PKEY_free(key);
 6450                    return NULL;
 6451                }
 6452            }
 6453            #endif /* NO_RSA */
 6454
 6455            /* decode ECC key */
 6456            #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
 6457            if (key->type == WC_EVP_PKEY_EC) {
 6458                word32 idx = 0;
 6459
 6460                key->ownEcc = 1;
 6461                key->ecc = wolfSSL_EC_KEY_new();
 6462                if (key->ecc == NULL || key->ecc->internal == NULL) {
 6463                    wolfSSL_EVP_PKEY_free(key);
 6464                    return NULL;
 6465                }
 6466
 6467                /* not using wolfSSL_EC_KEY_LoadDer because public key in x509
 6468                 * is in the format of x963 (no sequence at start of buffer) */
 6469                ret = wc_EccPublicKeyDecode((const unsigned char*)key->pkey.ptr,
 6470                                            &idx, (ecc_key*)key->ecc->internal,
 6471                                            key->pkey_sz);
 6472                if (ret < 0) {
 6473                    WOLFSSL_ERROR_VERBOSE(ret);
 6474                    WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
 6475                    wolfSSL_EVP_PKEY_free(key);
 6476                    return NULL;
 6477                }
 6478
 6479                if (SetECKeyExternal(key->ecc) != WOLFSSL_SUCCESS) {
 6480                    WOLFSSL_MSG("SetECKeyExternal failed");
 6481                    wolfSSL_EVP_PKEY_free(key);
 6482                    return NULL;
 6483                }
 6484
 6485                key->ecc->inSet = 1;
 6486            }
 6487            #endif /* HAVE_ECC && OPENSSL_EXTRA */
 6488
 6489            #ifndef NO_DSA
 6490            if (key->type == WC_EVP_PKEY_DSA) {
 6491                key->ownDsa = 1;
 6492                key->dsa = wolfSSL_DSA_new();
 6493                if (key->dsa == NULL) {
 6494                    wolfSSL_EVP_PKEY_free(key);
 6495                    return NULL;
 6496                }
 6497
 6498                if (wolfSSL_DSA_LoadDer_ex(key->dsa,
 6499                            (const unsigned char*)key->pkey.ptr, key->pkey_sz, \
 6500                            WOLFSSL_DSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
 6501                    wolfSSL_DSA_free(key->dsa);
 6502                    key->dsa = NULL;
 6503                    wolfSSL_EVP_PKEY_free(key);
 6504                    return NULL;
 6505                }
 6506            }
 6507            #endif /* NO_DSA */
 6508        }
 6509    }
 6510    return key;
 6511}
 6512#endif /* OPENSSL_EXTRA_X509_SMALL */
 6513
 6514/* End of smaller subset of X509 compatibility functions. Avoid increasing the
 6515 * size of this subset and its memory usage */
 6516#endif /* OPENSSL_EXTRA_X509_SMALL || KEEP_PEER_CERT || SESSION_CERTS */
 6517
 6518#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
 6519/*
 6520 * Converts a and b to DER and then does an XMEMCMP to check if they match.
 6521 * Returns 0 when certificates match and WOLFSSL_FATAL_ERROR when they don't.
 6522 */
 6523int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
 6524{
 6525        const byte* derA;
 6526        const byte* derB;
 6527        int outSzA = 0;
 6528        int outSzB = 0;
 6529
 6530        if (a == NULL || b == NULL) {
 6531            return BAD_FUNC_ARG;
 6532        }
 6533
 6534        derA = wolfSSL_X509_get_der((WOLFSSL_X509*)a, &outSzA);
 6535        if (derA == NULL) {
 6536            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate A has failed");
 6537            return WOLFSSL_FATAL_ERROR;
 6538        }
 6539        derB = wolfSSL_X509_get_der((WOLFSSL_X509*)b, &outSzB);
 6540        if (derB == NULL) {
 6541            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate B has failed");
 6542            return WOLFSSL_FATAL_ERROR;
 6543        }
 6544
 6545        if (outSzA != outSzB || XMEMCMP(derA, derB, outSzA) != 0) {
 6546            WOLFSSL_LEAVE("wolfSSL_X509_cmp", WOLFSSL_FATAL_ERROR);
 6547            return WOLFSSL_FATAL_ERROR;
 6548        }
 6549
 6550        WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0);
 6551
 6552        return 0;
 6553    }
 6554#endif /* OPENSSL_ALL */
 6555
 6556#if defined(OPENSSL_EXTRA)
 6557    int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
 6558    {
 6559        int isSet = 0;
 6560
 6561        WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
 6562
 6563        if (x509 != NULL) {
 6564            switch (nid) {
 6565                case WC_NID_basic_constraints:
 6566                    isSet = x509->basicConstSet; break;
 6567                case WC_NID_subject_alt_name:
 6568                    isSet = x509->subjAltNameSet; break;
 6569                case WC_NID_authority_key_identifier:
 6570                    isSet = x509->authKeyIdSet; break;
 6571                case WC_NID_subject_key_identifier:
 6572                    isSet = x509->subjKeyIdSet; break;
 6573                case WC_NID_key_usage:
 6574                    isSet = x509->keyUsageSet; break;
 6575                case WC_NID_crl_distribution_points:
 6576                    isSet = x509->CRLdistSet; break;
 6577                case WC_NID_ext_key_usage:
 6578                    isSet = ((x509->extKeyUsageSrc) ? 1 : 0); break;
 6579                case WC_NID_info_access:
 6580                    isSet = x509->authInfoSet; break;
 6581            #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
 6582                case WC_NID_certificate_policies:
 6583                    isSet = x509->certPolicySet; break;
 6584            #endif /* WOLFSSL_SEP || WOLFSSL_QT */
 6585                default:
 6586                    WOLFSSL_MSG("NID not in table");
 6587            }
 6588        }
 6589
 6590        WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
 6591
 6592        return isSet;
 6593    }
 6594
 6595
 6596    int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
 6597    {
 6598        int crit = 0;
 6599
 6600        WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
 6601
 6602        if (x509 != NULL) {
 6603            switch (nid) {
 6604                case WC_NID_basic_constraints:
 6605                    crit = x509->basicConstCrit; break;
 6606                case WC_NID_subject_alt_name:
 6607                    crit = x509->subjAltNameCrit; break;
 6608                case WC_NID_authority_key_identifier:
 6609                    crit = x509->authKeyIdCrit; break;
 6610                case WC_NID_subject_key_identifier:
 6611                    crit = x509->subjKeyIdCrit; break;
 6612                case WC_NID_key_usage:
 6613                    crit = x509->keyUsageCrit; break;
 6614                case WC_NID_crl_distribution_points:
 6615                    crit= x509->CRLdistCrit; break;
 6616                case WC_NID_ext_key_usage:
 6617                    crit= x509->extKeyUsageCrit; break;
 6618            #ifdef WOLFSSL_SEP
 6619                case WC_NID_certificate_policies:
 6620                    crit = x509->certPolicyCrit; break;
 6621            #endif /* WOLFSSL_SEP */
 6622            }
 6623        }
 6624
 6625        WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
 6626
 6627        return crit;
 6628    }
 6629
 6630
 6631    int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
 6632    {
 6633        int isSet = 0;
 6634
 6635        WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
 6636
 6637        if (x509 != NULL)
 6638            isSet = x509->basicConstPlSet;
 6639
 6640        WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
 6641
 6642        return isSet;
 6643    }
 6644
 6645
 6646    word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
 6647    {
 6648        word32 pathLength = 0;
 6649
 6650        WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
 6651
 6652        if (x509 != NULL)
 6653            pathLength = x509->pathLength;
 6654
 6655        WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
 6656
 6657        return pathLength;
 6658    }
 6659
 6660
 6661    unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
 6662    {
 6663        word16 usage = 0;
 6664
 6665        WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
 6666
 6667        if (x509 != NULL)
 6668            usage = x509->keyUsage;
 6669
 6670        WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
 6671
 6672        return usage;
 6673    }
 6674
 6675
 6676    byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
 6677                                          byte* dst, int* dstLen)
 6678    {
 6679        byte *id = NULL;
 6680        int copySz = 0;
 6681
 6682        WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
 6683
 6684        if (x509 != NULL) {
 6685            if (x509->authKeyIdSet) {
 6686                copySz = (int)min(dstLen != NULL ? (word32)*dstLen : 0,
 6687                                  x509->authKeyIdSz);
 6688                id = x509->authKeyId;
 6689            }
 6690
 6691            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
 6692                XMEMCPY(dst, id, copySz);
 6693                id = dst;
 6694                *dstLen = copySz;
 6695            }
 6696        }
 6697
 6698        WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
 6699
 6700        return id;
 6701    }
 6702
 6703    byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
 6704                                        byte* dst, int* dstLen)
 6705    {
 6706        byte *id = NULL;
 6707        int copySz = 0;
 6708
 6709        WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
 6710
 6711        if (x509 != NULL) {
 6712            if (x509->subjKeyIdSet) {
 6713                copySz = (int)min(dstLen != NULL ? (word32) *dstLen : 0,
 6714                                  x509->subjKeyIdSz);
 6715                id = x509->subjKeyId;
 6716            }
 6717
 6718            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
 6719                XMEMCPY(dst, id, copySz);
 6720                id = dst;
 6721                *dstLen = copySz;
 6722            }
 6723        }
 6724
 6725        WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
 6726
 6727        return id;
 6728    }
 6729
 6730    const WOLFSSL_ASN1_STRING *wolfSSL_X509_get0_subject_key_id(
 6731            WOLFSSL_X509 *x509)
 6732    {
 6733        WOLFSSL_ASN1_STRING* ret = NULL;
 6734
 6735        WOLFSSL_ENTER("wolfSSL_X509_get0_subject_key_id");
 6736
 6737        if (x509 != NULL && x509->subjKeyIdSet) {
 6738            if (x509->subjKeyIdStr == NULL) {
 6739                x509->subjKeyIdStr = wolfSSL_ASN1_STRING_new();
 6740                if (x509->subjKeyIdStr != NULL) {
 6741                    if (wolfSSL_ASN1_STRING_set(x509->subjKeyIdStr,
 6742                            x509->subjKeyId, x509->subjKeyIdSz) == 1) {
 6743                    }
 6744                    else {
 6745                        wolfSSL_ASN1_STRING_free(x509->subjKeyIdStr);
 6746                        x509->subjKeyIdStr = NULL;
 6747                    }
 6748                }
 6749            }
 6750            ret = x509->subjKeyIdStr;
 6751        }
 6752
 6753        WOLFSSL_LEAVE("wolfSSL_X509_get0_subject_key_id", ret != NULL);
 6754
 6755        return ret;
 6756    }
 6757#endif /* OPENSSL_EXTRA */
 6758
 6759#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
 6760    defined(OPENSSL_EXTRA_X509_SMALL)
 6761
 6762    /* Looks up the index of the first entry encountered with matching NID
 6763     * The search starts from index 'pos'
 6764     * returns a negative value on failure and positive index value on success*/
 6765    int wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME* name,
 6766                                          int nid, int pos)
 6767    {
 6768        int value = nid, i;
 6769
 6770        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_index_by_NID");
 6771
 6772        if (name == NULL) {
 6773            return BAD_FUNC_ARG;
 6774        }
 6775
 6776        i = pos + 1; /* start search after index passed in */
 6777        if (i < 0) {
 6778            i = 0;
 6779        }
 6780
 6781        for (;i < name->entrySz && i < MAX_NAME_ENTRIES; i++) {
 6782            if (name->entry[i].nid == value) {
 6783                return i;
 6784            }
 6785        }
 6786        return WOLFSSL_FATAL_ERROR;
 6787    }
 6788
 6789
 6790    WOLFSSL_ASN1_STRING*  wolfSSL_X509_NAME_ENTRY_get_data(
 6791                                                    WOLFSSL_X509_NAME_ENTRY* in)
 6792    {
 6793        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_data");
 6794        if (in == NULL)
 6795            return NULL;
 6796
 6797        return in->value;
 6798    }
 6799
 6800#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
 6801
 6802#ifdef OPENSSL_EXTRA
 6803#ifndef NO_BIO
 6804
 6805#ifndef MAX_WIDTH
 6806    #define MAX_WIDTH 80
 6807#endif
 6808
 6809#define ACERT_NUM_DIR_TAGS 4
 6810
 6811/* Convenience struct and function for printing the Holder sub fields
 6812 * of an X509 Attribute struct. */
 6813struct acert_dir_print_t {
 6814    const char * pfx;
 6815    const byte   tag[3];
 6816};
 6817
 6818static struct acert_dir_print_t acert_dir_print[ACERT_NUM_DIR_TAGS] =
 6819{
 6820    { "C=", {0x55, 0x04, ASN_COUNTRY_NAME} },
 6821    { "O=", {0x55, 0x04, ASN_ORG_NAME} },
 6822    { "OU=", {0x55, 0x04, ASN_ORGUNIT_NAME} },
 6823    { "CN=", {0x55, 0x04, ASN_COMMON_NAME} },
 6824};
 6825
 6826/* Print an entry of ASN_DIR_TYPE into dst of length max_len.
 6827 *
 6828 * Returns total_len of str on success.
 6829 * Returns < 0 on failure.
 6830 * */
 6831static int X509PrintDirType(char * dst, int max_len, const DNS_entry * entry)
 6832{
 6833    word32       k = 0;
 6834    word32       i = 0;
 6835    const char * src = entry->name;
 6836    word32       src_len = (word32)XSTRLEN(src);
 6837    int          total_len = 0;
 6838    int          bytes_left = max_len;
 6839    int          fld_len = 0;
 6840    int          match_found = 0;
 6841
 6842    XMEMSET(dst, 0, max_len);
 6843
 6844    /* loop over printable DIR tags. */
 6845    for (k = 0; k < ACERT_NUM_DIR_TAGS; ++k) {
 6846        const char * pfx = acert_dir_print[k].pfx;
 6847        const byte * tag = acert_dir_print[k].tag;
 6848        byte         asn_tag;
 6849
 6850        /* walk through entry looking for matches. */
 6851        for (i = 0; i < src_len - 5; ++i) {
 6852            if (XMEMCMP(tag, &src[i], 3) == 0) {
 6853                if (bytes_left < 5) {
 6854                    /* Not enough space left for name oid + tag + len. */
 6855                    break;
 6856                }
 6857
 6858                if (match_found) {
 6859                    /* append a {',', ' '} before doing anything else. */
 6860                    *dst++ = ',';
 6861                    *dst++ = ' ';
 6862                    total_len += 2;
 6863                    bytes_left -= 2;
 6864                }
 6865
 6866                i += 3;
 6867
 6868                /* Get the ASN Tag. */
 6869                if (GetASNTag((const byte *)src, &i, &asn_tag, src_len) < 0) {
 6870                    WOLFSSL_MSG("error: GetASNTag failed");
 6871                    break;
 6872                }
 6873
 6874                /* Check it is printable. */
 6875                if ((asn_tag != ASN_PRINTABLE_STRING) &&
 6876                    (asn_tag != ASN_IA5_STRING) &&
 6877                    (asn_tag != ASN_UTF8STRING)) {
 6878                    /* Don't know what this is but we can't print it. */
 6879                    WOLFSSL_MSG("error: asn tag not printable string");
 6880                    break;
 6881                }
 6882
 6883                /* Now get the length of the printable string. */
 6884                if (GetLength((const byte *)src, &i, &fld_len, src_len) < 0) {
 6885                    break;
 6886                }
 6887
 6888                /* Make sure we have space to fit it. */
 6889                if ((int) XSTRLEN(pfx) > bytes_left) {
 6890                    /* Not enough space left. */
 6891                    break;
 6892                }
 6893
 6894                /* Copy it in, decrement available space. */
 6895                XSTRNCPY(dst, pfx, bytes_left);
 6896                dst += XSTRLEN(pfx);
 6897                total_len += (int)XSTRLEN(pfx);
 6898                bytes_left -= (int)XSTRLEN(pfx);
 6899
 6900                if (fld_len > bytes_left) {
 6901                    /* Not enough space left. */
 6902                    break;
 6903                }
 6904
 6905                XMEMCPY(dst, &src[i], fld_len);
 6906                i += fld_len;
 6907                dst += fld_len;
 6908                total_len += fld_len;
 6909                bytes_left -= fld_len;
 6910
 6911                match_found = 1;
 6912            }
 6913        }
 6914    }
 6915
 6916    return total_len;
 6917}
 6918static int X509_print_name_entry(WOLFSSL_BIO* bio,
 6919                                 const DNS_entry* entry, int indent)
 6920{
 6921    int  ret = WOLFSSL_SUCCESS;
 6922    int  nameCount = 0;
 6923    char scratch[MAX_WIDTH];
 6924    int  len;
 6925
 6926    if (bio == NULL || entry == NULL) {
 6927        return WOLFSSL_FAILURE;
 6928    }
 6929
 6930    len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
 6931    if (len >= MAX_WIDTH) {
 6932        return WOLFSSL_FAILURE;
 6933    }
 6934
 6935    if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
 6936        return WOLFSSL_FAILURE;
 6937    }
 6938
 6939    while (entry != NULL) {
 6940        ++nameCount;
 6941        if (nameCount > 1) {
 6942            if (wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
 6943                ret = WOLFSSL_FAILURE;
 6944                break;
 6945            }
 6946        }
 6947
 6948        if (entry->type == ASN_DNS_TYPE) {
 6949            len = XSNPRINTF(scratch, MAX_WIDTH, "DNS:%s", entry->name);
 6950        }
 6951    #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
 6952        else if (entry->type == ASN_IP_TYPE) {
 6953            len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s",
 6954                    entry->ipString);
 6955        }
 6956    #else
 6957        else if (entry->type == ASN_IP_TYPE) {
 6958            /* iPAddress entries are now always parsed into altNames so
 6959             * name constraints can be enforced. Without the
 6960             * human-readable ipString field, emit a fixed label so this
 6961             * print path does not fail. */
 6962            len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:<unavailable>");
 6963        }
 6964    #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
 6965        else if (entry->type == ASN_RFC822_TYPE) {
 6966            len = XSNPRINTF(scratch, MAX_WIDTH, "email:%s",
 6967                    entry->name);
 6968        }
 6969        else if (entry->type == ASN_DIR_TYPE) {
 6970            len = X509PrintDirType(scratch, MAX_WIDTH, entry);
 6971        }
 6972        else if (entry->type == ASN_URI_TYPE) {
 6973            len = XSNPRINTF(scratch, MAX_WIDTH, "URI:%s",
 6974                entry->name);
 6975        }
 6976    #ifdef WOLFSSL_RID_ALT_NAME
 6977        else if (entry->type == ASN_RID_TYPE) {
 6978            len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:%s",
 6979                entry->ridString);
 6980        }
 6981    #else
 6982        else if (entry->type == ASN_RID_TYPE) {
 6983            /* registeredID entries are now always parsed into altNames
 6984             * so name constraints can be enforced. Without the
 6985             * human-readable ridString field, emit a fixed label so
 6986             * this print path does not fail. */
 6987            len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:<unavailable>");
 6988        }
 6989    #endif /* WOLFSSL_RID_ALT_NAME */
 6990        else if (entry->type == ASN_OTHER_TYPE) {
 6991            len = XSNPRINTF(scratch, MAX_WIDTH,
 6992                "othername <unsupported>");
 6993        }
 6994        else {
 6995            WOLFSSL_MSG("Bad alt name type.");
 6996            ret = WOLFSSL_FAILURE;
 6997            break;
 6998        }
 6999        if (len >= MAX_WIDTH) {
 7000            ret = WOLFSSL_FAILURE;
 7001            break;
 7002        }
 7003        if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch))
 7004                <= 0) {
 7005            ret = WOLFSSL_FAILURE;
 7006            break;
 7007        }
 7008
 7009        entry = entry->next;
 7010    }
 7011
 7012    if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
 7013        ret = WOLFSSL_FAILURE;
 7014    }
 7015
 7016    return ret;
 7017}
 7018
 7019#ifdef XSNPRINTF
 7020static int X509PrintKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
 7021{
 7022    int ret = WOLFSSL_SUCCESS;
 7023    const int usages[] = {
 7024        KEYUSE_DIGITAL_SIG,
 7025        KEYUSE_CONTENT_COMMIT,
 7026        KEYUSE_KEY_ENCIPHER,
 7027        KEYUSE_DATA_ENCIPHER,
 7028        KEYUSE_KEY_AGREE,
 7029        KEYUSE_KEY_CERT_SIGN,
 7030        KEYUSE_CRL_SIGN,
 7031        KEYUSE_ENCIPHER_ONLY,
 7032        KEYUSE_DECIPHER_ONLY
 7033    };
 7034    const char* usageStrs[] = {
 7035        "Digital Signature",
 7036        "Non Repudiation",
 7037        "Key Encipherment",
 7038        "Data Encipherment",
 7039        "Key Agreement",
 7040        "Certificate Sign",
 7041        "CRL Sign",
 7042        "Encipher Only",
 7043        "Decipher Only"
 7044    };
 7045
 7046    if (indent < 0) indent = 0;
 7047    if (indent > MAX_INDENT) indent = MAX_INDENT;
 7048
 7049    if (bio == NULL || x509 == NULL) {
 7050        ret = WOLFSSL_FAILURE;
 7051    }
 7052
 7053    if (ret == WOLFSSL_SUCCESS && x509->keyUsageSet && x509->keyUsage != 0) {
 7054        char scratch[MAX_WIDTH];
 7055        int len;
 7056        word32 i = 0;
 7057        int usageCount = 0;
 7058
 7059        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
 7060        if (len >= MAX_WIDTH)
 7061            ret = WOLFSSL_FAILURE;
 7062        if (ret == WOLFSSL_SUCCESS) {
 7063            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
 7064                ret = WOLFSSL_FAILURE;
 7065            }
 7066        }
 7067        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
 7068             i++) {
 7069            if (x509->keyUsage & usages[i]) {
 7070                ++usageCount;
 7071                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
 7072                    ret = WOLFSSL_FAILURE;
 7073                    break;
 7074                }
 7075                if (wolfSSL_BIO_write(bio, usageStrs[i],
 7076                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
 7077                    ret = WOLFSSL_FAILURE;
 7078                    break;
 7079                }
 7080            }
 7081        }
 7082        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
 7083            ret = WOLFSSL_FAILURE;
 7084        }
 7085    }
 7086
 7087    return ret;
 7088}
 7089
 7090static int X509PrintExtendedKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
 7091        int indent)
 7092{
 7093    int ret = WOLFSSL_SUCCESS;
 7094    const int usages[] = {
 7095        EXTKEYUSE_OCSP_SIGN,
 7096        EXTKEYUSE_TIMESTAMP,
 7097        EXTKEYUSE_EMAILPROT,
 7098        EXTKEYUSE_CODESIGN,
 7099        EXTKEYUSE_CLIENT_AUTH,
 7100        EXTKEYUSE_SERVER_AUTH
 7101    };
 7102    const char* usageStrs[] = {
 7103        "OCSP Signing",
 7104        "Time Stamping",
 7105        "E-mail Protection",
 7106        "Code Signing",
 7107        "TLS Web Client Authentication",
 7108        "TLS Web Server Authentication"
 7109    };
 7110
 7111    if (bio == NULL || x509 == NULL) {
 7112        ret = WOLFSSL_FAILURE;
 7113    }
 7114
 7115    if (ret == WOLFSSL_SUCCESS && x509->extKeyUsageCount > 0
 7116            && x509->extKeyUsage != 0) {
 7117        char scratch[MAX_WIDTH];
 7118        int len;
 7119        word32 i = 0;
 7120        int usageCount = 0;
 7121
 7122        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
 7123        if (len >= MAX_WIDTH)
 7124            ret = WOLFSSL_FAILURE;
 7125        if (ret == WOLFSSL_SUCCESS) {
 7126            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
 7127                ret = WOLFSSL_FAILURE;
 7128            }
 7129        }
 7130        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
 7131             i++) {
 7132            if (x509->extKeyUsage & usages[i]) {
 7133                ++usageCount;
 7134                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
 7135                    ret = WOLFSSL_FAILURE;
 7136                    break;
 7137                }
 7138                if (wolfSSL_BIO_write(bio, usageStrs[i],
 7139                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
 7140                    ret = WOLFSSL_FAILURE;
 7141                    break;
 7142                }
 7143            }
 7144        }
 7145        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
 7146            ret = WOLFSSL_FAILURE;
 7147        }
 7148    }
 7149
 7150    return ret;
 7151}
 7152
 7153
 7154/* print serial number out
 7155 * return WOLFSSL_SUCCESS on success
 7156 */
 7157static int X509PrintSerial_ex(WOLFSSL_BIO* bio, byte* serial, int sz,
 7158        int delimiter, int indent)
 7159{
 7160    char scratch[MAX_WIDTH];
 7161    const int scratchSz = sizeof(scratch);
 7162    int scratchLen;
 7163
 7164    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*sSerial Number:",
 7165                                 indent, "")) >= MAX_WIDTH) {
 7166        WOLFSSL_MSG("buffer overrun");
 7167        return WOLFSSL_FAILURE;
 7168    }
 7169    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7170        return WOLFSSL_FAILURE;
 7171    }
 7172
 7173    if (sz > (int)sizeof(byte)) {
 7174        int i;
 7175
 7176        /* serial is larger than int size so print off hex values */
 7177        if ((scratchLen = XSNPRINTF(
 7178                 scratch, MAX_WIDTH, "\n%*s", indent + 4, ""))
 7179                >= MAX_WIDTH) {
 7180            WOLFSSL_MSG("buffer overrun");
 7181            return WOLFSSL_FAILURE;
 7182        }
 7183        for (i = 0; i < sz; i++) {
 7184            int valLen;
 7185
 7186            if ((valLen = XSNPRINTF(
 7187                     scratch + scratchLen, scratchSz - scratchLen,
 7188                     "%02x%s", serial[i], (i < sz - 1) ?
 7189                     (delimiter ? ":" : "") : "\n"))
 7190                >= scratchSz - scratchLen) {
 7191                WOLFSSL_MSG("buffer overrun");
 7192                return WOLFSSL_FAILURE;
 7193            }
 7194            scratchLen += valLen;
 7195        }
 7196        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7197            return WOLFSSL_FAILURE;
 7198        }
 7199    }
 7200
 7201    /* if serial can fit into byte then print on the same line */
 7202    else  {
 7203        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n",
 7204                (char)serial[0], serial[0])) >= MAX_WIDTH) {
 7205            WOLFSSL_MSG("buffer overrun");
 7206            return WOLFSSL_FAILURE;
 7207        }
 7208        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7209            return WOLFSSL_FAILURE;
 7210        }
 7211    }
 7212    return WOLFSSL_SUCCESS;
 7213}
 7214
 7215static int X509PrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
 7216{
 7217    unsigned char serial[32];
 7218    int  sz = sizeof(serial);
 7219
 7220    if (indent < 0) indent = 0;
 7221    if (indent > MAX_INDENT) indent = MAX_INDENT;
 7222
 7223    XMEMSET(serial, 0, sz);
 7224    if (wolfSSL_X509_get_serial_number(x509, serial, &sz) == WOLFSSL_SUCCESS) {
 7225        X509PrintSerial_ex(bio, serial, sz, 1, indent);
 7226    }
 7227    return WOLFSSL_SUCCESS;
 7228}
 7229
 7230#ifndef NO_ASN_TIME
 7231static int X509PrintValidity(WOLFSSL_BIO* bio, WOLFSSL_ASN1_TIME * notBefore,
 7232                             WOLFSSL_ASN1_TIME * notAfter, int indent)
 7233{
 7234    char tmp[80];
 7235    (void) indent;
 7236
 7237    if (wolfSSL_BIO_write(bio, "        Validity\n",
 7238                  (int)XSTRLEN("        Validity\n")) <= 0) {
 7239        return WOLFSSL_FAILURE;
 7240    }
 7241
 7242    if (wolfSSL_BIO_write(bio, "            Not Before: ",
 7243                  (int)XSTRLEN("            Not Before: ")) <= 0) {
 7244        return WOLFSSL_FAILURE;
 7245    }
 7246    if (notBefore->length > 0) {
 7247        if (GetTimeString(notBefore->data, ASN_UTC_TIME,
 7248            tmp, sizeof(tmp), notBefore->length) != WOLFSSL_SUCCESS) {
 7249            if (GetTimeString(notBefore->data, ASN_GENERALIZED_TIME,
 7250            tmp, sizeof(tmp), notBefore->length) != WOLFSSL_SUCCESS) {
 7251                WOLFSSL_MSG("Error getting not before date");
 7252                return WOLFSSL_FAILURE;
 7253            }
 7254        }
 7255    }
 7256    else {
 7257        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
 7258    }
 7259    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
 7260    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 7261        return WOLFSSL_FAILURE;
 7262    }
 7263
 7264    if (wolfSSL_BIO_write(bio, "\n            Not After : ",
 7265                  (int)XSTRLEN("\n            Not After : ")) <= 0) {
 7266        return WOLFSSL_FAILURE;
 7267    }
 7268    if (notAfter->length > 0) {
 7269        if (GetTimeString(notAfter->data, ASN_UTC_TIME,
 7270            tmp, sizeof(tmp), notAfter->length) != WOLFSSL_SUCCESS) {
 7271            if (GetTimeString(notAfter->data, ASN_GENERALIZED_TIME,
 7272                tmp, sizeof(tmp), notAfter->length) != WOLFSSL_SUCCESS) {
 7273                WOLFSSL_MSG("Error getting not after date");
 7274                return WOLFSSL_FAILURE;
 7275            }
 7276        }
 7277    }
 7278    else {
 7279        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
 7280    }
 7281    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
 7282    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 7283        return WOLFSSL_FAILURE;
 7284    }
 7285
 7286    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
 7287        return WOLFSSL_FAILURE;
 7288    }
 7289
 7290    return WOLFSSL_SUCCESS;
 7291}
 7292#endif /* ifndef NO_ASN_TIME */
 7293
 7294static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
 7295                                int indent)
 7296{
 7297    if (!x509 || !x509->altNames || !x509->subjAltNameSet)
 7298        return WOLFSSL_FAILURE;
 7299    return X509_print_name_entry(bio, x509->altNames, indent);
 7300}
 7301
 7302/* iterate through certificate extensions printing them out in human readable
 7303 * form
 7304 * return WOLFSSL_SUCCESS on success
 7305 */
 7306static int X509PrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
 7307{
 7308    int  ret = WOLFSSL_SUCCESS;
 7309    char scratch[MAX_WIDTH];
 7310    const int scratchSz = sizeof(scratch);
 7311    int scratchLen;
 7312    int  count, i;
 7313    char* buf = NULL;
 7314
 7315    if (indent < 0) indent = 0;
 7316    if (indent > MAX_INDENT) indent = MAX_INDENT;
 7317
 7318    count = wolfSSL_X509_get_ext_count(x509);
 7319    if (count <= 0)
 7320        return WOLFSSL_SUCCESS;
 7321
 7322#ifdef WOLFSSL_CERT_REQ
 7323    if (x509->isCSR) {
 7324        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
 7325                      "Requested extensions:")) >= MAX_WIDTH) {
 7326            return WOLFSSL_FAILURE;
 7327        }
 7328    }
 7329    else
 7330#endif
 7331    {
 7332        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
 7333                                     "X509v3 extensions:")) >= MAX_WIDTH) {
 7334            return WOLFSSL_FAILURE;
 7335        }
 7336    }
 7337    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7338        return WOLFSSL_FAILURE;
 7339    }
 7340
 7341    buf = (char*)XMALLOC(MAX_WIDTH, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
 7342    if (buf == NULL) {
 7343        return WOLFSSL_FAILURE;
 7344    }
 7345
 7346    for (i = 0; (i < count) && (ret != WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); i++) {
 7347        WOLFSSL_X509_EXTENSION* ext;
 7348
 7349        ext = wolfSSL_X509_get_ext(x509, i);
 7350        if (ext != NULL) {
 7351            WOLFSSL_ASN1_OBJECT* obj;
 7352            int nid;
 7353            char val[6];
 7354            int valLen;
 7355            word32 j;
 7356
 7357            obj = wolfSSL_X509_EXTENSION_get_object(ext);
 7358            if (obj == NULL) {
 7359                ret = WOLFSSL_FAILURE;
 7360                break;
 7361            }
 7362            if (wolfSSL_OBJ_obj2txt(buf, MAX_WIDTH, obj, 0)
 7363                == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
 7364            {
 7365                ret = WOLFSSL_FAILURE;
 7366                break;
 7367            }
 7368            if ((scratchLen = XSNPRINTF(
 7369                     scratch, MAX_WIDTH, "%*s%s%s\n", indent + 4, "",
 7370                     buf,
 7371                     (wolfSSL_X509_EXTENSION_get_critical(ext)
 7372                      ? ": critical"
 7373                      : ": ")))
 7374                >= MAX_WIDTH)
 7375            {
 7376                ret = WOLFSSL_FAILURE;
 7377                break;
 7378            }
 7379
 7380            if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7381                ret = WOLFSSL_FAILURE;
 7382                break;
 7383            }
 7384            nid = wolfSSL_OBJ_obj2nid(obj);
 7385            switch (nid) {
 7386            case WC_NID_subject_alt_name:
 7387                ret = X509PrintSubjAltName(bio, x509, indent + 8);
 7388                break;
 7389
 7390            case WC_NID_subject_key_identifier:
 7391                if (!x509->subjKeyIdSet || x509->subjKeyId == NULL ||
 7392                    x509->subjKeyIdSz == 0)
 7393                {
 7394                    ret = WOLFSSL_FAILURE;
 7395                    break;
 7396                }
 7397
 7398                if ((scratchLen = XSNPRINTF(
 7399                         scratch, scratchSz,
 7400                         "%*s", indent + 8, "")) >= scratchSz)
 7401                {
 7402                    ret = WOLFSSL_FAILURE;
 7403                    break;
 7404                }
 7405                for (j = 0; j < x509->subjKeyIdSz; j++) {
 7406                    if ((valLen = XSNPRINTF(
 7407                             val, sizeof(val), "%02X%s",
 7408                             x509->subjKeyId[j],
 7409                             (j < x509->subjKeyIdSz - 1) ? ":" : "\n"))
 7410                        >= (int)sizeof(val))
 7411                    {
 7412                        ret = WOLFSSL_FAILURE;
 7413                        break;
 7414                    }
 7415                    if (scratchLen + valLen >= scratchSz) {
 7416                        if (wolfSSL_BIO_write(bio, scratch,
 7417                                              scratchLen) <= 0) {
 7418                            ret = WOLFSSL_FAILURE;
 7419                            break;
 7420                        }
 7421                        scratchLen = 0;
 7422                    }
 7423                    XMEMCPY(scratch + scratchLen, val, valLen);
 7424                    scratchLen += valLen;
 7425                }
 7426                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
 7427                    break;
 7428                if (wolfSSL_BIO_write(bio, scratch,
 7429                                      scratchLen) <= 0) {
 7430                    ret = WOLFSSL_FAILURE;
 7431                    break;
 7432                }
 7433                break;
 7434
 7435            case WC_NID_authority_key_identifier:
 7436                if (!x509->authKeyIdSet || x509->authKeyId == NULL ||
 7437                    x509->authKeyIdSz == 0) {
 7438                    ret = WOLFSSL_FAILURE;
 7439                    break;
 7440                }
 7441
 7442                if ((scratchLen = XSNPRINTF(
 7443                         scratch, scratchSz, "%*s%s",
 7444                         indent + 8, "", "keyid:")) >= scratchSz)
 7445                {
 7446                    ret = WOLFSSL_FAILURE;
 7447                    break;
 7448                }
 7449                for (j = 0; j < x509->authKeyIdSz; j++) {
 7450                    if ((valLen = XSNPRINTF(
 7451                             val, sizeof(val), "%02X%s",
 7452                             x509->authKeyId[j],
 7453                             (j < x509->authKeyIdSz - 1) ? ":" : "\n\n"))
 7454                        >= (int)sizeof(val))
 7455                    {
 7456                        ret = WOLFSSL_FAILURE;
 7457                        break;
 7458                    }
 7459                    if (scratchLen >= scratchSz - valLen) {
 7460                        if (wolfSSL_BIO_write(bio, scratch,
 7461                                              scratchLen) <= 0)
 7462                        {
 7463                            ret = WOLFSSL_FAILURE;
 7464                            break;
 7465                        }
 7466                        scratchLen = 0;
 7467                    }
 7468                    if (scratchLen + valLen >= scratchSz) {
 7469                        ret = WOLFSSL_FAILURE;
 7470                        break;
 7471                    }
 7472                    XMEMCPY(scratch + scratchLen, val, valLen);
 7473                    scratchLen += valLen;
 7474                }
 7475                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
 7476                    break;
 7477                if (wolfSSL_BIO_write(bio, scratch,
 7478                                      scratchLen) <= 0) {
 7479                    ret = WOLFSSL_FAILURE;
 7480                    break;
 7481                }
 7482                break;
 7483
 7484            case WC_NID_basic_constraints:
 7485                if (!x509->basicConstSet) {
 7486                    ret = WOLFSSL_FAILURE;
 7487                    break;
 7488                }
 7489                if ((scratchLen = XSNPRINTF(
 7490                         scratch, scratchSz,
 7491                         "%*sCA:%s\n",
 7492                         indent + 8, "", (x509->isCa)? "TRUE": "FALSE"))
 7493                    >= scratchSz)
 7494                {
 7495                    ret = WOLFSSL_FAILURE;
 7496                    break;
 7497                }
 7498                if (wolfSSL_BIO_write(bio, scratch,
 7499                                      scratchLen) <= 0) {
 7500                    ret = WOLFSSL_FAILURE;
 7501                    break;
 7502                }
 7503                break;
 7504
 7505            case WC_NID_key_usage:
 7506                ret = X509PrintKeyUsage(bio, x509, indent + 8);
 7507                break;
 7508
 7509            case WC_NID_ext_key_usage:
 7510                ret = X509PrintExtendedKeyUsage(bio, x509, indent + 8);
 7511                break;
 7512
 7513            default:
 7514                /* extension nid not yet supported */
 7515                if ((scratchLen = XSNPRINTF(
 7516                         scratch, MAX_WIDTH,
 7517                         "%*sNID %d print not yet supported\n",
 7518                         indent + 8, "", nid)) >= MAX_WIDTH)
 7519                {
 7520                    ret = WOLFSSL_FAILURE;
 7521                    break;
 7522                }
 7523
 7524                if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7525                    ret = WOLFSSL_FAILURE;
 7526                    break;
 7527                }
 7528            }
 7529        }
 7530    }
 7531
 7532    XFREE(buf, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
 7533
 7534    return ret;
 7535}
 7536
 7537
 7538/* print out the signature in human readable format for use with
 7539 * wolfSSL_X509_print()
 7540 * return WOLFSSL_SUCCESS on success
 7541 */
 7542static int X509PrintSignature_ex(WOLFSSL_BIO* bio, byte* sig,
 7543        int sigSz, int sigNid, int algOnly, int indent)
 7544{
 7545    char scratch[MAX_WIDTH];
 7546    int scratchLen;
 7547    WOLFSSL_ASN1_OBJECT* obj = NULL;
 7548    int ret = WOLFSSL_SUCCESS;
 7549    char tmp[100];
 7550    int tmpLen = 0;
 7551
 7552    if (sigSz <= 0) {
 7553        return WOLFSSL_SUCCESS;
 7554    }
 7555
 7556    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "",
 7557                                "Signature Algorithm: ")) >= MAX_WIDTH) {
 7558        ret = WOLFSSL_FAILURE;
 7559    }
 7560
 7561    if (ret == WOLFSSL_SUCCESS) {
 7562        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0)
 7563            ret = WOLFSSL_FAILURE;
 7564    }
 7565
 7566    if (ret == WOLFSSL_SUCCESS) {
 7567        obj = wolfSSL_OBJ_nid2obj(sigNid);
 7568        if (obj == NULL)
 7569            ret = WOLFSSL_FAILURE;
 7570    }
 7571    if (ret == WOLFSSL_SUCCESS) {
 7572        if (wolfSSL_OBJ_obj2txt(scratch, MAX_WIDTH, obj, 0)
 7573            == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
 7574        {
 7575            ret = WOLFSSL_FAILURE;
 7576        }
 7577    }
 7578
 7579    if (ret == WOLFSSL_SUCCESS) {
 7580        if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp),"%s\n", scratch))
 7581            >= (int)sizeof(tmp))
 7582        {
 7583            ret = WOLFSSL_FAILURE;
 7584        }
 7585    }
 7586    if (ret == WOLFSSL_SUCCESS) {
 7587        if (wolfSSL_BIO_write(bio, tmp, tmpLen) <= 0)
 7588            ret = WOLFSSL_FAILURE;
 7589    }
 7590
 7591    /* Leave function if the desired content to print
 7592     * is only the signature algorithm */
 7593    if (algOnly) {
 7594        if (obj != NULL)
 7595            wolfSSL_ASN1_OBJECT_free(obj);
 7596
 7597        return ret;
 7598    }
 7599
 7600    if (ret == WOLFSSL_SUCCESS) {
 7601        if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), "%*s", indent + 5, ""))
 7602            >= (int)sizeof(tmp))
 7603        {
 7604            ret = WOLFSSL_FAILURE;
 7605        }
 7606    }
 7607
 7608    if (ret == WOLFSSL_SUCCESS) {
 7609        int i;
 7610
 7611        for (i = 0; i < sigSz; i++) {
 7612            char val[6];
 7613            int valLen;
 7614
 7615            if (i == 0) {
 7616                if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
 7617                    >= (int)sizeof(val))
 7618                {
 7619                    ret = WOLFSSL_FAILURE;
 7620                    break;
 7621                }
 7622            }
 7623            else if (((i % 18) == 0)) {
 7624                if (wolfSSL_BIO_write(bio, tmp, tmpLen)
 7625                    <= 0) {
 7626                    ret = WOLFSSL_FAILURE;
 7627                    break;
 7628                }
 7629                if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), ":\n%*s",
 7630                                        indent + 5, ""))
 7631                    >= (int)sizeof(tmp))
 7632                {
 7633                    ret = WOLFSSL_FAILURE;
 7634                    break;
 7635                }
 7636                if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
 7637                    >= (int)sizeof(val))
 7638                {
 7639                    ret = WOLFSSL_FAILURE;
 7640                    break;
 7641                }
 7642            }
 7643            else {
 7644                if ((valLen = XSNPRINTF(val, sizeof(val), ":%02x", sig[i]))
 7645                    >= (int)sizeof(val))
 7646                {
 7647                    ret = WOLFSSL_FAILURE;
 7648                    break;
 7649                }
 7650            }
 7651            if ((tmpLen < 0) || (valLen < 0) ||
 7652                    (valLen >= ((int)sizeof(tmp) - tmpLen - 1))) {
 7653                ret = WOLFSSL_FAILURE;
 7654                break;
 7655            }
 7656            XMEMCPY(tmp + tmpLen, val, valLen);
 7657            tmpLen += valLen;
 7658            tmp[tmpLen] = 0;
 7659        }
 7660    }
 7661
 7662    /* print out remaining sig values */
 7663    if (ret == WOLFSSL_SUCCESS) {
 7664        if (tmpLen > 0) {
 7665            if (wolfSSL_BIO_write(bio, tmp, tmpLen)
 7666                <= 0)
 7667            {
 7668                ret = WOLFSSL_FAILURE;
 7669            }
 7670        }
 7671    }
 7672
 7673    if (obj != NULL)
 7674        wolfSSL_ASN1_OBJECT_free(obj);
 7675
 7676    return ret;
 7677}
 7678
 7679static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
 7680        int algOnly, int indent)
 7681{
 7682    int sigSz = 0;
 7683    if (wolfSSL_X509_get_signature(x509, NULL, &sigSz) <= 0) {
 7684        return WOLFSSL_FAILURE;
 7685    }
 7686
 7687    if (sigSz > 0) {
 7688        unsigned char* sig;
 7689        int sigNid;
 7690
 7691        sigNid = wolfSSL_X509_get_signature_nid(x509);
 7692        if (sigNid <= 0) {
 7693            return WOLFSSL_FAILURE;
 7694        }
 7695
 7696        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 7697        if (sig == NULL) {
 7698            return WOLFSSL_FAILURE;
 7699        }
 7700
 7701        if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) {
 7702            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 7703            return WOLFSSL_FAILURE;
 7704        }
 7705
 7706        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
 7707                != WOLFSSL_SUCCESS) {
 7708            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 7709            return WOLFSSL_FAILURE;
 7710        }
 7711
 7712        XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 7713
 7714    }
 7715
 7716    return WOLFSSL_SUCCESS;
 7717}
 7718
 7719
 7720/* print out the public key in human readable format for use with
 7721 * wolfSSL_X509_print()
 7722 * return WOLFSSL_SUCCESS on success
 7723 */
 7724static int X509PrintPubKey(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
 7725{
 7726    char scratch[MAX_WIDTH];
 7727    WOLFSSL_EVP_PKEY* pubKey;
 7728    int len;
 7729    int ret = WOLFSSL_SUCCESS;
 7730
 7731    if (indent < 0) indent = 0;
 7732    if (indent > MAX_INDENT) indent = MAX_INDENT;
 7733
 7734    if (bio == NULL || x509 == NULL)
 7735        return BAD_FUNC_ARG;
 7736
 7737    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sSubject Public Key Info:\n", indent,
 7738        "");
 7739    if (len >= MAX_WIDTH)
 7740        return WOLFSSL_FAILURE;
 7741    if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
 7742        return WOLFSSL_FAILURE;
 7743
 7744    switch (x509->pubKeyOID) {
 7745    #ifndef NO_RSA
 7746        case RSAk:
 7747            len = XSNPRINTF(scratch, MAX_WIDTH,
 7748                    "%*sPublic Key Algorithm: rsaEncryption\n", indent + 4, "");
 7749            if (len >= MAX_WIDTH)
 7750                return WOLFSSL_FAILURE;
 7751            if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
 7752                return WOLFSSL_FAILURE;
 7753            break;
 7754    #endif
 7755    #ifdef HAVE_ECC
 7756        case ECDSAk:
 7757            len = XSNPRINTF(scratch, MAX_WIDTH,
 7758                    "%*sPublic Key Algorithm: EC\n", indent + 4, "");
 7759            if ((len < 0) || (len >= MAX_WIDTH))
 7760                return WOLFSSL_FAILURE;
 7761            if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
 7762                return WOLFSSL_FAILURE;
 7763            break;
 7764    #endif
 7765        default:
 7766                WOLFSSL_MSG("Unknown key type");
 7767                return WOLFSSL_FAILURE;
 7768    }
 7769
 7770    pubKey = wolfSSL_X509_get_pubkey(x509);
 7771    if (pubKey == NULL)
 7772        return WOLFSSL_FAILURE;
 7773
 7774    ret = wolfSSL_EVP_PKEY_print_public(bio, pubKey, indent + 8, NULL);
 7775
 7776    wolfSSL_EVP_PKEY_free(pubKey);
 7777
 7778    return ret;
 7779}
 7780
 7781
 7782/* human readable print out of x509 name formatted for use with
 7783 * wolfSSL_X509_print()
 7784 * return WOLFSSL_SUCCESS on success
 7785 */
 7786static int X509PrintName(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
 7787        char* type, int indent)
 7788{
 7789    if (name != NULL) {
 7790        char scratch[MAX_WIDTH];
 7791        int scratchLen;
 7792
 7793        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
 7794                                     "%*s%s", indent, "", type))
 7795            >= MAX_WIDTH)
 7796        {
 7797            return WOLFSSL_FAILURE;
 7798        }
 7799        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7800            return WOLFSSL_FAILURE;
 7801        }
 7802        if (wolfSSL_X509_NAME_print_ex(bio, name, 1, 0) <= 0) {
 7803            return WOLFSSL_FAILURE;
 7804        }
 7805        if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
 7806            return WOLFSSL_FAILURE;
 7807        }
 7808    }
 7809    return WOLFSSL_SUCCESS;
 7810}
 7811
 7812
 7813/* human readable print out of x509 version
 7814 * return WOLFSSL_SUCCESS on success
 7815 */
 7816static int X509PrintVersion(WOLFSSL_BIO* bio, int version, int indent)
 7817{
 7818    char scratch[MAX_WIDTH];
 7819    int scratchLen;
 7820
 7821    if (indent < 0) indent = 0;
 7822    if (indent > MAX_INDENT) indent = MAX_INDENT;
 7823
 7824    scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Version:");
 7825    if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) {
 7826        return WOLFSSL_FAILURE;
 7827    }
 7828
 7829    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7830        return WOLFSSL_FAILURE;
 7831    }
 7832
 7833    scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n",
 7834                    version, (byte)version-1);
 7835    if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) {
 7836        return WOLFSSL_FAILURE;
 7837    }
 7838
 7839    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7840        return WOLFSSL_FAILURE;
 7841    }
 7842    return WOLFSSL_SUCCESS;
 7843}
 7844
 7845#ifdef WOLFSSL_CERT_REQ
 7846/* Print out of REQ attributes
 7847 * return WOLFSSL_SUCCESS on success
 7848 */
 7849static int X509PrintReqAttributes(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
 7850        int indent)
 7851{
 7852    WOLFSSL_X509_ATTRIBUTE* attr;
 7853    char scratch[MAX_WIDTH];
 7854    int scratchLen;
 7855    int i = 0;
 7856
 7857    if (indent < 0) indent = 0;
 7858    if (indent > MAX_INDENT) indent = MAX_INDENT;
 7859
 7860    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
 7861                                 "%*s%s", indent, "", "Attributes: \n"))
 7862        >= MAX_WIDTH)
 7863    {
 7864        return WOLFSSL_FAILURE;
 7865    }
 7866    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7867        return WOLFSSL_FAILURE;
 7868    }
 7869    do {
 7870        attr = wolfSSL_X509_REQ_get_attr(x509, i);
 7871        if (attr != NULL) {
 7872            char lName[NAME_SZ/4]; /* NAME_SZ default is 80 */
 7873            int lNameSz = NAME_SZ/4;
 7874            const byte* data;
 7875
 7876            if (wolfSSL_OBJ_obj2txt(lName, lNameSz, attr->object, 0)
 7877                == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
 7878            {
 7879                return WOLFSSL_FAILURE;
 7880            }
 7881            lNameSz = (int)XSTRLEN(lName);
 7882            data = wolfSSL_ASN1_STRING_get0_data(
 7883                    attr->value->value.asn1_string);
 7884            if (data == NULL) {
 7885                WOLFSSL_MSG("No REQ attribute found when expected");
 7886                return WOLFSSL_FAILURE;
 7887            }
 7888            if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
 7889                          "%*s%s%*s:%s\n", indent+4, "",
 7890                          lName, (NAME_SZ/4)-lNameSz, "", data))
 7891                >= MAX_WIDTH)
 7892            {
 7893                return WOLFSSL_FAILURE;
 7894            }
 7895            if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
 7896                WOLFSSL_MSG("Error writing REQ attribute");
 7897                return WOLFSSL_FAILURE;
 7898            }
 7899        }
 7900        i++;
 7901    } while (attr != NULL);
 7902
 7903    return WOLFSSL_SUCCESS;
 7904}
 7905
 7906
 7907/*
 7908 * return WOLFSSL_SUCCESS on success
 7909 */
 7910int wolfSSL_X509_REQ_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
 7911{
 7912    char subjType[] = "Subject: ";
 7913
 7914    if (bio == NULL || x509 == NULL) {
 7915        return WOLFSSL_FAILURE;
 7916    }
 7917
 7918    if (wolfSSL_BIO_write(bio, "Certificate Request:\n",
 7919                  (int)XSTRLEN("Certificate Request:\n")) <= 0) {
 7920            return WOLFSSL_FAILURE;
 7921    }
 7922
 7923    if (wolfSSL_BIO_write(bio, "    Data:\n",
 7924                  (int)XSTRLEN("    Data:\n")) <= 0) {
 7925            return WOLFSSL_FAILURE;
 7926    }
 7927
 7928    /* print version of cert.  Note that we increment by 1 because for REQs,
 7929     * the value stored in x509->version is the actual value of the field; not
 7930     * the version. */
 7931    if (X509PrintVersion(bio, (int)wolfSSL_X509_REQ_get_version(x509) + 1, 8)
 7932            != WOLFSSL_SUCCESS) {
 7933        return WOLFSSL_FAILURE;
 7934    }
 7935
 7936    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
 7937        return WOLFSSL_FAILURE;
 7938    }
 7939
 7940    /* print subject */
 7941    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
 7942            != WOLFSSL_SUCCESS) {
 7943        return WOLFSSL_FAILURE;
 7944    }
 7945
 7946    /* get and print public key */
 7947    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
 7948        return WOLFSSL_FAILURE;
 7949    }
 7950
 7951    /* print out extensions */
 7952    if (X509PrintExtensions(bio, x509, 4) != WOLFSSL_SUCCESS) {
 7953        return WOLFSSL_FAILURE;
 7954    }
 7955
 7956    /* print out req attributes */
 7957    if (X509PrintReqAttributes(bio, x509, 4) != WOLFSSL_SUCCESS) {
 7958        return WOLFSSL_FAILURE;
 7959    }
 7960
 7961    /* print out signature */
 7962    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
 7963        return WOLFSSL_FAILURE;
 7964    }
 7965
 7966    /* done with print out */
 7967    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
 7968        return WOLFSSL_FAILURE;
 7969    }
 7970
 7971    return WOLFSSL_SUCCESS;
 7972}
 7973#endif /* WOLFSSL_CERT_REQ */
 7974
 7975
 7976/* Writes the human readable form of x509 to bio.
 7977 *
 7978 * bio  WOLFSSL_BIO to write to.
 7979 * x509 Certificate to write.
 7980 *
 7981 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
 7982 */
 7983int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
 7984    unsigned long nmflags, unsigned long cflag)
 7985{
 7986    char issuType[] = "Issuer:";
 7987    char subjType[] = "Subject:";
 7988
 7989    WOLFSSL_ENTER("wolfSSL_X509_print_ex");
 7990
 7991    /* flags currently not supported */
 7992    (void)nmflags;
 7993    (void)cflag;
 7994
 7995    if (bio == NULL || x509 == NULL) {
 7996        return WOLFSSL_FAILURE;
 7997    }
 7998
 7999    if (wolfSSL_BIO_write(bio, "Certificate:\n",
 8000                  (int)XSTRLEN("Certificate:\n")) <= 0) {
 8001            return WOLFSSL_FAILURE;
 8002    }
 8003
 8004    if (wolfSSL_BIO_write(bio, "    Data:\n",
 8005                  (int)XSTRLEN("    Data:\n")) <= 0) {
 8006            return WOLFSSL_FAILURE;
 8007    }
 8008
 8009    /* print version of cert */
 8010    if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8)
 8011            != WOLFSSL_SUCCESS) {
 8012        return WOLFSSL_FAILURE;
 8013    }
 8014
 8015    /* print serial number out */
 8016    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
 8017        return WOLFSSL_FAILURE;
 8018    }
 8019
 8020    /* print out signature algo*/
 8021    if (X509PrintSignature(bio, x509, 1, 8) != WOLFSSL_SUCCESS) {
 8022        return WOLFSSL_FAILURE;
 8023    }
 8024
 8025    /* print issuer */
 8026    if (X509PrintName(bio, wolfSSL_X509_get_issuer_name(x509), issuType, 8)
 8027            != WOLFSSL_SUCCESS) {
 8028        return WOLFSSL_FAILURE;
 8029    }
 8030
 8031    #ifndef NO_ASN_TIME
 8032    /* print validity */
 8033    if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
 8034        != WOLFSSL_SUCCESS) {
 8035        return WOLFSSL_FAILURE;
 8036    }
 8037    #endif /* NO_ASN_TIME */
 8038
 8039    /* print subject */
 8040    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
 8041            != WOLFSSL_SUCCESS) {
 8042        return WOLFSSL_FAILURE;
 8043    }
 8044
 8045    /* get and print public key */
 8046    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
 8047        return WOLFSSL_FAILURE;
 8048    }
 8049
 8050    /* print out extensions */
 8051    if (X509PrintExtensions(bio, x509, 8) != WOLFSSL_SUCCESS) {
 8052        return WOLFSSL_FAILURE;
 8053    }
 8054
 8055    /* print out signature */
 8056    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
 8057        return WOLFSSL_FAILURE;
 8058    }
 8059
 8060    /* done with print out */
 8061    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
 8062        return WOLFSSL_FAILURE;
 8063    }
 8064
 8065    return WOLFSSL_SUCCESS;
 8066}
 8067int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
 8068{
 8069    return wolfSSL_X509_print_ex(bio, x509, 0, 0);
 8070}
 8071
 8072#if defined(WOLFSSL_ACERT)
 8073/* Retrieve sig NID from an ACERT.
 8074 *
 8075 * returns  NID on success
 8076 * returns  0 on failure
 8077 */
 8078int wolfSSL_X509_ACERT_get_signature_nid(const WOLFSSL_X509_ACERT *x509)
 8079{
 8080    if (x509 == NULL) {
 8081        return 0;
 8082    }
 8083
 8084    return oid2nid((word32)x509->sigOID, oidSigType);
 8085}
 8086
 8087static int X509AcertPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
 8088                                   int algOnly, int indent)
 8089{
 8090    int sigSz = 0;
 8091    if (wolfSSL_X509_ACERT_get_signature(x509, NULL, &sigSz) <= 0) {
 8092        return WOLFSSL_FAILURE;
 8093    }
 8094
 8095    if (sigSz > 0) {
 8096        unsigned char* sig;
 8097        int sigNid;
 8098
 8099        sigNid = wolfSSL_X509_ACERT_get_signature_nid(x509);
 8100        if (sigNid <= 0) {
 8101            return WOLFSSL_FAILURE;
 8102        }
 8103
 8104        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 8105        if (sig == NULL) {
 8106            return WOLFSSL_FAILURE;
 8107        }
 8108
 8109        if (wolfSSL_X509_ACERT_get_signature(x509, sig, &sigSz) <= 0) {
 8110            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 8111            return WOLFSSL_FAILURE;
 8112        }
 8113
 8114        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
 8115                != WOLFSSL_SUCCESS) {
 8116            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 8117            return WOLFSSL_FAILURE;
 8118        }
 8119
 8120        if (sig != NULL) {
 8121            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 8122        }
 8123
 8124    }
 8125
 8126    return WOLFSSL_SUCCESS;
 8127}
 8128
 8129static int X509AcertPrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
 8130                                int indent)
 8131{
 8132    unsigned char serial[32];
 8133    int  sz = sizeof(serial);
 8134
 8135    XMEMSET(serial, 0, sz);
 8136    if (wolfSSL_X509_ACERT_get_serial_number(x509, serial, &sz)
 8137        == WOLFSSL_SUCCESS) {
 8138        X509PrintSerial_ex(bio, serial, sz, 1, indent);
 8139    }
 8140    return WOLFSSL_SUCCESS;
 8141}
 8142
 8143int wolfSSL_X509_ACERT_print(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509)
 8144{
 8145    const char * hdr =                "Attribute Certificate:\n";
 8146    const char * data_hdr =           "    Data:\n";
 8147    const char * holder_hdr =         "        Holder:\n";
 8148    const char * holder_issuer_hdr =  "            Issuer:";
 8149    const char * holder_name_hdr =    "            Name:";
 8150    const char * attcert_issuer_hdr = "        Issuer:";
 8151
 8152    if (bio == NULL || x509 == NULL) {
 8153        return WOLFSSL_FAILURE;
 8154    }
 8155
 8156    /* print acert header */
 8157    if (wolfSSL_BIO_write(bio, hdr, (int)XSTRLEN(hdr)) <= 0) {
 8158        return WOLFSSL_FAILURE;
 8159    }
 8160
 8161    /* print data header */
 8162    if (wolfSSL_BIO_write(bio, data_hdr, (int)XSTRLEN(data_hdr)) <= 0) {
 8163        return WOLFSSL_FAILURE;
 8164    }
 8165
 8166    /* print version of cert */
 8167    if (X509PrintVersion(bio, wolfSSL_X509_ACERT_version(x509), 8)
 8168            != WOLFSSL_SUCCESS) {
 8169        return WOLFSSL_FAILURE;
 8170    }
 8171
 8172    /* print serial number out */
 8173    if (X509AcertPrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
 8174        return WOLFSSL_FAILURE;
 8175    }
 8176
 8177    /* print holder field */
 8178    if (wolfSSL_BIO_write(bio, holder_hdr, (int)XSTRLEN(holder_hdr)) <= 0) {
 8179        return WOLFSSL_FAILURE;
 8180    }
 8181
 8182    if (x509->holderEntityName != NULL) {
 8183        /* print issuer header */
 8184        if (wolfSSL_BIO_write(bio, holder_name_hdr,
 8185            (int)XSTRLEN(holder_name_hdr)) <= 0) {
 8186            return WOLFSSL_FAILURE;
 8187        }
 8188
 8189        if (X509_print_name_entry(bio, x509->holderEntityName, 1)
 8190                != WOLFSSL_SUCCESS) {
 8191            return WOLFSSL_FAILURE;
 8192        }
 8193    }
 8194
 8195    if (x509->holderIssuerName != NULL) {
 8196        /* print issuer header */
 8197        if (wolfSSL_BIO_write(bio, holder_issuer_hdr,
 8198            (int)XSTRLEN(holder_issuer_hdr)) <= 0) {
 8199            return WOLFSSL_FAILURE;
 8200        }
 8201
 8202        if (X509_print_name_entry(bio, x509->holderIssuerName, 1)
 8203            != WOLFSSL_SUCCESS) {
 8204            return WOLFSSL_FAILURE;
 8205        }
 8206    }
 8207
 8208    if (x509->holderSerialSz > 0) {
 8209        X509PrintSerial_ex(bio, x509->holderSerial, x509->holderSerialSz,
 8210                           1, 12);
 8211    }
 8212
 8213    /* print issuer header */
 8214    if (wolfSSL_BIO_write(bio, attcert_issuer_hdr,
 8215        (int)XSTRLEN(attcert_issuer_hdr)) <= 0) {
 8216        return WOLFSSL_FAILURE;
 8217    }
 8218
 8219    if (x509->AttCertIssuerName != NULL) {
 8220        if (X509_print_name_entry(bio, x509->AttCertIssuerName, 1)
 8221                != WOLFSSL_SUCCESS) {
 8222            return WOLFSSL_FAILURE;
 8223        }
 8224    }
 8225    else {
 8226        const char * msg = " Issuer type not supported.\n";
 8227        if (wolfSSL_BIO_write(bio, msg, (int)XSTRLEN(msg)) <= 0) {
 8228            return WOLFSSL_FAILURE;
 8229        }
 8230    }
 8231
 8232    #ifndef NO_ASN_TIME
 8233    /* print validity */
 8234    if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
 8235        != WOLFSSL_SUCCESS) {
 8236        return WOLFSSL_FAILURE;
 8237    }
 8238    #endif /* NO_ASN_TIME */
 8239
 8240    /* print raw attributes */
 8241    if (x509->rawAttr && x509->rawAttrLen > 0) {
 8242        char attr_hdr[128]; /* buffer for XSNPRINTF */
 8243
 8244        if (XSNPRINTF(attr_hdr, 128, "%*s%s: %d bytes\n", 8, "",
 8245                    "Attributes", x509->rawAttrLen) >= 128) {
 8246            return WOLFSSL_FAILURE;
 8247        }
 8248
 8249        if (wolfSSL_BIO_write(bio, attr_hdr, (int)XSTRLEN(attr_hdr)) <= 0) {
 8250                return WOLFSSL_FAILURE;
 8251        }
 8252    }
 8253
 8254    /* print out sig algo and signature */
 8255    if (X509AcertPrintSignature(bio, x509, 0, 8) != WOLFSSL_SUCCESS) {
 8256        return WOLFSSL_FAILURE;
 8257    }
 8258
 8259    /* done with print out */
 8260    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
 8261        return WOLFSSL_FAILURE;
 8262    }
 8263
 8264    return WOLFSSL_SUCCESS;
 8265}
 8266#endif /* WOLFSSL_ACERT */
 8267
 8268#ifndef NO_FILESYSTEM
 8269int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509)
 8270{
 8271    WOLFSSL_BIO* bio;
 8272    int ret;
 8273
 8274    WOLFSSL_ENTER("wolfSSL_X509_print_fp");
 8275
 8276    if (!fp || !x509) {
 8277        WOLFSSL_MSG("Bad parameter");
 8278        return WOLFSSL_FAILURE;
 8279    }
 8280
 8281    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()))) {
 8282        WOLFSSL_MSG("wolfSSL_BIO_new wolfSSL_BIO_s_file error");
 8283        return WOLFSSL_FAILURE;
 8284    }
 8285
 8286    if (wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
 8287        WOLFSSL_MSG("wolfSSL_BIO_set_fp error");
 8288        wolfSSL_BIO_free(bio);
 8289        return WOLFSSL_FAILURE;
 8290    }
 8291
 8292    ret = wolfSSL_X509_print(bio, x509);
 8293
 8294    wolfSSL_BIO_free(bio);
 8295
 8296    return ret;
 8297}
 8298#endif /* NO_FILESYSTEM */
 8299
 8300#endif /* XSNPRINTF */
 8301
 8302int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp,
 8303        const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig)
 8304{
 8305    int length = 0;
 8306    word32 idx = 0;
 8307    int i;
 8308
 8309    (void)sig;
 8310
 8311    WOLFSSL_ENTER("wolfSSL_X509_signature_print");
 8312
 8313    if (!bp || !sigalg) {
 8314        WOLFSSL_MSG("Bad parameter");
 8315        return WOLFSSL_FAILURE;
 8316    }
 8317
 8318    if ((sigalg->algorithm->obj == NULL) ||
 8319        (sigalg->algorithm->obj[idx] != ASN_OBJECT_ID)) {
 8320        WOLFSSL_MSG("Bad ASN1 Object");
 8321        return WOLFSSL_FAILURE;
 8322    }
 8323    idx++; /* skip object id */
 8324
 8325    if (GetLength((const byte*)sigalg->algorithm->obj, &idx, &length,
 8326                  sigalg->algorithm->objSz) < 0 || length < 0) {
 8327        return WOLFSSL_FAILURE;
 8328    }
 8329
 8330    if (wolfSSL_BIO_puts(bp, "    Raw Signature Algorithm:") <= 0) {
 8331        WOLFSSL_MSG("wolfSSL_BIO_puts error");
 8332        return WOLFSSL_FAILURE;
 8333    }
 8334
 8335    for (i = 0; i < length; ++i) {
 8336        char hex_digits[4];
 8337        if (XSNPRINTF(hex_digits, sizeof(hex_digits), "%c%02X", i>0 ? ':' : ' ',
 8338                  (unsigned int)sigalg->algorithm->obj[idx+i])
 8339            >= (int)sizeof(hex_digits))
 8340        {
 8341            WOLFSSL_MSG("buffer overrun");
 8342            return WOLFSSL_FAILURE;
 8343        }
 8344        if (wolfSSL_BIO_puts(bp, hex_digits) <= 0)
 8345            return WOLFSSL_FAILURE;
 8346    }
 8347
 8348    if (wolfSSL_BIO_puts(bp, "\n") <= 0)
 8349        return WOLFSSL_FAILURE;
 8350
 8351    return WOLFSSL_SUCCESS;
 8352}
 8353#endif /* !NO_BIO */
 8354
 8355#ifndef NO_WOLFSSL_STUB
 8356void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig,
 8357        const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509)
 8358{
 8359    (void)psig;
 8360    (void)palg;
 8361    (void)x509;
 8362    WOLFSSL_STUB("wolfSSL_X509_get0_signature");
 8363}
 8364#endif
 8365
 8366#endif /* OPENSSL_EXTRA */
 8367
 8368#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
 8369const char* wolfSSL_X509_verify_cert_error_string(long err)
 8370{
 8371    return wolfSSL_ERR_reason_error_string((unsigned long)err);
 8372}
 8373#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
 8374
 8375#ifdef OPENSSL_EXTRA
 8376
 8377/* Add directory path that will be used for loading certs and CRLs
 8378 * which have the <hash>.rn name format.
 8379 * type may be WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
 8380 * returns WOLFSSL_SUCCESS on successful, otherwise negative or zero. */
 8381int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
 8382                               long type)
 8383{
 8384    return wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, dir, type,
 8385                                    NULL);
 8386}
 8387
 8388int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
 8389                                 const char* file, long type)
 8390{
 8391#if !defined(NO_FILESYSTEM) && \
 8392    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
 8393    int           ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 8394    XFILE         fp;
 8395    long          sz;
 8396    byte*         pem = NULL;
 8397    byte*         curr = NULL;
 8398    byte*         prev = NULL;
 8399    const char* header = NULL;
 8400    const char* footer = NULL;
 8401
 8402    if (type != WOLFSSL_FILETYPE_PEM)
 8403        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
 8404
 8405    fp = XFOPEN(file, "rb");
 8406    if (fp == XBADFILE)
 8407        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
 8408
 8409    if (XFSEEK(fp, 0, XSEEK_END) != 0) {
 8410        XFCLOSE(fp);
 8411        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
 8412    }
 8413    sz = XFTELL(fp);
 8414    if (XFSEEK(fp, 0, XSEEK_SET) != 0) {
 8415        XFCLOSE(fp);
 8416        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
 8417    }
 8418
 8419    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
 8420        WOLFSSL_MSG("X509_LOOKUP_load_file size error");
 8421        goto end;
 8422    }
 8423
 8424    pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_PEM);
 8425    if (pem == NULL) {
 8426        ret = MEMORY_ERROR;
 8427        goto end;
 8428    }
 8429
 8430    /* Read in file which may be CRLs or certificates. */
 8431    if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
 8432        goto end;
 8433
 8434    prev = curr = pem;
 8435    do {
 8436        /* get PEM header and footer based on type */
 8437        if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
 8438                XSTRNSTR((char*)curr, header, sz) != NULL) {
 8439#ifdef HAVE_CRL
 8440            WOLFSSL_CERT_MANAGER* cm = lookup->store->cm;
 8441
 8442            if (cm->crl == NULL) {
 8443                if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK)
 8444                    != WOLFSSL_SUCCESS) {
 8445                    WOLFSSL_MSG("Enable CRL failed");
 8446                    goto end;
 8447                }
 8448            }
 8449
 8450            ret = BufferLoadCRL(cm->crl, curr, sz, WOLFSSL_FILETYPE_PEM,
 8451                NO_VERIFY);
 8452            if (ret != WOLFSSL_SUCCESS)
 8453                goto end;
 8454#endif
 8455            curr = (byte*)XSTRNSTR((char*)curr, footer, sz);
 8456        }
 8457        else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
 8458                XSTRNSTR((char*)curr, header, sz) != NULL) {
 8459            ret = X509StoreLoadCertBuffer(lookup->store, curr,
 8460                                        (word32)sz, WOLFSSL_FILETYPE_PEM);
 8461            if (ret != WOLFSSL_SUCCESS)
 8462                goto end;
 8463            curr = (byte*)XSTRNSTR((char*)curr, footer, sz);
 8464        }
 8465        else
 8466            goto end;
 8467
 8468        if (curr == NULL)
 8469            goto end;
 8470
 8471        curr++;
 8472        sz -= (long)(curr - prev);
 8473        prev = curr;
 8474    }
 8475    while (ret == WOLFSSL_SUCCESS);
 8476
 8477end:
 8478    XFREE(pem, 0, DYNAMIC_TYPE_PEM);
 8479    XFCLOSE(fp);
 8480    return WS_RETURN_CODE(ret, (int)WOLFSSL_FAILURE);
 8481#else
 8482    (void)lookup;
 8483    (void)file;
 8484    (void)type;
 8485    return WS_RETURN_CODE(WOLFSSL_FAILURE,WOLFSSL_FAILURE);
 8486#endif
 8487}
 8488
 8489WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
 8490{
 8491    /* Method implementation in functions. */
 8492    static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
 8493    return &meth;
 8494}
 8495
 8496WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
 8497{
 8498    /* Method implementation in functions. */
 8499    static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
 8500    return &meth;
 8501}
 8502
 8503/* set directory path to load certificate or CRL which have the hash.N form */
 8504/* for late use                                                             */
 8505/* @param ctx    a pointer to WOLFSSL_BY_DIR structure                      */
 8506/* @param argc   directory path                                             */
 8507/* @param argl   file type, either WOLFSSL_FILETYPE_PEM or                  */
 8508/*                                          WOLFSSL_FILETYPE_ASN1           */
 8509/* @return WOLFSSL_SUCCESS on successful, otherwise negative or zero        */
 8510static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
 8511{
 8512#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
 8513    WOLFSSL_BY_DIR_entry *entry;
 8514    size_t pathLen;
 8515    int i, num;
 8516    const char* c;
 8517    WC_DECLARE_VAR(buf, char, MAX_FILENAME_SZ, 0);
 8518
 8519    WOLFSSL_ENTER("x509AddCertDir");
 8520
 8521    pathLen = 0;
 8522    c = argc;
 8523    /* sanity check, zero length */
 8524    if (ctx == NULL || c == NULL || *c == '\0')
 8525        return WOLFSSL_FAILURE;
 8526
 8527#ifdef WOLFSSL_SMALL_STACK
 8528    buf = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_OPENSSL);
 8529    if (buf == NULL) {
 8530        WOLFSSL_LEAVE("x509AddCertDir", MEMORY_E);
 8531        return MEMORY_E;
 8532    }
 8533#endif
 8534
 8535    XMEMSET(buf, 0, MAX_FILENAME_SZ);
 8536
 8537    do {
 8538        if (*c == SEPARATOR_CHAR || *c == '\0') {
 8539
 8540            num = wolfSSL_sk_BY_DIR_entry_num(ctx->dir_entry);
 8541
 8542            for (i=0; i<num; i++) {
 8543
 8544                entry = wolfSSL_sk_BY_DIR_entry_value(ctx->dir_entry, i);
 8545
 8546                if (XSTRLEN(entry->dir_name) == pathLen &&
 8547                    XSTRNCMP(entry->dir_name, buf, pathLen) == 0) {
 8548                    WOLFSSL_MSG("dir entry found");
 8549                    break;
 8550                }
 8551            }
 8552
 8553            if (num == -1 || i == num) {
 8554                WOLFSSL_MSG("no entry found");
 8555
 8556                if (ctx->dir_entry == NULL) {
 8557                    ctx->dir_entry = wolfSSL_sk_BY_DIR_entry_new_null();
 8558
 8559                    if (ctx->dir_entry == NULL) {
 8560                        WOLFSSL_MSG("failed to allocate dir_entry");
 8561                            WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
 8562                        return 0;
 8563                    }
 8564                }
 8565
 8566                entry = wolfSSL_BY_DIR_entry_new();
 8567                if (entry == NULL) {
 8568                    WOLFSSL_MSG("failed to allocate dir entry");
 8569                        WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
 8570                    return 0;
 8571                }
 8572                entry->dir_type = (int)argl;
 8573                entry->dir_name = (char*)XMALLOC(pathLen + 1/* \0 termination*/
 8574                                                , NULL, DYNAMIC_TYPE_OPENSSL);
 8575                entry->hashes = wolfSSL_sk_BY_DIR_HASH_new_null();
 8576                if (entry->dir_name == NULL || entry->hashes == NULL) {
 8577                    WOLFSSL_MSG("failed to allocate dir name");
 8578                    wolfSSL_BY_DIR_entry_free(entry);
 8579                        WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
 8580                    return 0;
 8581                }
 8582
 8583                XSTRNCPY(entry->dir_name, buf, pathLen);
 8584                entry->dir_name[pathLen] = '\0';
 8585
 8586                if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry) <= 0) {
 8587                    wolfSSL_BY_DIR_entry_free(entry);
 8588                        WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
 8589                    return 0;
 8590                }
 8591            }
 8592            /* skip separator */
 8593            if (*c == SEPARATOR_CHAR) c++;
 8594
 8595            pathLen = 0;
 8596            XMEMSET(buf, 0, MAX_FILENAME_SZ);
 8597        }
 8598        buf[pathLen++] = *c;
 8599
 8600    } while(*c++ != '\0');
 8601
 8602    WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
 8603
 8604    return WOLFSSL_SUCCESS;
 8605#else
 8606    (void)ctx;
 8607    (void)argc;
 8608    (void)argl;
 8609    return WOLFSSL_NOT_IMPLEMENTED;
 8610#endif
 8611}
 8612
 8613/* set additional data to X509_LOOKUP                                   */
 8614/* @param ctx    a pointer to X509_LOOKUP structure                     */
 8615/* @param cmd    control command :                                      */
 8616/*               X509_L_FILE_LOAD, X509_L_ADD_DIR X509_L_ADD_STORE or   */
 8617/*               X509_L_LOAD_STORE                                      */
 8618/* @param argc   arguments for the control command                      */
 8619/* @param argl   arguments for the control command                      */
 8620/* @param **ret  return value of the control command                    */
 8621/* @return WOLFSSL_SUCCESS on successful, otherwise WOLFSSL_FAILURE     */
 8622/* note: WOLFSSL_X509_L_ADD_STORE and WOLFSSL_X509_L_LOAD_STORE have not*/
 8623/*       yet implemented. It returns WOLFSSL_NOT_IMPLEMENTED            */
 8624/*       when those control commands are passed.                        */
 8625int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd,
 8626        const char *argc, long argl, char **ret)
 8627{
 8628    int lret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 8629
 8630    WOLFSSL_ENTER("wolfSSL_X509_LOOKUP_ctrl");
 8631#if !defined(NO_FILESYSTEM)
 8632    if (ctx != NULL) {
 8633        switch (cmd) {
 8634        case WOLFSSL_X509_L_FILE_LOAD:
 8635            /* expects to return a number of processed cert or crl file */
 8636            lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, (int)argl) > 0 ?
 8637                            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
 8638            break;
 8639        case WOLFSSL_X509_L_ADD_DIR:
 8640            /* store directory location to use it later */
 8641#if !defined(NO_WOLFSSL_DIR)
 8642            lret = x509AddCertDir(ctx->dirs, argc, argl);
 8643#else
 8644            (void)x509AddCertDir;
 8645            lret = WOLFSSL_NOT_IMPLEMENTED;
 8646#endif
 8647            break;
 8648        case WOLFSSL_X509_L_ADD_STORE:
 8649        case WOLFSSL_X509_L_LOAD_STORE:
 8650            return WOLFSSL_NOT_IMPLEMENTED;
 8651
 8652        default:
 8653            break;
 8654        }
 8655    }
 8656    (void)ret;
 8657#else
 8658    (void)ctx;
 8659    (void)argc;
 8660    (void)argl;
 8661    (void)ret;
 8662    (void)cmd;
 8663    (void)x509AddCertDir;
 8664    lret = WOLFSSL_NOT_IMPLEMENTED;
 8665#endif
 8666    return lret;
 8667}
 8668
 8669
 8670#if defined(WOLFSSL_CERT_GEN)
 8671static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
 8672        unsigned char* der, int* derSz, int includeSig);
 8673#endif
 8674
 8675#ifdef WOLFSSL_CERT_GEN
 8676#ifndef NO_BIO
 8677/* Converts the X509 to DER format and outputs it into bio.
 8678 *
 8679 * bio  is the structure to hold output DER
 8680 * x509 certificate to create DER from
 8681 * req  if set then a CSR is generated
 8682 *
 8683 * returns WOLFSSL_SUCCESS on success
 8684 */
 8685static int loadX509orX509REQFromBio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
 8686    int req)
 8687{
 8688    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 8689    /* Get large buffer to hold cert der */
 8690    int derSz = X509_BUFFER_SZ;
 8691    WC_DECLARE_VAR(der, byte, X509_BUFFER_SZ, 0);
 8692    WOLFSSL_ENTER("wolfSSL_i2d_X509_bio");
 8693
 8694    if (bio == NULL || x509 == NULL) {
 8695        return WOLFSSL_FAILURE;
 8696    }
 8697
 8698#ifdef WOLFSSL_SMALL_STACK
 8699    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 8700    if (!der) {
 8701        WOLFSSL_MSG("malloc failed");
 8702        return WOLFSSL_FAILURE;
 8703    }
 8704#endif
 8705
 8706    if (wolfssl_x509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) {
 8707        goto cleanup;
 8708    }
 8709
 8710    if (wolfSSL_BIO_write(bio, der, derSz) != derSz) {
 8711        goto cleanup;
 8712    }
 8713
 8714    ret = WOLFSSL_SUCCESS;
 8715cleanup:
 8716    WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 8717
 8718    return ret;
 8719}
 8720
 8721/* Converts the X509 to DER format and outputs it into bio.
 8722 *
 8723 * bio  is the structure to hold output DER
 8724 * x509 certificate to create DER from
 8725 *
 8726 * returns WOLFSSL_SUCCESS on success
 8727 */
 8728int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
 8729{
 8730    return loadX509orX509REQFromBio(bio, x509, 0);
 8731}
 8732
 8733#ifdef WOLFSSL_CERT_REQ
 8734int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
 8735{
 8736    return loadX509orX509REQFromBio(bio, x509, 1);
 8737}
 8738#endif /* WOLFSSL_CERT_REQ */
 8739#endif /* !NO_BIO */
 8740#endif /* WOLFSSL_CERT_GEN */
 8741
 8742/* Converts an internal structure to a DER buffer
 8743 *
 8744 * x509 structure to get DER buffer from
 8745 * out  buffer to hold result. If NULL then *out is NULL then a new buffer is
 8746 *      created.
 8747 *
 8748 * returns the size of the DER result on success
 8749 */
 8750int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
 8751{
 8752    const unsigned char* der;
 8753    int derSz = 0;
 8754    int advance = 1;
 8755
 8756    WOLFSSL_ENTER("wolfSSL_i2d_X509");
 8757
 8758    if (x509 == NULL) {
 8759        WOLFSSL_LEAVE("wolfSSL_i2d_X509", BAD_FUNC_ARG);
 8760        return BAD_FUNC_ARG;
 8761    }
 8762
 8763    der = wolfSSL_X509_get_der(x509, &derSz);
 8764    if (der == NULL) {
 8765        WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
 8766        return MEMORY_E;
 8767    }
 8768
 8769    if (out != NULL && *out == NULL) {
 8770        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
 8771        if (*out == NULL) {
 8772            WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
 8773            return MEMORY_E;
 8774        }
 8775        advance = 0;
 8776    }
 8777
 8778    if (out != NULL) {
 8779        XMEMCPY(*out, der, derSz);
 8780        if (advance)
 8781            *out += derSz;
 8782    }
 8783
 8784    WOLFSSL_LEAVE("wolfSSL_i2d_X509", derSz);
 8785    return derSz;
 8786}
 8787
 8788#ifdef WOLFSSL_DUAL_ALG_CERTS
 8789/* Generate a der preTBS from a decoded cert, and write
 8790 * to buffer.
 8791 *
 8792 * @param [in]  cert  The decoded cert to parse.
 8793 * @param [out] der   The der buffer to write in.
 8794 * @param [in]  derSz The der buffer size.
 8795 *
 8796 * @return  preTBS der size on success.
 8797 * */
 8798int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
 8799    int ret = 0;
 8800    WOLFSSL_X509 *x = NULL;
 8801    byte certIsCSR = 0;
 8802
 8803    WOLFSSL_ENTER("wc_GeneratePreTBS");
 8804
 8805    if ((cert == NULL) || (der == NULL) || (derSz <= 0)) {
 8806        return BAD_FUNC_ARG;
 8807    }
 8808
 8809#ifdef WOLFSSL_CERT_REQ
 8810    certIsCSR = cert->isCSR;
 8811#endif
 8812
 8813    x = wolfSSL_X509_new();
 8814    if (x == NULL) {
 8815        ret = MEMORY_E;
 8816    }
 8817    else {
 8818        ret = CopyDecodedToX509(x, cert);
 8819    }
 8820
 8821    if (ret == 0) {
 8822        /* Remove the altsigval extension. */
 8823        XFREE(x->altSigValDer, x->heap, DYNAMIC_TYPE_X509_EXT);
 8824        x->altSigValDer = NULL;
 8825        x->altSigValLen = 0;
 8826        /* Remove sigOID so it won't be encoded. */
 8827        x->sigOID = 0;
 8828        /* We now have a PreTBS. Encode it. */
 8829        ret = wolfssl_x509_make_der(x, certIsCSR, der, &derSz, 0);
 8830        if (ret == WOLFSSL_SUCCESS) {
 8831            ret = derSz;
 8832        }
 8833    }
 8834
 8835    if (x != NULL) {
 8836        wolfSSL_X509_free(x);
 8837        x = NULL;
 8838    }
 8839
 8840    return ret;
 8841}
 8842#endif /* WOLFSSL_DUAL_ALG_CERTS */
 8843
 8844#ifndef NO_BIO
 8845/**
 8846 * Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
 8847 * @param bio  is the structure holding DER
 8848 * @param x509 certificate to create from DER. Can be NULL
 8849 * @param req  1 for a CSR and 0 for a x509 cert
 8850 * @return pointer to WOLFSSL_X509 structure on success and NULL on fail
 8851 */
 8852static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio,
 8853                                            WOLFSSL_X509** x509, int req)
 8854{
 8855    WOLFSSL_X509* localX509 = NULL;
 8856    byte* mem  = NULL;
 8857    int    size;
 8858
 8859    WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
 8860
 8861    if (bio == NULL) {
 8862        WOLFSSL_MSG("Bad Function Argument bio is NULL");
 8863        return NULL;
 8864    }
 8865
 8866    size = wolfSSL_BIO_get_len(bio);
 8867    if (size <= 0) {
 8868        WOLFSSL_MSG("wolfSSL_BIO_get_len error. Possibly no pending data.");
 8869        WOLFSSL_ERROR(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
 8870        return NULL;
 8871    }
 8872
 8873    if (!(mem = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL))) {
 8874        WOLFSSL_MSG("malloc error");
 8875        return NULL;
 8876    }
 8877
 8878    if ((size = wolfSSL_BIO_read(bio, mem, size)) == 0) {
 8879        WOLFSSL_MSG("wolfSSL_BIO_read error");
 8880        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
 8881        return NULL;
 8882    }
 8883
 8884    if (req) {
 8885#ifdef WOLFSSL_CERT_REQ
 8886        localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, size);
 8887#else
 8888        WOLFSSL_MSG("CSR not compiled in");
 8889#endif
 8890    }
 8891    else {
 8892        localX509 = wolfSSL_X509_d2i_ex(NULL, mem, size, bio->heap);
 8893    }
 8894    if (localX509 == NULL) {
 8895        WOLFSSL_MSG("wolfSSL_X509_d2i error");
 8896        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
 8897        return NULL;
 8898    }
 8899
 8900    if (x509 != NULL) {
 8901        *x509 = localX509;
 8902    }
 8903
 8904    XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
 8905    return localX509;
 8906}
 8907
 8908WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
 8909{
 8910    return d2i_X509orX509REQ_bio(bio, x509, 0);
 8911}
 8912
 8913#ifdef WOLFSSL_CERT_REQ
 8914WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
 8915{
 8916    return d2i_X509orX509REQ_bio(bio, x509, 1);
 8917}
 8918#endif
 8919#endif /* !NO_BIO */
 8920
 8921#endif /* OPENSSL_EXTRA */
 8922
 8923#ifdef OPENSSL_EXTRA
 8924/* Use the public key to verify the signature. Note: this only verifies
 8925 * the certificate signature.
 8926 * returns WOLFSSL_SUCCESS on successful signature verification */
 8927static int verifyX509orX509REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
 8928    int req)
 8929{
 8930    int ret;
 8931    const byte* der;
 8932    int derSz = 0;
 8933    int type;
 8934
 8935    (void)req;
 8936
 8937    if (x509 == NULL || pkey == NULL) {
 8938        return WOLFSSL_FATAL_ERROR;
 8939    }
 8940
 8941    der = wolfSSL_X509_get_der(x509, &derSz);
 8942    if (der == NULL) {
 8943        WOLFSSL_MSG("Error getting WOLFSSL_X509 DER");
 8944        return WOLFSSL_FATAL_ERROR;
 8945    }
 8946
 8947    switch (pkey->type) {
 8948        case WC_EVP_PKEY_RSA:
 8949            type = RSAk;
 8950            break;
 8951
 8952        case WC_EVP_PKEY_EC:
 8953            type = ECDSAk;
 8954            break;
 8955
 8956        case WC_EVP_PKEY_DSA:
 8957            type = DSAk;
 8958            break;
 8959
 8960        default:
 8961            WOLFSSL_MSG("Unknown pkey key type");
 8962            return WOLFSSL_FATAL_ERROR;
 8963    }
 8964
 8965#ifdef WOLFSSL_CERT_REQ
 8966    if (req)
 8967        ret = CheckCSRSignaturePubKey(der, (word32)derSz, x509->heap,
 8968                (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
 8969    else
 8970#endif
 8971        ret = CheckCertSignaturePubKey(der, (word32)derSz, x509->heap,
 8972                (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
 8973    if (ret == 0) {
 8974        return WOLFSSL_SUCCESS;
 8975    }
 8976    return WOLFSSL_FAILURE;
 8977}
 8978
 8979int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
 8980{
 8981    return verifyX509orX509REQ(x509, pkey, 0);
 8982}
 8983
 8984#ifdef WOLFSSL_CERT_REQ
 8985int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
 8986{
 8987    return verifyX509orX509REQ(x509, pkey, 1);
 8988}
 8989#endif /* WOLFSSL_CERT_REQ */
 8990
 8991#if !defined(NO_FILESYSTEM)
 8992static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
 8993{
 8994    void *newx509 = NULL;
 8995    byte *fileBuffer = NULL;
 8996    long sz = 0;
 8997
 8998    /* init variable */
 8999    if (x509)
 9000        *x509 = NULL;
 9001
 9002    /* argument check */
 9003    if (file == XBADFILE) {
 9004        return NULL;
 9005    }
 9006
 9007    /* determine file size */
 9008    if (XFSEEK(file, 0, XSEEK_END) != 0) {
 9009        return NULL;
 9010    }
 9011    sz = XFTELL(file);
 9012    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
 9013        return NULL;
 9014    }
 9015
 9016    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
 9017        WOLFSSL_MSG("d2i_X509_fp_ex file size error");
 9018        return NULL;
 9019    }
 9020
 9021    fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
 9022    if (fileBuffer != NULL) {
 9023        if ((long)XFREAD(fileBuffer, 1, (size_t)sz, file) != sz) {
 9024            WOLFSSL_MSG("File read failed");
 9025            goto err_exit;
 9026        }
 9027        if (type == CERT_TYPE) {
 9028            newx509 = (void *)wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
 9029        }
 9030    #ifdef HAVE_CRL
 9031        else if (type == CRL_TYPE) {
 9032            newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
 9033        }
 9034    #endif
 9035    #ifdef WOLFSSL_CERT_REQ
 9036        else if (type == CERTREQ_TYPE) {
 9037             newx509 = (void *)wolfSSL_X509_REQ_d2i(NULL, fileBuffer, (int)sz);
 9038        }
 9039    #endif
 9040    #if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
 9041        else if (type == PKCS12_TYPE) {
 9042            if ((newx509 = wc_PKCS12_new()) == NULL) {
 9043                goto err_exit;
 9044            }
 9045            if (wc_d2i_PKCS12(fileBuffer, (word32)sz,
 9046                                                     (WC_PKCS12*)newx509) < 0) {
 9047                goto err_exit;
 9048            }
 9049        }
 9050    #endif
 9051        else {
 9052            goto err_exit;
 9053        }
 9054        if (newx509 == NULL) {
 9055            WOLFSSL_MSG("X509 failed");
 9056            goto err_exit;
 9057        }
 9058    }
 9059
 9060    if (x509)
 9061        *x509 = newx509;
 9062
 9063    goto _exit;
 9064
 9065err_exit:
 9066#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
 9067    if ((newx509 != NULL) && (type == PKCS12_TYPE)) {
 9068        wc_PKCS12_free((WC_PKCS12*)newx509);
 9069        newx509 = NULL;
 9070    }
 9071#endif
 9072_exit:
 9073    XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
 9074
 9075    return newx509;
 9076}
 9077
 9078#ifdef WOLFSSL_CERT_REQ
 9079WOLFSSL_X509* wolfSSL_d2i_X509_REQ_fp(XFILE fp, WOLFSSL_X509 **req)
 9080{
 9081    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)req,
 9082                                                  CERTREQ_TYPE);
 9083}
 9084#endif /* WOLFSSL_CERT_REQ */
 9085
 9086WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509)
 9087{
 9088    WOLFSSL_ENTER("wolfSSL_d2i_X509_fp");
 9089    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE);
 9090}
 9091
 9092/* load certificate or CRL file, and add it to the STORE           */
 9093/* @param ctx    a pointer to X509_LOOKUP structure                */
 9094/* @param file   file name to load                                 */
 9095/* @param type   WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1     */
 9096/* @return a number of loading CRL or certificate, otherwise zero  */
 9097int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx,
 9098    const char *file, int type)
 9099{
 9100    WOLFSSL_X509 *x509 = NULL;
 9101
 9102    int cnt = 0;
 9103
 9104    WOLFSSL_ENTER("wolfSSL_X509_load_cert_crl_file");
 9105
 9106    /* stanity check */
 9107    if (ctx == NULL || file == NULL) {
 9108        WOLFSSL_MSG("bad arguments");
 9109        return 0;
 9110    }
 9111
 9112    if (type != WOLFSSL_FILETYPE_PEM) {
 9113        x509 = wolfSSL_X509_load_certificate_file(file, type);
 9114        if (x509 != NULL) {
 9115            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509)
 9116                                    == WOLFSSL_SUCCESS) {
 9117                cnt++;
 9118            }
 9119            else {
 9120                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert error");
 9121            }
 9122            wolfSSL_X509_free(x509);
 9123            x509 = NULL;
 9124        }
 9125        else {
 9126            WOLFSSL_MSG("wolfSSL_X509_load_certificate_file error");
 9127        }
 9128
 9129    }
 9130    else {
 9131#if defined(OPENSSL_ALL)
 9132    #if !defined(NO_BIO)
 9133        STACK_OF(WOLFSSL_X509_INFO) *info;
 9134        WOLFSSL_X509_INFO *info_tmp;
 9135        int i;
 9136        int num = 0;
 9137        WOLFSSL_BIO *bio = wolfSSL_BIO_new_file(file, "rb");
 9138        if (!bio) {
 9139            WOLFSSL_MSG("wolfSSL_BIO_new error");
 9140            return cnt;
 9141        }
 9142
 9143        info = wolfSSL_PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
 9144
 9145        wolfSSL_BIO_free(bio);
 9146
 9147        if (!info) {
 9148            WOLFSSL_MSG("wolfSSL_PEM_X509_INFO_read_bio error");
 9149            return cnt;
 9150        }
 9151        num = wolfSSL_sk_X509_INFO_num(info);
 9152        for (i=0; i < num; i++) {
 9153            info_tmp = wolfSSL_sk_X509_INFO_value(info, i);
 9154
 9155            if (info_tmp == NULL)
 9156                continue;
 9157
 9158            if (info_tmp->x509) {
 9159                if (wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509) ==
 9160                    WOLFSSL_SUCCESS) {
 9161                    cnt ++;
 9162                }
 9163                else {
 9164                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
 9165                }
 9166            }
 9167#ifdef HAVE_CRL
 9168            if (info_tmp->crl) {
 9169                if (wolfSSL_X509_STORE_add_crl(ctx->store, info_tmp->crl) ==
 9170                    WOLFSSL_SUCCESS) {
 9171                    cnt ++;
 9172                }
 9173                else {
 9174                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
 9175                }
 9176            }
 9177#endif
 9178        }
 9179        wolfSSL_sk_X509_INFO_pop_free(info, wolfSSL_X509_INFO_free);
 9180    #elif defined(HAVE_CRL)
 9181        /* Only supports one certificate or CRL in the file. */
 9182        WOLFSSL_X509_CRL* crl = NULL;
 9183        XFILE fp = XFOPEN(file, "rb");
 9184        if (fp == XBADFILE) {
 9185            WOLFSSL_MSG("XFOPEN error");
 9186            return cnt;
 9187        }
 9188
 9189        x509 = wolfSSL_PEM_read_X509(fp, NULL, NULL, NULL);
 9190        if (x509 != NULL) {
 9191            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509) ==
 9192                WOLFSSL_SUCCESS) {
 9193                cnt++;
 9194            }
 9195            else {
 9196                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
 9197            }
 9198        }
 9199        else {
 9200            if (XFSEEK(fp, 0, XSEEK_SET) != 0) {
 9201                WOLFSSL_MSG("XFSEEK error");
 9202                return cnt;
 9203            }
 9204            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
 9205            if (crl != NULL) {
 9206                if (wolfSSL_X509_STORE_add_crl(ctx->store, crl) ==
 9207                    WOLFSSL_SUCCESS) {
 9208                    cnt++;
 9209                }
 9210                else {
 9211                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
 9212                }
 9213            }
 9214            else {
 9215                WOLFSSL_MSG("Certificate and CRL not recognized");
 9216                return cnt;
 9217            }
 9218        }
 9219
 9220        wolfSSL_X509_free(x509);
 9221        wolfSSL_X509_CRL_free(crl);
 9222    #endif
 9223#else
 9224    (void)cnt;
 9225#endif /* OPENSSL_ALL && !NO_BIO */
 9226    }
 9227
 9228    WOLFSSL_LEAVE("wolfSSL_X509_load_ceretificate_crl_file", cnt);
 9229    return cnt;
 9230}
 9231#endif /* !NO_FILESYSTEM */
 9232
 9233
 9234#ifdef HAVE_CRL
 9235
 9236#ifndef NO_BIO
 9237WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_bio(WOLFSSL_BIO *bp,
 9238                                                    WOLFSSL_X509_CRL **x)
 9239{
 9240    int derSz;
 9241    byte* der = NULL;
 9242    WOLFSSL_X509_CRL* crl = NULL;
 9243
 9244    if (bp == NULL)
 9245        return NULL;
 9246
 9247    if ((derSz = wolfSSL_BIO_get_len(bp)) > 0) {
 9248        der = (byte*)XMALLOC(derSz, 0, DYNAMIC_TYPE_DER);
 9249        if (der != NULL) {
 9250            if (wolfSSL_BIO_read(bp, der, derSz) == derSz) {
 9251                crl = wolfSSL_d2i_X509_CRL(x, der, derSz);
 9252            }
 9253        }
 9254    }
 9255
 9256    XFREE(der, 0, DYNAMIC_TYPE_DER);
 9257
 9258    return crl;
 9259}
 9260#endif
 9261
 9262#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
 9263WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE fp, WOLFSSL_X509_CRL **crl)
 9264{
 9265    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_fp");
 9266    return (WOLFSSL_X509_CRL *)wolfSSL_d2i_X509_fp_ex(fp, (void **)crl,
 9267        CRL_TYPE);
 9268}
 9269
 9270/* Read CRL file, and add it to store and corresponding cert manager     */
 9271/* @param ctx   a pointer of X509_LOOKUP back to the X509_STORE          */
 9272/* @param file  a file to read                                           */
 9273/* @param type  WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1            */
 9274/* @return WOLFSSL_SUCCESS(1) on successful, otherwise WOLFSSL_FAILURE(0)*/
 9275int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx,
 9276                                             const char *file, int type)
 9277{
 9278#ifndef NO_BIO
 9279    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 9280    int count = 0;
 9281    WOLFSSL_BIO *bio = NULL;
 9282    WOLFSSL_X509_CRL *crl = NULL;
 9283
 9284    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
 9285
 9286    if (ctx == NULL || file == NULL)
 9287        return ret;
 9288
 9289    if ((bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file())) == NULL)
 9290        return ret;
 9291
 9292    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
 9293        wolfSSL_BIO_free(bio);
 9294        return ret;
 9295    }
 9296
 9297    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
 9298        wolfSSL_BIO_free(bio);
 9299        return ret;
 9300    }
 9301
 9302    if (type == WOLFSSL_FILETYPE_PEM) {
 9303        do {
 9304            crl = wolfSSL_PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
 9305            if (crl == NULL) {
 9306                if (count <= 0) {
 9307                    WOLFSSL_MSG("Load crl failed");
 9308                }
 9309                break;
 9310            }
 9311
 9312            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
 9313            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
 9314                WOLFSSL_MSG("Adding crl failed");
 9315                break;
 9316            }
 9317            count++;
 9318            wolfSSL_X509_CRL_free(crl);
 9319            crl = NULL;
 9320        }   while(crl == NULL);
 9321
 9322        ret = count;
 9323    }
 9324    else if (type == WOLFSSL_FILETYPE_ASN1) {
 9325        crl = wolfSSL_d2i_X509_CRL_bio(bio, NULL);
 9326        if (crl == NULL) {
 9327            WOLFSSL_MSG("Load crl failed");
 9328        }
 9329        else {
 9330            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
 9331            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
 9332                WOLFSSL_MSG("Adding crl failed");
 9333            }
 9334            else {
 9335                ret = 1;/* handled a file */
 9336            }
 9337        }
 9338    }
 9339    else {
 9340        WOLFSSL_MSG("Invalid file type");
 9341    }
 9342
 9343    wolfSSL_X509_CRL_free(crl);
 9344    wolfSSL_BIO_free(bio);
 9345
 9346    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
 9347    return ret;
 9348#else
 9349    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
 9350    int count = 0;
 9351    XFILE fp;
 9352    WOLFSSL_X509_CRL *crl = NULL;
 9353
 9354    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
 9355
 9356    if (ctx == NULL || file == NULL)
 9357        return ret;
 9358
 9359    if ((fp = XFOPEN(file, "rb")) == XBADFILE)
 9360        return ret;
 9361
 9362    if (type == WOLFSSL_FILETYPE_PEM) {
 9363        do {
 9364            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
 9365            if (crl == NULL) {
 9366                if (count <= 0) {
 9367                    WOLFSSL_MSG("Load crl failed");
 9368                }
 9369                break;
 9370            }
 9371
 9372            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
 9373            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
 9374                WOLFSSL_MSG("Adding crl failed");
 9375                break;
 9376            }
 9377            count++;
 9378            wolfSSL_X509_CRL_free(crl);
 9379            crl = NULL;
 9380        }
 9381        while(crl == NULL);
 9382
 9383        ret = count;
 9384    }
 9385    else if (type == WOLFSSL_FILETYPE_ASN1) {
 9386        crl = wolfSSL_d2i_X509_CRL_fp(fp, NULL);
 9387        if (crl == NULL) {
 9388            WOLFSSL_MSG("Load crl failed");
 9389        }
 9390        else {
 9391            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
 9392            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
 9393                WOLFSSL_MSG("Adding crl failed");
 9394            }
 9395            else {
 9396                ret = 1;/* handled a file */
 9397            }
 9398        }
 9399    }
 9400    else {
 9401        WOLFSSL_MSG("Invalid file type");
 9402    }
 9403
 9404    wolfSSL_X509_CRL_free(crl);
 9405    XFCLOSE(fp);
 9406
 9407    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
 9408    return ret;
 9409#endif /* !NO_BIO */
 9410}
 9411#endif /* !NO_FILESYSTEM */
 9412
 9413
 9414WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl,
 9415        const unsigned char* in, int len)
 9416{
 9417    WOLFSSL_X509_CRL *newcrl = NULL;
 9418    int ret = WOLFSSL_SUCCESS;
 9419
 9420    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL");
 9421
 9422    if (in == NULL) {
 9423        WOLFSSL_MSG("Bad argument value");
 9424    }
 9425    else {
 9426        newcrl =(WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL,
 9427                DYNAMIC_TYPE_CRL);
 9428        if (newcrl == NULL) {
 9429            WOLFSSL_MSG("New CRL allocation failed");
 9430        }
 9431        else {
 9432            ret = InitCRL(newcrl, NULL);
 9433            if (ret < 0) {
 9434                WOLFSSL_MSG("Init tmp CRL failed");
 9435            }
 9436            else {
 9437                ret = BufferLoadCRL(newcrl, in, len, WOLFSSL_FILETYPE_ASN1,
 9438                    NO_VERIFY);
 9439                if (ret != WOLFSSL_SUCCESS) {
 9440                    WOLFSSL_MSG("Buffer Load CRL failed");
 9441                }
 9442                else {
 9443                    if (crl) {
 9444                        *crl = newcrl;
 9445                    }
 9446                }
 9447            }
 9448        }
 9449    }
 9450
 9451    if ((ret != WOLFSSL_SUCCESS) && (newcrl != NULL)) {
 9452        wolfSSL_X509_CRL_free(newcrl);
 9453        newcrl = NULL;
 9454    }
 9455
 9456    return newcrl;
 9457}
 9458
 9459/* Retrieve issuer X509_NAME from CRL
 9460 * return X509_NAME*  on success
 9461 * return NULL on failure
 9462 */
 9463WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(const WOLFSSL_X509_CRL* crl)
 9464{
 9465    if (crl == NULL || crl->crlList == NULL)
 9466        return NULL;
 9467
 9468    return crl->crlList->issuer;
 9469}
 9470
 9471/* Set issuer name of CRL
 9472 * return WOLFSSL_SUCCESS on success
 9473 * return WOLFSSL_FAILURE on failure
 9474 */
 9475int wolfSSL_X509_CRL_set_issuer_name(WOLFSSL_X509_CRL* crl,
 9476                                     const WOLFSSL_X509_NAME* name)
 9477{
 9478    WOLFSSL_X509_NAME* newName;
 9479
 9480    if (crl == NULL || crl->crlList == NULL || name == NULL)
 9481        return WOLFSSL_FAILURE;
 9482
 9483    newName = wolfSSL_X509_NAME_dup(name);
 9484    if (newName == NULL)
 9485        return WOLFSSL_FAILURE;
 9486
 9487    if (crl->crlList->issuer != NULL) {
 9488        FreeX509Name(crl->crlList->issuer);
 9489        XFREE(crl->crlList->issuer, crl->heap, DYNAMIC_TYPE_X509);
 9490    }
 9491    crl->crlList->issuer = newName;
 9492
 9493    return WOLFSSL_SUCCESS;
 9494}
 9495
 9496/* Retrieve version from CRL
 9497 * return version on success
 9498 * return 0 on failure
 9499 */
 9500int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL* crl)
 9501{
 9502    if (crl == NULL || crl->crlList == NULL)
 9503        return 0;
 9504
 9505    return crl->crlList->version;
 9506}
 9507
 9508/* Set version of CRL
 9509 * Caller passes the RFC 5280 value: 0 for v1, 1 for v2.
 9510 * Internally wolfSSL stores version + 1 (v1 = 1, v2 = 2) to match
 9511 * what ParseCRL produces, so apply the same normalization here.
 9512 * return WOLFSSL_SUCCESS on success
 9513 * return WOLFSSL_FAILURE on failure
 9514 */
 9515int wolfSSL_X509_CRL_set_version(WOLFSSL_X509_CRL* crl, long version)
 9516{
 9517    if (crl == NULL || crl->crlList == NULL)
 9518        return WOLFSSL_FAILURE;
 9519
 9520    /* Only v1 (0) and v2 (1) are defined by RFC 5280. */
 9521    if (version < 0 || version > 1)
 9522        return WOLFSSL_FAILURE;
 9523
 9524    /* Store as version + 1 to match internal convention. */
 9525    crl->crlList->version = (int)version + 1;
 9526    return WOLFSSL_SUCCESS;
 9527}
 9528
 9529/* Retrieve sig OID from CRL
 9530 * return OID on success
 9531 * return 0 on failure
 9532 */
 9533int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl)
 9534{
 9535    if (crl == NULL || crl->crlList == NULL)
 9536        return 0;
 9537
 9538    return crl->crlList->signatureOID;
 9539}
 9540
 9541/* Set signature type of CRL
 9542 * return WOLFSSL_SUCCESS on success
 9543 * return WOLFSSL_FAILURE on failure
 9544 */
 9545int wolfSSL_X509_CRL_set_signature_type(WOLFSSL_X509_CRL* crl,
 9546                                        int signatureType)
 9547{
 9548    if (crl == NULL || crl->crlList == NULL)
 9549        return WOLFSSL_FAILURE;
 9550
 9551    crl->crlList->signatureOID = signatureType;
 9552    return WOLFSSL_SUCCESS;
 9553}
 9554
 9555/* Retrieve sig NID from CRL
 9556 * return NID on success
 9557 * return 0 on failure
 9558 */
 9559int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl)
 9560{
 9561    if (crl == NULL || crl->crlList == NULL)
 9562        return 0;
 9563
 9564    return oid2nid(crl->crlList->signatureOID, oidSigType);
 9565}
 9566
 9567/* Set signature NID of CRL
 9568 * return WOLFSSL_SUCCESS on success
 9569 * return negative value on failure
 9570 */
 9571int wolfSSL_X509_CRL_set_signature_nid(WOLFSSL_X509_CRL* crl, int nid)
 9572{
 9573    int ret = WOLFSSL_SUCCESS;
 9574    word32 oid;
 9575
 9576    if (crl == NULL || crl->crlList == NULL || nid <= 0) {
 9577        ret = BAD_FUNC_ARG;
 9578    }
 9579
 9580    if (ret == WOLFSSL_SUCCESS) {
 9581        oid = nid2oid(nid, oidSigType);
 9582        if (oid == (word32)-1 || oid == (word32)WOLFSSL_FATAL_ERROR) {
 9583            ret = WOLFSSL_FATAL_ERROR;
 9584        }
 9585        else {
 9586            crl->crlList->signatureOID = oid;
 9587        }
 9588    }
 9589
 9590    return ret;
 9591}
 9592
 9593/* Retrieve signature from CRL
 9594 * return WOLFSSL_SUCCESS on success and negative values on failure
 9595 */
 9596int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl,
 9597    unsigned char* buf, int* bufSz)
 9598{
 9599    WOLFSSL_ENTER("wolfSSL_X509_CRL_get_signature");
 9600
 9601    if (crl == NULL || crl->crlList == NULL ||
 9602        crl->crlList->signature == NULL || bufSz == NULL)
 9603        return BAD_FUNC_ARG;
 9604
 9605    if (buf != NULL) {
 9606        if (*bufSz < (int)crl->crlList->signatureSz) {
 9607            WOLFSSL_MSG("Signature buffer too small");
 9608            return BUFFER_E;
 9609        }
 9610        else {
 9611            XMEMCPY(buf, crl->crlList->signature, crl->crlList->signatureSz);
 9612        }
 9613    }
 9614    *bufSz = (int)crl->crlList->signatureSz;
 9615
 9616    return WOLFSSL_SUCCESS;
 9617}
 9618
 9619int wolfSSL_X509_CRL_set_signature(WOLFSSL_X509_CRL* crl,
 9620    unsigned char* buf, int bufSz)
 9621{
 9622    byte* newSig;
 9623
 9624    if (crl == NULL || crl->crlList == NULL || buf == NULL || bufSz <= 0) {
 9625        return BAD_FUNC_ARG;
 9626    }
 9627
 9628    /* Ensure signature buffer is allocated and large enough. */
 9629    if (crl->crlList->signature == NULL) {
 9630        crl->crlList->signature = (byte*)XMALLOC((word32)bufSz, crl->heap,
 9631                                                 DYNAMIC_TYPE_CRL_ENTRY);
 9632        if (crl->crlList->signature == NULL) {
 9633            return MEMORY_E;
 9634        }
 9635        crl->crlList->signatureSz = (word32)bufSz;
 9636    }
 9637    else if ((word32)bufSz > crl->crlList->signatureSz) {
 9638        newSig = (byte*)XMALLOC((word32)bufSz, crl->heap,
 9639                                DYNAMIC_TYPE_CRL_ENTRY);
 9640        if (newSig == NULL) {
 9641            return MEMORY_E;
 9642        }
 9643        XFREE(crl->crlList->signature, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
 9644        crl->crlList->signature = newSig;
 9645        crl->crlList->signatureSz = (word32)bufSz;
 9646    }
 9647    else {
 9648        /* Reuse existing buffer, clear contents in case new signature
 9649         * is smaller. Note that we do not shrink the buffer. */
 9650        XMEMSET(crl->crlList->signature, 0, crl->crlList->signatureSz);
 9651    }
 9652
 9653    XMEMCPY(crl->crlList->signature, buf, bufSz);
 9654    crl->crlList->signatureSz = (word32)bufSz;
 9655    return WOLFSSL_SUCCESS;
 9656}
 9657
 9658/* Retrieve serial number from RevokedCert
 9659 * return WOLFSSL_SUCCESS on success and negative values on failure
 9660 */
 9661int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev,
 9662    byte* in, int* inOutSz)
 9663{
 9664    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_serial_number");
 9665    if (rev == NULL || inOutSz == NULL) {
 9666        return BAD_FUNC_ARG;
 9667    }
 9668
 9669    if (in != NULL) {
 9670        if (*inOutSz < rev->serialSz) {
 9671            WOLFSSL_MSG("Serial buffer too small");
 9672            return BUFFER_E;
 9673        }
 9674        XMEMCPY(in, rev->serialNumber, rev->serialSz);
 9675    }
 9676    *inOutSz = rev->serialSz;
 9677
 9678    return WOLFSSL_SUCCESS;
 9679}
 9680
 9681const WOLFSSL_ASN1_INTEGER* wolfSSL_X509_REVOKED_get0_serial_number(const
 9682                                                      WOLFSSL_X509_REVOKED *rev)
 9683{
 9684    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get0_serial_number");
 9685
 9686    if (rev != NULL) {
 9687        return rev->serialNumber;
 9688    }
 9689    else
 9690        return NULL;
 9691}
 9692
 9693const WOLFSSL_ASN1_TIME* wolfSSL_X509_REVOKED_get0_revocation_date(const
 9694                                                      WOLFSSL_X509_REVOKED *rev)
 9695{
 9696    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get0_revocation_date");
 9697
 9698    if (rev != NULL) {
 9699        return rev->revocationDate;
 9700    }
 9701    return NULL;
 9702}
 9703
 9704
 9705#ifndef NO_BIO
 9706/* print serial number out
 9707*  return WOLFSSL_SUCCESS on success
 9708*/
 9709static int X509RevokedPrintSerial(WOLFSSL_BIO* bio, RevokedCert* rev,
 9710    int indent)
 9711{
 9712    unsigned char serial[32];
 9713    int  sz = sizeof(serial);
 9714
 9715    if (indent < 0) indent = 0;
 9716    if (indent > MAX_INDENT) indent = MAX_INDENT;
 9717
 9718    XMEMSET(serial, 0, sz);
 9719    if (wolfSSL_X509_REVOKED_get_serial_number(rev, serial, &sz)
 9720            == WOLFSSL_SUCCESS) {
 9721        X509PrintSerial_ex(bio, serial, sz, 0, indent);
 9722    }
 9723    return WOLFSSL_SUCCESS;
 9724}
 9725
 9726
 9727/* print out the signature in human readable format for use with
 9728* wolfSSL_X509_CRL_print()
 9729 * return WOLFSSL_SUCCESS on success
 9730 */
 9731static int X509CRLPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
 9732        int algOnly, int indent)
 9733{
 9734    int sigSz = 0;
 9735
 9736    if (wolfSSL_X509_CRL_get_signature(crl, NULL, &sigSz) <= 0) {
 9737        return WOLFSSL_FAILURE;
 9738    }
 9739
 9740    if (sigSz > 0) {
 9741        unsigned char* sig;
 9742        int sigNid = wolfSSL_X509_CRL_get_signature_nid(crl);
 9743
 9744        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 9745        if (sig == NULL) {
 9746            return WOLFSSL_FAILURE;
 9747        }
 9748
 9749        if (wolfSSL_X509_CRL_get_signature(crl, sig, &sigSz) <= 0) {
 9750            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 9751            return WOLFSSL_FAILURE;
 9752        }
 9753
 9754        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
 9755                != WOLFSSL_SUCCESS) {
 9756            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 9757            return WOLFSSL_FAILURE;
 9758        }
 9759
 9760        XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 9761
 9762    }
 9763
 9764    return WOLFSSL_SUCCESS;
 9765}
 9766#endif /* !NO_BIO */
 9767
 9768#if !defined(NO_BIO) && defined(XSNPRINTF)
 9769/* print out the extensions in human readable format for use with
 9770 * wolfSSL_X509_CRL_print()
 9771 * return WOLFSSL_SUCCESS on success
 9772 */
 9773static int X509CRLPrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
 9774        int indent)
 9775{
 9776    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
 9777    int  ret = 0;
 9778
 9779    if (indent < 0) indent = 0;
 9780    if (indent > MAX_INDENT) indent = MAX_INDENT;
 9781
 9782    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
 9783                "CRL extensions:") >= MAX_WIDTH) {
 9784        ret = WOLFSSL_FAILURE;
 9785    }
 9786
 9787    if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 9788        ret = WOLFSSL_FAILURE;
 9789    }
 9790
 9791    if (ret == 0 && crl->crlList->crlNumberSet) {
 9792        char dec_string[49]; /* 20 octets can express numbers up to approx
 9793                                49 decimal digits */
 9794        int freeMp = 0;
 9795    #ifdef WOLFSSL_SMALL_STACK
 9796        mp_int* dec_num = (mp_int*)XMALLOC(sizeof(*dec_num), NULL,
 9797                            DYNAMIC_TYPE_BIGINT);
 9798        if (dec_num == NULL) {
 9799            ret = MEMORY_E;
 9800        }
 9801    #else
 9802        mp_int dec_num[1];
 9803    #endif
 9804
 9805        if (ret == 0 && (mp_init(dec_num) != MP_OKAY)) {
 9806             ret = MP_INIT_E;
 9807        }
 9808        else if (ret == 0) {
 9809            freeMp = 1;
 9810        }
 9811
 9812        if (ret == 0 && mp_read_radix(dec_num, (char *)crl->crlList->crlNumber,
 9813                    MP_RADIX_HEX) != MP_OKAY) {
 9814            ret = WOLFSSL_FAILURE;
 9815        }
 9816
 9817        if (ret == 0 && mp_toradix(dec_num, dec_string, MP_RADIX_DEC)
 9818                    != MP_OKAY) {
 9819            ret = WOLFSSL_FAILURE;
 9820        }
 9821
 9822        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 4, "",
 9823                    "X509v3 CRL Number:") >= MAX_WIDTH) {
 9824            ret = WOLFSSL_FAILURE;
 9825        }
 9826
 9827        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 9828            ret = WOLFSSL_FAILURE;
 9829        }
 9830
 9831        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 8, "",
 9832            dec_string) >= MAX_WIDTH) {
 9833            ret = WOLFSSL_FAILURE;
 9834        }
 9835
 9836        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 9837            ret = WOLFSSL_FAILURE;
 9838        }
 9839
 9840        XMEMSET(tmp, 0, sizeof(tmp));
 9841
 9842        if (freeMp) {
 9843            mp_free(dec_num);
 9844        }
 9845
 9846        WC_FREE_VAR_EX(dec_num, NULL, DYNAMIC_TYPE_BIGINT);
 9847    }
 9848
 9849#if !defined(NO_SKID)
 9850    if (ret == 0 && crl->crlList->extAuthKeyIdSet &&
 9851            crl->crlList->extAuthKeyId[0] != 0) {
 9852        word32 i;
 9853        char val[5];
 9854        int valSz = 5;
 9855
 9856        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 4, "",
 9857                    "X509v3 Authority Key Identifier:") >= MAX_WIDTH) {
 9858            ret = WOLFSSL_FAILURE;
 9859        }
 9860
 9861        if (ret == 0) {
 9862            XSTRNCAT(tmp, "\n", MAX_WIDTH - XSTRLEN(tmp) - 1);
 9863        }
 9864
 9865        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 9866            ret = WOLFSSL_FAILURE;
 9867        }
 9868        XMEMSET(tmp, 0, MAX_WIDTH);
 9869
 9870        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH - 1, "%*s%s",
 9871                    indent + 8, "", "keyid") >= MAX_WIDTH) {
 9872            ret = WOLFSSL_FAILURE;
 9873        }
 9874
 9875
 9876        for (i = 0; i < XSTRLEN((char*)crl->crlList->extAuthKeyId); i++) {
 9877            /* check if buffer is almost full */
 9878            if (ret == 0 && XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
 9879                if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 9880                    ret = WOLFSSL_FAILURE;
 9881                }
 9882                tmp[0] = '\0';
 9883            }
 9884            if (ret == 0 && XSNPRINTF(val, (size_t)valSz, ":%02X",
 9885                    crl->crlList->extAuthKeyId[i]) >= valSz) {
 9886                WOLFSSL_MSG("buffer overrun");
 9887                ret = WOLFSSL_FAILURE;
 9888            }
 9889            if (ret == 0) {
 9890                XSTRNCAT(tmp, val, valSz);
 9891            }
 9892        }
 9893        if (ret == 0) {
 9894            XSTRNCAT(tmp, "\n", XSTRLEN("\n") + 1);
 9895        }
 9896        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 9897            ret = WOLFSSL_FAILURE;
 9898        }
 9899    }
 9900#endif
 9901
 9902    if (ret == 0) {
 9903        ret = WOLFSSL_SUCCESS;
 9904    }
 9905
 9906    return ret;
 9907}
 9908
 9909/* iterate through a CRL's Revoked Certs and print out in human
 9910 * readable format for use with wolfSSL_X509_CRL_print()
 9911 * return WOLFSSL_SUCCESS on success
 9912 */
 9913static int X509CRLPrintRevoked(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
 9914        int indent)
 9915{
 9916    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
 9917    int i;
 9918
 9919    if (crl->crlList->totalCerts > 0) {
 9920        RevokedCert* revoked = crl->crlList->certs;
 9921
 9922        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
 9923                    "Revoked Certificates:") >= MAX_WIDTH) {
 9924            return WOLFSSL_FAILURE;
 9925        }
 9926
 9927        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 9928            return WOLFSSL_FAILURE;
 9929        }
 9930        XMEMSET(tmp, 0, MAX_WIDTH);
 9931
 9932        for (i = 0; i < crl->crlList->totalCerts; i++) {
 9933            if (revoked->serialSz > 0) {
 9934                if (X509RevokedPrintSerial(bio, revoked, indent + 4)
 9935                        != WOLFSSL_SUCCESS) {
 9936                    return WOLFSSL_FAILURE;
 9937                }
 9938            }
 9939        #ifndef NO_ASN_TIME
 9940             if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 8, "",
 9941                         "Revocation Date: ") >= MAX_WIDTH) {
 9942                return WOLFSSL_FAILURE;
 9943            }
 9944
 9945            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 9946                return WOLFSSL_FAILURE;
 9947            }
 9948
 9949            if (revoked->revDate[0] != 0) {
 9950                if (GetTimeString(revoked->revDate, ASN_UTC_TIME,
 9951                    tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
 9952                    if (GetTimeString(revoked->revDate, ASN_GENERALIZED_TIME,
 9953                    tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
 9954                        WOLFSSL_MSG("Error getting revocation date");
 9955                        return WOLFSSL_FAILURE;
 9956                    }
 9957                }
 9958            }
 9959            else {
 9960                XSTRNCPY(tmp, "Not Set", MAX_WIDTH-1);
 9961            }
 9962            tmp[MAX_WIDTH - 1] = '\0'; /* make sure null terminated */
 9963            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
 9964                return WOLFSSL_FAILURE;
 9965            }
 9966
 9967            if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
 9968                return WOLFSSL_FAILURE;
 9969            }
 9970        #endif
 9971            revoked = revoked->next;
 9972        }
 9973    }
 9974    else {
 9975        if (wolfSSL_BIO_write(bio, "No Revoked Certificates.\n",
 9976                       (int)XSTRLEN("No Revoked Certificates.\n")) <= 0) {
 9977            return WOLFSSL_FAILURE;
 9978        }
 9979    }
 9980
 9981    return WOLFSSL_SUCCESS;
 9982}
 9983
 9984#ifndef NO_ASN_TIME
 9985/* print out the last/next update times in human readable
 9986 * format for use with wolfSSL_X509_CRL_print()
 9987 * return WOLFSSL_SUCCESS on success
 9988 */
 9989static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
 9990        int indent)
 9991{
 9992    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
 9993
 9994    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
 9995                "Last Update: ") >= MAX_WIDTH) {
 9996        return WOLFSSL_FAILURE;
 9997    }
 9998
 9999    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10000        return WOLFSSL_FAILURE;
10001    }
10002
10003    if (crl->crlList->lastDate[0] != 0) {
10004        if (GetTimeString(crl->crlList->lastDate, crl->crlList->lastDateFormat,
10005            tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10006            WOLFSSL_MSG("Error getting last update date");
10007            return WOLFSSL_FAILURE;
10008        }
10009    }
10010    else {
10011        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
10012    }
10013    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
10014    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10015        return WOLFSSL_FAILURE;
10016    }
10017
10018    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
10019        return WOLFSSL_FAILURE;
10020    }
10021
10022    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
10023                "Next Update: ") >= MAX_WIDTH) {
10024        return WOLFSSL_FAILURE;
10025    }
10026
10027    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10028        return WOLFSSL_FAILURE;
10029    }
10030
10031    if (crl->crlList->nextDate[0] != 0) {
10032        if (GetTimeString(crl->crlList->nextDate, crl->crlList->nextDateFormat,
10033            tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10034            WOLFSSL_MSG("Error getting next update date");
10035            return WOLFSSL_FAILURE;
10036        }
10037    }
10038    else {
10039        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
10040    }
10041    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
10042    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10043        return WOLFSSL_FAILURE;
10044    }
10045
10046    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
10047        return WOLFSSL_FAILURE;
10048    }
10049
10050    return WOLFSSL_SUCCESS;
10051}
10052#endif
10053
10054/* Writes the human readable form of x509 to bio.
10055 *
10056 * bio  WOLFSSL_BIO to write to.
10057 * crl Certificate revocation list to write.
10058 *
10059 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
10060 */
10061int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl)
10062{
10063    char issuType[] = "Issuer: ";
10064
10065    if (bio == NULL || crl == NULL || crl->crlList == NULL) {
10066        return WOLFSSL_FAILURE;
10067    }
10068
10069    if (wolfSSL_BIO_write(bio, "Certificate Revocation List (CRL):\n",
10070                  (int)XSTRLEN("Certificate Revocation List (CRL):\n")) <= 0) {
10071            return WOLFSSL_FAILURE;
10072    }
10073
10074    /* print version */
10075    if (X509PrintVersion(bio, wolfSSL_X509_CRL_version(crl), 8)
10076            != WOLFSSL_SUCCESS) {
10077        return WOLFSSL_FAILURE;
10078    }
10079
10080    /* print signature algo */
10081    if (X509CRLPrintSignature(bio, crl, 1, 8) != WOLFSSL_SUCCESS) {
10082        return WOLFSSL_FAILURE;
10083    }
10084
10085    /* print issuer name */
10086    if (X509PrintName(bio, wolfSSL_X509_CRL_get_issuer_name(crl), issuType, 8)
10087            != WOLFSSL_SUCCESS) {
10088        return WOLFSSL_FAILURE;
10089    }
10090
10091#ifndef NO_ASN_TIME
10092    /* print last and next update times */
10093    if (X509CRLPrintDates(bio, crl, 8) != WOLFSSL_SUCCESS) {
10094        return WOLFSSL_FAILURE;
10095    }
10096#endif
10097
10098    /* print CRL extensions */
10099    if (X509CRLPrintExtensions(bio, crl, 8) != WOLFSSL_SUCCESS) {
10100        return WOLFSSL_FAILURE;
10101    }
10102
10103    /* print CRL Revoked Certs */
10104    if (X509CRLPrintRevoked(bio, crl, 0) != WOLFSSL_SUCCESS) {
10105        return WOLFSSL_FAILURE;
10106    }
10107
10108    if (X509CRLPrintSignature(bio, crl, 0, 4) != WOLFSSL_SUCCESS) {
10109        return WOLFSSL_FAILURE;
10110    }
10111
10112    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
10113        return WOLFSSL_FAILURE;
10114    }
10115
10116    return WOLFSSL_SUCCESS;
10117}
10118#endif /* !NO_BIO && XSNPRINTF */
10119#endif /* HAVE_CRL */
10120#endif /* OPENSSL_EXTRA */
10121
10122#if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
10123void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl)
10124{
10125    WOLFSSL_ENTER("wolfSSL_X509_CRL_free");
10126
10127    if (crl)
10128        FreeCRL(crl, 1);
10129}
10130#endif /* HAVE_CRL && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
10131
10132#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
10133WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
10134{
10135    if ((crl != NULL) && (crl->crlList != NULL) &&
10136        (crl->crlList->lastDateAsn1.data[0] != 0)) {
10137        return &crl->crlList->lastDateAsn1;
10138    }
10139    return NULL;
10140}
10141
10142int wolfSSL_X509_CRL_set_lastUpdate(WOLFSSL_X509_CRL* crl,
10143                                    const WOLFSSL_ASN1_TIME* time)
10144{
10145    if (crl != NULL && crl->crlList != NULL && time != NULL) {
10146        crl->crlList->lastDateAsn1 = *time;
10147        return WOLFSSL_SUCCESS;
10148    }
10149    return WOLFSSL_FAILURE;
10150}
10151
10152WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
10153{
10154    if ((crl != NULL) && (crl->crlList != NULL) &&
10155        (crl->crlList->nextDateAsn1.data[0] != 0)) {
10156        return &crl->crlList->nextDateAsn1;
10157    }
10158    return NULL;
10159}
10160
10161int wolfSSL_X509_CRL_set_nextUpdate(WOLFSSL_X509_CRL* crl,
10162                                    const WOLFSSL_ASN1_TIME* time)
10163{
10164    if (crl != NULL && crl->crlList != NULL && time != NULL) {
10165        crl->crlList->nextDateAsn1 = *time;
10166        return WOLFSSL_SUCCESS;
10167    }
10168    return WOLFSSL_FAILURE;
10169}
10170
10171#ifndef NO_WOLFSSL_STUB
10172int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
10173{
10174    (void)crl;
10175    (void)key;
10176    WOLFSSL_STUB("X509_CRL_verify");
10177    return 0;
10178}
10179#endif
10180
10181/* Encode CRL to DER format in memory.
10182 *
10183 * If *out is NULL, allocates memory and returns it via *out.
10184 * If *out is not NULL, writes DER data starting at *out.
10185 *
10186 * @param crl  CRL to encode
10187 * @param out  Pointer to output buffer pointer
10188 * @return     Size of DER encoding on success, WOLFSSL_FAILURE on failure
10189 */
10190int wolfSSL_i2d_X509_CRL(WOLFSSL_X509_CRL* crl, unsigned char** out)
10191{
10192    int ret;
10193    long derSz = 0;
10194    byte* der = NULL;
10195    int alloced = 0;
10196
10197    WOLFSSL_ENTER("wolfSSL_i2d_X509_CRL");
10198
10199    if (crl == NULL) {
10200        return BAD_FUNC_ARG;
10201    }
10202
10203    /* Get required size */
10204    ret = BufferStoreCRL(crl, NULL, &derSz, WOLFSSL_FILETYPE_ASN1);
10205    if (ret != WOLFSSL_SUCCESS || derSz <= 0) {
10206        WOLFSSL_MSG("BufferStoreCRL failed to get size");
10207        return WOLFSSL_FAILURE;
10208    }
10209
10210    if (out == NULL) {
10211        /* Just return size */
10212        return (int)derSz;
10213    }
10214
10215    if (*out == NULL) {
10216        /* Allocate output buffer */
10217        der = (byte*)XMALLOC((size_t)derSz, NULL, DYNAMIC_TYPE_OPENSSL);
10218        if (der == NULL) {
10219            WOLFSSL_MSG("Memory allocation failed");
10220            return MEMORY_E;
10221        }
10222        alloced = 1;
10223    }
10224    else {
10225        der = *out;
10226    }
10227
10228    /* Encode CRL to DER */
10229    ret = BufferStoreCRL(crl, der, &derSz, WOLFSSL_FILETYPE_ASN1);
10230    if (ret != WOLFSSL_SUCCESS) {
10231        WOLFSSL_MSG("BufferStoreCRL failed to encode");
10232        if (alloced) {
10233            XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
10234        }
10235        return WOLFSSL_FAILURE;
10236    }
10237
10238    if (alloced) {
10239        *out = der;
10240    }
10241    else {
10242        *out += derSz;
10243    }
10244
10245    return (int)derSz;
10246}
10247#endif /* HAVE_CRL && OPENSSL_EXTRA */
10248
10249#if defined(WOLFSSL_CERT_EXT) && \
10250    (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
10251/* Set CRL Distribution Points from pre-encoded DER.
10252 *
10253 * x509  - Certificate to modify
10254 * der   - Pre-encoded CRLDistributionPoints DER
10255 * derSz - Size of DER in bytes
10256 *
10257 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
10258 */
10259int wolfSSL_X509_CRL_set_dist_points(WOLFSSL_X509* x509,
10260    const unsigned char* der, int derSz)
10261{
10262    WOLFSSL_ENTER("wolfSSL_X509_CRL_set_dist_points");
10263
10264    if (x509 == NULL || der == NULL || derSz <= 0) {
10265        return WOLFSSL_FAILURE;
10266    }
10267
10268    if (x509->rawCRLInfo != NULL) {
10269        XFREE(x509->rawCRLInfo, x509->heap, DYNAMIC_TYPE_X509_EXT);
10270    }
10271    x509->rawCRLInfo = (byte*)XMALLOC((word32)derSz, x509->heap,
10272                                       DYNAMIC_TYPE_X509_EXT);
10273    if (x509->rawCRLInfo == NULL) {
10274        return WOLFSSL_FAILURE;
10275    }
10276
10277    XMEMCPY(x509->rawCRLInfo, der, (word32)derSz);
10278    x509->rawCRLInfoSz = derSz;
10279    x509->CRLdistSet = 1;
10280
10281    return WOLFSSL_SUCCESS;
10282}
10283
10284/* Add CRL Distribution Point URI.
10285 * Encodes URI into proper CRLDistributionPoints DER format.
10286 *
10287 * x509     - Certificate to modify
10288 * uri      - URI string (e.g., "http://crl.example.com/ca.crl")
10289 * critical - Whether extension is critical
10290 *
10291 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
10292 */
10293int wolfSSL_X509_CRL_add_dist_point(WOLFSSL_X509* x509,
10294    const char* uri, int critical)
10295{
10296    word32 uriLen;
10297    byte* derBuf = NULL;
10298    word32 derSz;
10299    word32 idx;
10300    word32 uriTagLen;    /* [6] tag + length + URI */
10301    word32 genNamesLen;  /* [0] IMPLICIT GeneralNames wrapper */
10302    word32 distPtNmLen;  /* [0] EXPLICIT distributionPoint wrapper */
10303    word32 distPtSeqLen; /* SEQUENCE for DistributionPoint */
10304    word32 outerSeqLen;  /* SEQUENCE for CRLDistributionPoints */
10305    int ret = WOLFSSL_SUCCESS;
10306
10307    WOLFSSL_ENTER("wolfSSL_X509_CRL_add_dist_point");
10308
10309    if (x509 == NULL || uri == NULL) {
10310        return WOLFSSL_FAILURE;
10311    }
10312
10313    uriLen = (word32)XSTRLEN(uri);
10314    if (uriLen == 0) {
10315        WOLFSSL_MSG("URI empty");
10316        return WOLFSSL_FAILURE;
10317    }
10318
10319    /*
10320     * Encode CRL Distribution Points in DER format:
10321     * CRLDistributionPoints ::= SEQUENCE OF DistributionPoint
10322     * DistributionPoint ::= SEQUENCE {
10323     *     distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL
10324     * }
10325     * DistributionPointName ::= CHOICE {
10326     *     fullName [0] IMPLICIT GeneralNames
10327     * }
10328     * GeneralNames ::= SEQUENCE OF GeneralName
10329     * GeneralName ::= [6] IMPLICIT IA5String (uniformResourceIdentifier)
10330     */
10331
10332    /* Calculate sizes from innermost to outermost */
10333    /* [6] tag (1 byte) + length encoding + URI data */
10334    uriTagLen = ASN_TAG_SZ + SetLength(uriLen, NULL) + uriLen;
10335    /* [0] CONSTRUCTED tag (1 byte) + length encoding + uriTagLen */
10336    genNamesLen = ASN_TAG_SZ + SetLength(uriTagLen, NULL) + uriTagLen;
10337    /* [0] CONSTRUCTED tag (1 byte) + length encoding + genNamesLen */
10338    distPtNmLen = ASN_TAG_SZ + SetLength(genNamesLen, NULL) + genNamesLen;
10339    /* SEQUENCE header + distPtNmLen */
10340    distPtSeqLen = SetSequence(distPtNmLen, NULL) + distPtNmLen;
10341    /* Outer SEQUENCE header + distPtSeqLen */
10342    outerSeqLen = SetSequence(distPtSeqLen, NULL) + distPtSeqLen;
10343
10344    derSz = outerSeqLen;
10345
10346    /* Allocate buffer for DER encoding */
10347    derBuf = (byte*)XMALLOC(derSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
10348    if (derBuf == NULL) {
10349        return WOLFSSL_FAILURE;
10350    }
10351
10352    /* Build forward using SetSequence/SetHeader/SetLength */
10353    idx = 0;
10354
10355    /* SEQUENCE for CRLDistributionPoints (outer) */
10356    idx += SetSequence(distPtSeqLen, derBuf + idx);
10357
10358    /* SEQUENCE for DistributionPoint */
10359    idx += SetSequence(distPtNmLen, derBuf + idx);
10360
10361    /* [0] EXPLICIT wrapper for distributionPoint */
10362    derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
10363    idx += SetLength(genNamesLen, derBuf + idx);
10364
10365    /* [0] IMPLICIT wrapper for GeneralNames (constructed) */
10366    derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
10367    idx += SetLength(uriTagLen, derBuf + idx);
10368
10369    /* [6] IMPLICIT IA5String tag for URI (context-specific, primitive) */
10370    derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | 6); /* [6] tag */
10371    idx += SetLength(uriLen, derBuf + idx);
10372
10373    /* Copy URI string */
10374    XMEMCPY(derBuf + idx, uri, uriLen);
10375    idx += uriLen;
10376
10377    /* Store the encoded CRL info in x509 */
10378    {
10379        ret = wolfSSL_X509_CRL_set_dist_points(x509, derBuf, (int)idx);
10380        if (ret == WOLFSSL_SUCCESS && critical) {
10381            x509->CRLdistCrit = 1;
10382        }
10383    }
10384
10385    XFREE(derBuf, x509->heap, DYNAMIC_TYPE_X509_EXT);
10386
10387    return ret;
10388}
10389#endif /* WOLFSSL_CERT_EXT && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
10390
10391#ifdef OPENSSL_EXTRA
10392
10393
10394WOLFSSL_X509_VERIFY_PARAM* wolfSSL_X509_VERIFY_PARAM_new(void)
10395{
10396    WOLFSSL_X509_VERIFY_PARAM *param = NULL;
10397    param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
10398            sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL);
10399    if (param != NULL)
10400        XMEMSET(param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM ));
10401
10402    return(param);
10403}
10404
10405
10406void wolfSSL_X509_VERIFY_PARAM_free(WOLFSSL_X509_VERIFY_PARAM *param)
10407{
10408    XFREE(param, NULL, DYNAMIC_TYPE_OPENSSL);
10409}
10410
10411
10412/* Sets flags by OR'ing with existing value. */
10413int wolfSSL_X509_VERIFY_PARAM_set_flags(WOLFSSL_X509_VERIFY_PARAM *param,
10414        unsigned long flags)
10415{
10416    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10417
10418    if (param != NULL) {
10419        param->flags |= flags;
10420        ret = WOLFSSL_SUCCESS;
10421    }
10422
10423    return ret;
10424}
10425
10426
10427int wolfSSL_X509_VERIFY_PARAM_get_flags(WOLFSSL_X509_VERIFY_PARAM *param)
10428{
10429    int ret = 0;
10430
10431    if (param != NULL) {
10432        ret = (int)param->flags;
10433    }
10434
10435    return ret;
10436}
10437
10438
10439int wolfSSL_X509_VERIFY_PARAM_clear_flags(WOLFSSL_X509_VERIFY_PARAM *param,
10440        unsigned long flags)
10441{
10442    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10443
10444    if (param != NULL) {
10445        param->flags &= ~flags;
10446        ret = WOLFSSL_SUCCESS;
10447    }
10448
10449    return ret;
10450}
10451
10452/* note WOLFSSL_X509_VERIFY_PARAM does not record purpose, trust, depth, or
10453 * auth_level.
10454 */
10455static const WOLFSSL_X509_VERIFY_PARAM x509_verify_param_builtins[] = {
10456    {
10457     "ssl_client",              /* name */
10458     0,                         /* check_time */
10459     0,                         /* inherit_flags */
10460     0,                         /* flags */
10461     "",                        /* hostname */
10462     0,                         /* hostFlags */
10463     ""                         /* ipasc */
10464    },
10465    {
10466     "ssl_server",              /* name */
10467     0,                         /* check_time */
10468     0,                         /* inherit_flags */
10469     0,                         /* flags */
10470     "",                        /* hostname */
10471     0,                         /* hostFlags */
10472     ""                         /* ipasc */
10473    }
10474};
10475
10476const WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_VERIFY_PARAM_lookup(
10477    const char *name)
10478{
10479    const WOLFSSL_X509_VERIFY_PARAM *param = &x509_verify_param_builtins[0],
10480        *param_end = &x509_verify_param_builtins[
10481                                         XELEM_CNT(x509_verify_param_builtins)];
10482
10483    if (name == NULL) {
10484        return NULL;
10485    }
10486    while (param < param_end) {
10487        if (XSTRCMP(name, param->name) == 0)
10488            return param;
10489        ++param;
10490    }
10491    return NULL;
10492}
10493
10494/* inherits properties of param "to" to param "from"
10495*
10496* WOLFSSL_VPARAM_DEFAULT          any values in "src" is copied
10497*                                 if "src" value is new for "to".
10498* WOLFSSL_VPARAM_OVERWRITE        all values of "form" are copied to "to"
10499* WOLFSSL_VPARAM_RESET_FLAGS      the flag values are copied, not Ored
10500* WOLFSSL_VPARAM_LOCKED           don't copy any values
10501* WOLFSSL_VPARAM_ONCE             the current inherit_flags is zerroed
10502*/
10503int wolfSSL_X509_VERIFY_PARAM_inherit(WOLFSSL_X509_VERIFY_PARAM *to,
10504                                         const WOLFSSL_X509_VERIFY_PARAM *from)
10505{
10506    int ret = WOLFSSL_SUCCESS;
10507    int isOverWrite = 0;
10508    int isDefault = 0;
10509    unsigned int flags;
10510
10511    /* sanity check */
10512    if (!to || !from) {
10513        /* be compatible to openssl return value */
10514        return WOLFSSL_SUCCESS;
10515    }
10516    flags = to->inherit_flags | from->inherit_flags;
10517
10518    if (flags & WOLFSSL_VPARAM_LOCKED) {
10519        return WOLFSSL_SUCCESS;
10520    }
10521
10522    if (flags & WOLFSSL_VPARAM_ONCE) {
10523        to->inherit_flags = 0;
10524    }
10525
10526    isOverWrite = (flags & WOLFSSL_VPARAM_OVERWRITE);
10527    isDefault = (flags & WOLFSSL_VPARAM_DEFAULT);
10528
10529    /* copy check_time if check time is not set */
10530    if ((to->flags & WOLFSSL_USE_CHECK_TIME) == 0 || isOverWrite) {
10531           to->check_time = from->check_time;
10532           to->flags &= ~WOLFSSL_USE_CHECK_TIME;
10533    }
10534    /* host name */
10535    if (isOverWrite ||
10536        (from->hostName[0] != 0 && (to->hostName[0] == 0 || isDefault))) {
10537            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_host(to, from->hostName,
10538                (unsigned int)XSTRLEN(from->hostName))))
10539                return ret;
10540        to->hostFlags = from->hostFlags;
10541    }
10542    /* ip ascii */
10543    if (isOverWrite ||
10544        (from->ipasc[0] != 0 && (to->ipasc[0] == 0 || isDefault))) {
10545
10546            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(to, from->ipasc)))
10547                return ret;
10548    }
10549
10550    if (flags & WOLFSSL_VPARAM_RESET_FLAGS)
10551        to->flags = 0;
10552
10553    to->flags |= from->flags;
10554
10555    return ret;
10556}
10557
10558/******************************************************************************
10559* wolfSSL_X509_VERIFY_PARAM_set1_host - sets the DNS hostname to name
10560* hostnames is cleared if name is NULL or empty.
10561*
10562* RETURNS:
10563*
10564*/
10565int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam,
10566                                         const char* name,
10567                                         unsigned int nameSz)
10568{
10569    WOLFSSL_ENTER("wolfSSL_X509_VERIFY_PARAM_set1_host");
10570
10571    if (pParam == NULL)
10572        return WOLFSSL_FAILURE;
10573
10574    /* If name is NULL, clear hostname. */
10575    if (name == NULL) {
10576        XMEMSET(pParam->hostName, 0, WOLFSSL_HOST_NAME_MAX);
10577        return WOLFSSL_SUCCESS;
10578    }
10579
10580    /* If name is NULL-terminated, namelen can be set to zero. */
10581    if (nameSz == 0) {
10582        nameSz = (unsigned int)XSTRLEN(name);
10583    }
10584
10585    if (nameSz > 0 && name[nameSz - 1] == '\0')
10586        nameSz--;
10587
10588    if (nameSz > WOLFSSL_HOST_NAME_MAX-1) {
10589        WOLFSSL_MSG("Truncating name");
10590        nameSz = WOLFSSL_HOST_NAME_MAX-1;
10591    }
10592
10593    if (nameSz > 0) {
10594        XMEMCPY(pParam->hostName, name, nameSz);
10595        XMEMSET(pParam->hostName + nameSz, 0,
10596                WOLFSSL_HOST_NAME_MAX - nameSz);
10597    }
10598
10599    pParam->hostName[nameSz] = '\0';
10600
10601    return WOLFSSL_SUCCESS;
10602}
10603
10604/* Set VERIFY PARAM from "from" pointer to "to" pointer */
10605int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM *to,
10606                                   const WOLFSSL_X509_VERIFY_PARAM *from)
10607{
10608    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10609    unsigned int _inherit_flags;
10610
10611    if (!to) {
10612        return ret;
10613    }
10614    /* keeps the inherit flags for save */
10615    _inherit_flags = to->inherit_flags;
10616
10617    /* Ored DEFAULT inherit flag property to copy "from" contents to "to"
10618    *  contents
10619    */
10620    to->inherit_flags |= WOLFSSL_VPARAM_DEFAULT;
10621
10622    ret = wolfSSL_X509_VERIFY_PARAM_inherit(to, from);
10623
10624    /* restore inherit flag */
10625    to->inherit_flags = _inherit_flags;
10626
10627    return ret;
10628}
10629
10630/* Set the host flag in the X509_VERIFY_PARAM structure */
10631void wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM* param,
10632                                             unsigned int flags)
10633{
10634    if (param != NULL) {
10635        param->hostFlags = flags;
10636    }
10637}
10638
10639/* Sets the expected IP address to ipasc.
10640 *
10641 * param is a pointer to the X509_VERIFY_PARAM structure
10642 * ipasc is a NULL-terminated string with N.N.N.N for IPv4 and
10643 *       HH:HH ... HH:HH for IPv6. There is no validation performed on the
10644 *       parameter, and it must be an exact match with the IP in the cert.
10645 *
10646 * return 1 for success and 0 for failure*/
10647int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM *param,
10648        const char *ipasc)
10649{
10650    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10651
10652    if (param != NULL) {
10653        if (ipasc == NULL) {
10654            param->ipasc[0] = '\0';
10655        }
10656        else {
10657            XSTRLCPY(param->ipasc, ipasc, WOLFSSL_MAX_IPSTR);
10658            param->ipasc[WOLFSSL_MAX_IPSTR-1] = '\0';
10659        }
10660        ret = WOLFSSL_SUCCESS;
10661    }
10662
10663    return ret;
10664}
10665/* Sets the expected IP address to ip(asc)
10666 *          by re-constructing IP address in ascii
10667 * @param  param is a pointer to the X509_VERIFY_PARAM structure
10668 * @param  ip    in binary format of ip address
10669 * @param  iplen size of ip, 4 for ipv4, 16 for ipv6
10670 * @return 1 for success and 0 for failure
10671 */
10672int wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM* param,
10673    const unsigned char* ip, size_t iplen)
10674{
10675    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10676#ifndef NO_FILESYSTEM
10677    char* buf = NULL;
10678    char* p = NULL;
10679    word32 val = 0;
10680    int i;
10681    const size_t max_ipv6_len = 40;
10682    byte write_zero = 0;
10683#endif
10684
10685    /* sanity check */
10686    if (param == NULL || (iplen != 0 && iplen != 4 && iplen != 16)) {
10687        WOLFSSL_MSG("bad function arg");
10688        return ret;
10689    }
10690    if (ip == NULL && iplen != 0) {
10691        WOLFSSL_MSG("bad function arg");
10692        return ret;
10693    }
10694#ifndef NO_FILESYSTEM
10695    if (iplen == 4) {
10696        /* ipv4 www.xxx.yyy.zzz max 15 length + Null termination */
10697        buf = (char*)XMALLOC(16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10698        if (!buf) {
10699            WOLFSSL_MSG("failed malloc");
10700            return ret;
10701        }
10702
10703        (void)XSNPRINTF(buf, 16, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
10704        buf[15] = '\0'; /* null terminate */
10705    }
10706    else if (iplen == 16) {
10707        /* ipv6 normal address scheme
10708        *   y1:y2:y3:y4:y5:y6:y7:y8, len(yx):4, len(y1-y8):32. len(":"):7
10709        *   Max len is 32 + 7 + 1(Termination) = 40 bytes
10710        *
10711        *   ipv6 dual address
10712        *   Or y1:y2:y3:y4:y:y6:x.x.x.x yx is 4, y1-y6 is 24, ":" is 6
10713        *   x.x.x.x is 15.
10714        *   Max len is 24 + 6 + 15 + 1(Termination) = 46 bytes
10715        *
10716        *   Expect data in ip[16]
10717        *   e.g (aaaa):(bbbb):(cccc):....(hhhh)
10718        *   (aaaa) = (ip[0<<8)|ip[1]
10719        *   ......
10720        *   (hhhh) = (ip[14]<<8)|(ip[15])
10721        *
10722        *   e.g ::(gggg):(hhhh)
10723        *   ip[0]-[11] = 0
10724        *   (gggg) = (ip[12]<<8) |(ip[13])
10725        *   (hhhh) = (ip[14]<<8) |(ip[15])
10726        *
10727        *   Because it is not able to know which ivp6 scheme uses from data to
10728        *   reconstruct IP address, this function assumes
10729        *   ivp6 normal address scheme, not dual address scheme,
10730        *   to re-construct IP address in ascii.
10731        */
10732        buf = (char*)XMALLOC(max_ipv6_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10733        if (!buf) {
10734            WOLFSSL_MSG("failed malloc");
10735            return ret;
10736        }
10737        p = buf;
10738        for (i = 0; i < 16; i += 2) {
10739            val = (((word32)(ip[i]<<8)) | (ip[i+1])) & 0xFFFF;
10740            if (val == 0) {
10741                if (!write_zero) {
10742                    *p = ':';
10743                }
10744                p++;
10745                *p = '\0';
10746                write_zero = 1;
10747            }
10748            else {
10749                if (i != 0) {
10750                    *p++ = ':';
10751                }
10752                (void)XSNPRINTF(p, max_ipv6_len - (size_t)(p - buf), "%x", val);
10753            }
10754            /* sanity check */
10755            if (XSTRLEN(buf) > max_ipv6_len) {
10756                WOLFSSL_MSG("The target ip address exceeds buffer length(40)");
10757                XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10758                buf = NULL;
10759                break;
10760            }
10761            /* move the pointer to the last */
10762            /* XSTRLEN includes NULL because of XSPRINTF use */
10763            p = buf + (XSTRLEN(buf));
10764        }
10765        /* termination */
10766        if (i == 16 && buf) {
10767            p--;
10768            if ((*p) == ':') {
10769                /* when the last character is :, the following segments are zero
10770                 * Therefore, adding : and null termination */
10771                p++;
10772                *p++ = ':';
10773                *p = '\0';
10774            }
10775        }
10776    }
10777    else {
10778        WOLFSSL_MSG("iplen is zero, do nothing");
10779        return WOLFSSL_SUCCESS;
10780    }
10781
10782    if (buf) {
10783        /* set address to ip asc */
10784        ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, buf);
10785        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10786    }
10787#else
10788    (void)param;
10789    (void)ip;
10790    (void)iplen;
10791#endif
10792
10793    return ret;
10794}
10795
10796#ifndef NO_WOLFSSL_STUB
10797void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
10798{
10799    (void)obj;
10800    WOLFSSL_STUB("X509_OBJECT_free_contents");
10801}
10802#endif
10803
10804#ifndef NO_ASN_TIME
10805int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
10806{
10807    return wolfSSL_X509_cmp_time(asnTime, NULL);
10808}
10809
10810/* return WOLFSSL_FATAL_ERROR if asnTime is earlier than or equal to cmpTime,
10811 * and 1 otherwise
10812 * return 0 on error
10813 */
10814int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime)
10815{
10816    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10817    time_t tmpTime, *pTime = &tmpTime;
10818    struct tm ts, *tmpTs, *ct;
10819#if defined(NEED_TMP_TIME)
10820    /* for use with gmtime_r */
10821    struct tm tmpTimeStorage;
10822
10823    tmpTs = &tmpTimeStorage;
10824#else
10825    tmpTs = NULL;
10826#endif
10827    (void)tmpTs;
10828
10829    if (asnTime == NULL) {
10830        return WOLFSSL_FAILURE;
10831    }
10832
10833    if (cmpTime == NULL) {
10834        /* Use current time */
10835        *pTime = wc_Time(0);
10836    }
10837    else {
10838        pTime = cmpTime;
10839    }
10840
10841    if (wolfSSL_ASN1_TIME_to_tm((WOLFSSL_ASN1_TIME*)asnTime, &ts) !=
10842                                                              WOLFSSL_SUCCESS) {
10843        WOLFSSL_MSG("Failed to convert WOLFSSL_ASN1_TIME to struct tm.");
10844        return WOLFSSL_FAILURE;
10845    }
10846
10847    /* Convert to time struct*/
10848    ct = XGMTIME(pTime, tmpTs);
10849
10850    if (ct == NULL)
10851        return GETTIME_ERROR;
10852
10853    /* DateGreaterThan returns 1 for >; 0 for <= */
10854    ret = DateGreaterThan(&ts, ct) ? 1 : -1;
10855
10856    return ret;
10857}
10858#endif /* !NO_ASN_TIME */
10859
10860#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
10861    !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
10862WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTime,
10863    int offset_day, long offset_sec, time_t *in_tm)
10864{
10865    /* get current time if in_tm is null */
10866    time_t t = in_tm ? *in_tm : wc_Time(0);
10867    return wolfSSL_ASN1_TIME_adj(asnTime, t, offset_day, offset_sec);
10868}
10869
10870WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME *asnTime,
10871    long offset_sec, time_t *in_tm)
10872{
10873    return wolfSSL_X509_time_adj_ex(asnTime, 0, offset_sec, in_tm);
10874}
10875
10876WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj)
10877{
10878    return wolfSSL_X509_time_adj(s, adj, NULL);
10879}
10880#endif
10881
10882int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_STACK* sk)
10883{
10884    WOLFSSL_ENTER("wolfSSL_sk_X509_REVOKED_num");
10885    if (sk != NULL) {
10886        return (int)sk->num;
10887    }
10888    return 0;
10889}
10890
10891/* Free a WOLFSSL_X509_REVOKED and all its owned memory. */
10892void wolfSSL_X509_REVOKED_free(WOLFSSL_X509_REVOKED* rev)
10893{
10894    if (rev == NULL) {
10895        return;
10896    }
10897
10898    wolfSSL_ASN1_INTEGER_free(rev->serialNumber);
10899    wolfSSL_ASN1_TIME_free(rev->revocationDate);
10900
10901    if (rev->extensions != NULL) {
10902        wolfSSL_sk_pop_free(rev->extensions, NULL);
10903    }
10904    if (rev->issuer != NULL) {
10905        wolfSSL_sk_pop_free(rev->issuer, NULL);
10906    }
10907
10908    XFREE(rev, NULL, DYNAMIC_TYPE_OPENSSL);
10909}
10910
10911#ifdef HAVE_CRL
10912/* Build a WOLFSSL_X509_REVOKED from an internal RevokedCert.
10913 * Caller takes ownership of the returned object. */
10914static WOLFSSL_X509_REVOKED* RevokedCertToRevoked(RevokedCert* rc, int seq)
10915{
10916    WOLFSSL_X509_REVOKED* rev;
10917    WOLFSSL_ASN1_INTEGER* serial;
10918
10919    if (rc == NULL) {
10920        return NULL;
10921    }
10922
10923    rev = (WOLFSSL_X509_REVOKED*)XMALLOC(sizeof(WOLFSSL_X509_REVOKED), NULL,
10924                                          DYNAMIC_TYPE_OPENSSL);
10925    if (rev == NULL) {
10926        return NULL;
10927    }
10928    XMEMSET(rev, 0, sizeof(WOLFSSL_X509_REVOKED));
10929
10930    /* Serial number */
10931    serial = wolfSSL_ASN1_INTEGER_new();
10932    if (serial == NULL) {
10933        XFREE(rev, NULL, DYNAMIC_TYPE_OPENSSL);
10934        return NULL;
10935    }
10936    if (rc->serialSz > 0 && rc->serialSz <= EXTERNAL_SERIAL_SIZE) {
10937        serial->data = (unsigned char*)XMALLOC((size_t)rc->serialSz, NULL,
10938                                               DYNAMIC_TYPE_OPENSSL);
10939        if (serial->data == NULL) {
10940            wolfSSL_ASN1_INTEGER_free(serial);
10941            XFREE(rev, NULL, DYNAMIC_TYPE_OPENSSL);
10942            return NULL;
10943        }
10944        XMEMCPY(serial->data, rc->serialNumber, (size_t)rc->serialSz);
10945        serial->length = rc->serialSz;
10946        serial->dataMax = rc->serialSz;
10947        serial->isDynamic = 1;
10948    }
10949    rev->serialNumber = serial;
10950
10951    /* Revocation date */
10952    {
10953        WOLFSSL_ASN1_TIME* revDate = wolfSSL_ASN1_TIME_new();
10954        if (revDate != NULL) {
10955            int dateLen = 0;
10956            /* Determine date length from the format byte */
10957            if (rc->revDateFormat == ASN_UTC_TIME ||
10958                    rc->revDateFormat == ASN_GENERALIZED_TIME) {
10959                /* Find actual length: dates are null-terminated strings in
10960                 * revDate buffer up to MAX_DATE_SIZE */
10961                while (dateLen < MAX_DATE_SIZE && rc->revDate[dateLen] != 0)
10962                    dateLen++;
10963            }
10964            if (dateLen > 0 && dateLen < MAX_DATE_SIZE) {
10965                XMEMCPY(revDate->data, rc->revDate, (size_t)dateLen);
10966                revDate->length = dateLen;
10967                revDate->type = rc->revDateFormat;
10968            }
10969        }
10970        rev->revocationDate = revDate;
10971    }
10972
10973    /* Reason code */
10974    rev->reason = rc->reasonCode;
10975
10976    /* Sequence (load order) */
10977    rev->sequence = seq;
10978
10979    /* issuer: left as NULL (indirect CRL not yet supported) */
10980    /* extensions: left as NULL for now (raw DER available in RevokedCert
10981     * but decoded STACK_OF(X509_EXTENSION) build not yet implemented) */
10982
10983    return rev;
10984}
10985#endif /* HAVE_CRL */
10986
10987WOLFSSL_STACK* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
10988{
10989    WOLFSSL_ENTER("wolfSSL_X509_CRL_get_REVOKED");
10990
10991    if (crl == NULL) {
10992        return NULL;
10993    }
10994
10995#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
10996    /* Return cached stack if already built */
10997    if (crl->revokedStack != NULL) {
10998        return crl->revokedStack;
10999    }
11000
11001    /* Build the stack from the internal RevokedCert linked list */
11002    if (crl->crlList != NULL) {
11003        WOLFSSL_STACK* sk;
11004        RevokedCert* rc;
11005        int seq = 0;
11006
11007        sk = wolfSSL_sk_new_null();
11008        if (sk == NULL) {
11009            return NULL;
11010        }
11011        sk->type = STACK_TYPE_X509_REVOKED;
11012
11013        for (rc = crl->crlList->certs; rc != NULL; rc = rc->next) {
11014            WOLFSSL_X509_REVOKED* rev = RevokedCertToRevoked(rc, seq);
11015            if (rev == NULL) {
11016                /* Clean up on failure */
11017                wolfSSL_sk_pop_free(sk, NULL);
11018                return NULL;
11019            }
11020            /* Push to stack. wolfSSL_sk_push returns total count on success. */
11021            if (wolfSSL_sk_push(sk, rev) <= 0) {
11022                wolfSSL_X509_REVOKED_free(rev);
11023                wolfSSL_sk_pop_free(sk, NULL);
11024                return NULL;
11025            }
11026            seq++;
11027        }
11028
11029        crl->revokedStack = sk;
11030        return sk;
11031    }
11032#endif /* OPENSSL_EXTRA && HAVE_CRL */
11033
11034    return NULL;
11035}
11036
11037WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
11038                                    WOLFSSL_STACK* sk, int idx)
11039{
11040    WOLFSSL_ENTER("wolfSSL_sk_X509_REVOKED_value");
11041
11042    if (sk == NULL) {
11043        return NULL;
11044    }
11045
11046    return (WOLFSSL_X509_REVOKED*)wolfSSL_sk_value(sk, idx);
11047}
11048
11049/* Extension accessors for WOLFSSL_X509_REVOKED */
11050int wolfSSL_X509_REVOKED_get_ext_count(const WOLFSSL_X509_REVOKED* rev)
11051{
11052    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_ext_count");
11053    if (rev != NULL && rev->extensions != NULL) {
11054        return (int)rev->extensions->num;
11055    }
11056    return 0;
11057}
11058
11059WOLFSSL_X509_EXTENSION* wolfSSL_X509_REVOKED_get_ext(
11060                                     const WOLFSSL_X509_REVOKED* rev, int loc)
11061{
11062    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_ext");
11063    if (rev != NULL && rev->extensions != NULL) {
11064        return (WOLFSSL_X509_EXTENSION*)wolfSSL_sk_value(rev->extensions, loc);
11065    }
11066    return NULL;
11067}
11068
11069#endif /* OPENSSL_EXTRA */
11070
11071#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
11072
11073WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
11074{
11075    WOLFSSL_ASN1_INTEGER* a;
11076    int i = 0;
11077
11078    WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
11079
11080    if (x509 == NULL) {
11081        WOLFSSL_MSG("NULL function argument");
11082        return NULL;
11083    }
11084
11085    if (x509->serialNumber != NULL)
11086       return x509->serialNumber;
11087
11088    if (x509->serialSz < 0) {
11089        WOLFSSL_MSG("Invalid serial number size");
11090        return NULL;
11091    }
11092
11093    a = wolfSSL_ASN1_INTEGER_new();
11094    if (a == NULL)
11095        return NULL;
11096
11097    /* Make sure there is space for the data, ASN.1 type and length. */
11098    if (x509->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
11099        /* dynamically create data buffer, +2 for type and length */
11100        a->data = (unsigned char*)XMALLOC(x509->serialSz + 2, NULL,
11101                DYNAMIC_TYPE_OPENSSL);
11102        if (a->data == NULL) {
11103            wolfSSL_ASN1_INTEGER_free(a);
11104            return NULL;
11105        }
11106        a->dataMax   = (unsigned int)x509->serialSz + 2;
11107        a->isDynamic = 1;
11108    }
11109    else {
11110        /* Use array instead of dynamic memory */
11111        a->data    = a->intData;
11112        a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
11113    }
11114
11115    #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
11116        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
11117        a->length = x509->serialSz;
11118    #else
11119        a->data[i++] = ASN_INTEGER;
11120        i += SetLength(x509->serialSz, a->data + i);
11121        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
11122        a->length = x509->serialSz + 2;
11123    #endif
11124
11125    x509->serialNumber = a;
11126
11127    return a;
11128}
11129
11130#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
11131
11132#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
11133
11134#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
11135    defined(WOLFSSL_APACHE_HTTPD) || defined(WOLFSSL_HAPROXY) || \
11136    defined(WOLFSSL_WPAS)
11137WOLFSSL_X509_ALGOR* wolfSSL_X509_ALGOR_new(void)
11138{
11139    WOLFSSL_X509_ALGOR* ret;
11140    ret = (WOLFSSL_X509_ALGOR*)XMALLOC(sizeof(WOLFSSL_X509_ALGOR), NULL,
11141                                       DYNAMIC_TYPE_OPENSSL);
11142    if (ret) {
11143        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ALGOR));
11144    }
11145    return ret;
11146}
11147
11148void wolfSSL_X509_ALGOR_free(WOLFSSL_X509_ALGOR *alg)
11149{
11150    if (alg) {
11151        wolfSSL_ASN1_OBJECT_free(alg->algorithm);
11152        wolfSSL_ASN1_TYPE_free(alg->parameter);
11153        XFREE(alg, NULL, DYNAMIC_TYPE_OPENSSL);
11154    }
11155}
11156
11157/* Returns X509_ALGOR struct with signature algorithm */
11158const WOLFSSL_X509_ALGOR* wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 *x509)
11159{
11160    WOLFSSL_ENTER("wolfSSL_X509_get0_tbs_sigalg");
11161
11162    if (x509 == NULL) {
11163        WOLFSSL_MSG("x509 struct NULL error");
11164        return NULL;
11165    }
11166
11167    return &x509->algor;
11168}
11169
11170/* Sets paobj pointer to X509_ALGOR signature algorithm */
11171void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype,
11172                            const void **ppval, const WOLFSSL_X509_ALGOR *algor)
11173{
11174    WOLFSSL_ENTER("wolfSSL_X509_ALGOR_get0");
11175
11176    if (!algor) {
11177        WOLFSSL_MSG("algor object is NULL");
11178        return;
11179    }
11180
11181    if (paobj)
11182        *paobj = algor->algorithm;
11183    if (ppval && algor->parameter)
11184        *ppval = algor->parameter->value.ptr;
11185    if (pptype) {
11186        if (algor->parameter) {
11187            *pptype = algor->parameter->type;
11188        }
11189        else {
11190            /* Default to WOLFSSL_V_ASN1_OBJECT */
11191            *pptype = WOLFSSL_V_ASN1_OBJECT;
11192        }
11193    }
11194}
11195
11196/**
11197 * Populate algor members.
11198 *
11199 * @param algor The object to be set
11200 * @param aobj The value to be set in algor->algorithm
11201 * @param ptype The type of algor->parameter
11202 * @param pval The value of algor->parameter
11203 * @return WOLFSSL_SUCCESS on success
11204 *         WOLFSSL_FAILURE on missing parameters or bad malloc
11205 */
11206int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor,
11207                            WOLFSSL_ASN1_OBJECT *aobj, int ptype, void *pval)
11208{
11209    if (!algor) {
11210        return WOLFSSL_FAILURE;
11211    }
11212
11213    if (!algor->parameter) {
11214        algor->parameter = wolfSSL_ASN1_TYPE_new();
11215        if (!algor->parameter) {
11216            return WOLFSSL_FAILURE;
11217        }
11218    }
11219
11220    if (aobj) {
11221        algor->algorithm = aobj;
11222    }
11223    wolfSSL_ASN1_TYPE_set(algor->parameter, ptype, pval);
11224
11225    return WOLFSSL_SUCCESS;
11226}
11227
11228/**
11229 * Serialize object to DER encoding
11230 *
11231 * @param alg Object to serialize
11232 * @param pp  Output
11233 * @return Length on success
11234 *         Negative number on failure
11235 */
11236int wolfSSL_i2d_X509_ALGOR(const WOLFSSL_X509_ALGOR* alg,
11237        unsigned char** pp)
11238{
11239    int len;
11240    word32 oid = 0;
11241    word32 idx = 0;
11242    unsigned char* buf = NULL;
11243
11244    if (alg == NULL || alg->algorithm == 0) {
11245        WOLFSSL_MSG("alg is NULL or algorithm not set");
11246        return WOLFSSL_FATAL_ERROR;
11247    }
11248
11249    if (GetObjectId(alg->algorithm->obj, &idx, &oid,
11250            (word32)alg->algorithm->grp, alg->algorithm->objSz) < 0) {
11251        WOLFSSL_MSG("Issue getting OID of object");
11252        return WOLFSSL_FATAL_ERROR;
11253    }
11254
11255    len = (int)SetAlgoID((int)oid, NULL, alg->algorithm->grp, 0);
11256    if (len == 0) {
11257        WOLFSSL_MSG("SetAlgoID error");
11258        return WOLFSSL_FATAL_ERROR;
11259    }
11260
11261    if (pp != NULL) {
11262        if (*pp != NULL)
11263            buf = *pp;
11264        else {
11265            buf = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1);
11266            if (buf == NULL)
11267                return WOLFSSL_FATAL_ERROR;
11268        }
11269
11270        len = (int)SetAlgoID((int)oid, buf, alg->algorithm->grp, 0);
11271        if (len == 0) {
11272            WOLFSSL_MSG("SetAlgoID error");
11273            if (*pp == NULL)
11274                XFREE(buf, NULL, DYNAMIC_TYPE_ASN1);
11275            return WOLFSSL_FATAL_ERROR;
11276        }
11277
11278        if (*pp != NULL)
11279            *pp += len;
11280        else
11281            *pp = buf;
11282    }
11283
11284    return len;
11285}
11286
11287WOLFSSL_X509_ALGOR* wolfSSL_d2i_X509_ALGOR(WOLFSSL_X509_ALGOR** out,
11288        const byte** src, long len)
11289{
11290    WOLFSSL_X509_ALGOR* ret = NULL;
11291    word32 idx = 0;
11292    word32 oid = 0;
11293    int grp;
11294
11295    WOLFSSL_ENTER("wolfSSL_d2i_X509_ALGOR");
11296
11297    if (src == NULL || *src == NULL || len == 0)
11298        return NULL;
11299
11300    if (GetAlgoId(*src, &idx, &oid, oidIgnoreType, (word32)len) != 0)
11301        return NULL;
11302
11303    /* Try to guess the type */
11304    for (grp = 0; grp < oidIgnoreType; grp++) {
11305        word32 oidSz;
11306        if (OidFromId(oid, (word32)grp, &oidSz) != NULL)
11307            break;
11308    }
11309    if (grp == oidIgnoreType)
11310        return NULL;
11311
11312    ret = wolfSSL_X509_ALGOR_new();
11313    if (ret == NULL)
11314        return NULL;
11315
11316    ret->algorithm = wolfSSL_OBJ_nid2obj(oid2nid(oid, grp));
11317    if (ret->algorithm == NULL) {
11318        wolfSSL_X509_ALGOR_free(ret);
11319        return NULL;
11320    }
11321    *src += idx;
11322
11323    if (out != NULL) {
11324        if (*out != NULL)
11325            wolfSSL_X509_ALGOR_free(*out);
11326        *out = ret;
11327    }
11328
11329    return ret;
11330}
11331
11332/**
11333 * Allocate a new WOLFSSL_X509_PUBKEY object.
11334 *
11335 * @return New zero'ed WOLFSSL_X509_PUBKEY object
11336 */
11337WOLFSSL_X509_PUBKEY *wolfSSL_X509_PUBKEY_new(void)
11338{
11339    WOLFSSL_X509_PUBKEY *ret;
11340    ret = (WOLFSSL_X509_PUBKEY*)XMALLOC(sizeof(WOLFSSL_X509_PUBKEY), NULL,
11341                                        DYNAMIC_TYPE_OPENSSL);
11342    if (!ret) {
11343        return NULL;
11344    }
11345    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PUBKEY));
11346    ret->algor = wolfSSL_X509_ALGOR_new();
11347    if (!ret->algor) {
11348        wolfSSL_X509_PUBKEY_free(ret);
11349        return NULL;
11350    }
11351    return ret;
11352}
11353
11354/**
11355 * Free WOLFSSL_X509_PUBKEY and all its members.
11356 *
11357 * @param at Object to free
11358 */
11359void wolfSSL_X509_PUBKEY_free(WOLFSSL_X509_PUBKEY *x)
11360{
11361    if (x) {
11362        if (x->algor) {
11363            wolfSSL_X509_ALGOR_free(x->algor);
11364        }
11365        if (x->pkey) {
11366            wolfSSL_EVP_PKEY_free(x->pkey);
11367        }
11368        XFREE(x, NULL, DYNAMIC_TYPE_OPENSSL);
11369    }
11370}
11371
11372/* Returns X509_PUBKEY structure containing X509_ALGOR and EVP_PKEY */
11373WOLFSSL_X509_PUBKEY* wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509* x509)
11374{
11375    WOLFSSL_ENTER("wolfSSL_X509_get_X509_PUBKEY");
11376
11377    if (x509 == NULL) {
11378        WOLFSSL_MSG("x509 struct NULL error");
11379        return NULL;
11380    }
11381
11382    return (WOLFSSL_X509_PUBKEY*)&x509->key;
11383}
11384
11385/* Sets ppkalg pointer to X509_PUBKEY algorithm. Returns WOLFSSL_SUCCESS on
11386    success or WOLFSSL_FAILURE on error. */
11387int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg,
11388     const unsigned char **pk, int *ppklen, WOLFSSL_X509_ALGOR **pa,
11389     WOLFSSL_X509_PUBKEY *pub)
11390{
11391    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get0_param");
11392
11393    if (!pub || !pub->pubKeyOID) {
11394        WOLFSSL_MSG("X509_PUBKEY struct not populated");
11395        return WOLFSSL_FAILURE;
11396    }
11397
11398    if (!pub->algor) {
11399        if (!(pub->algor = wolfSSL_X509_ALGOR_new())) {
11400            return WOLFSSL_FAILURE;
11401        }
11402        pub->algor->algorithm = wolfSSL_OBJ_nid2obj(pub->pubKeyOID);
11403        if (pub->algor->algorithm == NULL) {
11404            WOLFSSL_MSG("Failed to create object from NID");
11405            return WOLFSSL_FAILURE;
11406        }
11407    }
11408
11409    if (pa)
11410        *pa = pub->algor;
11411    if (ppkalg)
11412        *ppkalg = pub->algor->algorithm;
11413    if (pk)
11414        *pk = (unsigned char*)pub->pkey->pkey.ptr;
11415    if (ppklen)
11416        *ppklen = pub->pkey->pkey_sz;
11417
11418    return WOLFSSL_SUCCESS;
11419}
11420
11421/* Returns a pointer to the pkey when passed a key */
11422WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key)
11423{
11424    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get");
11425    if (key == NULL || key->pkey == NULL) {
11426        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_FUNC_ARG);
11427        return NULL;
11428    }
11429    if (wolfSSL_EVP_PKEY_up_ref(key->pkey) != WOLFSSL_SUCCESS) {
11430        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_MUTEX_E);
11431        return NULL;
11432    }
11433    WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", WOLFSSL_SUCCESS);
11434    return key->pkey;
11435}
11436
11437int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
11438{
11439    WOLFSSL_X509_PUBKEY *pk = NULL;
11440    int ptype;
11441    void *pval;
11442#ifndef NO_DSA
11443    WOLFSSL_ASN1_STRING *str;
11444#endif
11445#ifdef HAVE_ECC
11446    int nid;
11447    const WOLFSSL_EC_GROUP *group;
11448#endif
11449    WOLFSSL_ASN1_OBJECT *keyTypeObj;
11450
11451    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_set");
11452
11453    if (!x || !key) {
11454        return WOLFSSL_FAILURE;
11455    }
11456
11457    if (!(pk = wolfSSL_X509_PUBKEY_new())) {
11458        return WOLFSSL_FAILURE;
11459    }
11460
11461    switch (key->type) {
11462#ifndef NO_RSA
11463    case WC_EVP_PKEY_RSA:
11464        pval = NULL;
11465        ptype = WOLFSSL_V_ASN1_NULL;
11466        pk->pubKeyOID = RSAk;
11467        break;
11468#endif
11469#ifndef NO_DSA
11470    case WC_EVP_PKEY_DSA:
11471        if (!key->dsa->p || !key->dsa->q || !key->dsa->g)
11472            goto error;
11473
11474        str = wolfSSL_ASN1_STRING_new();
11475        if (str == NULL)
11476            goto error;
11477
11478        str->length = wolfSSL_i2d_DSAparams(key->dsa,
11479             (unsigned char **)&str->data);
11480        if (str->length <= 0) {
11481            wolfSSL_ASN1_STRING_free(str);
11482            goto error;
11483        }
11484        str->isDynamic = 1;
11485
11486        pval = str;
11487        ptype = WOLFSSL_V_ASN1_SEQUENCE;
11488        pk->pubKeyOID = DSAk;
11489        break;
11490#endif
11491#ifdef HAVE_ECC
11492    case WC_EVP_PKEY_EC:
11493        group = wolfSSL_EC_KEY_get0_group(key->ecc);
11494        if (!group)
11495            goto error;
11496
11497        nid = wolfSSL_EC_GROUP_get_curve_name(group);
11498        if (nid <= 0) {
11499            /* TODO: Add support for no nid case */
11500            WOLFSSL_MSG("nid not found");
11501            goto error;
11502        }
11503
11504        pval = wolfSSL_OBJ_nid2obj(nid);
11505        if (!pval)
11506            goto error;
11507
11508        ptype = WOLFSSL_V_ASN1_OBJECT;
11509        pk->pubKeyOID = ECDSAk;
11510        break;
11511#endif
11512    default:
11513        WOLFSSL_MSG("Unknown key type");
11514        goto error;
11515    }
11516
11517    keyTypeObj = wolfSSL_OBJ_nid2obj(key->type);
11518    if (keyTypeObj == NULL) {
11519        if (ptype == WOLFSSL_V_ASN1_OBJECT)
11520            wolfSSL_ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
11521        else
11522            wolfSSL_ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
11523        goto error;
11524    }
11525    if (!wolfSSL_X509_ALGOR_set0(pk->algor, keyTypeObj, ptype, pval)) {
11526        WOLFSSL_MSG("Failed to create algorithm object");
11527        wolfSSL_ASN1_OBJECT_free(keyTypeObj);
11528        if (ptype == WOLFSSL_V_ASN1_OBJECT)
11529            wolfSSL_ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
11530        else
11531            wolfSSL_ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
11532        goto error;
11533    }
11534
11535    if (!wolfSSL_EVP_PKEY_up_ref(key)) {
11536        WOLFSSL_MSG("Failed to up key reference");
11537        goto error;
11538    }
11539    pk->pkey = key;
11540
11541    wolfSSL_X509_PUBKEY_free(*x);
11542    *x = pk;
11543    return WOLFSSL_SUCCESS;
11544error:
11545    if (pk) {
11546        wolfSSL_X509_PUBKEY_free(pk);
11547    }
11548    return WOLFSSL_FAILURE;
11549}
11550
11551#endif /* OPENSSL_ALL || OPENSSL_EXTRA || WOLFSSL_APACHE_HTTPD ||
11552        * WOLFSSL_HAPROXY || WOLFSSL_WPAS */
11553
11554#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_ASN) && \
11555    !defined(NO_PWDBASED)
11556
11557int wolfSSL_i2d_X509_PUBKEY(WOLFSSL_X509_PUBKEY* x509_PubKey,
11558    unsigned char** der)
11559{
11560    if (x509_PubKey == NULL)
11561        return WOLFSSL_FATAL_ERROR;
11562    return wolfSSL_i2d_PublicKey(x509_PubKey->pkey, der);
11563}
11564
11565#endif /* OPENSSL_EXTRA && !NO_CERTS && !NO_ASN && !NO_PWDBASED */
11566
11567#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
11568
11569#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
11570WOLFSSL_BASIC_CONSTRAINTS* wolfSSL_BASIC_CONSTRAINTS_new(void)
11571{
11572    WOLFSSL_BASIC_CONSTRAINTS* bc;
11573    bc = (WOLFSSL_BASIC_CONSTRAINTS*)
11574          XMALLOC(sizeof(WOLFSSL_BASIC_CONSTRAINTS), NULL,
11575          DYNAMIC_TYPE_X509_EXT);
11576    if (bc == NULL) {
11577        WOLFSSL_MSG("Failed to malloc basic constraints");
11578        return NULL;
11579    }
11580    XMEMSET(bc, 0, sizeof(WOLFSSL_BASIC_CONSTRAINTS));
11581    return bc;
11582}
11583
11584/* frees the wolfSSL_BASIC_CONSTRAINTS object */
11585void wolfSSL_BASIC_CONSTRAINTS_free(WOLFSSL_BASIC_CONSTRAINTS *bc)
11586{
11587    WOLFSSL_ENTER("wolfSSL_BASIC_CONSTRAINTS_free");
11588    if (bc == NULL) {
11589        WOLFSSL_MSG("Argument is NULL");
11590        return;
11591    }
11592    if (bc->pathlen) {
11593        wolfSSL_ASN1_INTEGER_free(bc->pathlen);
11594    }
11595    XFREE(bc, NULL, DYNAMIC_TYPE_OPENSSL);
11596}
11597
11598WOLFSSL_AUTHORITY_KEYID* wolfSSL_AUTHORITY_KEYID_new(void)
11599{
11600    WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)XMALLOC(
11601          sizeof(WOLFSSL_AUTHORITY_KEYID), NULL, DYNAMIC_TYPE_OPENSSL);
11602    if (!akey) {
11603        WOLFSSL_MSG("Issue creating WOLFSSL_AUTHORITY_KEYID struct");
11604        return NULL;
11605    }
11606    XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
11607    return akey;
11608}
11609
11610/* frees the wolfSSL_AUTHORITY_KEYID object */
11611void wolfSSL_AUTHORITY_KEYID_free(WOLFSSL_AUTHORITY_KEYID *id)
11612{
11613    WOLFSSL_ENTER("wolfSSL_AUTHORITY_KEYID_free");
11614    if (id == NULL) {
11615        WOLFSSL_MSG("Argument is NULL");
11616        return;
11617    }
11618    if (id->keyid) {
11619        wolfSSL_ASN1_STRING_free(id->keyid);
11620    }
11621    if (id->issuer) {
11622        wolfSSL_ASN1_OBJECT_free(id->issuer);
11623    }
11624    if (id->serial) {
11625        wolfSSL_ASN1_INTEGER_free(id->serial);
11626    }
11627    XFREE(id, NULL, DYNAMIC_TYPE_OPENSSL);
11628}
11629
11630#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
11631
11632#ifdef KEEP_PEER_CERT
11633char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
11634{
11635    if (x509 == NULL)
11636        return NULL;
11637
11638    return x509->subjectCN;
11639}
11640#endif /* KEEP_PEER_CERT */
11641
11642#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
11643/* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */
11644int wolfSSL_X509_up_ref(WOLFSSL_X509* x509)
11645{
11646    if (x509) {
11647        int ret;
11648        wolfSSL_RefInc(&x509->ref, &ret);
11649        if (ret != 0) {
11650            WOLFSSL_MSG("Failed to lock x509 mutex");
11651            return WOLFSSL_FAILURE;
11652        }
11653
11654        return WOLFSSL_SUCCESS;
11655    }
11656
11657    return WOLFSSL_FAILURE;
11658}
11659#endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
11660
11661#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
11662WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
11663        WOLF_STACK_OF(WOLFSSL_X509)* chain)
11664{
11665    /* wolfSSL_sk_dup takes care of doing a deep copy */
11666    return wolfSSL_sk_dup(chain);
11667}
11668#endif
11669
11670#if defined(OPENSSL_EXTRA)
11671
11672WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_sk_X509_OBJECT_deep_copy(
11673    const WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk,
11674    WOLFSSL_X509_OBJECT* (*c)(const WOLFSSL_X509_OBJECT*),
11675    void (*f)(WOLFSSL_X509_OBJECT*))
11676{
11677    (void)f; /* free function */
11678    (void)c; /* copy function */
11679    return wolfSSL_sk_dup((WOLFSSL_STACK*)sk);
11680}
11681#endif
11682
11683#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
11684    void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name)
11685    {
11686        WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
11687        FreeX509Name(name);
11688        if (name != NULL) {
11689            XFREE(name, name->heap, DYNAMIC_TYPE_X509);
11690        }
11691    }
11692
11693
11694    /* Malloc's a new WOLFSSL_X509_NAME structure
11695     *
11696     * returns NULL on failure, otherwise returns a new structure.
11697     */
11698    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new_ex(void *heap)
11699    {
11700        WOLFSSL_X509_NAME* name;
11701
11702        WOLFSSL_ENTER("wolfSSL_X509_NAME_new_ex");
11703
11704        name = (WOLFSSL_X509_NAME*)XMALLOC(sizeof(WOLFSSL_X509_NAME), heap,
11705                DYNAMIC_TYPE_X509);
11706        if (name != NULL) {
11707            InitX509Name(name, 1, heap);
11708        }
11709        return name;
11710    }
11711
11712    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void) {
11713        return wolfSSL_X509_NAME_new_ex(NULL);
11714    }
11715
11716    /* Creates a duplicate of a WOLFSSL_X509_NAME structure.
11717       Returns a new WOLFSSL_X509_NAME structure or NULL on failure */
11718    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(const WOLFSSL_X509_NAME *name)
11719    {
11720        WOLFSSL_X509_NAME* copy = NULL;
11721
11722        WOLFSSL_ENTER("wolfSSL_X509_NAME_dup");
11723
11724        if (name == NULL) {
11725            WOLFSSL_MSG("NULL parameter");
11726            return NULL;
11727        }
11728
11729        if (!(copy = wolfSSL_X509_NAME_new_ex(name->heap))) {
11730            return NULL;
11731        }
11732
11733        /* copy contents */
11734        InitX509Name(copy, 1, name->heap);
11735        if (wolfSSL_X509_NAME_copy(name, copy) != WOLFSSL_SUCCESS) {
11736            wolfSSL_X509_NAME_free(copy);
11737            return NULL;
11738        }
11739
11740        return copy;
11741    }
11742
11743#ifdef WOLFSSL_CERT_GEN
11744
11745#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
11746    defined(OPENSSL_EXTRA)
11747    /* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
11748    * a Cert structure.
11749    *
11750    * returns length of DER on success and a negative error value on failure
11751    */
11752    static int CopyX509NameToCert(WOLFSSL_X509_NAME* n, byte* out)
11753    {
11754        unsigned char* der = NULL;
11755        int length = WC_NO_ERR_TRACE(BAD_FUNC_ARG), ret;
11756        word32 idx = 0;
11757
11758        ret = wolfSSL_i2d_X509_NAME(n, &der);
11759        if (ret > (int)sizeof(CertName) || ret < 0) {
11760            WOLFSSL_MSG("Name conversion error");
11761            ret = MEMORY_E;
11762        }
11763
11764        if (ret > 0) {
11765            /* strip off sequence, this gets added on certificate creation */
11766            ret = GetSequence(der, &idx, &length, (word32)ret);
11767        }
11768
11769        if (ret > 0) {
11770            XMEMCPY(out, der + idx, length);
11771        }
11772
11773        XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
11774
11775        return length;
11776    }
11777#endif
11778
11779#ifdef WOLFSSL_CERT_REQ
11780    static int ReqCertFromX509(Cert* cert, WOLFSSL_X509* req)
11781    {
11782        int ret;
11783
11784        if (wc_InitCert(cert) != 0)
11785            return WOLFSSL_FAILURE;
11786
11787
11788        ret = CopyX509NameToCert(&req->subject, cert->sbjRaw);
11789        if (ret < 0) {
11790            WOLFSSL_MSG("REQ subject conversion error");
11791            ret = MEMORY_E;
11792        }
11793        else {
11794            ret = WOLFSSL_SUCCESS;
11795        }
11796
11797        if (ret == WOLFSSL_SUCCESS) {
11798            cert->version = req->version;
11799            cert->isCA = req->isCa;
11800            cert->basicConstSet = req->basicConstSet;
11801    #ifdef WOLFSSL_CERT_EXT
11802            if (req->subjKeyIdSz != 0) {
11803                if (req->subjKeyIdSz > CTC_MAX_SKID_SIZE) {
11804                    WOLFSSL_MSG("Subject Key ID too large");
11805                    WOLFSSL_ERROR_VERBOSE(BUFFER_E);
11806                    ret = WOLFSSL_FAILURE;
11807                }
11808                else if (req->subjKeyId == NULL) {
11809                    WOLFSSL_MSG("Subject Key ID missing");
11810                    WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
11811                    ret = WOLFSSL_FAILURE;
11812                }
11813                else {
11814                    XMEMCPY(cert->skid, req->subjKeyId,
11815                            req->subjKeyIdSz);
11816                    cert->skidSz = (int)req->subjKeyIdSz;
11817                }
11818            }
11819            if (req->keyUsageSet)
11820                cert->keyUsage = req->keyUsage;
11821
11822            cert->extKeyUsage = req->extKeyUsage;
11823    #endif
11824        }
11825
11826        if (ret == WOLFSSL_SUCCESS) {
11827        #if defined(OPENSSL_ALL)
11828            int idx;
11829        #endif
11830
11831            XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE);
11832            cert->challengePwPrintableString = req->challengePw[0] != 0;
11833
11834        #if defined(OPENSSL_ALL)
11835            idx = wolfSSL_X509_REQ_get_attr_by_NID(req,
11836                    WC_NID_pkcs9_unstructuredName, -1);
11837            if (idx != WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) {
11838                WOLFSSL_X509_ATTRIBUTE *attr;
11839                attr = wolfSSL_X509_REQ_get_attr(req, idx);
11840                if (attr != NULL) {
11841                    const unsigned char *attrData;
11842                    int attrDataSz;
11843
11844                    attrData = wolfSSL_ASN1_STRING_get0_data(
11845                            attr->value->value.asn1_string);
11846                    attrDataSz = wolfSSL_ASN1_STRING_length(
11847                            attr->value->value.asn1_string);
11848
11849                    /* +1 to make sure is terminated string */
11850                    if (attrDataSz + 1 > CTC_NAME_SIZE) {
11851                        WOLFSSL_MSG("attribute size was too large to copy");
11852                        ret = REQ_ATTRIBUTE_E;
11853                    }
11854                    else {
11855                        XMEMCPY(cert->unstructuredName, attrData, attrDataSz);
11856                        cert->unstructuredName[attrDataSz] = '\0';
11857                    }
11858                }
11859            }
11860
11861        #ifdef WOLFSSL_CUSTOM_OID
11862            if (ret == WOLFSSL_SUCCESS) {
11863                if ((req->customExtCount < 0) ||
11864                    (req->customExtCount >= NUM_CUSTOM_EXT)) {
11865                    WOLFSSL_MSG("Bad value for customExtCount.");
11866                    ret = WOLFSSL_FAILURE;
11867                }
11868
11869                if (ret == WOLFSSL_SUCCESS) {
11870                    for (idx = 0; idx < req->customExtCount; idx++) {
11871                        /* Note that ownership is NOT transferred.
11872                         * req->custom_exts buffers still need to be cleaned
11873                         * up. */
11874                        cert->customCertExt[idx] = req->custom_exts[idx];
11875                    }
11876                    cert->customCertExtCount = req->customExtCount;
11877                }
11878            }
11879        #endif /* WOLFSSL_CUSTOM_OID */
11880        #endif /* OPENSSL_ALL */
11881
11882    #ifdef WOLFSSL_ALT_NAMES
11883            if (ret == WOLFSSL_SUCCESS) {
11884                cert->altNamesSz = FlattenAltNames(cert->altNames,
11885                        sizeof(cert->altNames), req->altNames);
11886            }
11887    #endif /* WOLFSSL_ALT_NAMES */
11888        }
11889
11890        return ret;
11891    }
11892#endif /* WOLFSSL_CERT_REQ */
11893
11894/* converts WOLFSSL_AN1_TIME to Cert form, returns positive size on
11895 * success */
11896static int CertDateFromX509(byte* out, int outSz, WOLFSSL_ASN1_TIME* t)
11897{
11898    int sz, i;
11899
11900    if (t->length + 1 >= outSz) {
11901        return BUFFER_E;
11902    }
11903
11904    out[0] = (byte) t->type;
11905    sz = (int)SetLength((word32)t->length, out + 1) + 1;  /* gen tag */
11906    for (i = 0; i < t->length; i++) {
11907        out[sz + i] = t->data[i];
11908    }
11909    return t->length + sz;
11910}
11911
11912/* convert a WOLFSSL_X509 to a Cert structure for writing out */
11913static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
11914{
11915    int ret;
11916#ifdef WOLFSSL_CERT_EXT
11917    int i;
11918#endif
11919
11920    WOLFSSL_ENTER("wolfSSL_X509_to_Cert");
11921
11922    if (x509 == NULL || cert == NULL) {
11923        return BAD_FUNC_ARG;
11924    }
11925
11926    wc_InitCert(cert);
11927
11928    cert->version = (int)wolfSSL_X509_get_version(x509);
11929
11930    if (x509->notBefore.length > 0) {
11931        cert->beforeDateSz = CertDateFromX509(cert->beforeDate,
11932                    CTC_DATE_SIZE, &x509->notBefore);
11933        if (cert->beforeDateSz <= 0) {
11934            WOLFSSL_MSG("Error converting WOLFSSL_X509 not before date");
11935            return WOLFSSL_FAILURE;
11936        }
11937    }
11938    else {
11939        cert->beforeDateSz = 0;
11940    }
11941
11942    if (x509->notAfter.length > 0) {
11943        cert->afterDateSz = CertDateFromX509(cert->afterDate,
11944                    CTC_DATE_SIZE, &x509->notAfter);
11945        if (cert->afterDateSz <= 0) {
11946            WOLFSSL_MSG("Error converting WOLFSSL_X509 not after date");
11947            return WOLFSSL_FAILURE;
11948        }
11949    }
11950    else {
11951        cert->afterDateSz = 0;
11952    }
11953
11954#ifdef WOLFSSL_ALT_NAMES
11955    cert->altNamesSz = FlattenAltNames(cert->altNames,
11956            sizeof(cert->altNames), x509->altNames);
11957#endif /* WOLFSSL_ALT_NAMES */
11958
11959    cert->sigType = wolfSSL_X509_get_signature_type(x509);
11960    cert->keyType = x509->pubKeyOID;
11961    cert->isCA    = wolfSSL_X509_get_isCA(x509);
11962    cert->basicConstCrit = x509->basicConstCrit;
11963    cert->basicConstSet = x509->basicConstSet;
11964    cert->pathLen = (byte)x509->pathLength;
11965    cert->pathLenSet = x509->pathLengthSet;
11966
11967#ifdef WOLFSSL_CERT_EXT
11968    if (x509->subjKeyIdSz <= CTC_MAX_SKID_SIZE) {
11969        if (x509->subjKeyId) {
11970            XMEMCPY(cert->skid, x509->subjKeyId, x509->subjKeyIdSz);
11971        }
11972        cert->skidSz = (int)x509->subjKeyIdSz;
11973    }
11974    else {
11975        WOLFSSL_MSG("Subject Key ID too large");
11976        WOLFSSL_ERROR_VERBOSE(BUFFER_E);
11977        return WOLFSSL_FAILURE;
11978    }
11979
11980    #ifdef WOLFSSL_AKID_NAME
11981    cert->rawAkid = 0;
11982    if (x509->authKeyIdSrc) {
11983        if (x509->authKeyIdSrcSz > sizeof(cert->akid)) {
11984            WOLFSSL_MSG("Auth Key ID too large");
11985            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
11986            return WOLFSSL_FAILURE;
11987        }
11988        XMEMCPY(cert->akid, x509->authKeyIdSrc, x509->authKeyIdSrcSz);
11989        cert->akidSz = (int)x509->authKeyIdSrcSz;
11990        cert->rawAkid = 1;
11991    }
11992    else
11993    #endif
11994    if (x509->authKeyId) {
11995        if (x509->authKeyIdSz > sizeof(cert->akid)) {
11996            WOLFSSL_MSG("Auth Key ID too large");
11997            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
11998            return WOLFSSL_FAILURE;
11999        }
12000        XMEMCPY(cert->akid, x509->authKeyId, x509->authKeyIdSz);
12001        cert->akidSz = (int)x509->authKeyIdSz;
12002    }
12003
12004    for (i = 0; i < x509->certPoliciesNb; i++) {
12005        /* copy the smaller of MAX macros, by default they are currently equal*/
12006        if ((int)CTC_MAX_CERTPOL_SZ <= (int)MAX_CERTPOL_SZ) {
12007            XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
12008                    CTC_MAX_CERTPOL_SZ);
12009        }
12010        else {
12011            XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
12012                    MAX_CERTPOL_SZ);
12013        }
12014    }
12015    cert->certPoliciesNb = (word16)x509->certPoliciesNb;
12016
12017    cert->keyUsage = x509->keyUsage;
12018    cert->extKeyUsage = x509->extKeyUsage;
12019    cert->nsCertType = x509->nsCertType;
12020
12021    if (x509->rawCRLInfo != NULL) {
12022        if (x509->rawCRLInfoSz > CTC_MAX_CRLINFO_SZ) {
12023            WOLFSSL_MSG("CRL Info too large");
12024            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
12025            return WOLFSSL_FAILURE;
12026        }
12027        XMEMCPY(cert->crlInfo, x509->rawCRLInfo, x509->rawCRLInfoSz);
12028        cert->crlInfoSz = x509->rawCRLInfoSz;
12029    }
12030
12031#ifdef WOLFSSL_DUAL_ALG_CERTS
12032    /* We point to instance in x509 so DON'T need to be free'd. */
12033    cert->sapkiDer = x509->sapkiDer;
12034    cert->sapkiLen = x509->sapkiLen;
12035    cert->sapkiCrit = x509->sapkiCrit;
12036    cert->altSigAlgDer = x509->altSigAlgDer;
12037    cert->altSigAlgLen  = x509->altSigAlgLen;
12038    cert->altSigAlgCrit = x509->altSigAlgCrit;
12039    cert->altSigValDer = x509->altSigValDer;
12040    cert->altSigValLen = x509->altSigValLen;
12041    cert->altSigValCrit = x509->altSigValCrit;
12042#endif /* WOLFSSL_DUAL_ALG_CERTS */
12043
12044#if defined(WOLFSSL_ASN_TEMPLATE) && defined(WOLFSSL_CUSTOM_OID) && \
12045    defined(HAVE_OID_ENCODING)
12046
12047    if ((x509->customExtCount < 0) ||
12048            (x509->customExtCount >= NUM_CUSTOM_EXT)) {
12049        WOLFSSL_MSG("Bad value for customExtCount.");
12050        return WOLFSSL_FAILURE;
12051    }
12052
12053    for (i = 0; i < x509->customExtCount; i++) {
12054        if (wc_SetCustomExtension(cert, x509->custom_exts[i].crit,
12055                x509->custom_exts[i].oid, x509->custom_exts[i].val,
12056                x509->custom_exts[i].valSz))
12057        {
12058            return WOLFSSL_FAILURE;
12059        }
12060    }
12061#endif /* WOLFSSL_ASN_TEMPLATE && WOLFSSL_CUSTOM_OID && HAVE_OID_ENCODING */
12062
12063#endif /* WOLFSSL_CERT_EXT */
12064
12065#ifdef WOLFSSL_CERT_REQ
12066    /* copy over challenge password for REQ certs */
12067    XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE);
12068#endif
12069
12070    /* Only makes sense to do this for OPENSSL_EXTRA because without
12071     * this define the function will error out below */
12072    #ifdef OPENSSL_EXTRA
12073    if (x509->serialSz == 0 && x509->serialNumber != NULL &&
12074            /* Check if the buffer contains more than just the
12075             * ASN tag and length */
12076            x509->serialNumber->length > 2) {
12077        if (wolfSSL_X509_set_serialNumber(x509, x509->serialNumber)
12078                != WOLFSSL_SUCCESS) {
12079            WOLFSSL_MSG("Failed to set serial number");
12080            return WOLFSSL_FAILURE;
12081        }
12082    }
12083    #endif
12084
12085    /* set serial number */
12086    if (x509->serialSz > 0) {
12087    #if defined(OPENSSL_EXTRA)
12088        byte serial[EXTERNAL_SERIAL_SIZE];
12089        int  serialSz = EXTERNAL_SERIAL_SIZE;
12090
12091        ret = wolfSSL_X509_get_serial_number(x509, serial, &serialSz);
12092        if (ret != WOLFSSL_SUCCESS) {
12093            WOLFSSL_MSG("Serial size error");
12094            return WOLFSSL_FAILURE;
12095        }
12096
12097        if (serialSz > EXTERNAL_SERIAL_SIZE ||
12098                serialSz > CTC_SERIAL_SIZE) {
12099            WOLFSSL_MSG("Serial size too large error");
12100            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
12101            return WOLFSSL_FAILURE;
12102        }
12103        XMEMCPY(cert->serial, serial, serialSz);
12104        cert->serialSz = serialSz;
12105    #else
12106        WOLFSSL_MSG("Getting X509 serial number not supported");
12107        return WOLFSSL_FAILURE;
12108    #endif
12109    }
12110
12111    /* copy over Name structures */
12112    if (x509->issuerSet)
12113        cert->selfSigned = 0;
12114
12115#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
12116    ret = CopyX509NameToCert(&x509->subject, cert->sbjRaw);
12117    if (ret < 0) {
12118        WOLFSSL_MSG("Subject conversion error");
12119        return MEMORY_E;
12120    }
12121    if (cert->selfSigned) {
12122        XMEMCPY(cert->issRaw, cert->sbjRaw, sizeof(CertName));
12123    }
12124    else {
12125        ret = CopyX509NameToCert(&x509->issuer, cert->issRaw);
12126        if (ret < 0) {
12127            WOLFSSL_MSG("Issuer conversion error");
12128            return MEMORY_E;
12129        }
12130    }
12131#endif
12132
12133    cert->heap = x509->heap;
12134
12135    (void)ret;
12136    return WOLFSSL_SUCCESS;
12137}
12138
12139
12140    /* returns the sig type to use on success i.e CTC_SHAwRSA and WOLFSSL_FALURE
12141     * on fail case */
12142    static int wolfSSL_sigTypeFromPKEY(WOLFSSL_EVP_MD* md,
12143            WOLFSSL_EVP_PKEY* pkey)
12144    {
12145    #if !defined(NO_PWDBASED) && defined(OPENSSL_EXTRA)
12146        int hashType;
12147        int sigType = WOLFSSL_FAILURE;
12148
12149        /* Convert key type and hash algorithm to a signature algorithm */
12150        if (wolfSSL_EVP_get_hashinfo(md, &hashType, NULL)
12151            == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
12152        {
12153            return WOLFSSL_FAILURE;
12154        }
12155
12156        if (pkey->type == WC_EVP_PKEY_RSA) {
12157            switch (hashType) {
12158                case WC_HASH_TYPE_SHA:
12159                    sigType = CTC_SHAwRSA;
12160                    break;
12161                case WC_HASH_TYPE_SHA224:
12162                    sigType = CTC_SHA224wRSA;
12163                    break;
12164                case WC_HASH_TYPE_SHA256:
12165                    sigType = CTC_SHA256wRSA;
12166                    break;
12167                case WC_HASH_TYPE_SHA384:
12168                    sigType = CTC_SHA384wRSA;
12169                    break;
12170                case WC_HASH_TYPE_SHA512:
12171                    sigType = CTC_SHA512wRSA;
12172                    break;
12173            #ifdef WOLFSSL_SHA3
12174                case WC_HASH_TYPE_SHA3_224:
12175                    sigType = CTC_SHA3_224wRSA;
12176                    break;
12177                case WC_HASH_TYPE_SHA3_256:
12178                    sigType = CTC_SHA3_256wRSA;
12179                    break;
12180                case WC_HASH_TYPE_SHA3_384:
12181                    sigType = CTC_SHA3_384wRSA;
12182                    break;
12183                case WC_HASH_TYPE_SHA3_512:
12184                    sigType = CTC_SHA3_512wRSA;
12185                    break;
12186            #endif
12187                default:
12188                    return WOLFSSL_FAILURE;
12189            }
12190        }
12191        else if (pkey->type == WC_EVP_PKEY_EC) {
12192            switch (hashType) {
12193                case WC_HASH_TYPE_SHA:
12194                    sigType = CTC_SHAwECDSA;
12195                    break;
12196                case WC_HASH_TYPE_SHA224:
12197                    sigType = CTC_SHA224wECDSA;
12198                    break;
12199                case WC_HASH_TYPE_SHA256:
12200                    sigType = CTC_SHA256wECDSA;
12201                    break;
12202                case WC_HASH_TYPE_SHA384:
12203                    sigType = CTC_SHA384wECDSA;
12204                    break;
12205                case WC_HASH_TYPE_SHA512:
12206                    sigType = CTC_SHA512wECDSA;
12207                    break;
12208            #ifdef WOLFSSL_SHA3
12209                case WC_HASH_TYPE_SHA3_224:
12210                    sigType = CTC_SHA3_224wECDSA;
12211                    break;
12212                case WC_HASH_TYPE_SHA3_256:
12213                    sigType = CTC_SHA3_256wECDSA;
12214                    break;
12215                case WC_HASH_TYPE_SHA3_384:
12216                    sigType = CTC_SHA3_384wECDSA;
12217                    break;
12218                case WC_HASH_TYPE_SHA3_512:
12219                    sigType = CTC_SHA3_512wECDSA;
12220                    break;
12221            #endif
12222                default:
12223                    return WOLFSSL_FAILURE;
12224            }
12225        }
12226        else
12227            return WOLFSSL_FAILURE;
12228        return sigType;
12229#else
12230        (void)md;
12231        (void)pkey;
12232        WOLFSSL_MSG("Cannot get hashinfo when NO_PWDBASED is defined");
12233        return WOLFSSL_FAILURE;
12234#endif /* !NO_PWDBASED && OPENSSL_EXTRA */
12235    }
12236
12237
12238    /* generates DER buffer from WOLFSSL_X509
12239     * If req == 1 then creates a request DER buffer
12240     *
12241     * updates derSz with certificate body size on success
12242     * return WOLFSSL_SUCCESS on success
12243     */
12244    static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
12245            unsigned char* der, int* derSz, int includeSig)
12246    {
12247        int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
12248        int totalLen;
12249        Cert* cert = NULL;
12250        void* key = NULL;
12251        int type = -1;
12252    #ifndef NO_RSA
12253        RsaKey* rsa = NULL;
12254    #endif
12255    #ifdef HAVE_ECC
12256        ecc_key* ecc = NULL;
12257    #endif
12258    #ifndef NO_DSA
12259        DsaKey* dsa = NULL;
12260    #endif
12261    #if defined(HAVE_FALCON)
12262        falcon_key* falcon = NULL;
12263    #endif
12264    #if defined(HAVE_DILITHIUM)
12265        dilithium_key* dilithium = NULL;
12266    #endif
12267    #if defined(WOLFSSL_HAVE_SLHDSA)
12268        SlhDsaKey* slhdsa = NULL;
12269    #endif
12270        WC_RNG rng;
12271        word32 idx = 0;
12272
12273        if (x509 == NULL || der == NULL || derSz == NULL)
12274            return BAD_FUNC_ARG;
12275
12276    #ifndef WOLFSSL_CERT_REQ
12277        if (req) {
12278            WOLFSSL_MSG("WOLFSSL_CERT_REQ needed for certificate request");
12279            return WOLFSSL_FAILURE;
12280        }
12281    #endif
12282
12283        /* allocate Cert struct on heap since it is large */
12284        cert = (Cert*)XMALLOC(sizeof(Cert), NULL, DYNAMIC_TYPE_CERT);
12285        if (cert == NULL) {
12286            WOLFSSL_MSG("Failed to allocate memory for Cert struct");
12287            return WOLFSSL_FAILURE;
12288        }
12289        XMEMSET(cert, 0, sizeof(Cert));
12290
12291    #ifdef WOLFSSL_CERT_REQ
12292        if (req) {
12293            if (ReqCertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
12294                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12295                return WOLFSSL_FAILURE;
12296            }
12297        }
12298        else
12299    #endif
12300        {
12301            /* Create a Cert that has the certificate fields. */
12302            if (CertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
12303                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12304                return WOLFSSL_FAILURE;
12305            }
12306        }
12307
12308        /* Create a public key object from requests public key. */
12309    #ifndef NO_RSA
12310        if (x509->pubKeyOID == RSAk) {
12311
12312            rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
12313            if (rsa == NULL) {
12314                WOLFSSL_MSG("Failed to allocate memory for RsaKey");
12315                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12316                return WOLFSSL_FAILURE;
12317            }
12318
12319            type = RSA_TYPE;
12320            ret = wc_InitRsaKey(rsa, x509->heap);
12321            if (ret != 0) {
12322                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
12323                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12324                return ret;
12325            }
12326            ret = wc_RsaPublicKeyDecode(x509->pubKey.buffer, &idx, rsa,
12327                                                           x509->pubKey.length);
12328            if (ret != 0) {
12329                WOLFSSL_ERROR_VERBOSE(ret);
12330                wc_FreeRsaKey(rsa);
12331                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
12332                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12333                return ret;
12334            }
12335            key = (void*)rsa;
12336        }
12337    #endif
12338    #ifdef HAVE_ECC
12339        if (x509->pubKeyOID == ECDSAk) {
12340
12341            ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
12342            if (ecc == NULL) {
12343                WOLFSSL_MSG("Failed to allocate memory for ecc_key");
12344                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12345                return WOLFSSL_FAILURE;
12346            }
12347
12348            type = ECC_TYPE;
12349            ret = wc_ecc_init(ecc);
12350            if (ret != 0) {
12351                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
12352                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12353                return ret;
12354            }
12355            ret = wc_EccPublicKeyDecode(x509->pubKey.buffer, &idx, ecc,
12356                                                           x509->pubKey.length);
12357            if (ret != 0) {
12358                WOLFSSL_ERROR_VERBOSE(ret);
12359                wc_ecc_free(ecc);
12360                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
12361                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12362                return ret;
12363            }
12364            key = (void*)ecc;
12365        }
12366    #endif
12367    #ifndef NO_DSA
12368        if (x509->pubKeyOID == DSAk) {
12369
12370            dsa = (DsaKey*)XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
12371            if (dsa == NULL) {
12372                WOLFSSL_MSG("Failed to allocate memory for DsaKey");
12373                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12374                return WOLFSSL_FAILURE;
12375            }
12376
12377            type = DSA_TYPE;
12378            ret = wc_InitDsaKey(dsa);
12379            if (ret != 0) {
12380                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
12381                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12382                return ret;
12383            }
12384            ret = wc_DsaPublicKeyDecode(x509->pubKey.buffer, &idx, dsa,
12385                                                           x509->pubKey.length);
12386            if (ret != 0) {
12387                WOLFSSL_ERROR_VERBOSE(ret);
12388                wc_FreeDsaKey(dsa);
12389                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
12390                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12391                return ret;
12392            }
12393            key = (void*)dsa;
12394        }
12395    #endif
12396    #if defined(HAVE_FALCON)
12397        if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
12398            (x509->pubKeyOID == FALCON_LEVEL5k)) {
12399            falcon = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
12400                                          DYNAMIC_TYPE_FALCON);
12401            if (falcon == NULL) {
12402                WOLFSSL_MSG("Failed to allocate memory for falcon_key");
12403                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12404                return WOLFSSL_FAILURE;
12405            }
12406
12407            ret = wc_falcon_init(falcon);
12408            if (ret != 0) {
12409                XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
12410                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12411                return ret;
12412            }
12413
12414            if (x509->pubKeyOID == FALCON_LEVEL1k) {
12415                type = FALCON_LEVEL1_TYPE;
12416                wc_falcon_set_level(falcon, 1);
12417            }
12418            else if (x509->pubKeyOID == FALCON_LEVEL5k) {
12419                type = FALCON_LEVEL5_TYPE;
12420                wc_falcon_set_level(falcon, 5);
12421            }
12422
12423            ret = wc_Falcon_PublicKeyDecode(x509->pubKey.buffer, &idx, falcon,
12424                                            x509->pubKey.length);
12425            if (ret != 0) {
12426                WOLFSSL_ERROR_VERBOSE(ret);
12427                wc_falcon_free(falcon);
12428                XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
12429                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12430                return ret;
12431            }
12432            key = (void*)falcon;
12433        }
12434    #endif
12435    #if defined(HAVE_DILITHIUM)
12436        if ((x509->pubKeyOID == ML_DSA_LEVEL2k) ||
12437            (x509->pubKeyOID == ML_DSA_LEVEL3k) ||
12438            (x509->pubKeyOID == ML_DSA_LEVEL5k)
12439            #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
12440         || (x509->pubKeyOID == DILITHIUM_LEVEL2k)
12441         || (x509->pubKeyOID == DILITHIUM_LEVEL3k)
12442         || (x509->pubKeyOID == DILITHIUM_LEVEL5k)
12443            #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
12444            ) {
12445            dilithium = (dilithium_key*)XMALLOC(sizeof(dilithium_key), NULL,
12446                                          DYNAMIC_TYPE_DILITHIUM);
12447            if (dilithium == NULL) {
12448                WOLFSSL_MSG("Failed to allocate memory for dilithium_key");
12449                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12450                return WOLFSSL_FAILURE;
12451            }
12452
12453            ret = wc_dilithium_init(dilithium);
12454            if (ret != 0) {
12455                XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
12456                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12457                return ret;
12458            }
12459
12460            if (x509->pubKeyOID == ML_DSA_LEVEL2k) {
12461                type = ML_DSA_LEVEL2_TYPE;
12462                wc_dilithium_set_level(dilithium, WC_ML_DSA_44);
12463            }
12464            else if (x509->pubKeyOID == ML_DSA_LEVEL3k) {
12465                type = ML_DSA_LEVEL3_TYPE;
12466                wc_dilithium_set_level(dilithium, WC_ML_DSA_65);
12467            }
12468            else if (x509->pubKeyOID == ML_DSA_LEVEL5k) {
12469                type = ML_DSA_LEVEL5_TYPE;
12470                wc_dilithium_set_level(dilithium, WC_ML_DSA_87);
12471            }
12472            #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
12473            else if (x509->pubKeyOID == DILITHIUM_LEVEL2k) {
12474                type = DILITHIUM_LEVEL2_TYPE;
12475                wc_dilithium_set_level(dilithium, WC_ML_DSA_44_DRAFT);
12476            }
12477            else if (x509->pubKeyOID == DILITHIUM_LEVEL3k) {
12478                type = DILITHIUM_LEVEL3_TYPE;
12479                wc_dilithium_set_level(dilithium, WC_ML_DSA_65_DRAFT);
12480            }
12481            else if (x509->pubKeyOID == DILITHIUM_LEVEL5k) {
12482                type = DILITHIUM_LEVEL5_TYPE;
12483                wc_dilithium_set_level(dilithium, WC_ML_DSA_87_DRAFT);
12484            }
12485            #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
12486
12487            ret = wc_Dilithium_PublicKeyDecode(x509->pubKey.buffer, &idx,
12488                                    dilithium, x509->pubKey.length);
12489            if (ret != 0) {
12490                WOLFSSL_ERROR_VERBOSE(ret);
12491                wc_dilithium_free(dilithium);
12492                XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
12493                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12494                return ret;
12495            }
12496            key = (void*)dilithium;
12497        }
12498    #endif
12499    #if defined(WOLFSSL_HAVE_SLHDSA)
12500        if (wc_IsSlhDsaOid(x509->pubKeyOID)) {
12501            int paramInt = wc_SlhDsaOidToParam(x509->pubKeyOID);
12502            int certType = wc_SlhDsaOidToCertType(x509->pubKeyOID);
12503
12504            /* The OID is a recognised SLH-DSA OID but the parameter set
12505             * isn't built in; surface NOT_COMPILED_IN directly so
12506             * callers can render an accurate diagnostic. */
12507            if (paramInt == WC_NO_ERR_TRACE(NOT_COMPILED_IN) ||
12508                    certType == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
12509                WOLFSSL_MSG("SLH-DSA variant not compiled in");
12510                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12511                return NOT_COMPILED_IN;
12512            }
12513            /* Defensive: wc_IsSlhDsaOid already implies both lookups
12514             * succeed, but check explicitly so any future drift between the
12515             * three OID helpers surfaces as a clean failure rather than
12516             * undefined behaviour from casting -1 to enum SlhDsaParam. */
12517            if (paramInt < 0 || certType < 0) {
12518                WOLFSSL_MSG("SLH-DSA OID helper mismatch");
12519                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12520                return WOLFSSL_FAILURE;
12521            }
12522
12523            slhdsa = (SlhDsaKey*)XMALLOC(sizeof(SlhDsaKey), NULL,
12524                                          DYNAMIC_TYPE_SLHDSA);
12525            if (slhdsa == NULL) {
12526                WOLFSSL_MSG("Failed to allocate memory for SlhDsaKey");
12527                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12528                return WOLFSSL_FAILURE;
12529            }
12530
12531            type = certType;
12532
12533            ret = wc_SlhDsaKey_Init(slhdsa, (enum SlhDsaParam)paramInt, NULL,
12534                                    INVALID_DEVID);
12535            if (ret != 0) {
12536                XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA);
12537                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12538                return ret;
12539            }
12540
12541            ret = wc_SlhDsaKey_PublicKeyDecode(x509->pubKey.buffer, &idx,
12542                                               slhdsa, x509->pubKey.length);
12543            if (ret != 0) {
12544                WOLFSSL_ERROR_VERBOSE(ret);
12545                wc_SlhDsaKey_Free(slhdsa);
12546                XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA);
12547                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12548                return ret;
12549            }
12550            key = (void*)slhdsa;
12551        }
12552    #endif
12553        if (key == NULL) {
12554            WOLFSSL_MSG("No public key found for certificate");
12555            XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12556            return WOLFSSL_FAILURE;
12557        }
12558
12559        /* Make the body of the certificate request. */
12560    #ifdef WOLFSSL_CERT_REQ
12561        if (req) {
12562            ret = wc_MakeCertReq_ex(cert, der, *derSz, type, key);
12563        }
12564        else
12565    #endif
12566        {
12567            ret = wc_InitRng(&rng);
12568            if (ret != 0) {
12569                ret = WOLFSSL_FAILURE;
12570                goto cleanup;
12571            }
12572
12573            ret = wc_MakeCert_ex(cert, der, *derSz, type, key, &rng);
12574            wc_FreeRng(&rng);
12575        }
12576        if (ret <= 0) {
12577            WOLFSSL_ERROR_VERBOSE(ret);
12578            ret = WOLFSSL_FAILURE;
12579            goto cleanup;
12580        }
12581
12582        if ((x509->serialSz == 0) &&
12583                (cert->serialSz <= EXTERNAL_SERIAL_SIZE) &&
12584                (cert->serialSz > 0)) {
12585        #if defined(OPENSSL_EXTRA)
12586            WOLFSSL_ASN1_INTEGER *i = wolfSSL_ASN1_INTEGER_new();
12587
12588            if (i == NULL) {
12589                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
12590                ret = WOLFSSL_FAILURE;
12591                goto cleanup;
12592            }
12593            else {
12594                i->length = cert->serialSz + 2;
12595                i->data[0] = ASN_INTEGER;
12596                i->data[1] = (unsigned char)cert->serialSz;
12597                XMEMCPY(i->data + 2, cert->serial, cert->serialSz);
12598                if (wolfSSL_X509_set_serialNumber(x509, i) != WOLFSSL_SUCCESS) {
12599                    WOLFSSL_MSG("Issue setting generated serial number");
12600                    wolfSSL_ASN1_INTEGER_free(i);
12601                    ret = WOLFSSL_FAILURE;
12602                    goto cleanup;
12603                }
12604                wolfSSL_ASN1_INTEGER_free(i);
12605            }
12606        #else
12607            WOLFSSL_MSG("ASN1_INTEGER API not in build");
12608
12609            ret = WOLFSSL_FAILURE;
12610            goto cleanup;
12611        #endif /* OPENSSL_EXTRA */
12612        }
12613
12614        if (includeSig) {
12615            if (!x509->sig.buffer) {
12616                WOLFSSL_MSG("No signature buffer");
12617                ret = WOLFSSL_FAILURE;
12618                goto cleanup;
12619            }
12620            totalLen = AddSignature(NULL, ret, NULL, x509->sig.length,
12621                                  x509->sigOID);
12622            if (totalLen > *derSz) {
12623                WOLFSSL_MSG("Output der buffer too short");
12624                ret = WOLFSSL_FAILURE;
12625                goto cleanup;
12626            }
12627            ret = AddSignature(der, ret, x509->sig.buffer,
12628                               x509->sig.length, x509->sigOID);
12629        }
12630
12631        *derSz = ret;
12632        ret = WOLFSSL_SUCCESS;
12633cleanup:
12634        /* Dispose of the public key object. */
12635    #ifndef NO_RSA
12636        if (x509->pubKeyOID == RSAk) {
12637            wc_FreeRsaKey(rsa);
12638            XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
12639        }
12640    #endif
12641    #ifdef HAVE_ECC
12642        if (x509->pubKeyOID == ECDSAk) {
12643            wc_ecc_free(ecc);
12644            XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
12645        }
12646    #endif
12647    #ifndef NO_DSA
12648        if (x509->pubKeyOID == DSAk) {
12649            wc_FreeDsaKey(dsa);
12650            XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
12651        }
12652    #endif
12653    #if defined(HAVE_FALCON)
12654        if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
12655            (x509->pubKeyOID == FALCON_LEVEL5k)) {
12656            wc_falcon_free(falcon);
12657            XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
12658        }
12659    #endif
12660    #if defined(HAVE_DILITHIUM)
12661        if ((x509->pubKeyOID == ML_DSA_LEVEL2k) ||
12662            (x509->pubKeyOID == ML_DSA_LEVEL3k) ||
12663            (x509->pubKeyOID == ML_DSA_LEVEL5k)
12664        #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
12665         || (x509->pubKeyOID == DILITHIUM_LEVEL2k)
12666         || (x509->pubKeyOID == DILITHIUM_LEVEL3k)
12667         || (x509->pubKeyOID == DILITHIUM_LEVEL5k)
12668        #endif
12669        ) {
12670            wc_dilithium_free(dilithium);
12671            XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
12672        }
12673    #endif
12674    #if defined(WOLFSSL_HAVE_SLHDSA)
12675        /* wc_IsSlhDsaOid returns 1 even for OIDs whose backend is
12676         * NOT_COMPILED_IN; the early-return at the top of the SLH-DSA
12677         * branch keeps slhdsa==NULL in that case. Guard the cleanup so
12678         * future restructuring (a goto cleanup from inside the
12679         * unbuilt-variant handler) cannot dereference a NULL key. */
12680        if (wc_IsSlhDsaOid(x509->pubKeyOID) && slhdsa != NULL) {
12681            wc_SlhDsaKey_Free(slhdsa);
12682            XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA);
12683        }
12684    #endif
12685        XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12686
12687        return ret;
12688    }
12689
12690
12691    /* signs a der buffer for the WOLFSSL_X509 structure using the PKEY and MD
12692     * hash passed in
12693     *
12694     * WARNING: this free's and replaces the existing DER buffer in the
12695     *          WOLFSSL_X509 with the newly signed buffer.
12696     * returns size of signed buffer on success and negative values on fail
12697     */
12698    static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req,
12699            unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md,
12700            WOLFSSL_EVP_PKEY* pkey)
12701    {
12702        int ret;
12703        void* key = NULL;
12704        int type = -1;
12705        int sigType;
12706        WC_RNG rng;
12707
12708        (void)req;
12709        WOLFSSL_ENTER("wolfSSL_X509_resign_cert");
12710
12711        sigType = wolfSSL_sigTypeFromPKEY(md, pkey);
12712        if (sigType == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
12713            WOLFSSL_MSG("Error getting signature type from pkey");
12714            return WOLFSSL_FATAL_ERROR;
12715        }
12716
12717
12718        /* Get the private key object and type from pkey. */
12719    #ifndef NO_RSA
12720        if (pkey->type == WC_EVP_PKEY_RSA) {
12721            type = RSA_TYPE;
12722            key = pkey->rsa->internal;
12723        }
12724    #endif
12725    #ifdef HAVE_ECC
12726        if (pkey->type == WC_EVP_PKEY_EC) {
12727            type = ECC_TYPE;
12728            key = pkey->ecc->internal;
12729        }
12730    #endif
12731
12732        /* Sign the certificate (request) body. */
12733        ret = wc_InitRng(&rng);
12734        if (ret != 0)
12735            return ret;
12736        ret = wc_SignCert_ex(certBodySz, sigType, der, (word32)derSz, type, key,
12737            &rng);
12738        wc_FreeRng(&rng);
12739        if (ret < 0) {
12740            WOLFSSL_LEAVE("wolfSSL_X509_resign_cert", ret);
12741            return ret;
12742        }
12743        derSz = ret;
12744
12745        /* Extract signature from buffer */
12746        {
12747            word32 idx = 0;
12748            int    len = 0;
12749
12750            /* Read top level sequence */
12751            if (GetSequence(der, &idx, &len, (word32)derSz) < 0) {
12752                WOLFSSL_MSG("GetSequence error");
12753                return WOLFSSL_FATAL_ERROR;
12754            }
12755            /* Move idx to signature */
12756            idx += certBodySz;
12757            /* Read signature algo sequence */
12758            if (GetSequence(der, &idx, &len, (word32)derSz) < 0) {
12759                WOLFSSL_MSG("GetSequence error");
12760                return WOLFSSL_FATAL_ERROR;
12761            }
12762            idx += len;
12763            /* Read signature bit string */
12764            if (CheckBitString(der, &idx, &len, (word32)derSz, 0, NULL) != 0) {
12765                WOLFSSL_MSG("CheckBitString error");
12766                return WOLFSSL_FATAL_ERROR;
12767            }
12768            /* Sanity check */
12769            if (idx + len != (word32)derSz) {
12770                WOLFSSL_MSG("unexpected asn1 structure");
12771                return WOLFSSL_FATAL_ERROR;
12772            }
12773            x509->sig.length = 0;
12774            if (x509->sig.buffer)
12775                XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
12776            x509->sig.buffer = (byte*)XMALLOC(len, x509->heap,
12777                                              DYNAMIC_TYPE_SIGNATURE);
12778            if (!x509->sig.buffer) {
12779                WOLFSSL_MSG("malloc error");
12780                return WOLFSSL_FATAL_ERROR;
12781            }
12782            XMEMCPY(x509->sig.buffer, der + idx, len);
12783            x509->sig.length = (unsigned int)len;
12784        }
12785
12786        /* Put in the new certificate encoding into the x509 object. */
12787        FreeDer(&x509->derCert);
12788        type = CERT_TYPE;
12789    #ifdef WOLFSSL_CERT_REQ
12790        if (req) {
12791            type = CERTREQ_TYPE;
12792        }
12793    #endif
12794        if (AllocDer(&x509->derCert, (word32)derSz, type, NULL) != 0)
12795            return WOLFSSL_FATAL_ERROR;
12796        XMEMCPY(x509->derCert->buffer, der, derSz);
12797        x509->derCert->length = (word32)derSz;
12798
12799        return ret;
12800    }
12801
12802
12803#ifndef WC_MAX_X509_GEN
12804    /* able to override max size until dynamic buffer created */
12805    #define WC_MAX_X509_GEN 4096
12806#endif
12807
12808/* returns the size of signature on success */
12809int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
12810        const WOLFSSL_EVP_MD* md)
12811{
12812    int  ret;
12813    /* @TODO dynamic set based on expected cert size */
12814    byte *der = (byte *)XMALLOC(WC_MAX_X509_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12815    int  derSz = WC_MAX_X509_GEN;
12816
12817    WOLFSSL_ENTER("wolfSSL_X509_sign");
12818
12819    if (x509 == NULL || pkey == NULL || md == NULL) {
12820        ret = WOLFSSL_FAILURE;
12821        goto out;
12822    }
12823
12824    x509->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
12825    if ((ret = wolfssl_x509_make_der(x509, 0, der, &derSz, 0)) !=
12826            WOLFSSL_SUCCESS) {
12827        WOLFSSL_MSG("Unable to make DER for X509");
12828        WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
12829        (void)ret;
12830        ret = WOLFSSL_FAILURE;
12831        goto out;
12832    }
12833
12834    ret = wolfSSL_X509_resign_cert(x509, 0, der, WC_MAX_X509_GEN, derSz,
12835            (WOLFSSL_EVP_MD*)md, pkey);
12836    if (ret <= 0) {
12837        WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
12838        ret = WOLFSSL_FAILURE;
12839        goto out;
12840    }
12841
12842out:
12843    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12844
12845    return ret;
12846}
12847
12848#if defined(OPENSSL_EXTRA)
12849int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx)
12850{
12851    WOLFSSL_ENTER("wolfSSL_X509_sign_ctx");
12852
12853    if (!x509 || !ctx || !ctx->pctx || !ctx->pctx->pkey) {
12854        WOLFSSL_MSG("Bad parameter");
12855        return WOLFSSL_FAILURE;
12856    }
12857
12858    return wolfSSL_X509_sign(x509, ctx->pctx->pkey,
12859        wolfSSL_EVP_MD_CTX_md(ctx));
12860}
12861#endif /* OPENSSL_EXTRA */
12862#endif /* WOLFSSL_CERT_GEN */
12863
12864
12865#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
12866    defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
12867/* Converts from WC_NID_* value to wolfSSL value if needed.
12868 *
12869 * @param [in] nid  Numeric Id of a domain name component.
12870 * @return  Domain name tag values - wolfSSL internal values.
12871 * @return  -1 when nid isn't known.
12872 */
12873static int ConvertNIDToWolfSSL(int nid)
12874{
12875    switch (nid) {
12876        case WC_NID_commonName : return ASN_COMMON_NAME;
12877    #ifdef WOLFSSL_CERT_NAME_ALL
12878        case WC_NID_name :       return ASN_NAME;
12879        case WC_NID_givenName:   return ASN_GIVEN_NAME;
12880        case WC_NID_dnQualifier :   return ASN_DNQUALIFIER;
12881        case WC_NID_initials:   return ASN_INITIALS;
12882    #endif /* WOLFSSL_CERT_NAME_ALL */
12883        case WC_NID_surname :    return ASN_SUR_NAME;
12884        case WC_NID_countryName: return ASN_COUNTRY_NAME;
12885        case WC_NID_localityName: return ASN_LOCALITY_NAME;
12886        case WC_NID_stateOrProvinceName: return ASN_STATE_NAME;
12887        case WC_NID_streetAddress: return ASN_STREET_ADDR;
12888        case WC_NID_organizationName: return ASN_ORG_NAME;
12889        case WC_NID_organizationalUnitName: return ASN_ORGUNIT_NAME;
12890        case WC_NID_emailAddress: return ASN_EMAIL_NAME;
12891        case WC_NID_pkcs9_contentType: return ASN_CONTENT_TYPE;
12892        case WC_NID_serialNumber: return ASN_SERIAL_NUMBER;
12893        case WC_NID_userId: return ASN_USER_ID;
12894        case WC_NID_businessCategory: return ASN_BUS_CAT;
12895        case WC_NID_domainComponent: return ASN_DOMAIN_COMPONENT;
12896        case WC_NID_postalCode: return ASN_POSTAL_CODE;
12897        case WC_NID_rfc822Mailbox: return ASN_RFC822_MAILBOX;
12898        case WC_NID_favouriteDrink: return ASN_FAVOURITE_DRINK;
12899        default:
12900            WOLFSSL_MSG("Attribute NID not found");
12901            return WOLFSSL_FATAL_ERROR;
12902    }
12903}
12904#endif /* OPENSSL_ALL || OPENSSL_EXTRA ||
12905          OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL*/
12906
12907#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
12908    defined(OPENSSL_EXTRA_X509_SMALL)
12909/* This is to convert the x509 name structure into canonical DER format     */
12910/*  , which has the following rules:                                        */
12911/*   convert to UTF8                                                        */
12912/*   convert to lower case                                                  */
12913/*   multi-spaces collapsed                                                 */
12914/*   leading SEQUENCE header is skipped                                     */
12915/* @param  name a pointer to X509_NAME that is to be converted              */
12916/* @param  out  a pointer to converted data                                 */
12917/* @return a number of converted bytes, otherwise <=0 error code            */
12918int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out)
12919{
12920    int  totalBytes = 0, i, idx;
12921    byte *output, *local = NULL;
12922    WC_DECLARE_VAR(names, EncodedName, MAX_NAME_ENTRIES, 0);
12923
12924    if (name == NULL)
12925        return BAD_FUNC_ARG;
12926
12927    WC_ALLOC_VAR_EX(names, EncodedName, MAX_NAME_ENTRIES, NULL,
12928        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
12929
12930    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
12931
12932    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
12933        WOLFSSL_X509_NAME_ENTRY* entry;
12934        int ret;
12935
12936        entry = wolfSSL_X509_NAME_get_entry(name, i);
12937        if (entry != NULL && entry->set >= 1) {
12938            const char* nameStr;
12939            WOLFSSL_ASN1_STRING* data;
12940            WOLFSSL_ASN1_STRING* cano_data;
12941
12942            cano_data = wolfSSL_ASN1_STRING_new();
12943            if (cano_data == NULL) {
12944                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12945                return MEMORY_E;
12946            }
12947
12948            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
12949            if (data == NULL) {
12950                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12951                wolfSSL_ASN1_STRING_free(cano_data);
12952                WOLFSSL_MSG("Error getting entry data");
12953                return WOLFSSL_FATAL_ERROR;
12954            }
12955            if (wolfSSL_ASN1_STRING_canon(cano_data, data) != WOLFSSL_SUCCESS) {
12956                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12957                wolfSSL_ASN1_STRING_free(cano_data);
12958                return WOLFSSL_FAILURE;
12959            }
12960            nameStr = (const char*)wolfSSL_ASN1_STRING_data(cano_data);
12961
12962            /* allow for blank values in the name structure, eg OU= */
12963            if (nameStr)
12964            {
12965                ret = wc_EncodeNameCanonical(&names[i], nameStr, CTC_UTF8,
12966                    (byte)ConvertNIDToWolfSSL(entry->nid));
12967                if (ret < 0) {
12968                    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12969                    wolfSSL_ASN1_STRING_free(cano_data);
12970                    WOLFSSL_MSG("EncodeName failed");
12971                    return WOLFSSL_FATAL_ERROR;
12972                }
12973                totalBytes += ret;
12974            }
12975
12976            wolfSSL_ASN1_STRING_free(cano_data);
12977        }
12978    }
12979
12980    if (out == NULL) {
12981        /* If out is NULL, caller just wants length. */
12982        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12983        return totalBytes;
12984    }
12985
12986    /* skip header */
12987    /* check if using buffer passed in */
12988    if (*out == NULL) {
12989        *out = local = (unsigned char*)XMALLOC(totalBytes, NULL,
12990                DYNAMIC_TYPE_OPENSSL);
12991        if (*out == NULL) {
12992            return MEMORY_E;
12993        }
12994    }
12995    output = *out;
12996    idx = 0;
12997
12998    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
12999        if (names[i].used) {
13000            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
13001            idx += names[i].totalLen;
13002        }
13003    }
13004
13005    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13006
13007    /* used existing buffer passed in, so increment pointer */
13008    if (local == NULL) {
13009        *out += totalBytes;
13010    }
13011    return totalBytes;
13012}
13013#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
13014
13015#ifdef WOLFSSL_CERT_GEN
13016/* Guarded by either
13017 * A) WOLFSSL_WPAS_SMALL is on or
13018 * B) (OPENSSL_EXTRA or OPENSSL_EXTRA_X509_SMALL) + WOLFSSL_CERT_GEN +
13019 *    (WOLFSSL_CERT_REQ or WOLFSSL_CERT_EXT or OPENSSL_EXTRA) has been
13020 *    defined
13021 */
13022#if defined(WOLFSSL_WPAS_SMALL) || \
13023    (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13024    defined(WOLFSSL_CERT_GEN) && \
13025    (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
13026     defined(OPENSSL_EXTRA))
13027
13028/* Converts the x509 name structure into DER format.
13029 *
13030 * out  pointer to either a pre setup buffer or a pointer to null for
13031 *      creating a dynamic buffer. In the case that a pre-existing buffer is
13032 *      used out will be incremented the size of the DER buffer on success. If
13033 *      out is NULL, the function returns the necessary output buffer length.
13034 *
13035 * returns the size of the buffer on success, or negative value with failure
13036 */
13037int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
13038{
13039    int  totalBytes = 0, i, idx;
13040    byte temp[MAX_SEQ_SZ];
13041    byte *output, *local = NULL;
13042    WC_DECLARE_VAR(names, EncodedName, MAX_NAME_ENTRIES, 0);
13043
13044    if (name == NULL)
13045        return BAD_FUNC_ARG;
13046
13047    WC_ALLOC_VAR_EX(names, EncodedName, MAX_NAME_ENTRIES, NULL,
13048        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
13049
13050    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
13051
13052    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
13053        WOLFSSL_X509_NAME_ENTRY* entry;
13054        int ret;
13055
13056        entry = wolfSSL_X509_NAME_get_entry(name, i);
13057        if (entry != NULL && entry->set >= 1) {
13058            const char* nameStr;
13059            int type;
13060            WOLFSSL_ASN1_STRING* data;
13061
13062            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
13063            if (data == NULL) {
13064                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13065                WOLFSSL_MSG("Error getting entry data");
13066                return WOLFSSL_FATAL_ERROR;
13067            }
13068
13069            nameStr = (const char*)wolfSSL_ASN1_STRING_data(data);
13070            type    = wolfSSL_ASN1_STRING_type(data);
13071
13072            switch (type) {
13073                case WOLFSSL_MBSTRING_UTF8:
13074                    type = CTC_UTF8;
13075                    break;
13076                case WOLFSSL_MBSTRING_ASC:
13077                case WOLFSSL_V_ASN1_PRINTABLESTRING:
13078                    type = CTC_PRINTABLE;
13079                    break;
13080                default:
13081                    WOLFSSL_MSG(
13082                        "Unknown encoding type conversion UTF8 by default");
13083                    type = CTC_UTF8;
13084            }
13085            ret = wc_EncodeName(&names[i], nameStr, (char)type,
13086                (byte)ConvertNIDToWolfSSL(entry->nid));
13087            if (ret < 0) {
13088                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13089                WOLFSSL_MSG("EncodeName failed");
13090                return WOLFSSL_FATAL_ERROR;
13091            }
13092            totalBytes += ret;
13093        }
13094    }
13095
13096    /* header */
13097    idx = (int)SetSequence((word32)totalBytes, temp);
13098    if (totalBytes + idx > ASN_NAME_MAX) {
13099        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13100        WOLFSSL_MSG("Total Bytes is greater than ASN_NAME_MAX");
13101        return BUFFER_E;
13102    }
13103
13104    if (out == NULL) {
13105        /* If out is NULL, caller just wants length. */
13106        totalBytes += idx;
13107        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13108        return totalBytes;
13109    }
13110
13111    /* check if using buffer passed in */
13112    if (*out == NULL) {
13113        *out = local = (unsigned char*)XMALLOC(totalBytes + idx, name->heap,
13114                DYNAMIC_TYPE_OPENSSL);
13115        if (*out == NULL) {
13116            return MEMORY_E;
13117        }
13118    }
13119    output = *out;
13120
13121    idx = (int)SetSequence((word32)totalBytes, output);
13122    totalBytes += idx;
13123    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
13124        if (names[i].used) {
13125            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
13126            idx += names[i].totalLen;
13127        }
13128    }
13129
13130    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13131
13132    /* used existing buffer passed in, so increment pointer */
13133    if (local == NULL) {
13134        *out += totalBytes;
13135    }
13136    return totalBytes;
13137}
13138#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
13139#endif /* WOLFSSL_CERT_GEN */
13140
13141#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
13142    defined (WOLFSSL_WPAS_SMALL)
13143
13144    WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name,
13145                                             unsigned char **in, long length)
13146    {
13147        WOLFSSL_X509_NAME* tmp = NULL;
13148        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
13149
13150        WOLFSSL_ENTER("wolfSSL_d2i_X509_NAME");
13151
13152        if (!in || !*in || length <= 0) {
13153            WOLFSSL_MSG("Bad argument");
13154            return NULL;
13155        }
13156
13157        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
13158            return NULL);
13159
13160        /* Set the X509_NAME buffer as the input data for cert.
13161         * in is NOT a full certificate. Just the name. */
13162        InitDecodedCert(cert, *in, (word32)length, NULL);
13163
13164        /* Parse the X509 subject name */
13165        if (GetName(cert, ASN_SUBJECT, (int)length) != 0) {
13166            WOLFSSL_MSG("WOLFSSL_X509_NAME parse error");
13167            goto cleanup;
13168        }
13169
13170        if (!(tmp = wolfSSL_X509_NAME_new_ex(cert->heap))) {
13171            WOLFSSL_MSG("wolfSSL_X509_NAME_new_ex error");
13172            goto cleanup;
13173        }
13174
13175        if (wolfSSL_X509_NAME_copy((WOLFSSL_X509_NAME*)cert->subjectName,
13176                    tmp) != WOLFSSL_SUCCESS) {
13177            wolfSSL_X509_NAME_free(tmp);
13178            tmp = NULL;
13179            goto cleanup;
13180        }
13181
13182        if (name)
13183            *name = tmp;
13184cleanup:
13185        FreeDecodedCert(cert);
13186        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
13187        return tmp;
13188    }
13189#endif /* OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_WPAS_SMALL */
13190
13191
13192#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
13193
13194    /* Compares the two X509 names. If the size of x is larger then y then a
13195     * positive value is returned if x is smaller a negative value is returned.
13196     * In the case that the sizes are equal a the value of strcmp between the
13197     * two names is returned.
13198     *
13199     * x First name for comparison
13200     * y Second name to compare with x
13201     */
13202    int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x,
13203            const WOLFSSL_X509_NAME* y)
13204    {
13205        const char* _x;
13206        const char* _y;
13207        WOLFSSL_ENTER("wolfSSL_X509_NAME_cmp");
13208
13209        if (x == NULL || y == NULL) {
13210            WOLFSSL_MSG("Bad argument passed in");
13211            return -2;
13212        }
13213
13214        if (x == y) {
13215            return 0; /* match */
13216        }
13217
13218        if (x->sz != y->sz) {
13219            return x->sz - y->sz;
13220        }
13221
13222        /*
13223         * If the name member is not set or is immediately null terminated then
13224         * compare the staticName member
13225         */
13226        _x = (x->name && *x->name) ? x->name : x->staticName;
13227        _y = (y->name && *y->name) ? y->name : y->staticName;
13228
13229        return XSTRNCASECMP(_x, _y, x->sz); /* y sz is the same */
13230    }
13231
13232#ifndef NO_BIO
13233
13234static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
13235        WOLFSSL_X509 **x, wc_pem_password_cb *cb, void *u, int type)
13236{
13237    WOLFSSL_X509* x509 = NULL;
13238#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
13239    unsigned char* pem = NULL;
13240    int pemSz;
13241    long  i = 0, l, footerSz;
13242    const char* footer = NULL;
13243    int streaming = 0;  /* Flag to indicate if source is streaming (FIFO) */
13244    const char* altFooter = NULL;
13245    long altFooterSz = 0;
13246
13247    WOLFSSL_ENTER("loadX509orX509REQFromPemBio");
13248
13249    if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE &&
13250                       type != TRUSTED_CERT_TYPE)) {
13251        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
13252        return NULL;
13253    }
13254
13255    if ((l = wolfSSL_BIO_get_len(bp)) <= 0) {
13256        /* No certificate size available - could be FIFO or other streaming
13257         * source. Use MAX_X509_SIZE as initial buffer, will resize if needed. */
13258        l = MAX_X509_SIZE;
13259        streaming = 1;
13260    }
13261
13262    pemSz = (int)l;
13263    pem   = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
13264    if (pem == NULL)
13265        return NULL;
13266    XMEMSET(pem, 0, pemSz);
13267
13268    i = 0;
13269    if (wc_PemGetHeaderFooter(type, NULL, &footer) != 0) {
13270        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
13271        return NULL;
13272    }
13273    footerSz = (long)XSTRLEN(footer);
13274
13275    /* For TRUSTED_CERT_TYPE, also prepare to check for regular CERT footer
13276     * as the file might contain regular certificates instead of TRUSTED
13277     * format */
13278    if (type == TRUSTED_CERT_TYPE) {
13279        wc_PemGetHeaderFooter(CERT_TYPE, NULL, &altFooter);
13280        if (altFooter != NULL) {
13281            altFooterSz = (long)XSTRLEN(altFooter);
13282        }
13283    }
13284
13285    /* TODO: Inefficient
13286     * reading in one byte at a time until see the footer
13287     */
13288    while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
13289        int foundFooter = 0;
13290        i++;
13291        /* Check if buffer is full and we're reading from streaming source */
13292        if (i >= pemSz && streaming) {
13293            /* Double the buffer size for streaming sources */
13294            int newSz = pemSz * 2;
13295            unsigned char* newPem;
13296
13297            /* Sanity check: don't grow beyond reasonable limit */
13298            if (newSz > MAX_BIO_READ_BUFFER) {
13299                WOLFSSL_MSG("PEM data too large for streaming source");
13300                XFREE(pem, 0, DYNAMIC_TYPE_PEM);
13301                return NULL;
13302            }
13303
13304            newPem = (unsigned char*)XREALLOC(pem, newSz, 0, DYNAMIC_TYPE_PEM);
13305            if (newPem == NULL) {
13306                WOLFSSL_MSG("Failed to resize PEM buffer");
13307                XFREE(pem, 0, DYNAMIC_TYPE_PEM);
13308                return NULL;
13309            }
13310
13311            pem = newPem;
13312            pemSz = newSz;
13313        }
13314        else if (i >= pemSz) {
13315            /* Buffer full for non-streaming source - this shouldn't happen */
13316            break;
13317        }
13318
13319        /* Check for the expected footer OR alternate footer (for
13320         * TRUSTED_CERT_TYPE) */
13321        if (i > footerSz &&
13322            XMEMCMP((char *)&pem[i-footerSz], footer, footerSz) == 0) {
13323            foundFooter = 1;
13324        }
13325        else if (i > altFooterSz && altFooter != NULL &&
13326            XMEMCMP((char *)&pem[i-altFooterSz], altFooter, altFooterSz) == 0) {
13327            foundFooter = 1;
13328        }
13329
13330        if (foundFooter) {
13331            if (i < pemSz && wolfSSL_BIO_read(bp, (char *)&pem[i], 1) == 1) {
13332                /* attempt to read newline following footer */
13333                i++;
13334                if (i < pemSz && pem[i-1] == '\r') {
13335                    /* found \r , Windows line ending is \r\n so try to read one
13336                     * more byte for \n, ignoring return value */
13337                    (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
13338                }
13339            }
13340            break;
13341        }
13342    }
13343    if (l == 0 && i == 0) {
13344        WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
13345    }
13346    if (i > pemSz) {
13347        WOLFSSL_MSG("Error parsing PEM");
13348    }
13349    else {
13350        pemSz = (int)i;
13351    #ifdef WOLFSSL_CERT_REQ
13352        if (type == CERTREQ_TYPE)
13353            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
13354                CERTREQ_TYPE, cb, u);
13355        else
13356    #endif
13357        /* Use TRUSTED_CERT_TYPE if input was TRUSTED CERTIFICATE format,
13358         * otherwise use CERT_TYPE for regular certificates */
13359        if (type == TRUSTED_CERT_TYPE)
13360            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
13361                TRUSTED_CERT_TYPE, cb, u);
13362        else
13363            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
13364                CERT_TYPE, cb, u);
13365    }
13366
13367    if (x != NULL) {
13368        *x = x509;
13369    }
13370
13371    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
13372
13373#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
13374    (void)bp;
13375    (void)x;
13376    (void)cb;
13377    (void)u;
13378
13379    return x509;
13380}
13381
13382
13383WC_MAYBE_UNUSED
13384static unsigned char* ReadPemFromBioToBuffer(WOLFSSL_BIO *bp, int *pemSz)
13385{
13386    unsigned char* pem = NULL;
13387
13388    WOLFSSL_ENTER("ReadPemFromBioToBuffer");
13389
13390    if (bp == NULL || pemSz == NULL) {
13391        WOLFSSL_LEAVE("ReadPemFromBioToBuffer", BAD_FUNC_ARG);
13392        return NULL;
13393    }
13394
13395    if ((*pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
13396        /* No certificate size available - could be FIFO or other streaming
13397         * source. Use MAX_X509_SIZE as initial buffer, read in loop. */
13398        int totalRead = 0;
13399        int readSz;
13400
13401        *pemSz = MAX_X509_SIZE;
13402        pem = (unsigned char*)XMALLOC(*pemSz, 0, DYNAMIC_TYPE_PEM);
13403        if (pem == NULL) {
13404            return NULL;
13405        }
13406
13407        /* Read from streaming source until EOF or buffer full */
13408        while ((readSz = wolfSSL_BIO_read(bp, pem + totalRead,
13409                                          *pemSz - totalRead)) > 0) {
13410            totalRead += readSz;
13411
13412            /* If buffer is full, try to grow it */
13413            if (totalRead >= *pemSz) {
13414                int newSz = *pemSz * 2;
13415                unsigned char* newPem;
13416
13417                /* Sanity check */
13418                if (newSz > MAX_BIO_READ_BUFFER) {
13419                    WOLFSSL_MSG("PEM data too large for streaming source");
13420                    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
13421                    return NULL;
13422                }
13423
13424                newPem = (unsigned char*)XREALLOC(pem, newSz, 0,
13425                        DYNAMIC_TYPE_PEM);
13426                if (newPem == NULL) {
13427                    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
13428                    return NULL;
13429                }
13430                pem = newPem;
13431                *pemSz = newSz;
13432            }
13433        }
13434
13435        *pemSz = totalRead;
13436        if (*pemSz <= 0) {
13437            XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
13438            return NULL;
13439        }
13440    }
13441    else {
13442        /* Known size - allocate and read */
13443        pem = (unsigned char*)XMALLOC(*pemSz, 0, DYNAMIC_TYPE_PEM);
13444        if (pem == NULL) {
13445            return NULL;
13446        }
13447
13448        XMEMSET(pem, 0, *pemSz);
13449
13450        *pemSz = wolfSSL_BIO_read(bp, pem, *pemSz);
13451        if (*pemSz <= 0) {
13452            XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
13453            return NULL;
13454        }
13455    }
13456
13457    WOLFSSL_LEAVE("ReadPemFromBioToBuffer", 0);
13458    return pem;
13459}
13460
13461
13462
13463#if defined(WOLFSSL_ACERT)
13464    WOLFSSL_X509_ACERT *wolfSSL_PEM_read_bio_X509_ACERT(WOLFSSL_BIO *bp,
13465                                                        WOLFSSL_X509_ACERT **x,
13466                                                        wc_pem_password_cb *cb,
13467                                                        void *u)
13468    {
13469        WOLFSSL_X509_ACERT* x509 = NULL;
13470#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
13471        unsigned char * pem = NULL;
13472        int             pemSz;
13473
13474        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_ACERT");
13475
13476        if (bp == NULL) {
13477            return NULL;
13478        }
13479
13480        pem = ReadPemFromBioToBuffer(bp, &pemSz);
13481        if (pem == NULL) {
13482            return NULL;
13483        }
13484
13485        x509 = wolfSSL_X509_ACERT_load_certificate_buffer(pem, pemSz,
13486                                                          WOLFSSL_FILETYPE_PEM);
13487
13488        if (x != NULL) {
13489            *x = x509;
13490        }
13491
13492        XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
13493
13494#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
13495        (void)bp;
13496        (void)x;
13497        (void)cb;
13498        (void)u;
13499
13500        return x509;
13501
13502    }
13503#endif /* WOLFSSL_ACERT */
13504
13505    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
13506                                            wc_pem_password_cb *cb, void *u)
13507    {
13508        return loadX509orX509REQFromPemBio(bp, x, cb, u, CERT_TYPE);
13509    }
13510
13511    /*
13512     * bp : bio to read X509 from
13513     * x  : x509 to write to
13514     * cb : password call back for reading PEM
13515     * u  : password
13516     * _AUX is for working with a trusted X509 certificate
13517     */
13518    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
13519                               WOLFSSL_X509 **x, wc_pem_password_cb *cb,
13520                               void *u)
13521    {
13522        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_AUX");
13523
13524        /* AUX info is; trusted/rejected uses, friendly name, private key id,
13525         * and potentially a stack of "other" info. wolfSSL does not store
13526         * friendly name or private key id yet in WOLFSSL_X509 for human
13527         * readability and does not support extra trusted/rejected uses for
13528         * root CA. Use TRUSTED_CERT_TYPE to properly parse TRUSTED CERTIFICATE
13529         * format and strip auxiliary data. */
13530        return loadX509orX509REQFromPemBio(bp, x, cb, u, TRUSTED_CERT_TYPE);
13531    }
13532
13533#ifdef WOLFSSL_CERT_REQ
13534WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
13535                                                wc_pem_password_cb *cb, void *u)
13536{
13537    return loadX509orX509REQFromPemBio(bp, x, cb, u, CERTREQ_TYPE);
13538}
13539
13540#ifndef NO_FILESYSTEM
13541    WOLFSSL_X509* wolfSSL_PEM_read_X509_REQ(XFILE fp, WOLFSSL_X509** x,
13542                                            wc_pem_password_cb* cb, void* u)
13543    {
13544        int err = 0;
13545        WOLFSSL_X509* ret = NULL;
13546        WOLFSSL_BIO* bio = NULL;
13547
13548        WOLFSSL_ENTER("wolfSSL_PEM_read_X509_REQ");
13549
13550        if (fp == XBADFILE) {
13551            WOLFSSL_MSG("Invalid file.");
13552            err = 1;
13553        }
13554
13555        if (err == 0) {
13556            bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
13557            if (bio == NULL) {
13558                WOLFSSL_MSG("Failed to create new BIO with input file.");
13559                err = 1;
13560            }
13561        }
13562        if (err == 0 && wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_CLOSE)
13563                != WOLFSSL_SUCCESS) {
13564            WOLFSSL_MSG("Failed to set BIO file pointer.");
13565            err = 1;
13566        }
13567        if (err == 0) {
13568            ret = wolfSSL_PEM_read_bio_X509_REQ(bio, x, cb, u);
13569        }
13570
13571        wolfSSL_BIO_free(bio);
13572
13573        return ret;
13574    }
13575#endif /* !NO_FILESYSTEM */
13576#endif /* WOLFSSL_CERT_REQ */
13577
13578    WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp,
13579            WOLFSSL_X509_CRL **x, wc_pem_password_cb *cb, void *u)
13580    {
13581#if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL)
13582        WOLFSSL_X509_CRL* crl = NULL;
13583
13584        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_CRL");
13585
13586        /* OpenSSL's PEM_read_bio_X509_CRL skips intervening cert/key blocks
13587         * and returns the next CRL in the stream (NULL only at EOF). Mirror
13588         * that by looping over the per-block reader until we get a CRL or
13589         * the BIO has nothing left to parse. */
13590        for (;;) {
13591            WOLFSSL_X509*      x509   = NULL;
13592            WOLFSSL_X509_PKEY* x_pkey = NULL;
13593            if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bp, cb,
13594                        &x509, &crl, &x_pkey) != WOLFSSL_SUCCESS) {
13595                break;
13596            }
13597            if (crl != NULL) {
13598                break;
13599            }
13600            wolfSSL_X509_free(x509);
13601            wolfSSL_X509_PKEY_free(x_pkey);
13602        }
13603
13604        if (x != NULL) {
13605            if (*x != NULL && *x != crl) {
13606                wolfSSL_X509_CRL_free(*x);
13607            }
13608            *x = crl;
13609        }
13610
13611        (void)u;
13612
13613        return crl;
13614#else
13615        (void)bp;
13616        (void)x;
13617        (void)cb;
13618        (void)u;
13619
13620        return NULL;
13621#endif
13622    }
13623
13624#endif /* !NO_BIO */
13625
13626#if !defined(NO_FILESYSTEM)
13627static void* wolfSSL_PEM_read_X509_ex(XFILE fp, void **x,
13628    wc_pem_password_cb *cb, void *u, int type)
13629{
13630    unsigned char* pem = NULL;
13631    int pemSz;
13632    long i = 0, l;
13633    void *newx509;
13634    int derSz;
13635    DerBuffer* der = NULL;
13636
13637    WOLFSSL_ENTER("wolfSSL_PEM_read_X509");
13638
13639    if (fp == XBADFILE) {
13640        WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
13641        return NULL;
13642    }
13643    /* Read cert from file */
13644    i = XFTELL(fp);
13645    if (i < 0) {
13646        WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
13647        return NULL;
13648    }
13649
13650    if (XFSEEK(fp, 0, XSEEK_END) != 0)
13651        return NULL;
13652    l = XFTELL(fp);
13653    if (l < 0)
13654        return NULL;
13655    if (XFSEEK(fp, i, SEEK_SET) != 0)
13656        return NULL;
13657    pemSz = (int)(l - i);
13658
13659    /* check calculated length */
13660    if (pemSz > MAX_WOLFSSL_FILE_SIZE || pemSz <= 0) {
13661        WOLFSSL_MSG("PEM_read_X509_ex file size error");
13662        return NULL;
13663    }
13664
13665    /* allocate pem buffer */
13666    pem = (unsigned char*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_PEM);
13667    if (pem == NULL)
13668        return NULL;
13669
13670    if ((int)XFREAD((char *)pem, 1, (size_t)pemSz, fp) != pemSz)
13671        goto err_exit;
13672
13673    switch (type) {
13674        case CERT_TYPE:
13675            newx509 = (void *)wolfSSL_X509_load_certificate_buffer(pem,
13676                pemSz, WOLFSSL_FILETYPE_PEM);
13677            break;
13678
13679    #ifdef HAVE_CRL
13680        case CRL_TYPE:
13681            if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0)
13682                goto err_exit;
13683            derSz = (int)der->length;
13684            newx509 = (void*)wolfSSL_d2i_X509_CRL((WOLFSSL_X509_CRL **)x,
13685                (const unsigned char *)der->buffer, derSz);
13686            if (newx509 == NULL)
13687                goto err_exit;
13688            FreeDer(&der);
13689            break;
13690    #endif
13691
13692        default:
13693            goto err_exit;
13694    }
13695    if (x != NULL) {
13696        *x = newx509;
13697    }
13698    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
13699    return newx509;
13700
13701err_exit:
13702    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
13703    if (der != NULL)
13704        FreeDer(&der);
13705
13706    /* unused */
13707    (void)cb;
13708    (void)u;
13709    (void)derSz;
13710
13711    return NULL;
13712}
13713
13714WOLFSSL_X509* wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x,
13715                                                wc_pem_password_cb *cb, void *u)
13716{
13717    return (WOLFSSL_X509* )wolfSSL_PEM_read_X509_ex(fp, (void **)x, cb, u,
13718         CERT_TYPE);
13719}
13720
13721#if defined(HAVE_CRL)
13722WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp,
13723                        WOLFSSL_X509_CRL **crl, wc_pem_password_cb *cb, void *u)
13724{
13725    return (WOLFSSL_X509_CRL* )wolfSSL_PEM_read_X509_ex(fp, (void **)crl, cb, u,
13726         CRL_TYPE);
13727}
13728
13729/* Store CRL to file in DER or PEM format.
13730 * Returns WOLFSSL_SUCCESS on success, negative on failure.
13731 */
13732int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
13733{
13734    int ret;
13735    WOLFSSL_ENTER("wolfSSL_write_X509_CRL");
13736    ret = StoreCRL(crl, path, type);
13737    WOLFSSL_LEAVE("wolfSSL_write_X509_CRL", ret);
13738    return ret;
13739}
13740#endif
13741
13742#ifdef WOLFSSL_CERT_GEN
13743#ifndef NO_BIO
13744    int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509* x)
13745    {
13746        int ret;
13747        WOLFSSL_BIO* bio;
13748
13749        if (x == NULL || fp == XBADFILE)
13750            return 0;
13751
13752        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
13753        if (bio == NULL)
13754            return 0;
13755
13756        if (wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
13757            wolfSSL_BIO_free(bio);
13758            bio = NULL;
13759        }
13760
13761        ret = wolfSSL_PEM_write_bio_X509(bio, x);
13762
13763        if (bio != NULL)
13764            wolfSSL_BIO_free(bio);
13765
13766        return ret;
13767    }
13768#endif /* !NO_BIO */
13769#endif /* WOLFSSL_CERT_GEN */
13770#endif /* !NO_FILESYSTEM */
13771
13772#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
13773#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
13774
13775#ifndef NO_BIO
13776    /* create and return a new WOLFSSL_X509_PKEY structure or NULL on failure */
13777    static WOLFSSL_X509_PKEY* wolfSSL_X509_PKEY_new(void* heap)
13778    {
13779        WOLFSSL_X509_PKEY* ret;
13780
13781        ret = (WOLFSSL_X509_PKEY*)XMALLOC(sizeof(WOLFSSL_X509_PKEY), heap,
13782            DYNAMIC_TYPE_KEY);
13783        if (ret != NULL) {
13784            XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PKEY));
13785            ret->heap = heap;
13786        }
13787        return ret;
13788    }
13789#endif /* !NO_BIO */
13790
13791
13792    /* free up all memory used by "xPkey" passed in */
13793    void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey)
13794    {
13795        if (xPkey != NULL) {
13796            wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
13797            XFREE(xPkey, xPkey->heap, DYNAMIC_TYPE_KEY);
13798        }
13799    }
13800
13801
13802#ifndef NO_BIO
13803
13804#define PEM_COMPARE_HEADER(start, end, header) \
13805        ((end) - (start) == XSTR_SIZEOF(header) && XMEMCMP(start, header, \
13806                XSTR_SIZEOF(header)) == 0)
13807
13808    /**
13809     * This read one structure from bio and returns the read structure
13810     * in the appropriate output parameter (x509, crl, x_pkey). The
13811     * output parameters must be set to NULL.
13812     * @param bio    Input for reading structures
13813     * @param cb     Password callback
13814     * @param x509   Output
13815     * @param crl    Output
13816     * @param x_pkey Output
13817     * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE otherwise
13818     */
13819    int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(
13820            WOLFSSL_BIO* bio, wc_pem_password_cb* cb, WOLFSSL_X509** x509,
13821            WOLFSSL_X509_CRL** crl, WOLFSSL_X509_PKEY** x_pkey)
13822    {
13823
13824#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
13825        char* pem = NULL;
13826        long  i = pem_struct_min_sz, l;
13827        const char* header = NULL;
13828        const char* headerEnd = NULL;
13829        const char* footer = NULL;
13830        const char* footerEnd = NULL;
13831    #ifdef HAVE_CRL
13832        DerBuffer* der = NULL;
13833    #endif
13834        WOLFSSL_BIO* pemBio = NULL;
13835
13836        if (!bio || !x509 || *x509 || !crl || *crl || !x_pkey || *x_pkey) {
13837            WOLFSSL_MSG("Bad input parameter or output parameters "
13838                        "not set to a NULL value.");
13839            return WOLFSSL_FAILURE;
13840        }
13841
13842        l = wolfSSL_BIO_get_len(bio);
13843
13844        if (l < 0) {
13845            WOLFSSL_ERROR(BAD_FUNC_ARG);
13846            return WOLFSSL_FAILURE;
13847        }
13848
13849        if (l == 0) {
13850            /* Streaming BIO (pipe/FIFO/socket): size unknown, use the cap. */
13851            l = MAX_BIO_READ_BUFFER;
13852        }
13853        else if (l <= pem_struct_min_sz) {
13854            /* No certificate in buffer */
13855            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
13856            return WOLFSSL_FAILURE;
13857        }
13858
13859        pem = (char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM);
13860        if (pem == NULL)
13861            return WOLFSSL_FAILURE;
13862
13863        if (wolfSSL_BIO_read(bio, &pem[0], pem_struct_min_sz) !=
13864                pem_struct_min_sz) {
13865            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
13866            goto err;
13867        }
13868
13869        /* Read the header and footer */
13870        while (i < l && wolfSSL_BIO_read(bio, &pem[i], 1) == 1) {
13871            i++;
13872            if (!header) {
13873                header = XSTRNSTR(pem, "-----BEGIN ", i);
13874            }
13875            else if (!headerEnd) {
13876                headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "),
13877                        "-----",
13878                        i - (header + XSTR_SIZEOF("-----BEGIN ") - pem));
13879                if (headerEnd) {
13880                    headerEnd += XSTR_SIZEOF("-----");
13881                    /* Read in the newline */
13882                    if (wolfSSL_BIO_read(bio, &pem[i], 1) != 1) {
13883                        WOLFSSL_MSG("wolfSSL_BIO_read error");
13884                        goto err;
13885                    }
13886                    i++;
13887                    if (*headerEnd != '\n' && *headerEnd != '\r') {
13888                        WOLFSSL_MSG("Missing newline after header");
13889                        goto err;
13890                    }
13891                }
13892            }
13893            else if (!footer) {
13894                footer = XSTRNSTR(headerEnd, "-----END ",
13895                        i - (headerEnd - pem));
13896            }
13897            else if (!footerEnd) {
13898                footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"),
13899                        "-----",
13900                        i - (footer + XSTR_SIZEOF("-----") - pem));
13901                if (footerEnd) {
13902                    footerEnd += XSTR_SIZEOF("-----");
13903                    /* Now check that footer matches header */
13904                    if ((headerEnd - (header + XSTR_SIZEOF("-----BEGIN "))) ==
13905                        (footerEnd - (footer + XSTR_SIZEOF("-----END "))) &&
13906                        XMEMCMP(header + XSTR_SIZEOF("-----BEGIN "),
13907                                footer + XSTR_SIZEOF("-----END "),
13908                        headerEnd - (header + XSTR_SIZEOF("-----BEGIN ")))
13909                            != 0) {
13910                        WOLFSSL_MSG("Header and footer don't match");
13911                        goto err;
13912                    }
13913                    /* header and footer match */
13914                    break;
13915                }
13916            }
13917        }
13918        if (!footerEnd) {
13919            /* Only check footerEnd since it is set last */
13920            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
13921            goto err;
13922        }
13923        else {
13924            if (PEM_COMPARE_HEADER(header, headerEnd,
13925                    "-----BEGIN CERTIFICATE-----")) {
13926                /* We have a certificate */
13927                WOLFSSL_MSG("Parsing x509 cert");
13928                *x509 = wolfSSL_X509_load_certificate_buffer(
13929                        (const unsigned char*) header,
13930                        (int)(footerEnd - header), WOLFSSL_FILETYPE_PEM);
13931                if (!*x509) {
13932                    WOLFSSL_MSG("wolfSSL_X509_load_certificate_buffer error");
13933                    goto err;
13934                }
13935            }
13936    #ifdef HAVE_CRL
13937            else if (PEM_COMPARE_HEADER(header, headerEnd,
13938                        "-----BEGIN X509 CRL-----")) {
13939                /* We have a crl */
13940                WOLFSSL_MSG("Parsing crl");
13941                if ((PemToDer((const unsigned char*) header,
13942                        (long)(footerEnd - header), CRL_TYPE, &der, NULL, NULL,
13943                        NULL)) < 0) {
13944                    WOLFSSL_MSG("PemToDer error");
13945                    goto err;
13946                }
13947                *crl = wolfSSL_d2i_X509_CRL(NULL, der->buffer, der->length);
13948                if (!*crl) {
13949                    WOLFSSL_MSG("wolfSSL_d2i_X509_CRL error");
13950                    goto err;
13951                }
13952            }
13953    #endif
13954            else {
13955                WOLFSSL_MSG("Parsing x509 key");
13956
13957                if (!(*x_pkey = wolfSSL_X509_PKEY_new(NULL))) {
13958                    WOLFSSL_MSG("wolfSSL_X509_PKEY_new error");
13959                    goto err;
13960                }
13961
13962                if (!(pemBio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
13963                    WOLFSSL_MSG("wolfSSL_BIO_new error");
13964                    goto err;
13965                }
13966
13967                if (wolfSSL_BIO_write(pemBio, header,
13968                        (int)(footerEnd - header)) != footerEnd - header) {
13969                    WOLFSSL_MSG("wolfSSL_BIO_new error");
13970                    goto err;
13971                }
13972
13973                if (wolfSSL_PEM_read_bio_PrivateKey(pemBio,
13974                        &(*x_pkey)->dec_pkey, cb, NULL) == NULL) {
13975                    WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey error");
13976                    goto err;
13977                }
13978
13979                wolfSSL_BIO_free(pemBio);
13980            }
13981        }
13982
13983        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
13984    #ifdef HAVE_CRL
13985        if (der)
13986            FreeDer(&der);
13987    #endif
13988        return WOLFSSL_SUCCESS;
13989err:
13990        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
13991    #ifdef HAVE_CRL
13992        if (der)
13993            FreeDer(&der);
13994    #endif
13995        if (*x_pkey) {
13996            wolfSSL_X509_PKEY_free(*x_pkey);
13997            *x_pkey = NULL;
13998        }
13999        if (pemBio)
14000            wolfSSL_BIO_free(pemBio);
14001        return WOLFSSL_FAILURE;
14002#else /* ! (WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM) */
14003        return WOLFSSL_FAILURE;
14004#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
14005    }
14006
14007#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
14008#ifdef OPENSSL_ALL
14009
14010#ifndef NO_FILESYSTEM
14011    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read(
14012            XFILE fp, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
14013            pem_password_cb* cb, void* u)
14014    {
14015        WOLFSSL_BIO* fileBio = wolfSSL_BIO_new_fp(fp, WOLFSSL_BIO_NOCLOSE);
14016        WOLF_STACK_OF(WOLFSSL_X509_INFO)* ret = NULL;
14017
14018        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read");
14019        if (fileBio != NULL) {
14020            ret = wolfSSL_PEM_X509_INFO_read_bio(fileBio, sk, cb, u);
14021            wolfSSL_BIO_free(fileBio);
14022        }
14023        return ret;
14024    }
14025#endif /* !NO_FILESYSTEM */
14026
14027    /*
14028     * bio WOLFSSL_BIO to read certificates from
14029     * sk  possible stack to push more X509_INFO structs to. Can be NULL
14030     * cb  callback password for encrypted PEM certificates
14031     * u   user input such as password
14032     *
14033     * returns stack on success and NULL or default stack passed in on fail
14034     */
14035    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio(
14036        WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
14037        wc_pem_password_cb* cb, void* u)
14038    {
14039        WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk = NULL;
14040        int ret = WOLFSSL_SUCCESS;
14041        WOLFSSL_X509_INFO* current = NULL;
14042        WOLFSSL_X509*      x509 = NULL;
14043        WOLFSSL_X509_CRL*  crl  = NULL;
14044        WOLFSSL_X509_PKEY* x_pkey = NULL;
14045
14046        (void)u;
14047
14048        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio");
14049
14050        /* attempt to use passed in stack or create a new one */
14051        if (sk != NULL) {
14052            localSk = sk;
14053        }
14054        else {
14055            localSk = wolfSSL_sk_X509_INFO_new_null();
14056        }
14057        if (localSk == NULL) {
14058            WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio",
14059                    MEMORY_E);
14060            return NULL;
14061        }
14062
14063        /* parse through BIO and push new info's found onto stack */
14064        while (1) {
14065            x509 = NULL;
14066            crl  = NULL;
14067            x_pkey = NULL;
14068
14069            if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bio, cb,
14070                    &x509, &crl, &x_pkey) == WOLFSSL_SUCCESS) {
14071                if (current == NULL ||
14072                        (x509 && current->x509) ||
14073                        (crl && current->crl) ||
14074                        (x_pkey && current->x_pkey)) {
14075                    /* Need to create new current since existing one already
14076                     * has the member filled or this is the first successful
14077                     * read. */
14078                    current = wolfSSL_X509_INFO_new();
14079                    if (current == NULL) {
14080                        ret = MEMORY_E;
14081                        break;
14082                    }
14083                    if (wolfSSL_sk_X509_INFO_push(localSk, current) <= 0) {
14084                        wolfSSL_X509_INFO_free(current);
14085                        current = NULL;
14086                        ret = WOLFSSL_FAILURE;
14087                        break;
14088                    }
14089                }
14090
14091                if (x509) {
14092                    current->x509 = x509;
14093                }
14094                else if (crl) {
14095                    current->crl = crl;
14096                }
14097                else if (x_pkey) {
14098                    current->x_pkey = x_pkey;
14099                }
14100                else {
14101                    WOLFSSL_MSG("No output parameters set");
14102                    ret = WOLFSSL_FAILURE;
14103                    break;
14104                }
14105            }
14106            else {
14107#ifdef WOLFSSL_HAVE_ERROR_QUEUE
14108                unsigned long err;
14109                CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
14110                if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
14111                    ERR_GET_REASON(err) != PEM_R_NO_START_LINE) {
14112                    ret = WOLFSSL_FAILURE;
14113                }
14114#else
14115                if (wolfSSL_sk_X509_INFO_num(localSk) > 0) {
14116                    WOLFSSL_MSG("At least one X509_INFO object on stack."
14117                                "Assuming error means EOF or no more PEM"
14118                                "headers found.");
14119                }
14120                else {
14121                    ret = WOLFSSL_FAILURE;
14122                }
14123#endif
14124                break;
14125            }
14126        }
14127        if (ret != WOLFSSL_SUCCESS ||
14128                wolfSSL_sk_X509_INFO_num(localSk) == 0) {
14129            /* current should always be pushed onto the localsk stack at this
14130             * point. The only case when it isn't is when
14131             * wolfSSL_sk_X509_INFO_push fails but in that case the current
14132             * free is handled inside the loop. */
14133            if (localSk != sk) {
14134                wolfSSL_sk_pop_free(localSk, NULL);
14135            }
14136            wolfSSL_X509_free(x509);
14137#ifdef HAVE_CRL
14138            wolfSSL_X509_CRL_free(crl);
14139#endif
14140            wolfSSL_X509_PKEY_free(x_pkey);
14141            localSk = NULL;
14142        }
14143        WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret);
14144        return localSk;
14145    }
14146#endif /* !NO_BIO */
14147#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
14148
14149    void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne)
14150    {
14151        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_free");
14152        if (ne != NULL) {
14153            wolfSSL_ASN1_OBJECT_free(ne->object);
14154            if (ne->value != NULL) {
14155                wolfSSL_ASN1_STRING_free(ne->value);
14156            }
14157            XFREE(ne, NULL, DYNAMIC_TYPE_NAME_ENTRY);
14158        }
14159    }
14160
14161
14162    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void)
14163    {
14164        WOLFSSL_X509_NAME_ENTRY* ne;
14165
14166        ne = (WOLFSSL_X509_NAME_ENTRY*)XMALLOC(sizeof(WOLFSSL_X509_NAME_ENTRY),
14167                NULL, DYNAMIC_TYPE_NAME_ENTRY);
14168        if (ne != NULL) {
14169            XMEMSET(ne, 0, sizeof(WOLFSSL_X509_NAME_ENTRY));
14170        }
14171
14172        return ne;
14173    }
14174
14175
14176    static void wolfssl_x509_name_entry_set(WOLFSSL_X509_NAME_ENTRY* ne,
14177        int nid, int type, const unsigned char *data, int dataSz)
14178    {
14179        ne->nid = nid;
14180        /* Reuse the object if already available. */
14181        ne->object = wolfSSL_OBJ_nid2obj_ex(nid, ne->object);
14182        if (ne->value == NULL) {
14183            ne->value = wolfSSL_ASN1_STRING_type_new(type);
14184        }
14185        if (ne->value != NULL) {
14186            if (wolfSSL_ASN1_STRING_set(ne->value, (const void*)data,
14187                                            dataSz) == WOLFSSL_SUCCESS) {
14188                ne->set = 1;
14189            }
14190            else {
14191                /* Free the ASN1_STRING if it is not set. */
14192                wolfSSL_ASN1_STRING_free(ne->value);
14193                ne->value = NULL;
14194            }
14195        }
14196    }
14197
14198    /* Create a new WOLFSSL_X509_NAME_ENTRY structure based on the text passed
14199     * in. Returns NULL on failure */
14200    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_txt(
14201            WOLFSSL_X509_NAME_ENTRY **neIn, const char *txt, int type,
14202            const unsigned char *data, int dataSz)
14203    {
14204        int nid = -1;
14205        WOLFSSL_X509_NAME_ENTRY* ne = NULL;
14206
14207        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_txt");
14208
14209        if (txt == NULL) {
14210            return NULL;
14211        }
14212
14213        if (neIn != NULL) {
14214            ne = *neIn;
14215        }
14216
14217        nid = wolfSSL_OBJ_txt2nid(txt);
14218        if (nid == WC_NID_undef) {
14219            WOLFSSL_MSG("Unable to find text");
14220            ne = NULL;
14221        }
14222        else {
14223            if (ne == NULL) {
14224                ne = wolfSSL_X509_NAME_ENTRY_new();
14225                if (ne == NULL) {
14226                    return NULL;
14227                }
14228            }
14229
14230            wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
14231        }
14232
14233        return ne;
14234    }
14235
14236
14237    /* Creates a new entry given the NID, type, and data
14238     * "dataSz" is number of bytes in data, if set to -1 then XSTRLEN is used
14239     * "out" can be used to store the new entry data in an existing structure
14240     *       if NULL then a new WOLFSSL_X509_NAME_ENTRY structure is created
14241     * returns a pointer to WOLFSSL_X509_NAME_ENTRY on success and NULL on fail
14242     */
14243    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID(
14244            WOLFSSL_X509_NAME_ENTRY** out, int nid, int type,
14245            const unsigned char* data, int dataSz)
14246    {
14247        WOLFSSL_X509_NAME_ENTRY* ne;
14248
14249#ifdef WOLFSSL_DEBUG_OPENSSL
14250        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_NID");
14251#endif
14252
14253        if (!data) {
14254            WOLFSSL_MSG("Bad parameter");
14255            return NULL;
14256        }
14257
14258        if (out == NULL || *out == NULL) {
14259            ne = wolfSSL_X509_NAME_ENTRY_new();
14260            if (ne == NULL) {
14261                return NULL;
14262            }
14263            if (out != NULL) {
14264                *out = ne;
14265            }
14266        }
14267        else {
14268            ne = *out;
14269        }
14270
14271        wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
14272
14273        return ne;
14274    }
14275#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
14276
14277#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
14278    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
14279    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
14280    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
14281WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
14282    WOLFSSL_X509_NAME_ENTRY *ne)
14283{
14284    WOLFSSL_ASN1_OBJECT* object = NULL;
14285
14286#ifdef WOLFSSL_DEBUG_OPENSSL
14287    WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
14288#endif
14289
14290    if (ne != NULL) {
14291        /* Create object from nid - reuse existing object if possible. */
14292        object = wolfSSL_OBJ_nid2obj_ex(ne->nid, ne->object);
14293        if (object != NULL) {
14294            /* Set the object when no error. */
14295            ne->object = object;
14296        }
14297    }
14298
14299    return object;
14300}
14301#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
14302        * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
14303
14304#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
14305    /* add all entry of type "nid" to the buffer "fullName" and advance "idx"
14306     * since number of entries is small, a brute force search is used here
14307     * returns the number of entries added
14308     */
14309    static int AddAllEntry(WOLFSSL_X509_NAME* name, char* fullName,
14310            int fullNameSz, int* idx)
14311    {
14312        int i;
14313        int ret = 0;
14314
14315        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14316            if (name->entry[i].set) {
14317                WOLFSSL_X509_NAME_ENTRY* e;
14318                WOLFSSL_ASN1_OBJECT* obj;
14319
14320                int sz;
14321                unsigned char* data;
14322
14323                e = &name->entry[i];
14324                obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
14325                if (obj == NULL) {
14326                    return BAD_FUNC_ARG;
14327                }
14328
14329                XMEMCPY(fullName + *idx, "/", 1); *idx = *idx + 1;
14330                sz = (int)XSTRLEN(obj->sName);
14331                XMEMCPY(fullName + *idx, obj->sName, sz);
14332                *idx += sz;
14333                XMEMCPY(fullName + *idx, "=", 1); *idx = *idx + 1;
14334
14335                data = wolfSSL_ASN1_STRING_data(e->value);
14336                if (data != NULL) {
14337                    sz = (int)XSTRLEN((const char*)data);
14338                    XMEMCPY(fullName + *idx, data, sz);
14339                    *idx += sz;
14340                }
14341
14342                ret++;
14343            }
14344        }
14345        (void)fullNameSz;
14346        return ret;
14347    }
14348
14349
14350    /* Converts a list of entries in WOLFSSL_X509_NAME struct into a string
14351     * returns 0 on success */
14352    static int RebuildFullName(WOLFSSL_X509_NAME* name)
14353    {
14354        int totalLen = 0, i, idx, entryCount = 0;
14355
14356        if (name == NULL)
14357            return BAD_FUNC_ARG;
14358
14359        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14360            if (name->entry[i].set) {
14361                WOLFSSL_X509_NAME_ENTRY* e;
14362                WOLFSSL_ASN1_OBJECT* obj;
14363
14364                e = &name->entry[i];
14365                obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
14366                if (obj == NULL)
14367                    return BAD_FUNC_ARG;
14368
14369                totalLen += (int)XSTRLEN(obj->sName) + 2;/*+2 for '/' and '=' */
14370                totalLen += wolfSSL_ASN1_STRING_length(e->value);
14371            }
14372        }
14373
14374        if (name->dynamicName) {
14375            XFREE(name->name, name->heap, DYNAMIC_TYPE_X509);
14376            name->name = name->staticName;
14377            name->dynamicName = 0;
14378        }
14379
14380        if (totalLen >= ASN_NAME_MAX) {
14381            name->name = (char*)XMALLOC(totalLen + 1, name->heap,
14382                    DYNAMIC_TYPE_X509);
14383            if (name->name == NULL)
14384                return MEMORY_E;
14385            name->dynamicName = 1;
14386        }
14387
14388        idx = 0;
14389        entryCount = AddAllEntry(name, name->name, totalLen, &idx);
14390        if (entryCount < 0)
14391            return entryCount;
14392
14393        name->name[idx] = '\0';
14394        name->sz = idx + 1; /* size includes null terminator */
14395        name->entrySz = entryCount;
14396
14397        return 0;
14398    }
14399
14400    /* Copies entry into name. With it being copied freeing entry becomes the
14401     * callers responsibility.
14402     * returns 1 for success and 0 for error */
14403    int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name,
14404            WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set)
14405    {
14406        WOLFSSL_X509_NAME_ENTRY* current = NULL;
14407        int ret, i;
14408
14409#ifdef WOLFSSL_DEBUG_OPENSSL
14410        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry");
14411#endif
14412
14413        if (name == NULL || entry == NULL || entry->value == NULL) {
14414            WOLFSSL_MSG("NULL argument passed in");
14415            return WOLFSSL_FAILURE;
14416        }
14417
14418        if (idx >= 0) {
14419            /* place in specific index */
14420
14421            if (idx >= MAX_NAME_ENTRIES) {
14422                WOLFSSL_MSG("Error index to insert entry is larger than array");
14423                return WOLFSSL_FAILURE;
14424            }
14425            i = idx;
14426        }
14427        else {
14428            /* iterate through and find first open spot */
14429            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14430                if (name->entry[i].set == 0) { /* not set so overwritten */
14431                    WOLFSSL_MSG("Found place for name entry");
14432                    break;
14433                }
14434            }
14435
14436            if (i == MAX_NAME_ENTRIES) {
14437                WOLFSSL_MSG("No spot found for name entry");
14438                return WOLFSSL_FAILURE;
14439            }
14440        }
14441
14442        current = &name->entry[i];
14443        if (current->set == 0)
14444            name->entrySz++;
14445
14446        if (wolfSSL_X509_NAME_ENTRY_create_by_NID(&current,
14447                            entry->nid,
14448                            wolfSSL_ASN1_STRING_type(entry->value),
14449                            wolfSSL_ASN1_STRING_data(entry->value),
14450                            wolfSSL_ASN1_STRING_length(entry->value)) != NULL)
14451        {
14452            ret = WOLFSSL_SUCCESS;
14453        #ifdef OPENSSL_ALL
14454            if (name->entries == NULL) {
14455                name->entries = wolfSSL_sk_X509_NAME_new(NULL);
14456            }
14457            if (wolfSSL_sk_X509_NAME_ENTRY_push(name->entries, current) <= 0) {
14458                ret = WOLFSSL_FAILURE;
14459            }
14460        #endif
14461        }
14462        else {
14463            ret = WOLFSSL_FAILURE;
14464        }
14465
14466        if (ret != WOLFSSL_SUCCESS) {
14467            WOLFSSL_MSG("Error adding the name entry");
14468            if (current->set == 0)
14469                name->entrySz--;
14470            return WOLFSSL_FAILURE;
14471        }
14472
14473#ifdef WOLFSSL_PYTHON
14474        /* Set name index for OpenSSL stack index position and so Python can
14475         * generate tuples/sets from the list. */
14476        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14477            if (name->entry[i].set != 0)
14478                name->entry[i].set = i + 1;
14479        }
14480#endif
14481
14482        if (RebuildFullName(name) != 0)
14483            return WOLFSSL_FAILURE;
14484
14485        (void)set;
14486        return WOLFSSL_SUCCESS;
14487    }
14488
14489    int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name,
14490                                           const char *field, int type,
14491                                           const unsigned char *bytes, int len,
14492                                           int loc, int set)
14493    {
14494        int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
14495        int nid;
14496        WOLFSSL_X509_NAME_ENTRY* entry;
14497
14498        (void)type;
14499        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_txt");
14500
14501        if (name == NULL || field == NULL)
14502            return WOLFSSL_FAILURE;
14503
14504        if ((nid = wolfSSL_OBJ_txt2nid(field)) == WC_NID_undef) {
14505            WOLFSSL_MSG("Unable convert text to NID");
14506            return WOLFSSL_FAILURE;
14507        }
14508
14509        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL,
14510                  nid, type, (unsigned char*)bytes, len);
14511        if (entry == NULL)
14512            return WOLFSSL_FAILURE;
14513
14514        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
14515        wolfSSL_X509_NAME_ENTRY_free(entry);
14516
14517        return ret;
14518    }
14519
14520    int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int nid,
14521                                           int type, const unsigned char *bytes,
14522                                           int len, int loc, int set)
14523    {
14524        int ret;
14525        WOLFSSL_X509_NAME_ENTRY* entry;
14526        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_NID");
14527        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes,
14528                len);
14529        if (entry == NULL)
14530            return WOLFSSL_FAILURE;
14531        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
14532        wolfSSL_X509_NAME_ENTRY_free(entry);
14533        return ret;
14534    }
14535
14536    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_delete_entry(
14537            WOLFSSL_X509_NAME *name, int loc)
14538    {
14539        WOLFSSL_X509_NAME_ENTRY* ret;
14540        WOLFSSL_ENTER("wolfSSL_X509_NAME_delete_entry");
14541
14542        if (!name) {
14543            WOLFSSL_MSG("Bad parameter");
14544            return NULL;
14545        }
14546
14547        ret = wolfSSL_X509_NAME_get_entry(name, loc);
14548        if (!ret) {
14549            WOLFSSL_MSG("loc entry not found");
14550            return NULL;
14551        }
14552        name->entry[loc].set = 0;
14553#ifdef WOLFSSL_PYTHON
14554        {
14555            int i;
14556            /* Set name index for OpenSSL stack index position and so Python can
14557            * generate tuples/sets from the list. */
14558            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14559                if (name->entry[i].set != 0)
14560                    name->entry[i].set = i + 1;
14561            }
14562        }
14563#endif
14564        return ret;
14565    }
14566
14567#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
14568
14569#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
14570    int wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME *name,
14571                                           const WOLFSSL_ASN1_OBJECT *obj,
14572                                           int idx) {
14573        if (!name || idx >= MAX_NAME_ENTRIES ||
14574                !obj || !obj->obj) {
14575            return WOLFSSL_FATAL_ERROR;
14576        }
14577
14578        if (idx < 0) {
14579            idx = -1;
14580        }
14581
14582        for (idx++; idx < MAX_NAME_ENTRIES; idx++) {
14583            /* Find index of desired name */
14584            if (name->entry[idx].set) {
14585                if (XSTRLEN(obj->sName) ==
14586                        XSTRLEN(name->entry[idx].object->sName) &&
14587                    XSTRNCMP((const char*) obj->sName,
14588                        name->entry[idx].object->sName, obj->objSz - 1) == 0) {
14589                    return idx;
14590                }
14591            }
14592        }
14593        return WOLFSSL_FATAL_ERROR;
14594    }
14595#endif
14596
14597#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
14598    defined(OPENSSL_EXTRA_X509_SMALL)
14599
14600#ifdef OPENSSL_EXTRA
14601    int wolfSSL_X509_NAME_ENTRY_set(const WOLFSSL_X509_NAME_ENTRY *ne)
14602    {
14603        if (ne != NULL) {
14604            return ne->set;
14605        }
14606        return 0;
14607    }
14608#endif
14609
14610
14611    /* returns a pointer to the internal entry at location 'loc' on success,
14612     * a null pointer is returned in fail cases */
14613    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
14614                                        const WOLFSSL_X509_NAME *name, int loc)
14615    {
14616#ifdef WOLFSSL_DEBUG_OPENSSL
14617        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
14618#endif
14619
14620        if (name == NULL) {
14621            return NULL;
14622        }
14623
14624        if (loc < 0 || loc >= MAX_NAME_ENTRIES) {
14625            WOLFSSL_MSG("Bad argument");
14626            return NULL;
14627        }
14628
14629        if (name->entry[loc].set) {
14630            return (WOLFSSL_X509_NAME_ENTRY*)&name->entry[loc];
14631        }
14632        else {
14633            return NULL;
14634        }
14635    }
14636#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
14637
14638#ifdef OPENSSL_EXTRA
14639
14640int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key)
14641{
14642    WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
14643
14644    if (!x509 || !key) {
14645        WOLFSSL_MSG("Bad parameter");
14646        return WOLFSSL_FAILURE;
14647    }
14648
14649#ifndef NO_CHECK_PRIVATE_KEY
14650    return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz,
14651            x509->pubKey.buffer, x509->pubKey.length,
14652            (enum Key_Sum)x509->pubKeyOID, key->heap) == 1 ?
14653                    WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
14654#else
14655    /* not compiled in */
14656    return WOLFSSL_SUCCESS;
14657#endif
14658}
14659
14660#endif /* OPENSSL_EXTRA */
14661
14662#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
14663    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
14664#ifndef NO_BIO
14665
14666#ifdef WOLFSSL_CERT_GEN
14667
14668#ifdef WOLFSSL_CERT_REQ
14669/* writes the x509 from x to the WOLFSSL_BIO bp
14670 *
14671 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
14672 */
14673int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
14674{
14675    byte* pem;
14676    int   pemSz = 0;
14677    const unsigned char* der;
14678    int derSz;
14679    int ret;
14680
14681    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_REQ");
14682
14683    if (x == NULL || bp == NULL) {
14684        return WOLFSSL_FAILURE;
14685    }
14686
14687    der = wolfSSL_X509_get_der(x, &derSz);
14688    if (der == NULL) {
14689        return WOLFSSL_FAILURE;
14690    }
14691
14692    /* get PEM size */
14693    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERTREQ_TYPE);
14694    if (pemSz < 0) {
14695        return WOLFSSL_FAILURE;
14696    }
14697
14698    /* create PEM buffer and convert from DER */
14699    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14700    if (pem == NULL) {
14701        return WOLFSSL_FAILURE;
14702    }
14703    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERTREQ_TYPE) < 0) {
14704        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14705        return WOLFSSL_FAILURE;
14706    }
14707
14708    /* write the PEM to BIO */
14709    ret = wolfSSL_BIO_write(bp, pem, pemSz);
14710    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14711
14712    if (ret <= 0) return WOLFSSL_FAILURE;
14713    return WOLFSSL_SUCCESS;
14714}
14715#endif /* WOLFSSL_CERT_REQ */
14716
14717
14718/* writes the x509 from x to the WOLFSSL_BIO bp
14719 *
14720 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
14721 */
14722int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
14723{
14724    byte* pem;
14725    int   pemSz = 0;
14726    const unsigned char* der;
14727    int derSz;
14728    int ret;
14729
14730    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX");
14731
14732    if (bp == NULL || x == NULL) {
14733        WOLFSSL_MSG("NULL argument passed in");
14734        return WOLFSSL_FAILURE;
14735    }
14736
14737    der = wolfSSL_X509_get_der(x, &derSz);
14738    if (der == NULL) {
14739        return WOLFSSL_FAILURE;
14740    }
14741
14742    /* get PEM size */
14743    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERT_TYPE);
14744    if (pemSz < 0) {
14745        return WOLFSSL_FAILURE;
14746    }
14747
14748    /* create PEM buffer and convert from DER */
14749    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14750    if (pem == NULL) {
14751        return WOLFSSL_FAILURE;
14752    }
14753    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
14754        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14755        return WOLFSSL_FAILURE;
14756    }
14757
14758    /* write the PEM to BIO */
14759    ret = wolfSSL_BIO_write(bp, pem, pemSz);
14760    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14761
14762    if (ret <= 0) return WOLFSSL_FAILURE;
14763    return WOLFSSL_SUCCESS;
14764}
14765
14766int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
14767{
14768    byte* pem = NULL;
14769    int   pemSz = 0;
14770    /* Get large buffer to hold cert der */
14771    const byte* der = NULL;
14772    int derSz = X509_BUFFER_SZ;
14773    int ret;
14774
14775    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509");
14776
14777    if (bio == NULL || cert == NULL) {
14778        WOLFSSL_MSG("NULL argument passed in");
14779        return WOLFSSL_FAILURE;
14780    }
14781
14782    /* Do not call wolfssl_x509_make_der() here. If we did, then need to re-sign
14783     * because we don't know the original order of the extensions and so we must
14784     * assume our extensions are in a different order, thus need to re-sign. */
14785    der = wolfSSL_X509_get_der(cert, &derSz);
14786    if (der == NULL) {
14787        goto error;
14788    }
14789
14790    /* get PEM size */
14791    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERT_TYPE);
14792    if (pemSz < 0) {
14793        goto error;
14794    }
14795
14796    /* create PEM buffer and convert from DER */
14797    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14798    if (pem == NULL) {
14799        goto error;
14800    }
14801    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
14802        goto error;
14803    }
14804
14805    /* write the PEM to BIO */
14806    ret = wolfSSL_BIO_write(bio, pem, pemSz);
14807    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14808
14809    if (ret <= 0) return WOLFSSL_FAILURE;
14810    return WOLFSSL_SUCCESS;
14811
14812error:
14813    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14814    return WOLFSSL_FAILURE;
14815}
14816#endif /* WOLFSSL_CERT_GEN */
14817
14818#endif /* !NO_BIO */
14819#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
14820
14821#if defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
14822        defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
14823        defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH) || \
14824        defined(HAVE_SBLIM_SFCB)
14825
14826WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new(
14827        WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
14828{
14829    WOLFSSL_STACK* sk;
14830    (void)cb;
14831
14832    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_new");
14833
14834    sk = wolfSSL_sk_new_node(NULL);
14835    if (sk != NULL) {
14836        sk->type = STACK_TYPE_X509_NAME;
14837    }
14838
14839    return sk;
14840}
14841
14842int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk)
14843{
14844    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
14845
14846    if (sk == NULL)
14847        return BAD_FUNC_ARG;
14848
14849    return (int)sk->num;
14850}
14851
14852/* Getter function for WOLFSSL_X509_NAME pointer
14853 *
14854 * sk is the stack to retrieve pointer from
14855 * i  is the index value in stack
14856 *
14857 * returns a pointer to a WOLFSSL_X509_NAME structure on success and NULL on
14858 *         fail
14859 */
14860WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(
14861    const WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, int i)
14862{
14863    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
14864    return (WOLFSSL_X509_NAME*)wolfSSL_sk_value(sk, i);
14865}
14866
14867WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(
14868    WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
14869{
14870    return (WOLFSSL_X509_NAME*)wolfSSL_sk_pop(sk);
14871}
14872
14873void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
14874    void (*f) (WOLFSSL_X509_NAME*))
14875{
14876    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
14877    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
14878}
14879
14880/* Free only the sk structure, NOT X509_NAME members */
14881void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
14882{
14883    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_free");
14884    wolfSSL_sk_free(sk);
14885}
14886
14887int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
14888    WOLFSSL_X509_NAME* name)
14889{
14890    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_push");
14891
14892    return wolfSSL_sk_push(sk, name);
14893}
14894
14895/* return index of found, or negative to indicate not found */
14896int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk,
14897    WOLFSSL_X509_NAME *name)
14898{
14899    int i;
14900
14901    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_find");
14902
14903    if (sk == NULL)
14904        return BAD_FUNC_ARG;
14905
14906    for (i = 0; sk; i++, sk = sk->next) {
14907        if (wolfSSL_X509_NAME_cmp(sk->data.name, name) == 0) {
14908            return i;
14909        }
14910    }
14911    return WOLFSSL_FATAL_ERROR;
14912}
14913
14914/* Name Entry */
14915WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* wolfSSL_sk_X509_NAME_ENTRY_new(
14916    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME_ENTRY, cb))
14917{
14918    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
14919    if (sk != NULL) {
14920        sk->type = STACK_TYPE_X509_NAME_ENTRY;
14921        (void)cb;
14922    }
14923    return sk;
14924}
14925
14926int wolfSSL_sk_X509_NAME_ENTRY_push(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk,
14927    WOLFSSL_X509_NAME_ENTRY* name_entry)
14928{
14929    return wolfSSL_sk_push(sk, name_entry);
14930}
14931
14932WOLFSSL_X509_NAME_ENTRY* wolfSSL_sk_X509_NAME_ENTRY_value(
14933    const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk, int i)
14934{
14935    return (WOLFSSL_X509_NAME_ENTRY*)wolfSSL_sk_value(sk, i);
14936}
14937
14938int wolfSSL_sk_X509_NAME_ENTRY_num(
14939    const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
14940{
14941    if (sk == NULL)
14942        return BAD_FUNC_ARG;
14943    return (int)sk->num;
14944}
14945
14946void wolfSSL_sk_X509_NAME_ENTRY_free(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
14947{
14948    wolfSSL_sk_free(sk);
14949}
14950
14951#endif /* OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
14952            HAVE_LIGHTY || WOLFSSL_HAPROXY ||
14953            WOLFSSL_OPENSSH || HAVE_SBLIM_SFCB */
14954
14955#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
14956    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
14957    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
14958    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))
14959
14960#if defined(OPENSSL_ALL)
14961WOLFSSL_X509_INFO* wolfSSL_X509_INFO_new(void)
14962{
14963    WOLFSSL_X509_INFO* info;
14964    info = (WOLFSSL_X509_INFO*)XMALLOC(sizeof(WOLFSSL_X509_INFO), NULL,
14965        DYNAMIC_TYPE_X509);
14966    if (info) {
14967        XMEMSET(info, 0, sizeof(*info));
14968    }
14969    return info;
14970}
14971
14972void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info)
14973{
14974    if (info == NULL)
14975        return;
14976
14977    if (info->x509) {
14978        wolfSSL_X509_free(info->x509);
14979        info->x509 = NULL;
14980    }
14981#ifdef HAVE_CRL
14982    if (info->crl) {
14983        wolfSSL_X509_CRL_free(info->crl);
14984        info->crl = NULL;
14985    }
14986#endif
14987    wolfSSL_X509_PKEY_free(info->x_pkey);
14988    info->x_pkey = NULL;
14989
14990    XFREE(info, NULL, DYNAMIC_TYPE_X509);
14991}
14992#endif
14993
14994WOLFSSL_STACK* wolfSSL_sk_X509_INFO_new_null(void)
14995{
14996    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
14997    if (sk) {
14998        sk->type = STACK_TYPE_X509_INFO;
14999    }
15000    return sk;
15001}
15002
15003int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
15004{
15005    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num");
15006
15007    return wolfSSL_sk_num(sk);
15008}
15009
15010WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value(
15011        const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk, int i)
15012{
15013    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_value");
15014
15015    return (WOLFSSL_X509_INFO *)wolfSSL_sk_value(sk, i);
15016}
15017
15018WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(
15019        WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk)
15020{
15021    return (WOLFSSL_X509_INFO*)wolfSSL_sk_pop(sk);
15022}
15023
15024#if defined(OPENSSL_ALL)
15025void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
15026    void (*f) (WOLFSSL_X509_INFO*))
15027{
15028    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_pop_free");
15029    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
15030}
15031
15032void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
15033{
15034    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_free");
15035    wolfSSL_sk_free(sk);
15036}
15037
15038/* Adds the WOLFSSL_X509_INFO to the stack "sk". "sk" takes control of "in" and
15039 * tries to free it when the stack is free'd.
15040 *
15041 * return number of elements on success 0 on fail
15042 */
15043int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
15044                                                      WOLFSSL_X509_INFO* in)
15045{
15046    return wolfSSL_sk_push(sk, in);
15047}
15048
15049/* Creates a duplicate of WOLF_STACK_OF(WOLFSSL_X509_NAME).
15050 * Returns a new WOLF_STACK_OF(WOLFSSL_X509_NAME) or NULL on failure */
15051WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list(
15052    WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
15053{
15054    int i;
15055    const int num = wolfSSL_sk_X509_NAME_num(sk);
15056    WOLF_STACK_OF(WOLFSSL_X509_NAME) *copy;
15057    WOLFSSL_X509_NAME *name;
15058
15059    WOLFSSL_ENTER("wolfSSL_dup_CA_list");
15060
15061    copy = wolfSSL_sk_X509_NAME_new(NULL);
15062    if (copy == NULL) {
15063        WOLFSSL_MSG("Memory error");
15064        return NULL;
15065    }
15066
15067    for (i = 0; i < num; i++) {
15068        name = wolfSSL_X509_NAME_dup(wolfSSL_sk_X509_NAME_value(sk, i));
15069        if (name == NULL || wolfSSL_sk_X509_NAME_push(copy, name) <= 0) {
15070            WOLFSSL_MSG("Memory error");
15071            wolfSSL_sk_X509_NAME_pop_free(copy, wolfSSL_X509_NAME_free);
15072            wolfSSL_X509_NAME_free(name);
15073            return NULL;
15074        }
15075    }
15076
15077    return copy;
15078}
15079
15080void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk,
15081    int i)
15082{
15083    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_value");
15084    for (; sk != NULL && i > 0; i--)
15085        sk = sk->next;
15086
15087    if (i != 0 || sk == NULL)
15088        return NULL;
15089    return sk->data.x509_obj;
15090}
15091
15092int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s)
15093{
15094    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_num");
15095    if (s) {
15096        return (int)s->num;
15097    }
15098    else {
15099        return 0;
15100    }
15101}
15102
15103int wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
15104    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
15105{
15106    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_set_cmp_func");
15107
15108    if (sk == NULL)
15109        return BAD_FUNC_ARG;
15110
15111    WOLFSSL_MSG("Stack comparison not used in wolfSSL");
15112    (void)cb;
15113    return 0;
15114}
15115#endif /* OPENSSL_ALL */
15116
15117#ifndef NO_BIO
15118
15119/* Helper function for X509_NAME_print_ex. Sets *buf to string for domain
15120   name attribute based on NID. Returns size of buf */
15121static int get_dn_attr_by_nid(int n, const char** buf)
15122{
15123    int len = 0;
15124    const char *str;
15125
15126    switch(n)
15127    {
15128        case WC_NID_commonName :
15129            str = "CN";
15130            len = 2;
15131            break;
15132        case WC_NID_countryName:
15133            str = "C";
15134            len = 1;
15135            break;
15136        case WC_NID_localityName:
15137            str = "L";
15138            len = 1;
15139            break;
15140        case WC_NID_stateOrProvinceName:
15141            str = "ST";
15142            len = 2;
15143            break;
15144        case WC_NID_streetAddress:
15145            str = "street";
15146            len = 6;
15147            break;
15148        case WC_NID_organizationName:
15149            str = "O";
15150            len = 1;
15151            break;
15152        case WC_NID_organizationalUnitName:
15153            str = "OU";
15154            len = 2;
15155            break;
15156        case WC_NID_postalCode:
15157            str = "postalCode";
15158            len = 10;
15159            break;
15160        case WC_NID_emailAddress:
15161            str = "emailAddress";
15162            len = 12;
15163            break;
15164        case WC_NID_surname:
15165            str = "SN";
15166            len = 2;
15167            break;
15168        case WC_NID_givenName:
15169            str = "GN";
15170            len = 2;
15171            break;
15172        case WC_NID_dnQualifier:
15173            str = "dnQualifier";
15174            len = 11;
15175            break;
15176        case WC_NID_name:
15177            str = "name";
15178            len = 4;
15179            break;
15180        case WC_NID_initials:
15181            str = "initials";
15182            len = 8;
15183            break;
15184        case WC_NID_domainComponent:
15185            str = "DC";
15186            len = 2;
15187            break;
15188        case WC_NID_pkcs9_contentType:
15189            str = "contentType";
15190            len = 11;
15191            break;
15192        case WC_NID_userId:
15193            str = "UID";
15194            len = 3;
15195            break;
15196        case WC_NID_serialNumber:
15197            str = "serialNumber";
15198            len = 12;
15199            break;
15200        case WC_NID_title:
15201            str = "title";
15202            len = 5;
15203            break;
15204        case WC_NID_rfc822Mailbox:
15205            str = "mail";
15206            len = 4;
15207            break;
15208        default:
15209            WOLFSSL_MSG("Attribute type not found");
15210            str = NULL;
15211
15212    }
15213    if (buf != NULL)
15214        *buf = str;
15215    return len;
15216}
15217
15218/**
15219 * Escape input string for RFC2253 requirements. The following characters
15220 * are escaped with a backslash (\):
15221 *
15222 *     1. A space or '#' at the beginning of the string
15223 *     2. A space at the end of the string
15224 *     3. One of: ",", "+", """, "\", "<", ">", ";"
15225 *
15226 * in    - input string to escape
15227 * inSz  - length of in, not including the null terminator
15228 * out   - buffer for output string to be written, will be null terminated
15229 * outSz - size of out
15230 *
15231 * Returns size of output string (not counting NULL terminator) on success,
15232 * negative on error.
15233 */
15234static int wolfSSL_EscapeString_RFC2253(char* in, word32 inSz,
15235                                        char* out, word32 outSz)
15236{
15237    word32 inIdx = 0;
15238    word32 outIdx = 0;
15239
15240    if (in == NULL || out == NULL || inSz == 0 || outSz == 0) {
15241        return BAD_FUNC_ARG;
15242    }
15243
15244    for (inIdx = 0; inIdx < inSz; inIdx++) {
15245
15246        char c = in[inIdx];
15247
15248        if (((inIdx == 0) && (c == ' ' || c == '#')) ||
15249            ((inIdx == (inSz-1)) && (c == ' ')) ||
15250            c == ',' || c == '+' || c == '"' || c == '\\' ||
15251            c == '<' || c == '>' || c == ';') {
15252
15253            if (outIdx > (outSz - 1)) {
15254                return BUFFER_E;
15255            }
15256            out[outIdx] = '\\';
15257            outIdx++;
15258        }
15259        if (outIdx > (outSz - 1)) {
15260            return BUFFER_E;
15261        }
15262        out[outIdx] = c;
15263        outIdx++;
15264    }
15265
15266    /* null terminate out */
15267    if (outIdx > (outSz -1)) {
15268        return BUFFER_E;
15269    }
15270    out[outIdx] = '\0';
15271
15272    return (int)outIdx;
15273}
15274
15275/*
15276 * Print human readable version of X509_NAME to provided BIO.
15277 *
15278 * bio    - output BIO to place name string. Does not include null terminator.
15279 * name   - input name to convert to string
15280 * indent - number of indent spaces to prepend to name string
15281 * flags  - flags to control function behavior. Not all flags are currently
15282 *          supported/implemented. Currently supported are:
15283 *              XN_FLAG_RFC2253 - only the backslash escape requirements from
15284 *                                RFC22523 currently implemented.
15285 *              XN_FLAG_DN_REV  - print name reversed. Automatically done by
15286 *                                XN_FLAG_RFC2253.
15287 *              XN_FLAG_SPC_EQ  - spaces before and after '=' character
15288 *
15289 * Returns WOLFSSL_SUCCESS (1) on success, WOLFSSL_FAILURE (0) on failure.
15290 */
15291int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
15292                int indent, unsigned long flags)
15293{
15294    int i, count = 0, nameStrSz = 0, escapeSz = 0;
15295    int eqSpace  = 0;
15296    char eqStr[4];
15297    char* tmp = NULL;
15298    char* nameStr = NULL;
15299    const char *buf = NULL;
15300    WOLFSSL_X509_NAME_ENTRY* ne;
15301    WOLFSSL_ASN1_STRING* str;
15302    char escaped[ASN_NAME_MAX];
15303
15304    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
15305
15306    if ((name == NULL) || (bio == NULL))
15307        return WOLFSSL_FAILURE;
15308
15309    XMEMSET(eqStr, 0, sizeof(eqStr));
15310    if (flags & WOLFSSL_XN_FLAG_SPC_EQ) {
15311        eqSpace = 2;
15312        XSTRNCPY(eqStr, " = ", 4);
15313    }
15314    else {
15315        XSTRNCPY(eqStr, "=", 4);
15316    }
15317
15318    for (i = 0; i < indent; i++) {
15319        if (wolfSSL_BIO_write(bio, " ", 1) != 1)
15320            return WOLFSSL_FAILURE;
15321    }
15322
15323    count = wolfSSL_X509_NAME_entry_count(name);
15324
15325    for (i = 0; i < count; i++) {
15326        int len;
15327        int tmpSz;
15328
15329        /* reverse name order for RFC2253 and DN_REV */
15330        if ((flags & WOLFSSL_XN_FLAG_RFC2253) ||
15331            (flags & WOLFSSL_XN_FLAG_DN_REV)) {
15332            ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1);
15333        }
15334        else {
15335            ne = wolfSSL_X509_NAME_get_entry(name, i);
15336        }
15337        if (ne == NULL)
15338            return WOLFSSL_FAILURE;
15339
15340        str = wolfSSL_X509_NAME_ENTRY_get_data(ne);
15341        if (str == NULL)
15342            return WOLFSSL_FAILURE;
15343
15344        if (flags & WOLFSSL_XN_FLAG_RFC2253) {
15345            /* escape string for RFC 2253, ret sz not counting null term */
15346            escapeSz = wolfSSL_EscapeString_RFC2253(str->data,
15347                            str->length, escaped, sizeof(escaped));
15348            if (escapeSz < 0)
15349                return WOLFSSL_FAILURE;
15350
15351            nameStr = escaped;
15352            nameStrSz = escapeSz;
15353        }
15354        else {
15355            nameStr = str->data;
15356            nameStrSz = str->length;
15357        }
15358
15359        /* len is without null terminator */
15360        len = get_dn_attr_by_nid(ne->nid, &buf);
15361        if (len == 0 || buf == NULL)
15362            return WOLFSSL_FAILURE;
15363
15364        /* + 4 for '=', comma space and '\0'*/
15365        tmpSz = nameStrSz + len + 4 + eqSpace;
15366        tmp = (char*)XMALLOC(tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15367        if (tmp == NULL) {
15368            return WOLFSSL_FAILURE;
15369        }
15370
15371        if (i < count - 1) {
15372            if (XSNPRINTF(tmp, (size_t)tmpSz, "%s%s%s, ", buf, eqStr, nameStr)
15373                >= tmpSz)
15374            {
15375                WOLFSSL_MSG("buffer overrun");
15376                XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15377                return WOLFSSL_FAILURE;
15378            }
15379
15380            tmpSz = len + nameStrSz + 3 + eqSpace; /* 3 for '=', comma space */
15381        }
15382        else {
15383            if (XSNPRINTF(tmp, (size_t)tmpSz, "%s%s%s", buf, eqStr, nameStr)
15384                >= tmpSz)
15385            {
15386                WOLFSSL_MSG("buffer overrun");
15387                XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15388                return WOLFSSL_FAILURE;
15389            }
15390            tmpSz = len + nameStrSz + 1 + eqSpace; /* 1 for '=' */
15391            if (bio->type != WOLFSSL_BIO_FILE &&
15392                                              bio->type != WOLFSSL_BIO_MEMORY) {
15393                ++tmpSz; /* include the terminating null when not writing to a
15394                          * file.
15395                          */
15396            }
15397        }
15398
15399        if (wolfSSL_BIO_write(bio, tmp, tmpSz) != tmpSz) {
15400            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15401            return WOLFSSL_FAILURE;
15402        }
15403
15404        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15405    }
15406
15407    return WOLFSSL_SUCCESS;
15408}
15409
15410#ifndef NO_FILESYSTEM
15411int wolfSSL_X509_NAME_print_ex_fp(XFILE file, WOLFSSL_X509_NAME* name,
15412        int indent, unsigned long flags)
15413{
15414    WOLFSSL_BIO* bio;
15415    int ret;
15416
15417    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex_fp");
15418
15419    if (!(bio = wolfSSL_BIO_new_fp(file, WOLFSSL_BIO_NOCLOSE))) {
15420        WOLFSSL_MSG("wolfSSL_BIO_new_fp error");
15421        return WOLFSSL_FAILURE;
15422    }
15423
15424    ret = wolfSSL_X509_NAME_print_ex(bio, name, indent, flags);
15425
15426    wolfSSL_BIO_free(bio);
15427
15428    return ret;
15429}
15430#endif /* NO_FILESYSTEM */
15431#endif /* !NO_BIO */
15432
15433#ifndef NO_WOLFSSL_STUB
15434WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
15435{
15436    (void)x;
15437    WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
15438    WOLFSSL_STUB("X509_get0_pubkey_bitstr");
15439
15440    return NULL;
15441}
15442#endif
15443
15444#ifdef OPENSSL_ALL
15445WOLFSSL_X509_LOOKUP_TYPE wolfSSL_X509_OBJECT_get_type(
15446        const WOLFSSL_X509_OBJECT* obj)
15447{
15448    if (obj == NULL)
15449        return WOLFSSL_X509_LU_NONE;
15450    return obj->type;
15451}
15452
15453WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_new(void)
15454{
15455    WOLFSSL_X509_OBJECT* ret = (WOLFSSL_X509_OBJECT*)
15456            XMALLOC(sizeof(WOLFSSL_X509_OBJECT), NULL, DYNAMIC_TYPE_OPENSSL);
15457    if (ret != NULL)
15458        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_OBJECT));
15459    return ret;
15460}
15461
15462void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj)
15463{
15464    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free");
15465    if (obj != NULL) {
15466        if (obj->type == WOLFSSL_X509_LU_X509) {
15467            wolfSSL_X509_free(obj->data.x509);
15468        }
15469    #ifdef HAVE_CRL
15470        else if (obj->type == WOLFSSL_X509_LU_CRL) {
15471            wolfSSL_X509_CRL_free(obj->data.crl);
15472        }
15473    #endif
15474        else {
15475            /* We don't free as this will point to
15476             * store->cm->crl which we don't own */
15477            WOLFSSL_MSG("Not free'ing CRL in WOLFSSL_X509_OBJECT");
15478        }
15479        XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL);
15480    }
15481}
15482
15483WOLFSSL_X509_OBJECT *wolfSSL_X509_OBJECT_retrieve_by_subject(
15484        WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *sk,
15485        WOLFSSL_X509_LOOKUP_TYPE type,
15486        WOLFSSL_X509_NAME *name)
15487{
15488    int i;
15489
15490    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_retrieve_by_subject");
15491
15492    if (sk == NULL || name == NULL)
15493        return NULL;
15494
15495    for (i = 0; i < wolfSSL_sk_X509_OBJECT_num(sk); i++) {
15496        WOLFSSL_X509_OBJECT* obj = (WOLFSSL_X509_OBJECT *)
15497            wolfSSL_sk_X509_OBJECT_value(sk, i);
15498        if (obj != NULL && obj->type == type &&
15499            wolfSSL_X509_NAME_cmp(
15500                wolfSSL_X509_get_subject_name(obj->data.x509), name) == 0)
15501            return obj;
15502    }
15503    return NULL;
15504}
15505#endif /* OPENSSL_ALL */
15506
15507#ifndef NO_WOLFSSL_STUB
15508WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete(
15509    WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i)
15510{
15511    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_delete");
15512    WOLFSSL_STUB("wolfSSL_sk_X509_OBJECT_delete");
15513    (void)sk;
15514    (void)i;
15515    return NULL;
15516}
15517#endif
15518
15519WOLFSSL_X509 *wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT *obj)
15520{
15521    if (obj != NULL && obj->type == WOLFSSL_X509_LU_X509)
15522        return obj->data.x509;
15523    return NULL;
15524}
15525
15526WOLFSSL_X509_CRL *wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT *obj)
15527{
15528    if (obj != NULL && obj->type == WOLFSSL_X509_LU_CRL)
15529        return obj->data.crl;
15530    return NULL;
15531}
15532
15533#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
15534        * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
15535        * HAVE_SBLIM_SFCB)) */
15536
15537
15538#if defined(OPENSSL_EXTRA)
15539
15540int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s)
15541{
15542    WOLFSSL_ENTER("wolfSSL_sk_X509_num");
15543
15544    if (s == NULL)
15545        return WOLFSSL_FATAL_ERROR;
15546    return (int)s->num;
15547}
15548
15549#endif /* OPENSSL_EXTRA */
15550
15551#ifdef HAVE_EX_DATA_CRYPTO
15552int wolfSSL_X509_get_ex_new_index(int idx, void *arg,
15553                                  WOLFSSL_CRYPTO_EX_new* new_func,
15554                                  WOLFSSL_CRYPTO_EX_dup* dup_func,
15555                                  WOLFSSL_CRYPTO_EX_free* free_func)
15556{
15557    WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
15558
15559    return wolfssl_local_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509, idx, arg,
15560                                    new_func, dup_func, free_func);
15561}
15562#endif
15563
15564#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15565void *wolfSSL_X509_get_ex_data(WOLFSSL_X509 *x509, int idx)
15566{
15567    WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
15568#ifdef HAVE_EX_DATA
15569    if (x509 != NULL) {
15570        return wolfSSL_CRYPTO_get_ex_data(&x509->ex_data, idx);
15571    }
15572#else
15573    (void)x509;
15574    (void)idx;
15575#endif
15576    return NULL;
15577}
15578
15579int wolfSSL_X509_set_ex_data(WOLFSSL_X509 *x509, int idx, void *data)
15580{
15581    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
15582#ifdef HAVE_EX_DATA
15583    if (x509 != NULL) {
15584        return wolfSSL_CRYPTO_set_ex_data(&x509->ex_data, idx, data);
15585    }
15586#else
15587    (void)x509;
15588    (void)idx;
15589    (void)data;
15590#endif
15591    return WOLFSSL_FAILURE;
15592}
15593
15594#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
15595int wolfSSL_X509_set_ex_data_with_cleanup(
15596    WOLFSSL_X509 *x509,
15597    int idx,
15598    void *data,
15599    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
15600{
15601    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data_with_cleanup");
15602    if (x509 != NULL)
15603    {
15604        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&x509->ex_data, idx,
15605                                                       data, cleanup_routine);
15606    }
15607    return WOLFSSL_FAILURE;
15608}
15609#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
15610#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
15611
15612
15613#ifndef NO_ASN
15614int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen,
15615                    unsigned int flags, char **peername)
15616{
15617    int         ret;
15618    size_t      i;
15619    WC_DECLARE_VAR(dCert, DecodedCert, 1, 0);
15620
15621    WOLFSSL_ENTER("wolfSSL_X509_check_host");
15622
15623    /* flags and peername not needed for Nginx. */
15624    (void)peername;
15625
15626    if ((x == NULL) || (chk == NULL)) {
15627        WOLFSSL_MSG("Invalid parameter");
15628        return WOLFSSL_FAILURE;
15629    }
15630
15631    if (flags & WOLFSSL_NO_WILDCARDS) {
15632        WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented");
15633        return WOLFSSL_FAILURE;
15634    }
15635    if (flags & WOLFSSL_NO_PARTIAL_WILDCARDS) {
15636        WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
15637        return WOLFSSL_FAILURE;
15638    }
15639    if (flags & WOLFSSL_MULTI_LABEL_WILDCARDS) {
15640        WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
15641        return WOLFSSL_FAILURE;
15642    }
15643
15644#ifdef WOLFSSL_SMALL_STACK
15645    dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
15646                                   DYNAMIC_TYPE_DCERT);
15647    if (dCert == NULL) {
15648        WOLFSSL_MSG("\tout of memory");
15649        return WOLFSSL_FATAL_ERROR;
15650    }
15651#endif
15652
15653    InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
15654    ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
15655    if (ret != 0) {
15656        goto out;
15657    }
15658
15659    /* Replicate openssl behavior for checklen */
15660    if (chklen == 0) {
15661        chklen = (size_t)(XSTRLEN(chk));
15662    }
15663    else {
15664        for (i = 0; i < (chklen > 1 ? chklen - 1 : chklen); i++) {
15665            if (chk[i] == '\0') {
15666                ret = WOLFSSL_FATAL_ERROR;
15667                goto out;
15668            }
15669        }
15670    }
15671    if (chklen > 1 && (chk[chklen - 1] == '\0')) {
15672        chklen--;
15673    }
15674
15675#ifdef WOLFSSL_IP_ALT_NAME
15676    ret = CheckIPAddr(dCert, (char *)chk);
15677    if (ret == 0) {
15678        goto out;
15679    }
15680#endif /* WOLFSSL_IP_ALT_NAME */
15681
15682    ret = CheckHostName(dCert, (char *)chk, chklen, flags, 0);
15683
15684out:
15685
15686    FreeDecodedCert(dCert);
15687    WC_FREE_VAR_EX(dCert, x->heap, DYNAMIC_TYPE_DCERT);
15688
15689    if (ret != 0)
15690        return WOLFSSL_FAILURE;
15691    return WOLFSSL_SUCCESS;
15692}
15693
15694
15695int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc,
15696        unsigned int flags)
15697{
15698    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
15699    WC_DECLARE_VAR(dCert, DecodedCert, 1, 0);
15700
15701    WOLFSSL_ENTER("wolfSSL_X509_check_ip_asc");
15702
15703    /* flags not yet implemented */
15704    (void)flags;
15705
15706    if ((x == NULL) || (x->derCert == NULL) || (ipasc == NULL)) {
15707        WOLFSSL_MSG("Invalid parameter");
15708    }
15709    else {
15710        ret = WOLFSSL_SUCCESS;
15711    }
15712
15713#ifdef WOLFSSL_SMALL_STACK
15714    if (ret == WOLFSSL_SUCCESS) {
15715        dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
15716                                       DYNAMIC_TYPE_DCERT);
15717        if (dCert == NULL) {
15718            WOLFSSL_MSG("\tout of memory");
15719            ret = WOLFSSL_FAILURE;
15720        }
15721    }
15722#endif
15723
15724    if (ret == WOLFSSL_SUCCESS) {
15725        InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
15726        ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
15727        if (ret != 0) {
15728            ret = WOLFSSL_FAILURE;
15729        }
15730        else {
15731            ret = CheckIPAddr(dCert, ipasc);
15732            if (ret != 0) {
15733                ret = WOLFSSL_FAILURE;
15734            }
15735            else {
15736                ret = WOLFSSL_SUCCESS;
15737            }
15738        }
15739        FreeDecodedCert(dCert);
15740    }
15741
15742#ifdef WOLFSSL_SMALL_STACK
15743    if (x != NULL) {
15744        XFREE(dCert, x->heap, DYNAMIC_TYPE_DCERT);
15745    }
15746#endif
15747
15748    return ret;
15749}
15750#endif
15751
15752#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
15753int wolfSSL_X509_check_email(WOLFSSL_X509 *x, const char *chk, size_t chkLen,
15754                             unsigned int flags)
15755{
15756    WOLFSSL_X509_NAME *subjName;
15757    int emailLen;
15758    char *emailBuf;
15759
15760    (void)flags;
15761
15762    WOLFSSL_ENTER("wolfSSL_X509_check_email");
15763
15764    if ((x == NULL) || (chk == NULL)) {
15765        WOLFSSL_MSG("Invalid parameter");
15766        return WOLFSSL_FAILURE;
15767    }
15768
15769    subjName = wolfSSL_X509_get_subject_name(x);
15770    if (subjName == NULL)
15771        return WOLFSSL_FAILURE;
15772
15773    /* Call with NULL buffer to get required length. */
15774    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, WC_NID_emailAddress,
15775                                                 NULL, 0);
15776    if (emailLen < 0)
15777        return WOLFSSL_FAILURE;
15778
15779    ++emailLen; /* Add 1 for the NUL. */
15780
15781    emailBuf = (char*)XMALLOC(emailLen, x->heap, DYNAMIC_TYPE_OPENSSL);
15782    if (emailBuf == NULL)
15783        return WOLFSSL_FAILURE;
15784
15785    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, WC_NID_emailAddress,
15786                                                 emailBuf, emailLen);
15787    if (emailLen < 0) {
15788        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
15789        return WOLFSSL_FAILURE;
15790    }
15791
15792    if (chkLen == 0)
15793        chkLen = XSTRLEN(chk);
15794
15795    if (chkLen != (size_t)emailLen
15796     || XSTRNCMP(chk, emailBuf, chkLen)) {
15797        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
15798        return WOLFSSL_FAILURE;
15799    }
15800
15801    XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
15802    return WOLFSSL_SUCCESS;
15803}
15804#endif /* OPENSSL_EXTRA && WOLFSSL_CERT_GEN */
15805
15806#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
15807    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
15808
15809int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
15810        const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
15811{
15812    WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
15813
15814    if (name == NULL || type == NULL)
15815        return WOLFSSL_FAILURE;
15816
15817#if !defined(NO_FILESYSTEM) && !defined(NO_PWDBASED)
15818    return wolfSSL_EVP_Digest((unsigned char*)name->name,
15819                              name->sz, md, len, type, NULL);
15820#else
15821    (void)md;
15822    (void)len;
15823    return NOT_COMPILED_IN;
15824#endif
15825}
15826
15827#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
15828    OPENSSL_EXTRA || HAVE_LIGHTY */
15829
15830#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
15831    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
15832
15833void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
15834{
15835    wolfSSL_sk_pop_free(sk, NULL);
15836}
15837
15838static int x509_aia_append_string(WOLFSSL_STACK* list, const byte* uri,
15839        word32 uriSz)
15840{
15841    WOLFSSL_STRING url = (WOLFSSL_STRING)XMALLOC(uriSz + 1, NULL,
15842            DYNAMIC_TYPE_OPENSSL);
15843    if (url == NULL)
15844        return -1;
15845    XMEMCPY(url, uri, uriSz);
15846    url[uriSz] = '\0';
15847
15848    if (wolfSSL_sk_push(list, url) <= 0) {
15849        XFREE(url, NULL, DYNAMIC_TYPE_OPENSSL);
15850        return -1;
15851    }
15852
15853    return 0;
15854}
15855
15856static WOLFSSL_STACK* x509_get1_aia_by_method(WOLFSSL_X509* x, word32 method,
15857    const byte* fallback, int fallbackSz)
15858{
15859    WOLFSSL_STACK* ret = NULL;
15860    int i;
15861
15862    if (x == NULL)
15863        return NULL;
15864
15865    ret = wolfSSL_sk_WOLFSSL_STRING_new();
15866    if (ret == NULL)
15867        return NULL;
15868
15869    /* Build from multi-entry list when available; otherwise fall back to the
15870     * legacy single-entry fields to preserve previous behavior. */
15871    if (x->authInfoListSz > 0) {
15872        for (i = 0; i < x->authInfoListSz; i++) {
15873            if (x->authInfoList[i].method != method ||
15874                    x->authInfoList[i].uri == NULL ||
15875                    x->authInfoList[i].uriSz == 0) {
15876                continue;
15877            }
15878
15879            if (x509_aia_append_string(ret, x->authInfoList[i].uri,
15880                    x->authInfoList[i].uriSz) != 0) {
15881                wolfSSL_X509_email_free(ret);
15882                return NULL;
15883            }
15884        }
15885    }
15886    /* Only use fallback when nothing was found in the list */
15887    if (wolfSSL_sk_num(ret) == 0 && fallback != NULL && fallbackSz > 0) {
15888        if (x509_aia_append_string(ret, fallback, (word32)fallbackSz) != 0) {
15889            wolfSSL_X509_email_free(ret);
15890            return NULL;
15891        }
15892    }
15893
15894    /* Return NULL when empty */
15895    if (wolfSSL_sk_num(ret) == 0) {
15896        wolfSSL_X509_email_free(ret);
15897        ret = NULL;
15898    }
15899
15900    return ret;
15901}
15902
15903WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
15904{
15905    if (x == NULL)
15906        return NULL;
15907    return x509_get1_aia_by_method(x, AIA_OCSP_OID, x->authInfo, x->authInfoSz);
15908}
15909
15910int wolfSSL_X509_get_aia_overflow(WOLFSSL_X509 *x)
15911{
15912    int overflow = 0;
15913
15914    WOLFSSL_ENTER("wolfSSL_X509_get_aia_overflow");
15915
15916    if (x != NULL) {
15917        overflow = x->authInfoListOverflow;
15918    }
15919
15920    WOLFSSL_LEAVE("wolfSSL_X509_get_aia_overflow", overflow);
15921
15922    return overflow;
15923}
15924
15925#ifdef WOLFSSL_ASN_CA_ISSUER
15926WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ca_issuers(WOLFSSL_X509 *x)
15927{
15928    if (x == NULL)
15929        return NULL;
15930    return x509_get1_aia_by_method(x, AIA_CA_ISSUER_OID, x->authInfoCaIssuer,
15931            x->authInfoCaIssuerSz);
15932}
15933#endif /* WOLFSSL_ASN_CA_ISSUER */
15934
15935int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
15936{
15937    WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
15938    WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
15939
15940    if (issuerName == NULL || subjectName == NULL)
15941        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
15942
15943    /* Literal matching of encoded names and key ids. */
15944    if (issuerName->sz != subjectName->sz ||
15945           XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
15946        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
15947    }
15948
15949    if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
15950        if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
15951                XMEMCMP(subject->authKeyId, issuer->subjKeyId,
15952                        issuer->subjKeyIdSz) != 0) {
15953            return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
15954        }
15955    }
15956
15957    return WOLFSSL_X509_V_OK;
15958}
15959
15960#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
15961
15962#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
15963    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
15964WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
15965{
15966    WOLFSSL_ENTER("wolfSSL_X509_dup");
15967
15968    if (x == NULL) {
15969        WOLFSSL_MSG("Error: NULL input");
15970        return NULL;
15971    }
15972
15973    if (x->derCert == NULL) {
15974        WOLFSSL_MSG("Error: NULL derCert parameter");
15975        return NULL;
15976    }
15977
15978    return wolfSSL_X509_d2i_ex(NULL, x->derCert->buffer, x->derCert->length,
15979        x->heap);
15980}
15981#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_PEER_CERT || \
15982          SESSION_CERTS */
15983
15984#if defined(OPENSSL_EXTRA)
15985int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509)
15986{
15987    WOLFSSL_ENTER("wolfSSL_X509_check_ca");
15988
15989    if (x509 == NULL)
15990        return WOLFSSL_FAILURE;
15991    if (x509->isCa)
15992        return 1;
15993    if (x509->extKeyUsageCrit)
15994        return 4;
15995
15996    return 0;
15997}
15998#endif /* OPENSSL_EXTRA */
15999
16000#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16001long wolfSSL_X509_get_version(const WOLFSSL_X509 *x509)
16002{
16003    int version = 0;
16004
16005    WOLFSSL_ENTER("wolfSSL_X509_get_version");
16006
16007    if (x509 == NULL) {
16008        WOLFSSL_MSG("invalid parameter");
16009        return 0L;
16010    }
16011    version = x509->version;
16012    if (version != 0)
16013        return (long)version - 1L;
16014
16015    return 0L;
16016}
16017#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
16018
16019#if defined(OPENSSL_EXTRA)
16020int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509 *x)
16021{
16022    if (x == NULL)
16023        return 0;
16024
16025    return oid2nid((word32)x->sigOID, oidSigType);
16026}
16027#endif  /* OPENSSL_EXTRA */
16028
16029#if defined(OPENSSL_EXTRA)
16030WOLFSSL_STACK* wolfSSL_sk_X509_new(WOLF_SK_COMPARE_CB(WOLFSSL_X509, cb))
16031{
16032    (void)cb;
16033    return wolfSSL_sk_X509_new_null();
16034}
16035
16036WOLFSSL_STACK* wolfSSL_sk_X509_new_null(void)
16037{
16038    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
16039            DYNAMIC_TYPE_OPENSSL);
16040    if (s != NULL) {
16041        XMEMSET(s, 0, sizeof(*s));
16042        s->type = STACK_TYPE_X509;
16043    }
16044
16045    return s;
16046}
16047#endif  /* OPENSSL_EXTRA */
16048
16049#ifdef OPENSSL_ALL
16050
16051WOLFSSL_STACK* wolfSSL_sk_X509_OBJECT_new(void)
16052{
16053    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
16054            DYNAMIC_TYPE_OPENSSL);
16055    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_new");
16056    if (s != NULL) {
16057        XMEMSET(s, 0, sizeof(*s));
16058        s->type = STACK_TYPE_X509_OBJ;
16059    }
16060    return s;
16061}
16062
16063void wolfSSL_sk_X509_OBJECT_free(WOLFSSL_STACK* s)
16064{
16065    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_free");
16066    wolfSSL_sk_free(s);
16067}
16068
16069void wolfSSL_sk_X509_OBJECT_pop_free(WOLFSSL_STACK* s,
16070        void (*f) (WOLFSSL_X509_OBJECT*))
16071{
16072    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_pop_free");
16073    wolfSSL_sk_pop_free(s, (wolfSSL_sk_freefunc)f);
16074}
16075
16076int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj)
16077{
16078    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_push");
16079
16080    if (sk == NULL || obj == NULL) {
16081        return WOLFSSL_FAILURE;
16082    }
16083
16084    return wolfSSL_sk_push(sk, obj);
16085}
16086
16087#endif /* OPENSSL_ALL */
16088
16089#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16090/* unlike wolfSSL_X509_NAME_dup this does not malloc a duplicate, only deep
16091 * copy. "to" is expected to be a fresh blank name, if not pointers could be
16092 * lost */
16093int wolfSSL_X509_NAME_copy(const WOLFSSL_X509_NAME* from, WOLFSSL_X509_NAME* to)
16094{
16095    int i;
16096
16097    WOLFSSL_ENTER("wolfSSL_X509_NAME_copy");
16098
16099    if (from == NULL || to == NULL) {
16100        WOLFSSL_MSG("NULL parameter");
16101        return BAD_FUNC_ARG;
16102    }
16103
16104#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
16105    if (from->rawLen > 0) {
16106        if (from->rawLen > ASN_NAME_MAX) {
16107            WOLFSSL_MSG("Bad raw size");
16108            return BAD_FUNC_ARG;
16109        }
16110        XMEMCPY(to->raw, from->raw, from->rawLen);
16111        to->rawLen = from->rawLen;
16112    }
16113#endif
16114
16115    if (from->dynamicName) {
16116        to->name = (char*)XMALLOC(from->sz, to->heap, DYNAMIC_TYPE_SUBJECT_CN);
16117        if (to->name == NULL)
16118            return WOLFSSL_FAILURE;
16119        to->dynamicName = 1;
16120    }
16121    XMEMCPY(to->name, from->name, from->sz);
16122    to->sz = from->sz;
16123
16124    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
16125        WOLFSSL_X509_NAME_ENTRY* ne = wolfSSL_X509_NAME_get_entry(from, i);
16126        if (ne != NULL) {
16127            if (wolfSSL_X509_NAME_add_entry(to, ne, i, 1) != WOLFSSL_SUCCESS) {
16128                return WOLFSSL_FAILURE;
16129            }
16130        }
16131    }
16132    to->entrySz = from->entrySz;
16133    return WOLFSSL_SUCCESS;
16134}
16135
16136
16137/* copies over information from "name" to the "cert" subject name
16138 * returns WOLFSSL_SUCCESS on success */
16139int wolfSSL_X509_set_subject_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
16140{
16141    WOLFSSL_ENTER("wolfSSL_X509_set_subject_name");
16142    if (cert == NULL || name == NULL)
16143        return WOLFSSL_FAILURE;
16144
16145    FreeX509Name(&cert->subject);
16146    InitX509Name(&cert->subject, 0, cert->heap);
16147
16148    if (wolfSSL_X509_NAME_copy(name, &cert->subject) != WOLFSSL_SUCCESS) {
16149        FreeX509Name(&cert->subject);
16150        return WOLFSSL_FAILURE;
16151    }
16152
16153    cert->subject.x509 = cert;
16154    return WOLFSSL_SUCCESS;
16155}
16156
16157
16158/* copies over information from "name" to the "cert" issuer name
16159 * returns WOLFSSL_SUCCESS on success */
16160int wolfSSL_X509_set_issuer_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
16161{
16162    WOLFSSL_ENTER("wolfSSL_X509_set_issuer_name");
16163    if (cert == NULL || name == NULL)
16164        return WOLFSSL_FAILURE;
16165
16166    FreeX509Name(&cert->issuer);
16167    InitX509Name(&cert->issuer, 0, cert->heap);
16168
16169    if (wolfSSL_X509_NAME_copy(name, &cert->issuer) != WOLFSSL_SUCCESS) {
16170        FreeX509Name(&cert->issuer);
16171        return WOLFSSL_FAILURE;
16172    }
16173
16174    cert->issuer.x509 = cert;
16175    cert->issuerSet = 1;
16176
16177    return WOLFSSL_SUCCESS;
16178}
16179
16180
16181int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
16182{
16183    if (x509 == NULL || t == NULL) {
16184        return WOLFSSL_FAILURE;
16185    }
16186
16187    if (t->length < 0 || t->length > CTC_DATE_SIZE - 2) {
16188        return WOLFSSL_FAILURE;
16189    }
16190
16191    x509->notAfter.type = t->type;
16192    x509->notAfter.length = t->length;
16193
16194    XMEMCPY(x509->notAfter.data, t->data, CTC_DATE_SIZE);
16195
16196    return WOLFSSL_SUCCESS;
16197}
16198
16199int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
16200{
16201    if (x509 == NULL || t == NULL) {
16202        return WOLFSSL_FAILURE;
16203    }
16204
16205    if (t->length < 0 || t->length > CTC_DATE_SIZE - 2) {
16206        return WOLFSSL_FAILURE;
16207    }
16208
16209    x509->notBefore.type = t->type;
16210    x509->notBefore.length = t->length;
16211
16212    XMEMCPY(x509->notBefore.data, t->data, CTC_DATE_SIZE);
16213
16214    return WOLFSSL_SUCCESS;
16215}
16216
16217int wolfSSL_X509_set1_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t)
16218{
16219    return wolfSSL_X509_set_notAfter(x509, t);
16220}
16221
16222int wolfSSL_X509_set1_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t)
16223{
16224    return wolfSSL_X509_set_notBefore(x509, t);
16225}
16226
16227int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s)
16228{
16229    WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber");
16230    if (x509 == NULL || s == NULL || s->data == NULL ||
16231            s->length >= EXTERNAL_SERIAL_SIZE)
16232        return WOLFSSL_FAILURE;
16233
16234    /* WOLFSSL_ASN1_INTEGER has type | size | data
16235     * Sanity check that the data is actually in ASN format */
16236    if (s->length < 3 || s->data[0] != ASN_INTEGER ||
16237            s->data[1] != s->length - 2) {
16238        return WOLFSSL_FAILURE;
16239    }
16240    XMEMCPY(x509->serial, s->data + 2, s->length - 2);
16241    x509->serialSz = s->length - 2;
16242    x509->serial[x509->serialSz] = 0;
16243
16244    return WOLFSSL_SUCCESS;
16245}
16246
16247
16248int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
16249{
16250    byte* p = NULL;
16251    int derSz = 0;
16252    WOLFSSL_ENTER("wolfSSL_X509_set_pubkey");
16253
16254    if (cert == NULL || pkey == NULL)
16255        return WOLFSSL_FAILURE;
16256
16257    /* Regenerate since pkey->pkey.ptr may contain private key */
16258    switch (pkey->type) {
16259#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA)
16260    case WC_EVP_PKEY_RSA:
16261        {
16262            RsaKey* rsa;
16263
16264            if (pkey->rsa == NULL || pkey->rsa->internal == NULL)
16265                return WOLFSSL_FAILURE;
16266
16267            rsa = (RsaKey*)pkey->rsa->internal;
16268            derSz = wc_RsaPublicKeyDerSize(rsa, 1);
16269            if (derSz <= 0)
16270                return WOLFSSL_FAILURE;
16271
16272            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16273            if (p == NULL)
16274                return WOLFSSL_FAILURE;
16275
16276            if ((derSz = wc_RsaKeyToPublicDer(rsa, p, (word32)derSz)) <= 0) {
16277                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16278                return WOLFSSL_FAILURE;
16279            }
16280            cert->pubKeyOID = RSAk;
16281        }
16282        break;
16283#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
16284#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
16285        defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
16286    case WC_EVP_PKEY_DSA:
16287        {
16288            DsaKey* dsa;
16289
16290            if (pkey->dsa == NULL || pkey->dsa->internal == NULL)
16291                return WOLFSSL_FAILURE;
16292
16293            dsa = (DsaKey*)pkey->dsa->internal;
16294            /* size of pub, priv, p, q, g + ASN.1 additional information */
16295            derSz = 5 * mp_unsigned_bin_size(&dsa->g) + MAX_ALGO_SZ;
16296            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16297            if (p == NULL)
16298                return WOLFSSL_FAILURE;
16299
16300            if ((derSz = wc_DsaKeyToPublicDer(dsa, p, (word32)derSz)) <= 0) {
16301                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16302                return WOLFSSL_FAILURE;
16303            }
16304            cert->pubKeyOID = DSAk;
16305        }
16306        break;
16307#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */
16308#ifdef HAVE_ECC
16309    case WC_EVP_PKEY_EC:
16310        {
16311            ecc_key* ecc;
16312
16313            if (pkey->ecc == NULL || pkey->ecc->internal == NULL)
16314                return WOLFSSL_FAILURE;
16315
16316            ecc = (ecc_key*)pkey->ecc->internal;
16317            derSz = wc_EccPublicKeyDerSize(ecc, 1);
16318            if (derSz <= 0)
16319                return WOLFSSL_FAILURE;
16320
16321            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16322            if (p == NULL)
16323                return WOLFSSL_FAILURE;
16324
16325            if ((derSz = wc_EccPublicKeyToDer(ecc, p, (word32)derSz, 1)) <= 0) {
16326                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16327                return WOLFSSL_FAILURE;
16328            }
16329            cert->pubKeyOID = ECDSAk;
16330        }
16331        break;
16332#endif
16333    default:
16334        return WOLFSSL_FAILURE;
16335    }
16336    XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16337    cert->pubKey.buffer = p;
16338    cert->pubKey.length = (unsigned int)derSz;
16339
16340    return WOLFSSL_SUCCESS;
16341}
16342
16343int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v)
16344{
16345    WOLFSSL_ENTER("wolfSSL_X509_set_version");
16346    if ((x509 == NULL) || (v < 0) || (v >= INT_MAX)) {
16347        return WOLFSSL_FAILURE;
16348    }
16349    x509->version = (int) v + 1;
16350
16351    return WOLFSSL_SUCCESS;
16352}
16353
16354#ifdef WOLFSSL_CERT_EXT
16355/* Set Subject Key Identifier from raw bytes.
16356 *
16357 * x509  - Certificate to modify
16358 * skid  - Raw SKID bytes
16359 * skidSz - Size of SKID in bytes
16360 *
16361 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
16362 */
16363int wolfSSL_X509_set_subject_key_id(WOLFSSL_X509* x509,
16364    const unsigned char* skid, int skidSz)
16365{
16366    WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id");
16367
16368    if (x509 == NULL || skid == NULL || skidSz <= 0) {
16369        return WOLFSSL_FAILURE;
16370    }
16371
16372    /* Allocate/reallocate memory for subjKeyId */
16373    if (x509->subjKeyId == NULL || (int)x509->subjKeyIdSz < skidSz) {
16374        if (x509->subjKeyId != NULL) {
16375            XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
16376        }
16377        x509->subjKeyId = (byte*)XMALLOC((word32)skidSz, x509->heap,
16378                                          DYNAMIC_TYPE_X509_EXT);
16379        if (x509->subjKeyId == NULL) {
16380            return WOLFSSL_FAILURE;
16381        }
16382    }
16383
16384    XMEMCPY(x509->subjKeyId, skid, (word32)skidSz);
16385    x509->subjKeyIdSz = (word32)skidSz;
16386    x509->subjKeyIdSet = 1;
16387
16388    return WOLFSSL_SUCCESS;
16389}
16390
16391#ifndef NO_SHA
16392/* Set Subject Key Identifier by computing SHA-1 hash of the public key.
16393 *
16394 * x509 - Certificate to modify (must have public key set)
16395 *
16396 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
16397 */
16398int wolfSSL_X509_set_subject_key_id_ex(WOLFSSL_X509* x509)
16399{
16400    byte hash[WC_SHA_DIGEST_SIZE];
16401    int ret;
16402
16403    WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id_ex");
16404
16405    if (x509 == NULL) {
16406        return WOLFSSL_FAILURE;
16407    }
16408
16409    /* Check if public key has been set */
16410    if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
16411        WOLFSSL_MSG("Public key not set");
16412        return WOLFSSL_FAILURE;
16413    }
16414
16415    /* Compute SHA-1 hash of the public key */
16416    ret = wc_ShaHash(x509->pubKey.buffer, x509->pubKey.length, hash);
16417    if (ret != 0) {
16418        WOLFSSL_MSG("wc_ShaHash failed");
16419        return WOLFSSL_FAILURE;
16420    }
16421
16422    return wolfSSL_X509_set_subject_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
16423}
16424#endif /* !NO_SHA */
16425
16426/* Set Authority Key Identifier from raw bytes.
16427 * The bytes passed in are the keyIdentifier OCTET STRING contents only,
16428 * they must not be a pre-encoded AuthorityKeyIdentifier SEQUENCE.
16429 * The cert encoder wraps them in SEQUENCE { [0] keyIdentifier } at sign time.
16430 *
16431 * x509   - Certificate to modify
16432 * akid   - Raw AKID bytes
16433 * akidSz - Size of AKID in bytes
16434 *
16435 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
16436 */
16437int wolfSSL_X509_set_authority_key_id(WOLFSSL_X509* x509,
16438    const unsigned char* akid, int akidSz)
16439{
16440    byte* newAkid = NULL;
16441
16442    WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id");
16443
16444    if (x509 == NULL || akid == NULL || akidSz <= 0) {
16445        return WOLFSSL_FAILURE;
16446    }
16447
16448    /* Allocate new buffer up front so failure leaves prior state intact */
16449    newAkid = (byte*)XMALLOC((word32)akidSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
16450    if (newAkid == NULL) {
16451        return WOLFSSL_FAILURE;
16452    }
16453    XMEMCPY(newAkid, akid, (word32)akidSz);
16454
16455    /* Free any prior storage. authKeyIdSrc may be populated from a prior
16456     * parse cert operation. authKeyId aliases inside that buffer, so
16457     * authKeyIdSrc must be freed first to avoid a dangling authKeyId. */
16458    if (x509->authKeyIdSrc != NULL) {
16459        XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
16460        x509->authKeyIdSrc = NULL;
16461        x509->authKeyIdSrcSz = 0;
16462    }
16463    else if (x509->authKeyId != NULL) {
16464        XFREE(x509->authKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
16465    }
16466
16467    /* Store newAkid as authKeyId only, do not populate authKeyIdSrc.
16468     * When authKeyIdSrc is non-NULL, the encoder writes those bytes without
16469     * SEQUENCE/[0] wrapper. authKeyIdSrc must be NULL here so encoder does
16470     * wrap them. */
16471    x509->authKeyId = newAkid;
16472    x509->authKeyIdSz = (word32)akidSz;
16473    x509->authKeyIdSet = 1;
16474
16475    return WOLFSSL_SUCCESS;
16476}
16477
16478#ifndef NO_SHA
16479/* Set Authority Key Identifier from issuer certificate.
16480 * Extracts SKID from issuer (or computes from issuer's public key).
16481 *
16482 * x509   - Certificate to modify
16483 * issuer - Issuer certificate
16484 *
16485 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
16486 */
16487int wolfSSL_X509_set_authority_key_id_ex(WOLFSSL_X509* x509,
16488    WOLFSSL_X509* issuer)
16489{
16490    byte hash[WC_SHA_DIGEST_SIZE];
16491    int ret;
16492
16493    WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id_ex");
16494
16495    if (x509 == NULL || issuer == NULL) {
16496        return WOLFSSL_FAILURE;
16497    }
16498
16499    /* First try to use issuer's SKID if it's set */
16500    if (issuer->subjKeyIdSet && issuer->subjKeyId != NULL &&
16501        issuer->subjKeyIdSz > 0) {
16502        return wolfSSL_X509_set_authority_key_id(x509, issuer->subjKeyId,
16503                                                  (int)issuer->subjKeyIdSz);
16504    }
16505
16506    /* Otherwise compute from issuer's public key */
16507    if (issuer->pubKey.buffer == NULL || issuer->pubKey.length == 0) {
16508        WOLFSSL_MSG("Issuer public key not available");
16509        return WOLFSSL_FAILURE;
16510    }
16511
16512    ret = wc_ShaHash(issuer->pubKey.buffer, issuer->pubKey.length, hash);
16513    if (ret != 0) {
16514        WOLFSSL_MSG("wc_ShaHash failed");
16515        return WOLFSSL_FAILURE;
16516    }
16517
16518    return wolfSSL_X509_set_authority_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
16519}
16520#endif /* !NO_SHA */
16521#endif /* WOLFSSL_CERT_EXT */
16522
16523#ifndef IGNORE_NETSCAPE_CERT_TYPE
16524/* Set Netscape Certificate Type extension.
16525 *
16526 * x509       - Certificate to modify
16527 * nsCertType - Bitwise OR of NS_SSL_CLIENT, NS_SSL_SERVER, etc.
16528 *
16529 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
16530 */
16531int wolfSSL_X509_set_ns_cert_type(WOLFSSL_X509* x509, int nsCertType)
16532{
16533    WOLFSSL_ENTER("wolfSSL_X509_set_ns_cert_type");
16534
16535    if (x509 == NULL) {
16536        return WOLFSSL_FAILURE;
16537    }
16538
16539    x509->nsCertType = (byte)nsCertType;
16540
16541    return WOLFSSL_SUCCESS;
16542}
16543#endif /* !IGNORE_NETSCAPE_CERT_TYPE */
16544
16545#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */
16546
16547#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) &&           \
16548    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
16549
16550void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer,
16551        WOLFSSL_X509* subject, WOLFSSL_X509* req, WOLFSSL_X509_CRL* crl,
16552        int flag)
16553{
16554    int ret = WOLFSSL_SUCCESS;
16555    WOLFSSL_ENTER("wolfSSL_X509V3_set_ctx");
16556    if (!ctx) {
16557        ret = WOLFSSL_FAILURE;
16558        WOLFSSL_MSG("wolfSSL_X509V3_set_ctx() called with null ctx.");
16559    }
16560
16561    if (ret == WOLFSSL_SUCCESS && (ctx->x509 != NULL)) {
16562        ret = WOLFSSL_FAILURE;
16563        WOLFSSL_MSG("wolfSSL_X509V3_set_ctx() called "
16564                    "with ctx->x509 already allocated.");
16565    }
16566
16567    if (ret == WOLFSSL_SUCCESS) {
16568        ctx->x509 = wolfSSL_X509_new_ex(
16569            (issuer && issuer->heap) ? issuer->heap :
16570            (subject && subject->heap) ? subject->heap :
16571            (req && req->heap) ? req->heap :
16572            NULL);
16573        if (!ctx->x509) {
16574            ret = WOLFSSL_FAILURE;
16575            WOLFSSL_MSG("wolfSSL_X509_new_ex() failed "
16576                        "in wolfSSL_X509V3_set_ctx().");
16577        }
16578    }
16579
16580    /* Set parameters in ctx as long as ret == WOLFSSL_SUCCESS */
16581    if (ret == WOLFSSL_SUCCESS && issuer)
16582        ret = wolfSSL_X509_set_issuer_name(ctx->x509, &issuer->issuer);
16583
16584    if (ret == WOLFSSL_SUCCESS && subject)
16585        ret = wolfSSL_X509_set_subject_name(ctx->x509, &subject->subject);
16586
16587    if (ret == WOLFSSL_SUCCESS && req) {
16588        WOLFSSL_MSG("req not implemented.");
16589    }
16590
16591    if (ret == WOLFSSL_SUCCESS && crl) {
16592        WOLFSSL_MSG("crl not implemented.");
16593    }
16594
16595    if (ret == WOLFSSL_SUCCESS && flag) {
16596        WOLFSSL_MSG("flag not implemented.");
16597    }
16598
16599    if (ret != WOLFSSL_SUCCESS) {
16600        WOLFSSL_MSG("Error setting WOLFSSL_X509V3_CTX parameters.");
16601    }
16602}
16603
16604#ifndef NO_BIO
16605int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out)
16606{
16607    int derSz = 0;
16608    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
16609    WOLFSSL_BIO* bio = NULL;
16610    WOLFSSL_ENTER("wolfSSL_i2d_X509_REQ");
16611
16612    if (req == NULL || out == NULL) {
16613        return BAD_FUNC_ARG;
16614    }
16615
16616    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
16617        return WOLFSSL_FAILURE;
16618    }
16619
16620    if (wolfSSL_i2d_X509_REQ_bio(bio, req) != WOLFSSL_SUCCESS) {
16621        WOLFSSL_MSG("wolfSSL_i2d_X509_REQ_bio error");
16622        goto cleanup;
16623    }
16624
16625    derSz = wolfSSL_BIO_get_len(bio);
16626
16627    if (*out == NULL) {
16628        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
16629        if (!*out) {
16630            WOLFSSL_MSG("malloc error");
16631            ret = MEMORY_E;
16632            goto cleanup;
16633        }
16634    }
16635
16636    if (wolfSSL_BIO_read(bio, *out, derSz) != derSz) {
16637        WOLFSSL_MSG("wolfSSL_BIO_read error");
16638        goto cleanup;
16639    }
16640
16641    ret = derSz;
16642cleanup:
16643    wolfSSL_BIO_free(bio);
16644
16645    return ret;
16646}
16647#endif /* !NO_BIO */
16648
16649WOLFSSL_X509* wolfSSL_X509_REQ_new(void)
16650{
16651    return wolfSSL_X509_new();
16652}
16653
16654void wolfSSL_X509_REQ_free(WOLFSSL_X509* req)
16655{
16656    wolfSSL_X509_free(req);
16657}
16658
16659int wolfSSL_X509_REQ_set_version(WOLFSSL_X509 *x, long version)
16660{
16661    WOLFSSL_ENTER("wolfSSL_X509_REQ_set_version");
16662    if ((x == NULL) || (version < 0) || (version >= INT_MAX)) {
16663        return WOLFSSL_FAILURE;
16664    }
16665    x->version = (int)version;
16666    return WOLFSSL_SUCCESS;
16667}
16668
16669long wolfSSL_X509_REQ_get_version(const WOLFSSL_X509 *req)
16670{
16671    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_version");
16672    if (req == NULL) {
16673        return 0; /* invalid arg */
16674    }
16675    return (long)req->version;
16676}
16677
16678int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
16679                          const WOLFSSL_EVP_MD *md)
16680{
16681    int ret;
16682    WC_DECLARE_VAR(der, byte, 2048, 0);
16683    int derSz = 2048;
16684
16685    if (req == NULL || pkey == NULL || md == NULL) {
16686        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", BAD_FUNC_ARG);
16687        return WOLFSSL_FAILURE;
16688    }
16689
16690    WC_ALLOC_VAR_EX(der, byte, derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER,
16691        return WOLFSSL_FAILURE);
16692
16693    /* Create a Cert that has the certificate request fields. */
16694    req->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
16695    ret = wolfssl_x509_make_der(req, 1, der, &derSz, 0);
16696    if (ret != WOLFSSL_SUCCESS) {
16697        WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16698        WOLFSSL_MSG("Unable to make DER for X509");
16699        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", ret);
16700        return WOLFSSL_FAILURE;
16701    }
16702
16703    if (wolfSSL_X509_resign_cert(req, 1, der, 2048, derSz,
16704            (WOLFSSL_EVP_MD*)md, pkey) <= 0) {
16705        WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16706        return WOLFSSL_FAILURE;
16707    }
16708    WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16709    return WOLFSSL_SUCCESS;
16710}
16711
16712int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req,
16713                              WOLFSSL_EVP_MD_CTX* md_ctx)
16714{
16715    if (md_ctx && md_ctx->pctx)
16716        return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey,
16717                wolfSSL_EVP_MD_CTX_md(md_ctx));
16718    else
16719        return WOLFSSL_FAILURE;
16720}
16721
16722static int regenX509REQDerBuffer(WOLFSSL_X509* x509)
16723{
16724    int derSz = X509_BUFFER_SZ;
16725    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
16726#ifndef WOLFSSL_SMALL_STACK
16727    byte der[X509_BUFFER_SZ];
16728#else
16729    byte* der;
16730
16731    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16732    if (!der) {
16733        WOLFSSL_MSG("malloc failed");
16734        return WOLFSSL_FAILURE;
16735    }
16736#endif
16737
16738    if (wolfssl_x509_make_der(x509, 1, der, &derSz, 0) == WOLFSSL_SUCCESS) {
16739        FreeDer(&x509->derCert);
16740        if (AllocDer(&x509->derCert, (word32)derSz, CERT_TYPE,
16741                                                             x509->heap) == 0) {
16742            XMEMCPY(x509->derCert->buffer, der, derSz);
16743            ret = WOLFSSL_SUCCESS;
16744        }
16745        else {
16746            WOLFSSL_MSG("Failed to allocate DER buffer for X509");
16747        }
16748    }
16749    else {
16750        WOLFSSL_MSG("Unable to make DER for X509 REQ");
16751    }
16752    WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16753    return ret;
16754}
16755
16756int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req,
16757        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk)
16758{
16759    WOLFSSL_X509_EXTENSION* ext = NULL;
16760
16761    if (!req || !ext_sk) {
16762        WOLFSSL_MSG("Bad parameter");
16763        return WOLFSSL_FAILURE;
16764    }
16765
16766    /* It is not an error if the stack is empty. */
16767    ext = ext_sk->data.ext;
16768    if (ext == NULL) {
16769        return WOLFSSL_SUCCESS;
16770    }
16771
16772    while (ext_sk) {
16773        ext = ext_sk->data.ext;
16774
16775        if (wolfSSL_X509_add_ext(req, ext, -1) != WOLFSSL_SUCCESS) {
16776            WOLFSSL_MSG("wolfSSL_X509_add_ext error");
16777            return WOLFSSL_FAILURE;
16778        }
16779
16780        ext_sk = ext_sk->next;
16781    }
16782
16783    return regenX509REQDerBuffer(req);
16784}
16785
16786int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req,
16787                              const char *attrname, int type,
16788                              const unsigned char *bytes, int len)
16789{
16790    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_txt");
16791
16792#ifdef HAVE_LIBEST
16793    if (!req || !attrname || !bytes || type != MBSTRING_ASC) {
16794        WOLFSSL_MSG("Bad parameter");
16795        return WOLFSSL_FAILURE;
16796    }
16797
16798    if (len < 0) {
16799        len = (int)XSTRLEN((char*)bytes);
16800    }
16801
16802    /* For now just pretend that we support this for libest testing */
16803    if (len == XSTR_SIZEOF("1.3.6.1.1.1.1.22") &&
16804            XMEMCMP("1.3.6.1.1.1.1.22", bytes, len) == 0) {
16805        /* MAC Address */
16806    }
16807    else if (len == XSTR_SIZEOF("1.2.840.10045.2.1") &&
16808            XMEMCMP("1.2.840.10045.2.1", bytes, len) == 0) {
16809        /* ecPublicKey */
16810    }
16811    else if (len == XSTR_SIZEOF("1.2.840.10045.4.3.3") &&
16812            XMEMCMP("1.2.840.10045.4.3.3", bytes, len) == 0) {
16813        /* ecdsa-with-SHA384 */
16814    }
16815    else {
16816        return WOLFSSL_FAILURE;
16817    }
16818
16819    /* return error if not built for libest */
16820    return WOLFSSL_SUCCESS;
16821#else
16822    (void)req;
16823    (void)attrname;
16824    (void)type;
16825    (void)bytes;
16826    (void)len;
16827    return WOLFSSL_FAILURE;
16828#endif
16829}
16830
16831
16832static int wolfSSL_X509_ATTRIBUTE_set(WOLFSSL_X509_ATTRIBUTE* attr,
16833        const char* data, int dataSz, int type, int nid)
16834{
16835    if (attr) {
16836        attr->value->value.asn1_string = wolfSSL_ASN1_STRING_new();
16837        if (wolfSSL_ASN1_STRING_set(attr->value->value.asn1_string,
16838                data, dataSz) != WOLFSSL_SUCCESS) {
16839            wolfSSL_ASN1_STRING_free(attr->value->value.asn1_string);
16840            WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
16841            return WOLFSSL_FAILURE;
16842        }
16843        attr->value->type = type;
16844        attr->object->nid = nid;
16845    }
16846    else {
16847        WOLFSSL_MSG("wolfSSL_X509_ATTRIBUTE_new error");
16848        return WOLFSSL_FAILURE;
16849    }
16850
16851    return WOLFSSL_SUCCESS;
16852}
16853
16854
16855int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req,
16856                                      int nid, int type,
16857                                      const unsigned char *bytes,
16858                                      int len)
16859{
16860    int ret;
16861    WOLFSSL_X509_ATTRIBUTE* attr;
16862
16863    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID");
16864
16865    if (!req || !bytes || type != WOLFSSL_MBSTRING_ASC) {
16866        WOLFSSL_MSG("Bad parameter");
16867        return WOLFSSL_FAILURE;
16868    }
16869
16870    switch (nid) {
16871    case WC_NID_pkcs9_challengePassword:
16872        if (len < 0)
16873            len = (int)XSTRLEN((char*)bytes);
16874        if (len < CTC_NAME_SIZE) {
16875            XMEMCPY(req->challengePw, bytes, len);
16876            req->challengePw[len] = '\0';
16877        }
16878        else {
16879            WOLFSSL_MSG("Challenge password too long");
16880            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
16881            return WOLFSSL_FAILURE;
16882        }
16883        break;
16884    case WC_NID_serialNumber:
16885        if (len < 0)
16886            len = (int)XSTRLEN((char*)bytes);
16887        if (len + 1 > EXTERNAL_SERIAL_SIZE) {
16888            WOLFSSL_MSG("SerialNumber too long");
16889            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
16890            return WOLFSSL_FAILURE;
16891        }
16892        XMEMCPY(req->serial, bytes, len);
16893        req->serialSz = len;
16894        break;
16895
16896    case WC_NID_pkcs9_unstructuredName:
16897    case WC_NID_pkcs9_contentType:
16898    case WC_NID_surname:
16899    case WC_NID_initials:
16900    case WC_NID_givenName:
16901    case WC_NID_dnQualifier:
16902        break;
16903
16904    default:
16905        WOLFSSL_MSG("Unsupported attribute");
16906        return WOLFSSL_FAILURE;
16907    }
16908
16909    attr = wolfSSL_X509_ATTRIBUTE_new();
16910    ret = wolfSSL_X509_ATTRIBUTE_set(attr, (const char*)bytes, len,
16911            WOLFSSL_V_ASN1_PRINTABLESTRING, nid);
16912    if (ret != WOLFSSL_SUCCESS) {
16913        wolfSSL_X509_ATTRIBUTE_free(attr);
16914    }
16915    else {
16916        if (req->reqAttributes == NULL) {
16917            req->reqAttributes = wolfSSL_sk_new_node(req->heap);
16918            if (req->reqAttributes != NULL) {
16919                req->reqAttributes->type = STACK_TYPE_X509_REQ_ATTR;
16920            }
16921        }
16922        if ((req->reqAttributes != NULL) &&
16923                (req->reqAttributes->type == STACK_TYPE_X509_REQ_ATTR)) {
16924            /* Using wolfSSL_sk_insert to maintain backwards compatibility with
16925             * earlier versions of _push API that pushed items to the start of
16926             * the list instead of the end. */
16927            ret = wolfSSL_sk_insert(req->reqAttributes, attr, 0) > 0
16928                    ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
16929        }
16930        else {
16931            ret = WOLFSSL_FAILURE;
16932        }
16933        if (ret != WOLFSSL_SUCCESS)
16934            wolfSSL_X509_ATTRIBUTE_free(attr);
16935    }
16936
16937    return ret;
16938}
16939
16940WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x,
16941        WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md)
16942{
16943    WOLFSSL_ENTER("wolfSSL_X509_to_X509_REQ");
16944    (void)pkey;
16945    (void)md;
16946    return wolfSSL_X509_dup(x);
16947}
16948
16949int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req,
16950                                      WOLFSSL_X509_NAME *name)
16951{
16952    return wolfSSL_X509_set_subject_name(req, name);
16953}
16954
16955int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey)
16956{
16957    return wolfSSL_X509_set_pubkey(req, pkey);
16958}
16959#endif /* OPENSSL_ALL && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
16960
16961#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
16962    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ))
16963
16964WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type(
16965        WOLFSSL_X509_ATTRIBUTE *attr, int idx)
16966{
16967    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_get0_type");
16968
16969    if (!attr || idx != 0) {
16970        WOLFSSL_MSG("Bad parameter");
16971        return NULL;
16972    }
16973
16974    return attr->value;
16975}
16976
16977
16978/**
16979 * @param req X509_REQ containing attribute
16980 * @return the number of attributes
16981 */
16982int wolfSSL_X509_REQ_get_attr_count(const WOLFSSL_X509 *req)
16983{
16984    if (req == NULL || req->reqAttributes == NULL)
16985        return 0;
16986
16987    return wolfSSL_sk_num(req->reqAttributes);
16988}
16989
16990
16991/**
16992 * @param req X509_REQ containing attribute
16993 * @param loc NID of the attribute to return
16994 */
16995WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr(
16996        const WOLFSSL_X509 *req, int loc)
16997{
16998    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr");
16999
17000    if (!req || req->reqAttributes == NULL) {
17001        WOLFSSL_MSG("Bad parameter");
17002        return NULL;
17003    }
17004
17005    return (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, loc);
17006}
17007
17008/* Return NID as the attr index */
17009int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req,
17010        int nid, int lastpos)
17011{
17012    int idx;
17013
17014    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID");
17015
17016    if (!req) {
17017        WOLFSSL_MSG("Bad parameter");
17018        return WOLFSSL_FATAL_ERROR;
17019    }
17020
17021    /* search through stack for first matching nid */
17022    for (idx = lastpos + 1; idx < wolfSSL_sk_num(req->reqAttributes); idx++) {
17023        WOLFSSL_X509_ATTRIBUTE* attr =
17024             (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, idx);
17025        if (attr != NULL && attr->object != NULL && attr->object->nid == nid)
17026            return idx;
17027    }
17028
17029    return WOLFSSL_FATAL_ERROR;
17030}
17031
17032WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void)
17033{
17034    WOLFSSL_X509_ATTRIBUTE* ret;
17035    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_new");
17036    ret = (WOLFSSL_X509_ATTRIBUTE*)XMALLOC(sizeof(WOLFSSL_X509_ATTRIBUTE),
17037            NULL, DYNAMIC_TYPE_OPENSSL);
17038    if (!ret) {
17039        WOLFSSL_MSG("malloc error");
17040        return NULL;
17041    }
17042    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ATTRIBUTE));
17043    ret->object = wolfSSL_ASN1_OBJECT_new();
17044    ret->value = wolfSSL_ASN1_TYPE_new();
17045    /* Don't allocate ret->set since WOLFSSL_ASN1_TYPE
17046     * is not supported as a stack type */
17047    if (!ret->object || !ret->value) {
17048        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new or wolfSSL_ASN1_TYPE_new error");
17049        wolfSSL_X509_ATTRIBUTE_free(ret);
17050        return NULL;
17051    }
17052    return ret;
17053}
17054
17055void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr)
17056{
17057    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_free");
17058    if (attr) {
17059        if (attr->object) {
17060            wolfSSL_ASN1_OBJECT_free(attr->object);
17061        }
17062        if (attr->value) {
17063            wolfSSL_ASN1_TYPE_free(attr->value);
17064        }
17065        if (attr->set) {
17066            wolfSSL_sk_pop_free(attr->set, NULL);
17067        }
17068        XFREE(attr, NULL, DYNAMIC_TYPE_OPENSSL);
17069    }
17070}
17071#endif /* (OPENSSL_ALL || OPENSSL_EXTRA) &&
17072          (WOLFSSL_CERT_GEN || WOLFSSL_CERT_REQ) */
17073
17074#if defined(WOLFSSL_ACERT) && \
17075   (defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA))
17076
17077/* Allocate and return a new WOLFSSL_X509_ACERT struct pointer.
17078 *
17079 * @param [in]      heap        heap hint
17080 *
17081 * @return  pointer  on success
17082 * @return  NULL     on error
17083 * */
17084WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_new_ex(void* heap)
17085{
17086    WOLFSSL_X509_ACERT * x509 = NULL;
17087
17088    WOLFSSL_ENTER("wolfSSL_X509_ACERT_new");
17089
17090    x509 = (WOLFSSL_X509_ACERT*) XMALLOC(sizeof(WOLFSSL_X509_ACERT), heap,
17091                                         DYNAMIC_TYPE_X509_ACERT);
17092
17093    if (x509 != NULL) {
17094        wolfSSL_X509_ACERT_init(x509, 1, heap);
17095    }
17096
17097    return x509;
17098}
17099
17100WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_new(void)
17101{
17102    return wolfSSL_X509_ACERT_new_ex(NULL);
17103}
17104
17105/* Initialize a WOLFSSL_X509_ACERT struct.
17106 *
17107 * If dynamic == 1, then the x509 pointer will be freed
17108 * in wolfSSL_X509_ACERT_free.
17109 *
17110 * @param [in]      x509        x509 acert pointer
17111 * @param [in]      dynamic     dynamic mem flag
17112 * @param [in]      heap        heap hint
17113 *
17114 * @return  void
17115 * */
17116void wolfSSL_X509_ACERT_init(WOLFSSL_X509_ACERT * x509, int dynamic, void* heap)
17117{
17118    WOLFSSL_ENTER("wolfSSL_X509_ACERT_init");
17119
17120    if (x509 == NULL) {
17121        WOLFSSL_MSG("error: InitX509Acert: null parameter");
17122        return;
17123    }
17124
17125    XMEMSET(x509, 0, sizeof(*x509));
17126
17127    x509->heap = heap;
17128    x509->dynamic = dynamic;
17129}
17130
17131/* Free a WOLFSSL_X509_ACERT struct and its sub-fields.
17132 *
17133 * If this ACERT was initialized with dynamic == 1, then
17134 * the x509 pointer itself will be freed as well.
17135 *
17136 * @param [in]      x509        x509 acert pointer
17137 *
17138 * @return  void
17139 * */
17140void wolfSSL_X509_ACERT_free(WOLFSSL_X509_ACERT * x509)
17141{
17142    int    dynamic = 0;
17143    void * heap = NULL;
17144
17145    WOLFSSL_ENTER("wolfSSL_X509_ACERT_free");
17146
17147    if (x509 == NULL) {
17148        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_free: null parameter");
17149        return;
17150    }
17151
17152    dynamic = x509->dynamic;
17153    heap = x509->heap;
17154
17155    /* Free holder and att cert issuer structures. */
17156    if (x509->holderIssuerName) {
17157        FreeAltNames(x509->holderIssuerName, heap);
17158        x509->holderIssuerName = NULL;
17159    }
17160
17161    if (x509->holderEntityName) {
17162        FreeAltNames(x509->holderEntityName, heap);
17163        x509->holderEntityName = NULL;
17164    }
17165
17166    if (x509->AttCertIssuerName) {
17167        FreeAltNames(x509->AttCertIssuerName, heap);
17168        x509->AttCertIssuerName = NULL;
17169    }
17170
17171    if (x509->rawAttr != NULL) {
17172        XFREE(x509->rawAttr, heap, DYNAMIC_TYPE_X509_EXT);
17173        x509->rawAttr = NULL;
17174        x509->rawAttrLen = 0;
17175    }
17176
17177    /* Free derCert source and signature buffer. */
17178    FreeDer(&x509->derCert);
17179
17180    if (x509->sig.buffer != NULL) {
17181        XFREE(x509->sig.buffer, heap, DYNAMIC_TYPE_SIGNATURE);
17182        x509->sig.buffer = NULL;
17183    }
17184
17185    /* Finally memset and free x509 acert structure. */
17186    XMEMSET(x509, 0, sizeof(*x509));
17187
17188    if (dynamic == 1) {
17189        XFREE(x509, heap, DYNAMIC_TYPE_X509_ACERT);
17190    }
17191
17192    return;
17193}
17194
17195#if defined(OPENSSL_EXTRA)
17196long wolfSSL_X509_ACERT_get_version(const WOLFSSL_X509_ACERT* x509)
17197{
17198    int version = 0;
17199
17200    if (x509 == NULL) {
17201        return 0L;
17202    }
17203
17204    version = x509->version;
17205
17206    return version != 0 ? (long)version - 1L : 0L;
17207}
17208#endif /* OPENSSL_EXTRA */
17209
17210int wolfSSL_X509_ACERT_version(WOLFSSL_X509_ACERT* x509)
17211{
17212    if (x509 == NULL) {
17213        return 0;
17214    }
17215
17216    return x509->version;
17217}
17218
17219/* Retrieve the serial number from an ACERT.
17220 *
17221 * @param [in]       x509    the x509 attribute certificate
17222 * @param [in, out]  buf     the serial number buffer pointer
17223 * @param [in, out]  bufSz   the serial number buffer size pointer
17224 *
17225 * buf may be null, but bufSz is required. On success, sets
17226 * bufSz pointer to signature length, and copies signature
17227 * to buf if provided.
17228 *
17229 * Returns  WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
17230 * Returns  WOLFSSL_SUCCESS on success.
17231 */
17232int wolfSSL_X509_ACERT_get_serial_number(WOLFSSL_X509_ACERT* x509,
17233                                         byte* buf, int* bufSz)
17234{
17235    WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_serial_number");
17236
17237    if (x509 == NULL || bufSz == NULL) {
17238        WOLFSSL_MSG("error: null argument passed in");
17239        return BAD_FUNC_ARG;
17240    }
17241
17242    if (buf != NULL) {
17243        if (*bufSz < x509->serialSz) {
17244            WOLFSSL_MSG("error: serial buffer too small");
17245            return BUFFER_E;
17246        }
17247
17248        XMEMCPY(buf, x509->serial, x509->serialSz);
17249    }
17250
17251    *bufSz = x509->serialSz;
17252
17253    return WOLFSSL_SUCCESS;
17254}
17255
17256/* Sets buf pointer and len to raw Attribute buffer and buffer len
17257 * in X509 struct.
17258 *
17259 * Returns WOLFSSL_SUCCESS on success.
17260 * Returns BAD_FUNC_ARG if input pointers are null.
17261 * */
17262int wolfSSL_X509_ACERT_get_attr_buf(const WOLFSSL_X509_ACERT* x509,
17263                                                const byte ** rawAttr,
17264                                                word32 * rawAttrLen)
17265{
17266    if (x509 == NULL || rawAttr == NULL || rawAttrLen == NULL) {
17267        return BAD_FUNC_ARG;
17268    }
17269
17270    *rawAttr = x509->rawAttr;
17271    *rawAttrLen = x509->rawAttrLen;
17272
17273    return WOLFSSL_SUCCESS;
17274}
17275
17276#ifndef NO_WOLFSSL_STUB
17277int wolfSSL_X509_ACERT_sign(WOLFSSL_X509_ACERT * x509,
17278                                        WOLFSSL_EVP_PKEY * pkey,
17279                                        const WOLFSSL_EVP_MD * md)
17280{
17281    WOLFSSL_STUB("X509_ACERT_sign");
17282    (void) x509;
17283    (void) pkey;
17284    (void) md;
17285    return WOLFSSL_NOT_IMPLEMENTED;
17286}
17287#endif /* NO_WOLFSSL_STUB */
17288
17289/* Helper function for ACERT_verify.
17290 *
17291 * @param [in]       x509    the x509 attribute certificate
17292 * @param [in, out]  outSz   the x509 der length
17293 *
17294 * @return  der buffer on success
17295 * @return  NULL on error
17296 * */
17297static const byte* acert_get_der(WOLFSSL_X509_ACERT * x509, int* outSz)
17298{
17299    if (x509 == NULL || x509->derCert == NULL || outSz == NULL) {
17300        return NULL;
17301    }
17302
17303    *outSz = (int)x509->derCert->length;
17304    return x509->derCert->buffer;
17305}
17306
17307/* Given an X509_ACERT and EVP_PKEY, verify the acert's signature.
17308 *
17309 * @param [in]    x509    the x509 attribute certificate
17310 * @param [in]    pkey    the evp_pkey
17311 *
17312 * @return  WOLFSSL_SUCCESS on verify success
17313 * @return  < 0 on error
17314 * */
17315int wolfSSL_X509_ACERT_verify(WOLFSSL_X509_ACERT* x509, WOLFSSL_EVP_PKEY* pkey)
17316{
17317    int          ret = 0;
17318    const byte * der = NULL;
17319    int          derSz = 0;
17320    int          pkey_type;
17321
17322    if (x509 == NULL || pkey == NULL) {
17323        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: bad arg");
17324        return WOLFSSL_FATAL_ERROR;
17325    }
17326
17327    WOLFSSL_ENTER("wolfSSL_X509_ACERT_verify");
17328
17329    der = acert_get_der(x509, &derSz);
17330
17331    if (der == NULL || derSz <= 0) {
17332        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: get der failed");
17333        return WOLFSSL_FATAL_ERROR;
17334    }
17335
17336    switch (pkey->type) {
17337    case WC_EVP_PKEY_RSA:
17338        pkey_type = RSAk;
17339        break;
17340
17341    case WC_EVP_PKEY_EC:
17342        pkey_type = ECDSAk;
17343        break;
17344
17345    case WC_EVP_PKEY_DSA:
17346        pkey_type = DSAk;
17347        break;
17348
17349    default:
17350        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: unknown pkey type");
17351        return WOLFSSL_FATAL_ERROR;
17352    }
17353
17354
17355    ret = VerifyX509Acert(der, (word32)derSz,
17356                          (const byte *)pkey->pkey.ptr, pkey->pkey_sz,
17357                          pkey_type, x509->heap);
17358
17359    return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
17360}
17361
17362/* Loads an x509 attribute certificate from buffer, and returns
17363 * pointer to new WOLFSSL_X509_ACERT struct on success.
17364 *
17365 * @param [in]  buf    The acert buffer to load.
17366 * @param [in]  sz     The size of the buffer.
17367 * @param [in]  format The format of the buffer data.
17368 * @param [in]  heap   Dynamic memory allocation hint.
17369 *
17370 * @return  pointer to WOLFSSL_X509_ACERT on success.
17371 * @return  NULL on error.
17372 * */
17373WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer_ex(
17374    const unsigned char* buf, int sz, int format, void * heap)
17375{
17376    int                  ret = 0;
17377    WOLFSSL_X509_ACERT * x509 = NULL;
17378    DerBuffer *          der = NULL;
17379    WC_DECLARE_VAR(acert, DecodedAcert, 1, 0);
17380
17381    WOLFSSL_ENTER("wolfSSL_X509_ACERT_load_certificate_buffer");
17382
17383    if (format == WOLFSSL_FILETYPE_PEM) {
17384    #ifdef WOLFSSL_PEM_TO_DER
17385        ret = PemToDer(buf, sz, ACERT_TYPE, &der, heap, NULL, NULL);
17386
17387        if (ret != 0 || der == NULL || der->buffer == NULL) {
17388            WOLFSSL_ERROR(ret);
17389
17390            if (der != NULL) {
17391                FreeDer(&der);
17392            }
17393
17394            return NULL;
17395        }
17396    #else
17397        WOLFSSL_ERROR(NOT_COMPILED_IN);
17398        return NULL;
17399    #endif
17400    }
17401    else {
17402        ret = AllocDer(&der, (word32)sz, ACERT_TYPE, heap);
17403
17404        if (ret != 0 || der == NULL || der->buffer == NULL) {
17405            WOLFSSL_ERROR(ret);
17406            return NULL;
17407        }
17408
17409        XMEMCPY(der->buffer, buf, sz);
17410    }
17411
17412    #ifdef WOLFSSL_SMALL_STACK
17413    acert = (DecodedAcert*)XMALLOC(sizeof(DecodedAcert), heap,
17414                                   DYNAMIC_TYPE_DCERT);
17415    if (acert == NULL) {
17416        WOLFSSL_ERROR(MEMORY_ERROR);
17417        FreeDer(&der);
17418        return NULL;
17419    }
17420    #endif
17421
17422    InitDecodedAcert(acert, der->buffer, der->length, heap);
17423
17424    ret = ParseX509Acert(acert, VERIFY_SKIP_DATE);
17425
17426    if (ret == 0) {
17427        x509 = wolfSSL_X509_ACERT_new_ex(heap);
17428
17429        if (x509 != NULL) {
17430            ret = CopyDecodedAcertToX509(x509, acert);
17431
17432            if (ret != 0) {
17433                wolfSSL_X509_ACERT_free(x509);
17434                x509 = NULL;
17435            }
17436        }
17437        else {
17438            ret = MEMORY_ERROR;
17439        }
17440    }
17441
17442    FreeDecodedAcert(acert);
17443
17444    WC_FREE_VAR_EX(acert, heap, DYNAMIC_TYPE_DCERT);
17445
17446    FreeDer(&der);
17447
17448    if (ret != 0) {
17449        WOLFSSL_ERROR(ret);
17450    }
17451
17452    return x509;
17453}
17454
17455WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer(
17456    const unsigned char* buf, int sz, int format)
17457{
17458    return wolfSSL_X509_ACERT_load_certificate_buffer_ex(buf, sz, format, NULL);
17459}
17460
17461/* Retrieve the signature from an ACERT.
17462 *
17463 * @param [in]       x509    the x509 attribute certificate
17464 * @param [in, out]  buf     the signature buffer pointer
17465 * @param [in, out]  bufSz   the signature buffer size pointer
17466 *
17467 * buf may be null, but bufSz is required. On success, sets
17468 * bufSz pointer to signature length, and copies signature
17469 * to buf if provided.
17470 *
17471 * Returns  WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
17472 * Returns  WOLFSSL_SUCCESS on success.
17473 */
17474int wolfSSL_X509_ACERT_get_signature(WOLFSSL_X509_ACERT* x509,
17475                                     unsigned char* buf, int* bufSz)
17476{
17477    WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_signature");
17478
17479    if (x509 == NULL || bufSz == NULL) {
17480        return WOLFSSL_FATAL_ERROR;
17481    }
17482
17483    /* If buf array is provided, it must be long enough. */
17484    if (buf != NULL && *bufSz < (int)x509->sig.length) {
17485        return WOLFSSL_FATAL_ERROR;
17486    }
17487
17488    if (buf != NULL) {
17489        /* Copy in buffer if provided. */
17490        XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
17491    }
17492
17493    *bufSz = (int)x509->sig.length;
17494
17495    return WOLFSSL_SUCCESS;
17496}
17497#endif /* WOLFSSL_ACERT && (OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA) */
17498
17499#endif /* !NO_CERTS */
17500
17501#endif /* !WOLFCRYPT_ONLY */
17502
17503#endif /* WOLFSSL_X509_INCLUDED */