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