diff --git a/Makefile.am.bak b/Makefile.am.bak new file mode 100644 index 000000000..664704289 --- /dev/null +++ b/Makefile.am.bak @@ -0,0 +1,694 @@ +noinst_LIBRARIES = libbibledit.a + +libbibledit_a_SOURCES = \ + library/bibledit.cpp \ + library/locks.c \ + webserver/webserver.cpp \ + webserver/http.cpp \ + webserver/request.cpp \ + bootstrap/bootstrap.cpp \ + filter/url.cpp \ + filter/string.cpp \ + filter/roles.cpp \ + filter/md5.cpp \ + filter/usfm.cpp \ + filter/archive.cpp \ + filter/text.cpp \ + filter/passage.cpp \ + filter/css.cpp \ + filter/git.cpp \ + filter/html.cpp \ + filter/diff.cpp \ + filter/shell.cpp \ + filter/merge.cpp \ + filter/date.cpp \ + filter/memory.cpp \ + filter/webview.cpp \ + filter/mail.cpp \ + filter/note.cpp \ + flate/flate.cpp \ + assets/view.cpp \ + assets/page.cpp \ + assets/header.cpp \ + assets/external.cpp \ + index/index.cpp \ + index/listing.cpp \ + config/globals.cpp \ + menu/logic.cpp \ + menu/index.cpp \ + locale/translate.cpp \ + locale/logic.cpp \ + database/config/general.cpp \ + database/config/bible.cpp \ + database/config/user.cpp \ + database/users.cpp \ + database/logs.cpp \ + database/sqlite.cpp \ + database/styles.cpp \ + database/bibles.cpp \ + database/books.cpp \ + database/bibleactions.cpp \ + database/check.cpp \ + database/localization.cpp \ + database/confirm.cpp \ + database/ipc.cpp \ + database/jobs.cpp \ + database/kjv.cpp \ + database/logic.cpp \ + database/oshb.cpp \ + database/sblgnt.cpp \ + database/sprint.cpp \ + database/mail.cpp \ + database/navigation.cpp \ + database/usfmresources.cpp \ + database/mappings.cpp \ + database/noteactions.cpp \ + database/versifications.cpp \ + database/modifications.cpp \ + database/notes.cpp \ + database/volatile.cpp \ + database/maintenance.cpp \ + database/imageresources.cpp \ + database/state.cpp \ + database/noteassignment.cpp \ + database/strong.cpp \ + database/morphgnt.cpp \ + database/etcbc4.cpp \ + database/hebrewlexicon.cpp \ + database/cache.cpp \ + database/login.cpp \ + database/privileges.cpp \ + database/git.cpp \ + database/userresources.cpp \ + database/statistics.cpp \ + database/sample.cpp \ + session/logic.cpp \ + session/login.cpp \ + session/logout.cpp \ + session/password.cpp \ + session/signup.cpp \ + session/switch.cpp \ + parsewebdata/ParseMultipartFormData.cpp \ + parsewebdata/ParseWebData.cpp \ + setup/index.cpp \ + setup/logic.cpp \ + journal/index.cpp \ + journal/logic.cpp \ + styles/logic.cpp \ + styles/indexm.cpp \ + styles/sheetm.cpp \ + styles/view.cpp \ + styles/css.cpp \ + styles/sheets.cpp \ + text/text.cpp \ + esword/text.cpp \ + olb/text.cpp \ + html/text.cpp \ + html/header.cpp \ + odf/text.cpp \ + timer/index.cpp \ + tasks/logic.cpp \ + tasks/run.cpp \ + config/logic.cpp \ + bb/logic.cpp \ + bb/manage.cpp \ + bb/settings.cpp \ + bb/book.cpp \ + bb/chapter.cpp \ + bb/import_run.cpp \ + bb/import.cpp \ + bb/order.cpp \ + bb/css.cpp \ + notes/logic.cpp \ + notes/actions.cpp \ + notes/note.cpp \ + notes/status-1.cpp \ + notes/assign-1.cpp \ + notes/notes.cpp \ + notes/status-n.cpp \ + notes/assign-n.cpp \ + notes/click.cpp \ + notes/poll.cpp \ + notes/summary.cpp \ + notes/bb-1.cpp \ + notes/comment.cpp \ + notes/select.cpp \ + notes/unassign-n.cpp \ + notes/bb-n.cpp \ + notes/create.cpp \ + notes/severity-1.cpp \ + notes/verses.cpp \ + notes/bulk.cpp \ + notes/edit.cpp \ + notes/index.cpp \ + notes/severity-n.cpp \ + trash/handler.cpp \ + help/index.cpp \ + confirm/worker.cpp \ + email/index.cpp \ + email/send.cpp \ + email/receive.cpp \ + user/notifications.cpp \ + user/account.cpp \ + user/logic.cpp \ + manage/index.cpp \ + manage/users.cpp \ + manage/accounts.cpp \ + manage/exports.cpp \ + manage/hyphenation.cpp \ + manage/hyphenate.cpp \ + manage/write.cpp \ + manage/privileges.cpp \ + system/index.cpp \ + system/logic.cpp \ + collaboration/index.cpp \ + collaboration/link.cpp \ + collaboration/settings.cpp \ + search/rebibles.cpp \ + search/renotes.cpp \ + access/user.cpp \ + access/bible.cpp \ + access/logic.cpp \ + dialog/entry.cpp \ + dialog/list.cpp \ + dialog/list2.cpp \ + dialog/yes.cpp \ + dialog/color.cpp \ + dialog/books.cpp \ + dialog/upload.cpp \ + fonts/logic.cpp \ + versification/index.cpp \ + versification/system.cpp \ + versification/logic.cpp \ + book/create.cpp \ + compare/index.cpp \ + compare/compare.cpp \ + jobs/index.cpp \ + redirect/index.cpp \ + editone2/index.cpp \ + editone2/load.cpp \ + editone2/save.cpp \ + editone2/verse.cpp \ + editone2/logic.cpp \ + editone2/update.cpp \ + navigation/passage.cpp \ + navigation/update.cpp \ + navigation/poll.cpp \ + navigation/paratext.cpp \ + ipc/focus.cpp \ + ipc/notes.cpp \ + checksum/logic.cpp \ + editusfm/focus.cpp \ + editusfm/index.cpp \ + editusfm/load.cpp \ + editusfm/offset.cpp \ + editusfm/save.cpp \ + editor/styles.cpp \ + editor/html2usfm.cpp \ + editor/usfm2html.cpp \ + editor/select.cpp \ + editor/html2format.cpp \ + editor/id.cpp \ + editor/style.cpp \ + edit/edit.cpp \ + edit/id.cpp \ + edit/index.cpp \ + edit/load.cpp \ + edit/save.cpp \ + edit/styles.cpp \ + edit/logic.cpp \ + edit/preview.cpp \ + edit/position.cpp \ + edit/navigate.cpp \ + edit/update.cpp \ + search/all.cpp \ + search/index.cpp \ + search/replace.cpp \ + search/getids.cpp \ + search/replacepre.cpp \ + search/replacego.cpp \ + search/search2.cpp \ + search/replace2.cpp \ + search/replacepre2.cpp \ + search/getids2.cpp \ + search/replacego2.cpp \ + search/similar.cpp \ + search/strongs.cpp \ + search/strong.cpp \ + search/originals.cpp \ + tmp/tmp.cpp \ + workspace/index.cpp \ + workspace/logic.cpp \ + workspace/settings.cpp \ + workspace/organize.cpp \ + sendreceive/logic.cpp \ + sendreceive/index.cpp \ + sendreceive/sendreceive.cpp \ + sendreceive/settings.cpp \ + sendreceive/bibles.cpp \ + sendreceive/notes.cpp \ + sendreceive/changes.cpp \ + sendreceive/files.cpp \ + sendreceive/resources.cpp \ + demo/logic.cpp \ + client/index.cpp \ + client/logic.cpp \ + sync/logic.cpp \ + sync/setup.cpp \ + sync/settings.cpp \ + sync/bibles.cpp \ + sync/usfmresources.cpp \ + sync/notes.cpp \ + sync/changes.cpp \ + sync/files.cpp \ + sync/resources.cpp \ + sync/mail.cpp \ + resource/index.cpp \ + resource/organize.cpp \ + resource/logic.cpp \ + resource/get.cpp \ + resource/external.cpp \ + resource/bb2resource.cpp \ + resource/convert2resource.cpp \ + resource/convert2bible.cpp \ + resource/manage.cpp \ + resource/print.cpp \ + resource/download.cpp \ + resource/images.cpp \ + resource/image.cpp \ + resource/img.cpp \ + resource/imagefetch.cpp \ + resource/sword.cpp \ + resource/select.cpp \ + resource/cache.cpp \ + resource/user9edit.cpp \ + resource/user1edit.cpp \ + resource/user9view.cpp \ + resource/user1view.cpp \ + resource/bbgateway.cpp \ + resource/studylight.cpp \ + resource/unload.cpp \ + jsonxx/jsonxx.cpp \ + mapping/index.cpp \ + mapping/map.cpp \ + statistics/statistics.cpp \ + changes/change.cpp \ + changes/changes.cpp \ + changes/logic.cpp \ + changes/manage.cpp \ + changes/modifications.cpp \ + changes/statistics.cpp \ + sprint/burndown.cpp \ + sprint/index.cpp \ + checks/run.cpp \ + checks/headers.cpp \ + checks/index.cpp \ + checks/logic.cpp \ + checks/sentences.cpp \ + checks/settings.cpp \ + checks/settingspatterns.cpp \ + checks/settingssentences.cpp \ + checks/space.cpp \ + checks/suppress.cpp \ + checks/usfm.cpp \ + checks/verses.cpp \ + checks/versification.cpp \ + checks/pairs.cpp \ + checks/settingspairs.cpp \ + checks/french.cpp \ + consistency/index.cpp \ + consistency/input.cpp \ + consistency/logic.cpp \ + consistency/poll.cpp \ + export/esword.cpp \ + export/html.cpp \ + export/index.cpp \ + export/info.cpp \ + export/logic.cpp \ + export/odt.cpp \ + export/onlinebible.cpp \ + export/textusfm.cpp \ + export/usfm.cpp \ + export/web.cpp \ + export/bibledropbox.cpp \ + webbb/search.cpp \ + developer/index.cpp \ + developer/logic.cpp \ + paratext/logic.cpp \ + paratext/index.cpp \ + personalize/index.cpp \ + lexicon/logic.cpp \ + lexicon/definition.cpp \ + sources/etcbc4.cpp \ + sources/kjv.cpp \ + sources/morphhb.cpp \ + sources/morphgnt.cpp \ + sources/hebrewlexicon.cpp \ + sources/oshb.cpp \ + sword/logic.cpp \ + pugixml/pugixml.cpp \ + pugixml/utils.cpp \ + public/index.cpp \ + public/logic.cpp \ + public/login.cpp \ + public/chapter.cpp \ + public/notes.cpp \ + public/new.cpp \ + public/create.cpp \ + public/note.cpp \ + public/comment.cpp \ + utf8proc/utf8proc.c \ + search/logic.cpp \ + mbedtls/aes.c \ + mbedtls/arc4.c \ + mbedtls/asn1parse.c \ + mbedtls/asn1write.c \ + mbedtls/base64.c \ + mbedtls/bignum.c \ + mbedtls/blowfish.c \ + mbedtls/camellia.c \ + mbedtls/ccm.c \ + mbedtls/certs.c \ + mbedtls/chacha20.c \ + mbedtls/chachapoly.c \ + mbedtls/cipher.c \ + mbedtls/cipher_wrap.c \ + mbedtls/ctr_drbg.c \ + mbedtls/debug.c \ + mbedtls/des.c \ + mbedtls/dhm.c \ + mbedtls/ecdh.c \ + mbedtls/ecdsa.c \ + mbedtls/ecp.c \ + mbedtls/ecp_curves.c \ + mbedtls/entropy.c \ + mbedtls/entropy_poll.c \ + mbedtls/error.c \ + mbedtls/gcm.c \ + mbedtls/hmac_drbg.c \ + mbedtls/md.c \ + mbedtls/md5.c \ + mbedtls/md_wrap.c \ + mbedtls/net_sockets.c \ + mbedtls/oid.c \ + mbedtls/pem.c \ + mbedtls/pk.c \ + mbedtls/pk_wrap.c \ + mbedtls/pkcs12.c \ + mbedtls/pkcs5.c \ + mbedtls/pkparse.c \ + mbedtls/pkwrite.c \ + mbedtls/platform_util.c \ + mbedtls/platform.c \ + mbedtls/poly1305.c \ + mbedtls/ripemd160.c \ + mbedtls/rsa.c \ + mbedtls/rsa_internal.c \ + mbedtls/sha1.c \ + mbedtls/sha256.c \ + mbedtls/sha512.c \ + mbedtls/ssl_cache.c \ + mbedtls/ssl_ciphersuites.c \ + mbedtls/ssl_cli.c \ + mbedtls/ssl_cookie.c \ + mbedtls/ssl_srv.c \ + mbedtls/ssl_ticket.c \ + mbedtls/ssl_tls.c \ + mbedtls/threading.c \ + mbedtls/timing.c \ + mbedtls/version.c \ + mbedtls/version_features.c \ + mbedtls/x509.c \ + mbedtls/x509_create.c \ + mbedtls/x509_crl.c \ + mbedtls/x509_crt.c \ + mbedtls/x509_csr.c \ + mbedtls/x509write_crt.c \ + mbedtls/x509write_csr.c \ + mbedtls/xtea.c \ + related/logic.cpp \ + sqlite/sqlite3.c \ + ldap/logic.cpp \ + quill/logic.cpp \ + rss/logic.cpp \ + rss/feed.cpp \ + microtar/microtar.c \ + miniz/miniz.c \ + nmt/index.cpp \ + nmt/logic.cpp \ + tbsx/text.cpp \ + read/index.cpp \ + read/load.cpp \ + read/verse.cpp \ + resource/divider.cpp \ + session/confirm.cpp \ + sources/abbott-smith.cpp \ + database/abbottsmith.cpp \ + resource/comparative9edit.cpp \ + resource/comparative1edit.cpp \ + resource/translated9edit.cpp \ + resource/translated1edit.cpp \ + developer/delay.cpp \ + images/index.cpp \ + images/view.cpp \ + images/fetch.cpp \ + images/logic.cpp \ + database/bibleimages.cpp \ + filter/image.cpp \ + mimetic098/header.cxx \ + mimetic098/contentid.cxx \ + mimetic098/contenttransferencoding.cxx \ + mimetic098/contentdisposition.cxx \ + mimetic098/contentdescription.cxx \ + mimetic098/mimeversion.cxx \ + mimetic098/contenttype.cxx \ + mimetic098/version.cxx \ + mimetic098/fieldparam.cxx \ + mimetic098/mimeentity.cxx \ + mimetic098/strutils.cxx \ + mimetic098/body.cxx \ + mimetic098/utils.cxx \ + mimetic098/rfc822/field.cxx \ + mimetic098/rfc822/header.cxx \ + mimetic098/rfc822/message.cxx \ + mimetic098/rfc822/addresslist.cxx \ + mimetic098/rfc822/fieldvalue.cxx \ + mimetic098/rfc822/mailbox.cxx \ + mimetic098/rfc822/messageid.cxx \ + mimetic098/rfc822/datetime.cxx \ + mimetic098/rfc822/group.cxx \ + mimetic098/rfc822/mailboxlist.cxx \ + mimetic098/rfc822/address.cxx \ + mimetic098/os/utils.cxx \ + mimetic098/os/file_iterator.cxx \ + mimetic098/os/mmfile.cxx \ + mimetic098/codec/base64.cxx \ + system/googletranslate.cpp \ + filter/google.cpp \ + i18n/logic.cpp \ + tidy/access.c \ + tidy/alloc.c \ + tidy/attrdict.c \ + tidy/attrs.c \ + tidy/buffio.c \ + tidy/charsets.c \ + tidy/clean.c \ + tidy/config.c \ + tidy/entities.c \ + tidy/fileio.c \ + tidy/gdoc.c \ + tidy/istack.c \ + tidy/language.c \ + tidy/lexer.c \ + tidy/mappedio.c \ + tidy/message.c \ + tidy/messageobj.c \ + tidy/parser.c \ + tidy/pprint.c \ + tidy/sprtf.c \ + tidy/streamio.c \ + tidy/tagask.c \ + tidy/tags.c \ + tidy/tidylib.c \ + tidy/tmbstr.c \ + tidy/utf8.c + +bin_PROGRAMS = server generate + +server_SOURCES = executable/bibledit.cpp + +server_LDADD = libbibledit.a + +unittest_SOURCES = \ + unittests/unittest.cpp \ + unittests/utilities.cpp \ + unittests/sqlite.cpp \ + unittests/session.cpp \ + unittests/folders.cpp \ + unittests/flate.cpp \ + unittests/checksum.cpp \ + unittests/bibles.cpp \ + unittests/html2usfm.cpp \ + unittests/usfm2html.cpp \ + unittests/usfm2html2usfm.cpp \ + unittests/workspaces.cpp \ + unittests/client.cpp \ + unittests/sentences.cpp \ + unittests/versification.cpp \ + unittests/usfm.cpp \ + unittests/verses.cpp \ + unittests/pairs.cpp \ + unittests/paratext.cpp \ + unittests/hyphenate.cpp \ + unittests/search.cpp \ + unittests/json.cpp \ + unittests/related.cpp \ + unittests/editone.cpp \ + unittests/http.cpp \ + unittests/memory.cpp \ + unittests/tasks.cpp \ + unittests/biblegateway.cpp \ + unittests/rss.cpp \ + unittests/space.cpp \ + unittests/roles.cpp \ + unittests/md5.cpp \ + unittests/string.cpp \ + unittests/users.cpp \ + unittests/date.cpp \ + unittests/export.cpp \ + unittests/html.cpp \ + unittests/archive.cpp \ + unittests/odf.cpp \ + unittests/text.cpp \ + unittests/url.cpp \ + unittests/passage.cpp \ + unittests/styles.cpp \ + unittests/diff.cpp \ + unittests/git.cpp \ + unittests/ipc.cpp \ + unittests/shell.cpp \ + unittests/ldap.cpp \ + unittests/dev.cpp \ + unittests/sample.cpp \ + unittests/config.cpp \ + unittests/log.cpp \ + unittests/books.cpp \ + unittests/check.cpp \ + unittests/localization.cpp \ + unittests/confirm.cpp \ + unittests/jobs.cpp \ + unittests/kjv.cpp \ + unittests/oshb.cpp \ + unittests/sblgnt.cpp \ + unittests/sprint.cpp \ + unittests/mail.cpp \ + unittests/navigation.cpp \ + unittests/resources.cpp \ + unittests/notes.cpp \ + unittests/modifications.cpp \ + unittests/volatile.cpp \ + unittests/state.cpp \ + unittests/strong.cpp \ + unittests/morphgnt.cpp \ + unittests/etcbc4.cpp \ + unittests/lexicon.cpp \ + unittests/cache.cpp \ + unittests/login.cpp \ + unittests/privileges.cpp \ + unittests/statistics.cpp \ + unittests/webview.cpp \ + unittests/javascript.cpp \ + unittests/french.cpp \ + unittests/merge.cpp \ + unittests/nmt.cpp \ + unittests/html2format.cpp \ + unittests/studylight.cpp \ + unittests/gbs.cpp \ + unittests/bibleimages.cpp \ + unittests/image.cpp \ + unittests/easyenglishbible.cpp + +unittest_LDADD = libbibledit.a + +generate_SOURCES = \ + executable/generate.cpp \ + sources/styles.cpp + +generate_LDADD = libbibledit.a + +AM_CFLAGS = -g +AM_CFLAGS += $(OPENSSL_CFLAGS) + +AM_CXXFLAGS = -fno-var-tracking -g +if COMPILERWARNINGS +AM_CFLAGS += -Wall -Wno-unknown-pragmas -Wextra -pedantic -Wno-pragmas +AM_CXXFLAGS += -Wall -Wno-unknown-pragmas -Wextra -pedantic -Wshadow -Warray-bounds -Wcast-align -Wcast-qual -Wconversion -Wctor-dtor-privacy -Wdelete-non-virtual-dtor -Weffc++ -Wextra-semi -Wfloat-equal -Wformat=2 -Wmissing-include-dirs -Wmissing-noreturn -Wnull-dereference -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wsign-promo -Wsuggest-override -Wswitch-default -Wswitch-enum -Wundef -Wuninitialized -Wunused-but-set-parameter -Wunused-macros -Wunused-parameter -Wvla -Wzero-as-null-pointer-constant -Wmismatched-tags +if COMPILERGCC +AM_CXXFLAGS += -Wcatch-value=2 -Wconditionally-supported -Wduplicated-branches -Wduplicated-cond -Wformat-overflow=2 -Wlogical-op -Wnoexcept -Wno-non-template-friend -Wrestrict -Wstrict-null-sentinel -Wuseless-cast -Wcomma-subscript -Wredundant-tags -Wvolatile +endif +endif +if COMPILERCLANG +endif +AM_CXXFLAGS += $(CURL_CFLAGS) +AM_CXXFLAGS += $(OPENSSL_CFLAGS) +AM_CXXFLAGS += $(GTK_CFLAGS) +AM_CXXFLAGS += $(WEBKIT2GTK_CFLAGS) +AM_CXXFLAGS += $(ICU_CFLAGS) +AM_CXXFLAGS += $(XML2_CFLAGS) +# AM_CXXFLAGS += $(TIDY_CFLAGS) -I/usr/include/tidy +AM_CXXFLAGS += $(GTEST_CFLAGS) + +if MACFLAGS +# Building Bibledit for macOS for two architectures +# due to the switch from macOS from the x86_64 to the arm64 architecture. +# Additionally it uses the includes and libraries from the macOS SDK. +# Generate the macOS SDK path: $ xcrun --show-sdk-path +AM_CXXFLAGS += -mmacosx-version-min=10.10 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -arch x86_64 -arch arm64 +AM_CFLAGS += -mmacosx-version-min=10.10 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -arch x86_64 -arch arm64 +endif + +LIBS = -Wall -lpthread -L. -g -rdynamic -ldl +LIBS += $(CURL_LIBS) +LIBS += $(OPENSSL_LIBS) +LIBS += $(GTK_LIBS) +LIBS += $(WEBKIT2GTK_LIBS) +LIBS += $(ICU_LIBS) +LIBS += $(XML2_LIBS) +# LIBS += $(TIDY_LIBS) +LIBS += $(GTEST_LIBS) + +# The core library compiles and embeds the mbedtls library. +# On Debian this gives a lintian error: +# E: bibledit: embedded-library usr/bin/bibledit: mbedtls +# Solve this on Debian by omitting that library from the core, +# and by linking to the mbed TLS library provided by the system. +# For other platforms, the library remains in the core. +# debian LIBS += -lmbedtls -lmbedcrypto -lmbedx509 + +EXTRA_DIST = a* bb bibledit bibles book bootstrap c* d* D* e* f* g* h* i* j* l* m* n* o* p* q* r* s* t* u* v* w* + +dist-hook: + rm -rf `find $(distdir) -name *.o` + rm -rf `find $(distdir) -name *.a` + rm -rf `find $(distdir) -name autom4te.cache` + rm -f $(distdir)/server + rm -f $(distdir)/unittest + rm -rf `find $(distdir) -name .dirstamp` + rm -rf `find $(distdir) -name .deps` + rm -rf `find $(distdir) -name *~` + rm -f $(distdir)/config.h + rm -f $(distdir)/config.log + rm -f $(distdir)/config.status + +CLEANFILES = bibledit*.gz *~ + +all-local: + pkgdata/create.sh + +install-data-hook: + $(srcdir)/pkgdata/install.sh $(srcdir) $(DESTDIR) $(pkgdatadir) + +uninstall-local: + rm -rf $(DESTDIR)$(pkgdatadir)/* + +man_MANS = man/bibledit.1 man/bibledit-cloud.1 diff --git a/Makefile.bak b/Makefile.bak new file mode 100644 index 000000000..509c417d6 --- /dev/null +++ b/Makefile.bak @@ -0,0 +1,5585 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + + +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/bibledit +pkgincludedir = $(includedir)/bibledit +pkglibdir = $(libdir)/bibledit +pkglibexecdir = $(libexecdir)/bibledit +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = x86_64-apple-darwin22.6.0 +bin_PROGRAMS = server$(EXEEXT) generate$(EXEEXT) +#am__append_1 = -Wall -Wno-unknown-pragmas -Wextra -pedantic -Wno-pragmas +#am__append_2 = -Wall -Wno-unknown-pragmas -Wextra -pedantic -Wshadow -Warray-bounds -Wcast-align -Wcast-qual -Wconversion -Wctor-dtor-privacy -Wdelete-non-virtual-dtor -Weffc++ -Wextra-semi -Wfloat-equal -Wformat=2 -Wmissing-include-dirs -Wmissing-noreturn -Wnull-dereference -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wsign-promo -Wsuggest-override -Wswitch-default -Wswitch-enum -Wundef -Wuninitialized -Wunused-but-set-parameter -Wunused-macros -Wunused-parameter -Wvla -Wzero-as-null-pointer-constant -Wmismatched-tags +##am__append_3 = -Wcatch-value=2 -Wconditionally-supported -Wduplicated-branches -Wduplicated-cond -Wformat-overflow=2 -Wlogical-op -Wnoexcept -Wno-non-template-friend -Wrestrict -Wstrict-null-sentinel -Wuseless-cast -Wcomma-subscript -Wredundant-tags -Wvolatile +# AM_CXXFLAGS += $(TIDY_CFLAGS) -I/usr/include/tidy + +# Building Bibledit for macOS for two architectures +# due to the switch from macOS from the x86_64 to the arm64 architecture. +# Additionally it uses the includes and libraries from the macOS SDK. +# Generate the macOS SDK path: $ xcrun --show-sdk-path +am__append_4 = -mmacosx-version-min=10.10 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -arch x86_64 -arch arm64 +am__append_5 = -mmacosx-version-min=10.10 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -arch x86_64 -arch arm64 +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +AM_V_AR = $(am__v_AR_$(V)) +am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY)) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libbibledit_a_AR = $(AR) $(ARFLAGS) +libbibledit_a_LIBADD = +am__dirstamp = $(am__leading_dot)dirstamp +am_libbibledit_a_OBJECTS = library/bibledit.$(OBJEXT) \ + library/locks.$(OBJEXT) webserver/webserver.$(OBJEXT) \ + webserver/http.$(OBJEXT) webserver/request.$(OBJEXT) \ + bootstrap/bootstrap.$(OBJEXT) filter/url.$(OBJEXT) \ + filter/string.$(OBJEXT) filter/roles.$(OBJEXT) \ + filter/md5.$(OBJEXT) filter/usfm.$(OBJEXT) \ + filter/archive.$(OBJEXT) filter/text.$(OBJEXT) \ + filter/passage.$(OBJEXT) filter/css.$(OBJEXT) \ + filter/git.$(OBJEXT) filter/html.$(OBJEXT) \ + filter/diff.$(OBJEXT) filter/shell.$(OBJEXT) \ + filter/merge.$(OBJEXT) filter/date.$(OBJEXT) \ + filter/memory.$(OBJEXT) filter/webview.$(OBJEXT) \ + filter/mail.$(OBJEXT) filter/note.$(OBJEXT) \ + flate/flate.$(OBJEXT) assets/view.$(OBJEXT) \ + assets/page.$(OBJEXT) assets/header.$(OBJEXT) \ + assets/external.$(OBJEXT) index/index.$(OBJEXT) \ + index/listing.$(OBJEXT) config/globals.$(OBJEXT) \ + menu/logic.$(OBJEXT) menu/index.$(OBJEXT) \ + locale/translate.$(OBJEXT) locale/logic.$(OBJEXT) \ + database/config/general.$(OBJEXT) \ + database/config/bible.$(OBJEXT) database/config/user.$(OBJEXT) \ + database/users.$(OBJEXT) database/logs.$(OBJEXT) \ + database/sqlite.$(OBJEXT) database/styles.$(OBJEXT) \ + database/bibles.$(OBJEXT) database/books.$(OBJEXT) \ + database/bibleactions.$(OBJEXT) database/check.$(OBJEXT) \ + database/localization.$(OBJEXT) database/confirm.$(OBJEXT) \ + database/ipc.$(OBJEXT) database/jobs.$(OBJEXT) \ + database/kjv.$(OBJEXT) database/logic.$(OBJEXT) \ + database/oshb.$(OBJEXT) database/sblgnt.$(OBJEXT) \ + database/sprint.$(OBJEXT) database/mail.$(OBJEXT) \ + database/navigation.$(OBJEXT) database/usfmresources.$(OBJEXT) \ + database/mappings.$(OBJEXT) database/noteactions.$(OBJEXT) \ + database/versifications.$(OBJEXT) \ + database/modifications.$(OBJEXT) database/notes.$(OBJEXT) \ + database/volatile.$(OBJEXT) database/maintenance.$(OBJEXT) \ + database/imageresources.$(OBJEXT) database/state.$(OBJEXT) \ + database/noteassignment.$(OBJEXT) database/strong.$(OBJEXT) \ + database/morphgnt.$(OBJEXT) database/etcbc4.$(OBJEXT) \ + database/hebrewlexicon.$(OBJEXT) database/cache.$(OBJEXT) \ + database/login.$(OBJEXT) database/privileges.$(OBJEXT) \ + database/git.$(OBJEXT) database/userresources.$(OBJEXT) \ + database/statistics.$(OBJEXT) database/sample.$(OBJEXT) \ + session/logic.$(OBJEXT) session/login.$(OBJEXT) \ + session/logout.$(OBJEXT) session/password.$(OBJEXT) \ + session/signup.$(OBJEXT) session/switch.$(OBJEXT) \ + parsewebdata/ParseMultipartFormData.$(OBJEXT) \ + parsewebdata/ParseWebData.$(OBJEXT) setup/index.$(OBJEXT) \ + setup/logic.$(OBJEXT) journal/index.$(OBJEXT) \ + journal/logic.$(OBJEXT) styles/logic.$(OBJEXT) \ + styles/indexm.$(OBJEXT) styles/sheetm.$(OBJEXT) \ + styles/view.$(OBJEXT) styles/css.$(OBJEXT) \ + styles/sheets.$(OBJEXT) text/text.$(OBJEXT) \ + esword/text.$(OBJEXT) olb/text.$(OBJEXT) html/text.$(OBJEXT) \ + html/header.$(OBJEXT) odf/text.$(OBJEXT) timer/index.$(OBJEXT) \ + tasks/logic.$(OBJEXT) tasks/run.$(OBJEXT) \ + config/logic.$(OBJEXT) bb/logic.$(OBJEXT) bb/manage.$(OBJEXT) \ + bb/settings.$(OBJEXT) bb/book.$(OBJEXT) bb/chapter.$(OBJEXT) \ + bb/import_run.$(OBJEXT) bb/import.$(OBJEXT) bb/order.$(OBJEXT) \ + bb/css.$(OBJEXT) notes/logic.$(OBJEXT) notes/actions.$(OBJEXT) \ + notes/note.$(OBJEXT) notes/status-1.$(OBJEXT) \ + notes/assign-1.$(OBJEXT) notes/notes.$(OBJEXT) \ + notes/status-n.$(OBJEXT) notes/assign-n.$(OBJEXT) \ + notes/click.$(OBJEXT) notes/poll.$(OBJEXT) \ + notes/summary.$(OBJEXT) notes/bb-1.$(OBJEXT) \ + notes/comment.$(OBJEXT) notes/select.$(OBJEXT) \ + notes/unassign-n.$(OBJEXT) notes/bb-n.$(OBJEXT) \ + notes/create.$(OBJEXT) notes/severity-1.$(OBJEXT) \ + notes/verses.$(OBJEXT) notes/bulk.$(OBJEXT) \ + notes/edit.$(OBJEXT) notes/index.$(OBJEXT) \ + notes/severity-n.$(OBJEXT) trash/handler.$(OBJEXT) \ + help/index.$(OBJEXT) confirm/worker.$(OBJEXT) \ + email/index.$(OBJEXT) email/send.$(OBJEXT) \ + email/receive.$(OBJEXT) user/notifications.$(OBJEXT) \ + user/account.$(OBJEXT) user/logic.$(OBJEXT) \ + manage/index.$(OBJEXT) manage/users.$(OBJEXT) \ + manage/accounts.$(OBJEXT) manage/exports.$(OBJEXT) \ + manage/hyphenation.$(OBJEXT) manage/hyphenate.$(OBJEXT) \ + manage/write.$(OBJEXT) manage/privileges.$(OBJEXT) \ + system/index.$(OBJEXT) system/logic.$(OBJEXT) \ + collaboration/index.$(OBJEXT) collaboration/link.$(OBJEXT) \ + collaboration/settings.$(OBJEXT) search/rebibles.$(OBJEXT) \ + search/renotes.$(OBJEXT) access/user.$(OBJEXT) \ + access/bible.$(OBJEXT) access/logic.$(OBJEXT) \ + dialog/entry.$(OBJEXT) dialog/list.$(OBJEXT) \ + dialog/list2.$(OBJEXT) dialog/yes.$(OBJEXT) \ + dialog/color.$(OBJEXT) dialog/books.$(OBJEXT) \ + dialog/upload.$(OBJEXT) fonts/logic.$(OBJEXT) \ + versification/index.$(OBJEXT) versification/system.$(OBJEXT) \ + versification/logic.$(OBJEXT) book/create.$(OBJEXT) \ + compare/index.$(OBJEXT) compare/compare.$(OBJEXT) \ + jobs/index.$(OBJEXT) redirect/index.$(OBJEXT) \ + editone2/index.$(OBJEXT) editone2/load.$(OBJEXT) \ + editone2/save.$(OBJEXT) editone2/verse.$(OBJEXT) \ + editone2/logic.$(OBJEXT) editone2/update.$(OBJEXT) \ + navigation/passage.$(OBJEXT) navigation/update.$(OBJEXT) \ + navigation/poll.$(OBJEXT) navigation/paratext.$(OBJEXT) \ + ipc/focus.$(OBJEXT) ipc/notes.$(OBJEXT) \ + checksum/logic.$(OBJEXT) editusfm/focus.$(OBJEXT) \ + editusfm/index.$(OBJEXT) editusfm/load.$(OBJEXT) \ + editusfm/offset.$(OBJEXT) editusfm/save.$(OBJEXT) \ + editor/styles.$(OBJEXT) editor/html2usfm.$(OBJEXT) \ + editor/usfm2html.$(OBJEXT) editor/select.$(OBJEXT) \ + editor/html2format.$(OBJEXT) editor/id.$(OBJEXT) \ + editor/style.$(OBJEXT) edit/edit.$(OBJEXT) edit/id.$(OBJEXT) \ + edit/index.$(OBJEXT) edit/load.$(OBJEXT) edit/save.$(OBJEXT) \ + edit/styles.$(OBJEXT) edit/logic.$(OBJEXT) \ + edit/preview.$(OBJEXT) edit/position.$(OBJEXT) \ + edit/navigate.$(OBJEXT) edit/update.$(OBJEXT) \ + search/all.$(OBJEXT) search/index.$(OBJEXT) \ + search/replace.$(OBJEXT) search/getids.$(OBJEXT) \ + search/replacepre.$(OBJEXT) search/replacego.$(OBJEXT) \ + search/search2.$(OBJEXT) search/replace2.$(OBJEXT) \ + search/replacepre2.$(OBJEXT) search/getids2.$(OBJEXT) \ + search/replacego2.$(OBJEXT) search/similar.$(OBJEXT) \ + search/strongs.$(OBJEXT) search/strong.$(OBJEXT) \ + search/originals.$(OBJEXT) tmp/tmp.$(OBJEXT) \ + workspace/index.$(OBJEXT) workspace/logic.$(OBJEXT) \ + workspace/settings.$(OBJEXT) workspace/organize.$(OBJEXT) \ + sendreceive/logic.$(OBJEXT) sendreceive/index.$(OBJEXT) \ + sendreceive/sendreceive.$(OBJEXT) \ + sendreceive/settings.$(OBJEXT) sendreceive/bibles.$(OBJEXT) \ + sendreceive/notes.$(OBJEXT) sendreceive/changes.$(OBJEXT) \ + sendreceive/files.$(OBJEXT) sendreceive/resources.$(OBJEXT) \ + demo/logic.$(OBJEXT) client/index.$(OBJEXT) \ + client/logic.$(OBJEXT) sync/logic.$(OBJEXT) \ + sync/setup.$(OBJEXT) sync/settings.$(OBJEXT) \ + sync/bibles.$(OBJEXT) sync/usfmresources.$(OBJEXT) \ + sync/notes.$(OBJEXT) sync/changes.$(OBJEXT) \ + sync/files.$(OBJEXT) sync/resources.$(OBJEXT) \ + sync/mail.$(OBJEXT) resource/index.$(OBJEXT) \ + resource/organize.$(OBJEXT) resource/logic.$(OBJEXT) \ + resource/get.$(OBJEXT) resource/external.$(OBJEXT) \ + resource/bb2resource.$(OBJEXT) \ + resource/convert2resource.$(OBJEXT) \ + resource/convert2bible.$(OBJEXT) resource/manage.$(OBJEXT) \ + resource/print.$(OBJEXT) resource/download.$(OBJEXT) \ + resource/images.$(OBJEXT) resource/image.$(OBJEXT) \ + resource/img.$(OBJEXT) resource/imagefetch.$(OBJEXT) \ + resource/sword.$(OBJEXT) resource/select.$(OBJEXT) \ + resource/cache.$(OBJEXT) resource/user9edit.$(OBJEXT) \ + resource/user1edit.$(OBJEXT) resource/user9view.$(OBJEXT) \ + resource/user1view.$(OBJEXT) resource/bbgateway.$(OBJEXT) \ + resource/studylight.$(OBJEXT) resource/unload.$(OBJEXT) \ + jsonxx/jsonxx.$(OBJEXT) mapping/index.$(OBJEXT) \ + mapping/map.$(OBJEXT) statistics/statistics.$(OBJEXT) \ + changes/change.$(OBJEXT) changes/changes.$(OBJEXT) \ + changes/logic.$(OBJEXT) changes/manage.$(OBJEXT) \ + changes/modifications.$(OBJEXT) changes/statistics.$(OBJEXT) \ + sprint/burndown.$(OBJEXT) sprint/index.$(OBJEXT) \ + checks/run.$(OBJEXT) checks/headers.$(OBJEXT) \ + checks/index.$(OBJEXT) checks/logic.$(OBJEXT) \ + checks/sentences.$(OBJEXT) checks/settings.$(OBJEXT) \ + checks/settingspatterns.$(OBJEXT) \ + checks/settingssentences.$(OBJEXT) checks/space.$(OBJEXT) \ + checks/suppress.$(OBJEXT) checks/usfm.$(OBJEXT) \ + checks/verses.$(OBJEXT) checks/versification.$(OBJEXT) \ + checks/pairs.$(OBJEXT) checks/settingspairs.$(OBJEXT) \ + checks/french.$(OBJEXT) consistency/index.$(OBJEXT) \ + consistency/input.$(OBJEXT) consistency/logic.$(OBJEXT) \ + consistency/poll.$(OBJEXT) export/esword.$(OBJEXT) \ + export/html.$(OBJEXT) export/index.$(OBJEXT) \ + export/info.$(OBJEXT) export/logic.$(OBJEXT) \ + export/odt.$(OBJEXT) export/onlinebible.$(OBJEXT) \ + export/textusfm.$(OBJEXT) export/usfm.$(OBJEXT) \ + export/web.$(OBJEXT) export/bibledropbox.$(OBJEXT) \ + webbb/search.$(OBJEXT) developer/index.$(OBJEXT) \ + developer/logic.$(OBJEXT) paratext/logic.$(OBJEXT) \ + paratext/index.$(OBJEXT) personalize/index.$(OBJEXT) \ + lexicon/logic.$(OBJEXT) lexicon/definition.$(OBJEXT) \ + sources/etcbc4.$(OBJEXT) sources/kjv.$(OBJEXT) \ + sources/morphhb.$(OBJEXT) sources/morphgnt.$(OBJEXT) \ + sources/hebrewlexicon.$(OBJEXT) sources/oshb.$(OBJEXT) \ + sword/logic.$(OBJEXT) pugixml/pugixml.$(OBJEXT) \ + pugixml/utils.$(OBJEXT) public/index.$(OBJEXT) \ + public/logic.$(OBJEXT) public/login.$(OBJEXT) \ + public/chapter.$(OBJEXT) public/notes.$(OBJEXT) \ + public/new.$(OBJEXT) public/create.$(OBJEXT) \ + public/note.$(OBJEXT) public/comment.$(OBJEXT) \ + utf8proc/utf8proc.$(OBJEXT) search/logic.$(OBJEXT) \ + mbedtls/aes.$(OBJEXT) mbedtls/arc4.$(OBJEXT) \ + mbedtls/asn1parse.$(OBJEXT) mbedtls/asn1write.$(OBJEXT) \ + mbedtls/base64.$(OBJEXT) mbedtls/bignum.$(OBJEXT) \ + mbedtls/blowfish.$(OBJEXT) mbedtls/camellia.$(OBJEXT) \ + mbedtls/ccm.$(OBJEXT) mbedtls/certs.$(OBJEXT) \ + mbedtls/chacha20.$(OBJEXT) mbedtls/chachapoly.$(OBJEXT) \ + mbedtls/cipher.$(OBJEXT) mbedtls/cipher_wrap.$(OBJEXT) \ + mbedtls/ctr_drbg.$(OBJEXT) mbedtls/debug.$(OBJEXT) \ + mbedtls/des.$(OBJEXT) mbedtls/dhm.$(OBJEXT) \ + mbedtls/ecdh.$(OBJEXT) mbedtls/ecdsa.$(OBJEXT) \ + mbedtls/ecp.$(OBJEXT) mbedtls/ecp_curves.$(OBJEXT) \ + mbedtls/entropy.$(OBJEXT) mbedtls/entropy_poll.$(OBJEXT) \ + mbedtls/error.$(OBJEXT) mbedtls/gcm.$(OBJEXT) \ + mbedtls/hmac_drbg.$(OBJEXT) mbedtls/md.$(OBJEXT) \ + mbedtls/md5.$(OBJEXT) mbedtls/md_wrap.$(OBJEXT) \ + mbedtls/net_sockets.$(OBJEXT) mbedtls/oid.$(OBJEXT) \ + mbedtls/pem.$(OBJEXT) mbedtls/pk.$(OBJEXT) \ + mbedtls/pk_wrap.$(OBJEXT) mbedtls/pkcs12.$(OBJEXT) \ + mbedtls/pkcs5.$(OBJEXT) mbedtls/pkparse.$(OBJEXT) \ + mbedtls/pkwrite.$(OBJEXT) mbedtls/platform_util.$(OBJEXT) \ + mbedtls/platform.$(OBJEXT) mbedtls/poly1305.$(OBJEXT) \ + mbedtls/ripemd160.$(OBJEXT) mbedtls/rsa.$(OBJEXT) \ + mbedtls/rsa_internal.$(OBJEXT) mbedtls/sha1.$(OBJEXT) \ + mbedtls/sha256.$(OBJEXT) mbedtls/sha512.$(OBJEXT) \ + mbedtls/ssl_cache.$(OBJEXT) mbedtls/ssl_ciphersuites.$(OBJEXT) \ + mbedtls/ssl_cli.$(OBJEXT) mbedtls/ssl_cookie.$(OBJEXT) \ + mbedtls/ssl_srv.$(OBJEXT) mbedtls/ssl_ticket.$(OBJEXT) \ + mbedtls/ssl_tls.$(OBJEXT) mbedtls/threading.$(OBJEXT) \ + mbedtls/timing.$(OBJEXT) mbedtls/version.$(OBJEXT) \ + mbedtls/version_features.$(OBJEXT) mbedtls/x509.$(OBJEXT) \ + mbedtls/x509_create.$(OBJEXT) mbedtls/x509_crl.$(OBJEXT) \ + mbedtls/x509_crt.$(OBJEXT) mbedtls/x509_csr.$(OBJEXT) \ + mbedtls/x509write_crt.$(OBJEXT) \ + mbedtls/x509write_csr.$(OBJEXT) mbedtls/xtea.$(OBJEXT) \ + related/logic.$(OBJEXT) sqlite/sqlite3.$(OBJEXT) \ + ldap/logic.$(OBJEXT) quill/logic.$(OBJEXT) rss/logic.$(OBJEXT) \ + rss/feed.$(OBJEXT) microtar/microtar.$(OBJEXT) \ + miniz/miniz.$(OBJEXT) nmt/index.$(OBJEXT) nmt/logic.$(OBJEXT) \ + tbsx/text.$(OBJEXT) read/index.$(OBJEXT) read/load.$(OBJEXT) \ + read/verse.$(OBJEXT) resource/divider.$(OBJEXT) \ + session/confirm.$(OBJEXT) sources/abbott-smith.$(OBJEXT) \ + database/abbottsmith.$(OBJEXT) \ + resource/comparative9edit.$(OBJEXT) \ + resource/comparative1edit.$(OBJEXT) \ + resource/translated9edit.$(OBJEXT) \ + resource/translated1edit.$(OBJEXT) developer/delay.$(OBJEXT) \ + images/index.$(OBJEXT) images/view.$(OBJEXT) \ + images/fetch.$(OBJEXT) images/logic.$(OBJEXT) \ + database/bibleimages.$(OBJEXT) filter/image.$(OBJEXT) \ + mimetic098/header.$(OBJEXT) mimetic098/contentid.$(OBJEXT) \ + mimetic098/contenttransferencoding.$(OBJEXT) \ + mimetic098/contentdisposition.$(OBJEXT) \ + mimetic098/contentdescription.$(OBJEXT) \ + mimetic098/mimeversion.$(OBJEXT) \ + mimetic098/contenttype.$(OBJEXT) mimetic098/version.$(OBJEXT) \ + mimetic098/fieldparam.$(OBJEXT) \ + mimetic098/mimeentity.$(OBJEXT) mimetic098/strutils.$(OBJEXT) \ + mimetic098/body.$(OBJEXT) mimetic098/utils.$(OBJEXT) \ + mimetic098/rfc822/field.$(OBJEXT) \ + mimetic098/rfc822/header.$(OBJEXT) \ + mimetic098/rfc822/message.$(OBJEXT) \ + mimetic098/rfc822/addresslist.$(OBJEXT) \ + mimetic098/rfc822/fieldvalue.$(OBJEXT) \ + mimetic098/rfc822/mailbox.$(OBJEXT) \ + mimetic098/rfc822/messageid.$(OBJEXT) \ + mimetic098/rfc822/datetime.$(OBJEXT) \ + mimetic098/rfc822/group.$(OBJEXT) \ + mimetic098/rfc822/mailboxlist.$(OBJEXT) \ + mimetic098/rfc822/address.$(OBJEXT) \ + mimetic098/os/utils.$(OBJEXT) \ + mimetic098/os/file_iterator.$(OBJEXT) \ + mimetic098/os/mmfile.$(OBJEXT) \ + mimetic098/codec/base64.$(OBJEXT) \ + system/googletranslate.$(OBJEXT) filter/google.$(OBJEXT) \ + i18n/logic.$(OBJEXT) tidy/access.$(OBJEXT) \ + tidy/alloc.$(OBJEXT) tidy/attrdict.$(OBJEXT) \ + tidy/attrs.$(OBJEXT) tidy/buffio.$(OBJEXT) \ + tidy/charsets.$(OBJEXT) tidy/clean.$(OBJEXT) \ + tidy/config.$(OBJEXT) tidy/entities.$(OBJEXT) \ + tidy/fileio.$(OBJEXT) tidy/gdoc.$(OBJEXT) \ + tidy/istack.$(OBJEXT) tidy/language.$(OBJEXT) \ + tidy/lexer.$(OBJEXT) tidy/mappedio.$(OBJEXT) \ + tidy/message.$(OBJEXT) tidy/messageobj.$(OBJEXT) \ + tidy/parser.$(OBJEXT) tidy/pprint.$(OBJEXT) \ + tidy/sprtf.$(OBJEXT) tidy/streamio.$(OBJEXT) \ + tidy/tagask.$(OBJEXT) tidy/tags.$(OBJEXT) \ + tidy/tidylib.$(OBJEXT) tidy/tmbstr.$(OBJEXT) \ + tidy/utf8.$(OBJEXT) +libbibledit_a_OBJECTS = $(am_libbibledit_a_OBJECTS) +am_generate_OBJECTS = executable/generate.$(OBJEXT) \ + sources/styles.$(OBJEXT) +generate_OBJECTS = $(am_generate_OBJECTS) +generate_DEPENDENCIES = libbibledit.a +am_server_OBJECTS = executable/bibledit.$(OBJEXT) +server_OBJECTS = $(am_server_OBJECTS) +server_DEPENDENCIES = libbibledit.a +AM_V_P = $(am__v_P_$(V)) +am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I. +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = access/$(DEPDIR)/bible.Po \ + access/$(DEPDIR)/logic.Po access/$(DEPDIR)/user.Po \ + assets/$(DEPDIR)/external.Po assets/$(DEPDIR)/header.Po \ + assets/$(DEPDIR)/page.Po assets/$(DEPDIR)/view.Po \ + bb/$(DEPDIR)/book.Po bb/$(DEPDIR)/chapter.Po \ + bb/$(DEPDIR)/css.Po bb/$(DEPDIR)/import.Po \ + bb/$(DEPDIR)/import_run.Po bb/$(DEPDIR)/logic.Po \ + bb/$(DEPDIR)/manage.Po bb/$(DEPDIR)/order.Po \ + bb/$(DEPDIR)/settings.Po book/$(DEPDIR)/create.Po \ + bootstrap/$(DEPDIR)/bootstrap.Po changes/$(DEPDIR)/change.Po \ + changes/$(DEPDIR)/changes.Po changes/$(DEPDIR)/logic.Po \ + changes/$(DEPDIR)/manage.Po changes/$(DEPDIR)/modifications.Po \ + changes/$(DEPDIR)/statistics.Po checks/$(DEPDIR)/french.Po \ + checks/$(DEPDIR)/headers.Po checks/$(DEPDIR)/index.Po \ + checks/$(DEPDIR)/logic.Po checks/$(DEPDIR)/pairs.Po \ + checks/$(DEPDIR)/run.Po checks/$(DEPDIR)/sentences.Po \ + checks/$(DEPDIR)/settings.Po checks/$(DEPDIR)/settingspairs.Po \ + checks/$(DEPDIR)/settingspatterns.Po \ + checks/$(DEPDIR)/settingssentences.Po \ + checks/$(DEPDIR)/space.Po checks/$(DEPDIR)/suppress.Po \ + checks/$(DEPDIR)/usfm.Po checks/$(DEPDIR)/verses.Po \ + checks/$(DEPDIR)/versification.Po checksum/$(DEPDIR)/logic.Po \ + client/$(DEPDIR)/index.Po client/$(DEPDIR)/logic.Po \ + collaboration/$(DEPDIR)/index.Po \ + collaboration/$(DEPDIR)/link.Po \ + collaboration/$(DEPDIR)/settings.Po \ + compare/$(DEPDIR)/compare.Po compare/$(DEPDIR)/index.Po \ + config/$(DEPDIR)/globals.Po config/$(DEPDIR)/logic.Po \ + confirm/$(DEPDIR)/worker.Po consistency/$(DEPDIR)/index.Po \ + consistency/$(DEPDIR)/input.Po consistency/$(DEPDIR)/logic.Po \ + consistency/$(DEPDIR)/poll.Po \ + database/$(DEPDIR)/abbottsmith.Po \ + database/$(DEPDIR)/bibleactions.Po \ + database/$(DEPDIR)/bibleimages.Po database/$(DEPDIR)/bibles.Po \ + database/$(DEPDIR)/books.Po database/$(DEPDIR)/cache.Po \ + database/$(DEPDIR)/check.Po database/$(DEPDIR)/confirm.Po \ + database/$(DEPDIR)/etcbc4.Po database/$(DEPDIR)/git.Po \ + database/$(DEPDIR)/hebrewlexicon.Po \ + database/$(DEPDIR)/imageresources.Po database/$(DEPDIR)/ipc.Po \ + database/$(DEPDIR)/jobs.Po database/$(DEPDIR)/kjv.Po \ + database/$(DEPDIR)/localization.Po database/$(DEPDIR)/logic.Po \ + database/$(DEPDIR)/login.Po database/$(DEPDIR)/logs.Po \ + database/$(DEPDIR)/mail.Po database/$(DEPDIR)/maintenance.Po \ + database/$(DEPDIR)/mappings.Po \ + database/$(DEPDIR)/modifications.Po \ + database/$(DEPDIR)/morphgnt.Po \ + database/$(DEPDIR)/navigation.Po \ + database/$(DEPDIR)/noteactions.Po \ + database/$(DEPDIR)/noteassignment.Po \ + database/$(DEPDIR)/notes.Po database/$(DEPDIR)/oshb.Po \ + database/$(DEPDIR)/privileges.Po database/$(DEPDIR)/sample.Po \ + database/$(DEPDIR)/sblgnt.Po database/$(DEPDIR)/sprint.Po \ + database/$(DEPDIR)/sqlite.Po database/$(DEPDIR)/state.Po \ + database/$(DEPDIR)/statistics.Po database/$(DEPDIR)/strong.Po \ + database/$(DEPDIR)/styles.Po \ + database/$(DEPDIR)/userresources.Po \ + database/$(DEPDIR)/users.Po \ + database/$(DEPDIR)/usfmresources.Po \ + database/$(DEPDIR)/versifications.Po \ + database/$(DEPDIR)/volatile.Po \ + database/config/$(DEPDIR)/bible.Po \ + database/config/$(DEPDIR)/general.Po \ + database/config/$(DEPDIR)/user.Po demo/$(DEPDIR)/logic.Po \ + developer/$(DEPDIR)/delay.Po developer/$(DEPDIR)/index.Po \ + developer/$(DEPDIR)/logic.Po dialog/$(DEPDIR)/books.Po \ + dialog/$(DEPDIR)/color.Po dialog/$(DEPDIR)/entry.Po \ + dialog/$(DEPDIR)/list.Po dialog/$(DEPDIR)/list2.Po \ + dialog/$(DEPDIR)/upload.Po dialog/$(DEPDIR)/yes.Po \ + edit/$(DEPDIR)/edit.Po edit/$(DEPDIR)/id.Po \ + edit/$(DEPDIR)/index.Po edit/$(DEPDIR)/load.Po \ + edit/$(DEPDIR)/logic.Po edit/$(DEPDIR)/navigate.Po \ + edit/$(DEPDIR)/position.Po edit/$(DEPDIR)/preview.Po \ + edit/$(DEPDIR)/save.Po edit/$(DEPDIR)/styles.Po \ + edit/$(DEPDIR)/update.Po editone2/$(DEPDIR)/index.Po \ + editone2/$(DEPDIR)/load.Po editone2/$(DEPDIR)/logic.Po \ + editone2/$(DEPDIR)/save.Po editone2/$(DEPDIR)/update.Po \ + editone2/$(DEPDIR)/verse.Po editor/$(DEPDIR)/html2format.Po \ + editor/$(DEPDIR)/html2usfm.Po editor/$(DEPDIR)/id.Po \ + editor/$(DEPDIR)/select.Po editor/$(DEPDIR)/style.Po \ + editor/$(DEPDIR)/styles.Po editor/$(DEPDIR)/usfm2html.Po \ + editusfm/$(DEPDIR)/focus.Po editusfm/$(DEPDIR)/index.Po \ + editusfm/$(DEPDIR)/load.Po editusfm/$(DEPDIR)/offset.Po \ + editusfm/$(DEPDIR)/save.Po email/$(DEPDIR)/index.Po \ + email/$(DEPDIR)/receive.Po email/$(DEPDIR)/send.Po \ + esword/$(DEPDIR)/text.Po executable/$(DEPDIR)/bibledit.Po \ + executable/$(DEPDIR)/generate.Po \ + export/$(DEPDIR)/bibledropbox.Po export/$(DEPDIR)/esword.Po \ + export/$(DEPDIR)/html.Po export/$(DEPDIR)/index.Po \ + export/$(DEPDIR)/info.Po export/$(DEPDIR)/logic.Po \ + export/$(DEPDIR)/odt.Po export/$(DEPDIR)/onlinebible.Po \ + export/$(DEPDIR)/textusfm.Po export/$(DEPDIR)/usfm.Po \ + export/$(DEPDIR)/web.Po filter/$(DEPDIR)/archive.Po \ + filter/$(DEPDIR)/css.Po filter/$(DEPDIR)/date.Po \ + filter/$(DEPDIR)/diff.Po filter/$(DEPDIR)/git.Po \ + filter/$(DEPDIR)/google.Po filter/$(DEPDIR)/html.Po \ + filter/$(DEPDIR)/image.Po filter/$(DEPDIR)/mail.Po \ + filter/$(DEPDIR)/md5.Po filter/$(DEPDIR)/memory.Po \ + filter/$(DEPDIR)/merge.Po filter/$(DEPDIR)/note.Po \ + filter/$(DEPDIR)/passage.Po filter/$(DEPDIR)/roles.Po \ + filter/$(DEPDIR)/shell.Po filter/$(DEPDIR)/string.Po \ + filter/$(DEPDIR)/text.Po filter/$(DEPDIR)/url.Po \ + filter/$(DEPDIR)/usfm.Po filter/$(DEPDIR)/webview.Po \ + flate/$(DEPDIR)/flate.Po fonts/$(DEPDIR)/logic.Po \ + help/$(DEPDIR)/index.Po html/$(DEPDIR)/header.Po \ + html/$(DEPDIR)/text.Po i18n/$(DEPDIR)/logic.Po \ + images/$(DEPDIR)/fetch.Po images/$(DEPDIR)/index.Po \ + images/$(DEPDIR)/logic.Po images/$(DEPDIR)/view.Po \ + index/$(DEPDIR)/index.Po index/$(DEPDIR)/listing.Po \ + ipc/$(DEPDIR)/focus.Po ipc/$(DEPDIR)/notes.Po \ + jobs/$(DEPDIR)/index.Po journal/$(DEPDIR)/index.Po \ + journal/$(DEPDIR)/logic.Po jsonxx/$(DEPDIR)/jsonxx.Po \ + ldap/$(DEPDIR)/logic.Po lexicon/$(DEPDIR)/definition.Po \ + lexicon/$(DEPDIR)/logic.Po library/$(DEPDIR)/bibledit.Po \ + library/$(DEPDIR)/locks.Po locale/$(DEPDIR)/logic.Po \ + locale/$(DEPDIR)/translate.Po manage/$(DEPDIR)/accounts.Po \ + manage/$(DEPDIR)/exports.Po manage/$(DEPDIR)/hyphenate.Po \ + manage/$(DEPDIR)/hyphenation.Po manage/$(DEPDIR)/index.Po \ + manage/$(DEPDIR)/privileges.Po manage/$(DEPDIR)/users.Po \ + manage/$(DEPDIR)/write.Po mapping/$(DEPDIR)/index.Po \ + mapping/$(DEPDIR)/map.Po mbedtls/$(DEPDIR)/aes.Po \ + mbedtls/$(DEPDIR)/arc4.Po mbedtls/$(DEPDIR)/asn1parse.Po \ + mbedtls/$(DEPDIR)/asn1write.Po mbedtls/$(DEPDIR)/base64.Po \ + mbedtls/$(DEPDIR)/bignum.Po mbedtls/$(DEPDIR)/blowfish.Po \ + mbedtls/$(DEPDIR)/camellia.Po mbedtls/$(DEPDIR)/ccm.Po \ + mbedtls/$(DEPDIR)/certs.Po mbedtls/$(DEPDIR)/chacha20.Po \ + mbedtls/$(DEPDIR)/chachapoly.Po mbedtls/$(DEPDIR)/cipher.Po \ + mbedtls/$(DEPDIR)/cipher_wrap.Po mbedtls/$(DEPDIR)/ctr_drbg.Po \ + mbedtls/$(DEPDIR)/debug.Po mbedtls/$(DEPDIR)/des.Po \ + mbedtls/$(DEPDIR)/dhm.Po mbedtls/$(DEPDIR)/ecdh.Po \ + mbedtls/$(DEPDIR)/ecdsa.Po mbedtls/$(DEPDIR)/ecp.Po \ + mbedtls/$(DEPDIR)/ecp_curves.Po mbedtls/$(DEPDIR)/entropy.Po \ + mbedtls/$(DEPDIR)/entropy_poll.Po mbedtls/$(DEPDIR)/error.Po \ + mbedtls/$(DEPDIR)/gcm.Po mbedtls/$(DEPDIR)/hmac_drbg.Po \ + mbedtls/$(DEPDIR)/md.Po mbedtls/$(DEPDIR)/md5.Po \ + mbedtls/$(DEPDIR)/md_wrap.Po mbedtls/$(DEPDIR)/net_sockets.Po \ + mbedtls/$(DEPDIR)/oid.Po mbedtls/$(DEPDIR)/pem.Po \ + mbedtls/$(DEPDIR)/pk.Po mbedtls/$(DEPDIR)/pk_wrap.Po \ + mbedtls/$(DEPDIR)/pkcs12.Po mbedtls/$(DEPDIR)/pkcs5.Po \ + mbedtls/$(DEPDIR)/pkparse.Po mbedtls/$(DEPDIR)/pkwrite.Po \ + mbedtls/$(DEPDIR)/platform.Po \ + mbedtls/$(DEPDIR)/platform_util.Po \ + mbedtls/$(DEPDIR)/poly1305.Po mbedtls/$(DEPDIR)/ripemd160.Po \ + mbedtls/$(DEPDIR)/rsa.Po mbedtls/$(DEPDIR)/rsa_internal.Po \ + mbedtls/$(DEPDIR)/sha1.Po mbedtls/$(DEPDIR)/sha256.Po \ + mbedtls/$(DEPDIR)/sha512.Po mbedtls/$(DEPDIR)/ssl_cache.Po \ + mbedtls/$(DEPDIR)/ssl_ciphersuites.Po \ + mbedtls/$(DEPDIR)/ssl_cli.Po mbedtls/$(DEPDIR)/ssl_cookie.Po \ + mbedtls/$(DEPDIR)/ssl_srv.Po mbedtls/$(DEPDIR)/ssl_ticket.Po \ + mbedtls/$(DEPDIR)/ssl_tls.Po mbedtls/$(DEPDIR)/threading.Po \ + mbedtls/$(DEPDIR)/timing.Po mbedtls/$(DEPDIR)/version.Po \ + mbedtls/$(DEPDIR)/version_features.Po \ + mbedtls/$(DEPDIR)/x509.Po mbedtls/$(DEPDIR)/x509_create.Po \ + mbedtls/$(DEPDIR)/x509_crl.Po mbedtls/$(DEPDIR)/x509_crt.Po \ + mbedtls/$(DEPDIR)/x509_csr.Po \ + mbedtls/$(DEPDIR)/x509write_crt.Po \ + mbedtls/$(DEPDIR)/x509write_csr.Po mbedtls/$(DEPDIR)/xtea.Po \ + menu/$(DEPDIR)/index.Po menu/$(DEPDIR)/logic.Po \ + microtar/$(DEPDIR)/microtar.Po mimetic098/$(DEPDIR)/body.Po \ + mimetic098/$(DEPDIR)/contentdescription.Po \ + mimetic098/$(DEPDIR)/contentdisposition.Po \ + mimetic098/$(DEPDIR)/contentid.Po \ + mimetic098/$(DEPDIR)/contenttransferencoding.Po \ + mimetic098/$(DEPDIR)/contenttype.Po \ + mimetic098/$(DEPDIR)/fieldparam.Po \ + mimetic098/$(DEPDIR)/header.Po \ + mimetic098/$(DEPDIR)/mimeentity.Po \ + mimetic098/$(DEPDIR)/mimeversion.Po \ + mimetic098/$(DEPDIR)/strutils.Po mimetic098/$(DEPDIR)/utils.Po \ + mimetic098/$(DEPDIR)/version.Po \ + mimetic098/codec/$(DEPDIR)/base64.Po \ + mimetic098/os/$(DEPDIR)/file_iterator.Po \ + mimetic098/os/$(DEPDIR)/mmfile.Po \ + mimetic098/os/$(DEPDIR)/utils.Po \ + mimetic098/rfc822/$(DEPDIR)/address.Po \ + mimetic098/rfc822/$(DEPDIR)/addresslist.Po \ + mimetic098/rfc822/$(DEPDIR)/datetime.Po \ + mimetic098/rfc822/$(DEPDIR)/field.Po \ + mimetic098/rfc822/$(DEPDIR)/fieldvalue.Po \ + mimetic098/rfc822/$(DEPDIR)/group.Po \ + mimetic098/rfc822/$(DEPDIR)/header.Po \ + mimetic098/rfc822/$(DEPDIR)/mailbox.Po \ + mimetic098/rfc822/$(DEPDIR)/mailboxlist.Po \ + mimetic098/rfc822/$(DEPDIR)/message.Po \ + mimetic098/rfc822/$(DEPDIR)/messageid.Po \ + miniz/$(DEPDIR)/miniz.Po navigation/$(DEPDIR)/paratext.Po \ + navigation/$(DEPDIR)/passage.Po navigation/$(DEPDIR)/poll.Po \ + navigation/$(DEPDIR)/update.Po nmt/$(DEPDIR)/index.Po \ + nmt/$(DEPDIR)/logic.Po notes/$(DEPDIR)/actions.Po \ + notes/$(DEPDIR)/assign-1.Po notes/$(DEPDIR)/assign-n.Po \ + notes/$(DEPDIR)/bb-1.Po notes/$(DEPDIR)/bb-n.Po \ + notes/$(DEPDIR)/bulk.Po notes/$(DEPDIR)/click.Po \ + notes/$(DEPDIR)/comment.Po notes/$(DEPDIR)/create.Po \ + notes/$(DEPDIR)/edit.Po notes/$(DEPDIR)/index.Po \ + notes/$(DEPDIR)/logic.Po notes/$(DEPDIR)/note.Po \ + notes/$(DEPDIR)/notes.Po notes/$(DEPDIR)/poll.Po \ + notes/$(DEPDIR)/select.Po notes/$(DEPDIR)/severity-1.Po \ + notes/$(DEPDIR)/severity-n.Po notes/$(DEPDIR)/status-1.Po \ + notes/$(DEPDIR)/status-n.Po notes/$(DEPDIR)/summary.Po \ + notes/$(DEPDIR)/unassign-n.Po notes/$(DEPDIR)/verses.Po \ + odf/$(DEPDIR)/text.Po olb/$(DEPDIR)/text.Po \ + paratext/$(DEPDIR)/index.Po paratext/$(DEPDIR)/logic.Po \ + parsewebdata/$(DEPDIR)/ParseMultipartFormData.Po \ + parsewebdata/$(DEPDIR)/ParseWebData.Po \ + personalize/$(DEPDIR)/index.Po public/$(DEPDIR)/chapter.Po \ + public/$(DEPDIR)/comment.Po public/$(DEPDIR)/create.Po \ + public/$(DEPDIR)/index.Po public/$(DEPDIR)/logic.Po \ + public/$(DEPDIR)/login.Po public/$(DEPDIR)/new.Po \ + public/$(DEPDIR)/note.Po public/$(DEPDIR)/notes.Po \ + pugixml/$(DEPDIR)/pugixml.Po pugixml/$(DEPDIR)/utils.Po \ + quill/$(DEPDIR)/logic.Po read/$(DEPDIR)/index.Po \ + read/$(DEPDIR)/load.Po read/$(DEPDIR)/verse.Po \ + redirect/$(DEPDIR)/index.Po related/$(DEPDIR)/logic.Po \ + resource/$(DEPDIR)/bb2resource.Po \ + resource/$(DEPDIR)/bbgateway.Po resource/$(DEPDIR)/cache.Po \ + resource/$(DEPDIR)/comparative1edit.Po \ + resource/$(DEPDIR)/comparative9edit.Po \ + resource/$(DEPDIR)/convert2bible.Po \ + resource/$(DEPDIR)/convert2resource.Po \ + resource/$(DEPDIR)/divider.Po resource/$(DEPDIR)/download.Po \ + resource/$(DEPDIR)/external.Po resource/$(DEPDIR)/get.Po \ + resource/$(DEPDIR)/image.Po resource/$(DEPDIR)/imagefetch.Po \ + resource/$(DEPDIR)/images.Po resource/$(DEPDIR)/img.Po \ + resource/$(DEPDIR)/index.Po resource/$(DEPDIR)/logic.Po \ + resource/$(DEPDIR)/manage.Po resource/$(DEPDIR)/organize.Po \ + resource/$(DEPDIR)/print.Po resource/$(DEPDIR)/select.Po \ + resource/$(DEPDIR)/studylight.Po resource/$(DEPDIR)/sword.Po \ + resource/$(DEPDIR)/translated1edit.Po \ + resource/$(DEPDIR)/translated9edit.Po \ + resource/$(DEPDIR)/unload.Po resource/$(DEPDIR)/user1edit.Po \ + resource/$(DEPDIR)/user1view.Po \ + resource/$(DEPDIR)/user9edit.Po \ + resource/$(DEPDIR)/user9view.Po rss/$(DEPDIR)/feed.Po \ + rss/$(DEPDIR)/logic.Po search/$(DEPDIR)/all.Po \ + search/$(DEPDIR)/getids.Po search/$(DEPDIR)/getids2.Po \ + search/$(DEPDIR)/index.Po search/$(DEPDIR)/logic.Po \ + search/$(DEPDIR)/originals.Po search/$(DEPDIR)/rebibles.Po \ + search/$(DEPDIR)/renotes.Po search/$(DEPDIR)/replace.Po \ + search/$(DEPDIR)/replace2.Po search/$(DEPDIR)/replacego.Po \ + search/$(DEPDIR)/replacego2.Po search/$(DEPDIR)/replacepre.Po \ + search/$(DEPDIR)/replacepre2.Po search/$(DEPDIR)/search2.Po \ + search/$(DEPDIR)/similar.Po search/$(DEPDIR)/strong.Po \ + search/$(DEPDIR)/strongs.Po sendreceive/$(DEPDIR)/bibles.Po \ + sendreceive/$(DEPDIR)/changes.Po \ + sendreceive/$(DEPDIR)/files.Po sendreceive/$(DEPDIR)/index.Po \ + sendreceive/$(DEPDIR)/logic.Po sendreceive/$(DEPDIR)/notes.Po \ + sendreceive/$(DEPDIR)/resources.Po \ + sendreceive/$(DEPDIR)/sendreceive.Po \ + sendreceive/$(DEPDIR)/settings.Po session/$(DEPDIR)/confirm.Po \ + session/$(DEPDIR)/logic.Po session/$(DEPDIR)/login.Po \ + session/$(DEPDIR)/logout.Po session/$(DEPDIR)/password.Po \ + session/$(DEPDIR)/signup.Po session/$(DEPDIR)/switch.Po \ + setup/$(DEPDIR)/index.Po setup/$(DEPDIR)/logic.Po \ + sources/$(DEPDIR)/abbott-smith.Po sources/$(DEPDIR)/etcbc4.Po \ + sources/$(DEPDIR)/hebrewlexicon.Po sources/$(DEPDIR)/kjv.Po \ + sources/$(DEPDIR)/morphgnt.Po sources/$(DEPDIR)/morphhb.Po \ + sources/$(DEPDIR)/oshb.Po sources/$(DEPDIR)/styles.Po \ + sprint/$(DEPDIR)/burndown.Po sprint/$(DEPDIR)/index.Po \ + sqlite/$(DEPDIR)/sqlite3.Po statistics/$(DEPDIR)/statistics.Po \ + styles/$(DEPDIR)/css.Po styles/$(DEPDIR)/indexm.Po \ + styles/$(DEPDIR)/logic.Po styles/$(DEPDIR)/sheetm.Po \ + styles/$(DEPDIR)/sheets.Po styles/$(DEPDIR)/view.Po \ + sword/$(DEPDIR)/logic.Po sync/$(DEPDIR)/bibles.Po \ + sync/$(DEPDIR)/changes.Po sync/$(DEPDIR)/files.Po \ + sync/$(DEPDIR)/logic.Po sync/$(DEPDIR)/mail.Po \ + sync/$(DEPDIR)/notes.Po sync/$(DEPDIR)/resources.Po \ + sync/$(DEPDIR)/settings.Po sync/$(DEPDIR)/setup.Po \ + sync/$(DEPDIR)/usfmresources.Po \ + system/$(DEPDIR)/googletranslate.Po system/$(DEPDIR)/index.Po \ + system/$(DEPDIR)/logic.Po tasks/$(DEPDIR)/logic.Po \ + tasks/$(DEPDIR)/run.Po tbsx/$(DEPDIR)/text.Po \ + text/$(DEPDIR)/text.Po tidy/$(DEPDIR)/access.Po \ + tidy/$(DEPDIR)/alloc.Po tidy/$(DEPDIR)/attrdict.Po \ + tidy/$(DEPDIR)/attrs.Po tidy/$(DEPDIR)/buffio.Po \ + tidy/$(DEPDIR)/charsets.Po tidy/$(DEPDIR)/clean.Po \ + tidy/$(DEPDIR)/config.Po tidy/$(DEPDIR)/entities.Po \ + tidy/$(DEPDIR)/fileio.Po tidy/$(DEPDIR)/gdoc.Po \ + tidy/$(DEPDIR)/istack.Po tidy/$(DEPDIR)/language.Po \ + tidy/$(DEPDIR)/lexer.Po tidy/$(DEPDIR)/mappedio.Po \ + tidy/$(DEPDIR)/message.Po tidy/$(DEPDIR)/messageobj.Po \ + tidy/$(DEPDIR)/parser.Po tidy/$(DEPDIR)/pprint.Po \ + tidy/$(DEPDIR)/sprtf.Po tidy/$(DEPDIR)/streamio.Po \ + tidy/$(DEPDIR)/tagask.Po tidy/$(DEPDIR)/tags.Po \ + tidy/$(DEPDIR)/tidylib.Po tidy/$(DEPDIR)/tmbstr.Po \ + tidy/$(DEPDIR)/utf8.Po timer/$(DEPDIR)/index.Po \ + tmp/$(DEPDIR)/tmp.Po trash/$(DEPDIR)/handler.Po \ + user/$(DEPDIR)/account.Po user/$(DEPDIR)/logic.Po \ + user/$(DEPDIR)/notifications.Po utf8proc/$(DEPDIR)/utf8proc.Po \ + versification/$(DEPDIR)/index.Po \ + versification/$(DEPDIR)/logic.Po \ + versification/$(DEPDIR)/system.Po webbb/$(DEPDIR)/search.Po \ + webserver/$(DEPDIR)/http.Po webserver/$(DEPDIR)/request.Po \ + webserver/$(DEPDIR)/webserver.Po workspace/$(DEPDIR)/index.Po \ + workspace/$(DEPDIR)/logic.Po workspace/$(DEPDIR)/organize.Po \ + workspace/$(DEPDIR)/settings.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_$(V)) +am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY)) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_$(V)) +am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libbibledit_a_SOURCES) $(generate_SOURCES) \ + $(server_SOURCES) +DIST_SOURCES = $(libbibledit_a_SOURCES) $(generate_SOURCES) \ + $(server_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +AM_RECURSIVE_TARGETS = cscope +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ + COPYING ChangeLog INSTALL NEWS README compile config.guess \ + config.sub depcomp install-sh missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = ${SHELL} '/Users/teus/dev/macos/swift/webroot/missing' aclocal-1.16 +AMTAR = $${TAR-tar} +AM_DEFAULT_VERBOSITY = 1 +AUTOCONF = ${SHELL} '/Users/teus/dev/macos/swift/webroot/missing' autoconf +AUTOHEADER = ${SHELL} '/Users/teus/dev/macos/swift/webroot/missing' autoheader +AUTOMAKE = ${SHELL} '/Users/teus/dev/macos/swift/webroot/missing' automake-1.16 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 +CPPFLAGS = +CSCOPE = cscope +CTAGS = ctags +CURL_CFLAGS = -I. -I.. +CURL_LIBS = -L. -lcurl +CXX = g++ -std=c++17 +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -g -O2 +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DIATHEKE_PATH = /opt/local/bin/diatheke +ECHO_C = \c +ECHO_N = +ECHO_T = +ETAGS = etags +EXEEXT = +FIND_TAR = /usr/bin/tar +GTEST_CFLAGS = -DGTEST_HAS_PTHREAD=1 -I. -I.. +GTEST_LIBS = -L. -lgtest +GUMBO_CFLAGS = -I. -I.. +GUMBO_LIBS = -L. -lgumbo +GUNZIP_PATH = /usr/bin/gunzip +GZIP_PATH = /usr/bin/gzip +HAVE_CXX17 = 1 +INSTALL = /usr/bin/install -c +INSTALLMGR_PATH = /opt/local/bin/installmgr +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LDFLAGS = +LIBOBJS = +LIBS = -Wall -lpthread -L. -g -rdynamic -ldl $(CURL_LIBS) \ + $(OPENSSL_LIBS) $(GTK_LIBS) $(WEBKIT2GTK_LIBS) $(ICU_LIBS) \ + $(XML2_LIBS) +LTLIBOBJS = +MAKEINFO = ${SHELL} '/Users/teus/dev/macos/swift/webroot/missing' makeinfo +MKDIR_P = /opt/local/bin/gmkdir -p +OBJEXT = o +OPENSSL_CFLAGS = -I.exec/openssl3/include +PACKAGE = bibledit +PACKAGE_BUGREPORT = http://bibledit.org +PACKAGE_NAME = bibledit +PACKAGE_STRING = bibledit 5.1.010 +PACKAGE_TARNAME = bibledit +PACKAGE_URL = +PACKAGE_VERSION = 5.1.010 +PATH_SEPARATOR = : +PKG_CONFIG = /opt/local/bin/pkg-config +PKG_CONFIG_LIBDIR = +PKG_CONFIG_PATH = +PUGIXML_CFLAGS = -I. -I.. +PUGIXML_LIBS = -L. -lpugixml +RANLIB = ranlib +SET_MAKE = +SHELL = /bin/sh +STRIP = +UNZIP_PATH = /usr/bin/unzip +UTF8PROC_CFLAGS = -DUTF8PROC_EXPORTS -I. -I.. +UTF8PROC_LIBS = -L. -lutf8proc +VERSION = 5.1.010 +XML2_LIBS = -L. -lxml2 +ZIP_PATH = /usr/bin/zip +abs_builddir = /Users/teus/dev/macos/swift/webroot +abs_srcdir = /Users/teus/dev/macos/swift/webroot +abs_top_builddir = /Users/teus/dev/macos/swift/webroot +abs_top_srcdir = /Users/teus/dev/macos/swift/webroot +ac_ct_CC = gcc +ac_ct_CXX = g++ +am__include = include +am__leading_dot = . +am__quote = +am__tar = tar --format=ustar -chf - "$$tardir" +am__untar = tar -xf - +bindir = ${exec_prefix}/bin +build = x86_64-apple-darwin22.6.0 +build_alias = +build_cpu = x86_64 +build_os = darwin22.6.0 +build_vendor = apple +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host_alias = +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /Users/teus/dev/macos/swift/webroot/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = $(MKDIR_P) +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr +program_transform_name = s,x,x, +psdir = ${docdir} +runstatedir = ${localstatedir}/run +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = +top_builddir = . +top_srcdir = . +noinst_LIBRARIES = libbibledit.a +libbibledit_a_SOURCES = \ + library/bibledit.cpp \ + library/locks.c \ + webserver/webserver.cpp \ + webserver/http.cpp \ + webserver/request.cpp \ + bootstrap/bootstrap.cpp \ + filter/url.cpp \ + filter/string.cpp \ + filter/roles.cpp \ + filter/md5.cpp \ + filter/usfm.cpp \ + filter/archive.cpp \ + filter/text.cpp \ + filter/passage.cpp \ + filter/css.cpp \ + filter/git.cpp \ + filter/html.cpp \ + filter/diff.cpp \ + filter/shell.cpp \ + filter/merge.cpp \ + filter/date.cpp \ + filter/memory.cpp \ + filter/webview.cpp \ + filter/mail.cpp \ + filter/note.cpp \ + flate/flate.cpp \ + assets/view.cpp \ + assets/page.cpp \ + assets/header.cpp \ + assets/external.cpp \ + index/index.cpp \ + index/listing.cpp \ + config/globals.cpp \ + menu/logic.cpp \ + menu/index.cpp \ + locale/translate.cpp \ + locale/logic.cpp \ + database/config/general.cpp \ + database/config/bible.cpp \ + database/config/user.cpp \ + database/users.cpp \ + database/logs.cpp \ + database/sqlite.cpp \ + database/styles.cpp \ + database/bibles.cpp \ + database/books.cpp \ + database/bibleactions.cpp \ + database/check.cpp \ + database/localization.cpp \ + database/confirm.cpp \ + database/ipc.cpp \ + database/jobs.cpp \ + database/kjv.cpp \ + database/logic.cpp \ + database/oshb.cpp \ + database/sblgnt.cpp \ + database/sprint.cpp \ + database/mail.cpp \ + database/navigation.cpp \ + database/usfmresources.cpp \ + database/mappings.cpp \ + database/noteactions.cpp \ + database/versifications.cpp \ + database/modifications.cpp \ + database/notes.cpp \ + database/volatile.cpp \ + database/maintenance.cpp \ + database/imageresources.cpp \ + database/state.cpp \ + database/noteassignment.cpp \ + database/strong.cpp \ + database/morphgnt.cpp \ + database/etcbc4.cpp \ + database/hebrewlexicon.cpp \ + database/cache.cpp \ + database/login.cpp \ + database/privileges.cpp \ + database/git.cpp \ + database/userresources.cpp \ + database/statistics.cpp \ + database/sample.cpp \ + session/logic.cpp \ + session/login.cpp \ + session/logout.cpp \ + session/password.cpp \ + session/signup.cpp \ + session/switch.cpp \ + parsewebdata/ParseMultipartFormData.cpp \ + parsewebdata/ParseWebData.cpp \ + setup/index.cpp \ + setup/logic.cpp \ + journal/index.cpp \ + journal/logic.cpp \ + styles/logic.cpp \ + styles/indexm.cpp \ + styles/sheetm.cpp \ + styles/view.cpp \ + styles/css.cpp \ + styles/sheets.cpp \ + text/text.cpp \ + esword/text.cpp \ + olb/text.cpp \ + html/text.cpp \ + html/header.cpp \ + odf/text.cpp \ + timer/index.cpp \ + tasks/logic.cpp \ + tasks/run.cpp \ + config/logic.cpp \ + bb/logic.cpp \ + bb/manage.cpp \ + bb/settings.cpp \ + bb/book.cpp \ + bb/chapter.cpp \ + bb/import_run.cpp \ + bb/import.cpp \ + bb/order.cpp \ + bb/css.cpp \ + notes/logic.cpp \ + notes/actions.cpp \ + notes/note.cpp \ + notes/status-1.cpp \ + notes/assign-1.cpp \ + notes/notes.cpp \ + notes/status-n.cpp \ + notes/assign-n.cpp \ + notes/click.cpp \ + notes/poll.cpp \ + notes/summary.cpp \ + notes/bb-1.cpp \ + notes/comment.cpp \ + notes/select.cpp \ + notes/unassign-n.cpp \ + notes/bb-n.cpp \ + notes/create.cpp \ + notes/severity-1.cpp \ + notes/verses.cpp \ + notes/bulk.cpp \ + notes/edit.cpp \ + notes/index.cpp \ + notes/severity-n.cpp \ + trash/handler.cpp \ + help/index.cpp \ + confirm/worker.cpp \ + email/index.cpp \ + email/send.cpp \ + email/receive.cpp \ + user/notifications.cpp \ + user/account.cpp \ + user/logic.cpp \ + manage/index.cpp \ + manage/users.cpp \ + manage/accounts.cpp \ + manage/exports.cpp \ + manage/hyphenation.cpp \ + manage/hyphenate.cpp \ + manage/write.cpp \ + manage/privileges.cpp \ + system/index.cpp \ + system/logic.cpp \ + collaboration/index.cpp \ + collaboration/link.cpp \ + collaboration/settings.cpp \ + search/rebibles.cpp \ + search/renotes.cpp \ + access/user.cpp \ + access/bible.cpp \ + access/logic.cpp \ + dialog/entry.cpp \ + dialog/list.cpp \ + dialog/list2.cpp \ + dialog/yes.cpp \ + dialog/color.cpp \ + dialog/books.cpp \ + dialog/upload.cpp \ + fonts/logic.cpp \ + versification/index.cpp \ + versification/system.cpp \ + versification/logic.cpp \ + book/create.cpp \ + compare/index.cpp \ + compare/compare.cpp \ + jobs/index.cpp \ + redirect/index.cpp \ + editone2/index.cpp \ + editone2/load.cpp \ + editone2/save.cpp \ + editone2/verse.cpp \ + editone2/logic.cpp \ + editone2/update.cpp \ + navigation/passage.cpp \ + navigation/update.cpp \ + navigation/poll.cpp \ + navigation/paratext.cpp \ + ipc/focus.cpp \ + ipc/notes.cpp \ + checksum/logic.cpp \ + editusfm/focus.cpp \ + editusfm/index.cpp \ + editusfm/load.cpp \ + editusfm/offset.cpp \ + editusfm/save.cpp \ + editor/styles.cpp \ + editor/html2usfm.cpp \ + editor/usfm2html.cpp \ + editor/select.cpp \ + editor/html2format.cpp \ + editor/id.cpp \ + editor/style.cpp \ + edit/edit.cpp \ + edit/id.cpp \ + edit/index.cpp \ + edit/load.cpp \ + edit/save.cpp \ + edit/styles.cpp \ + edit/logic.cpp \ + edit/preview.cpp \ + edit/position.cpp \ + edit/navigate.cpp \ + edit/update.cpp \ + search/all.cpp \ + search/index.cpp \ + search/replace.cpp \ + search/getids.cpp \ + search/replacepre.cpp \ + search/replacego.cpp \ + search/search2.cpp \ + search/replace2.cpp \ + search/replacepre2.cpp \ + search/getids2.cpp \ + search/replacego2.cpp \ + search/similar.cpp \ + search/strongs.cpp \ + search/strong.cpp \ + search/originals.cpp \ + tmp/tmp.cpp \ + workspace/index.cpp \ + workspace/logic.cpp \ + workspace/settings.cpp \ + workspace/organize.cpp \ + sendreceive/logic.cpp \ + sendreceive/index.cpp \ + sendreceive/sendreceive.cpp \ + sendreceive/settings.cpp \ + sendreceive/bibles.cpp \ + sendreceive/notes.cpp \ + sendreceive/changes.cpp \ + sendreceive/files.cpp \ + sendreceive/resources.cpp \ + demo/logic.cpp \ + client/index.cpp \ + client/logic.cpp \ + sync/logic.cpp \ + sync/setup.cpp \ + sync/settings.cpp \ + sync/bibles.cpp \ + sync/usfmresources.cpp \ + sync/notes.cpp \ + sync/changes.cpp \ + sync/files.cpp \ + sync/resources.cpp \ + sync/mail.cpp \ + resource/index.cpp \ + resource/organize.cpp \ + resource/logic.cpp \ + resource/get.cpp \ + resource/external.cpp \ + resource/bb2resource.cpp \ + resource/convert2resource.cpp \ + resource/convert2bible.cpp \ + resource/manage.cpp \ + resource/print.cpp \ + resource/download.cpp \ + resource/images.cpp \ + resource/image.cpp \ + resource/img.cpp \ + resource/imagefetch.cpp \ + resource/sword.cpp \ + resource/select.cpp \ + resource/cache.cpp \ + resource/user9edit.cpp \ + resource/user1edit.cpp \ + resource/user9view.cpp \ + resource/user1view.cpp \ + resource/bbgateway.cpp \ + resource/studylight.cpp \ + resource/unload.cpp \ + jsonxx/jsonxx.cpp \ + mapping/index.cpp \ + mapping/map.cpp \ + statistics/statistics.cpp \ + changes/change.cpp \ + changes/changes.cpp \ + changes/logic.cpp \ + changes/manage.cpp \ + changes/modifications.cpp \ + changes/statistics.cpp \ + sprint/burndown.cpp \ + sprint/index.cpp \ + checks/run.cpp \ + checks/headers.cpp \ + checks/index.cpp \ + checks/logic.cpp \ + checks/sentences.cpp \ + checks/settings.cpp \ + checks/settingspatterns.cpp \ + checks/settingssentences.cpp \ + checks/space.cpp \ + checks/suppress.cpp \ + checks/usfm.cpp \ + checks/verses.cpp \ + checks/versification.cpp \ + checks/pairs.cpp \ + checks/settingspairs.cpp \ + checks/french.cpp \ + consistency/index.cpp \ + consistency/input.cpp \ + consistency/logic.cpp \ + consistency/poll.cpp \ + export/esword.cpp \ + export/html.cpp \ + export/index.cpp \ + export/info.cpp \ + export/logic.cpp \ + export/odt.cpp \ + export/onlinebible.cpp \ + export/textusfm.cpp \ + export/usfm.cpp \ + export/web.cpp \ + export/bibledropbox.cpp \ + webbb/search.cpp \ + developer/index.cpp \ + developer/logic.cpp \ + paratext/logic.cpp \ + paratext/index.cpp \ + personalize/index.cpp \ + lexicon/logic.cpp \ + lexicon/definition.cpp \ + sources/etcbc4.cpp \ + sources/kjv.cpp \ + sources/morphhb.cpp \ + sources/morphgnt.cpp \ + sources/hebrewlexicon.cpp \ + sources/oshb.cpp \ + sword/logic.cpp \ + pugixml/pugixml.cpp \ + pugixml/utils.cpp \ + public/index.cpp \ + public/logic.cpp \ + public/login.cpp \ + public/chapter.cpp \ + public/notes.cpp \ + public/new.cpp \ + public/create.cpp \ + public/note.cpp \ + public/comment.cpp \ + utf8proc/utf8proc.c \ + search/logic.cpp \ + mbedtls/aes.c \ + mbedtls/arc4.c \ + mbedtls/asn1parse.c \ + mbedtls/asn1write.c \ + mbedtls/base64.c \ + mbedtls/bignum.c \ + mbedtls/blowfish.c \ + mbedtls/camellia.c \ + mbedtls/ccm.c \ + mbedtls/certs.c \ + mbedtls/chacha20.c \ + mbedtls/chachapoly.c \ + mbedtls/cipher.c \ + mbedtls/cipher_wrap.c \ + mbedtls/ctr_drbg.c \ + mbedtls/debug.c \ + mbedtls/des.c \ + mbedtls/dhm.c \ + mbedtls/ecdh.c \ + mbedtls/ecdsa.c \ + mbedtls/ecp.c \ + mbedtls/ecp_curves.c \ + mbedtls/entropy.c \ + mbedtls/entropy_poll.c \ + mbedtls/error.c \ + mbedtls/gcm.c \ + mbedtls/hmac_drbg.c \ + mbedtls/md.c \ + mbedtls/md5.c \ + mbedtls/md_wrap.c \ + mbedtls/net_sockets.c \ + mbedtls/oid.c \ + mbedtls/pem.c \ + mbedtls/pk.c \ + mbedtls/pk_wrap.c \ + mbedtls/pkcs12.c \ + mbedtls/pkcs5.c \ + mbedtls/pkparse.c \ + mbedtls/pkwrite.c \ + mbedtls/platform_util.c \ + mbedtls/platform.c \ + mbedtls/poly1305.c \ + mbedtls/ripemd160.c \ + mbedtls/rsa.c \ + mbedtls/rsa_internal.c \ + mbedtls/sha1.c \ + mbedtls/sha256.c \ + mbedtls/sha512.c \ + mbedtls/ssl_cache.c \ + mbedtls/ssl_ciphersuites.c \ + mbedtls/ssl_cli.c \ + mbedtls/ssl_cookie.c \ + mbedtls/ssl_srv.c \ + mbedtls/ssl_ticket.c \ + mbedtls/ssl_tls.c \ + mbedtls/threading.c \ + mbedtls/timing.c \ + mbedtls/version.c \ + mbedtls/version_features.c \ + mbedtls/x509.c \ + mbedtls/x509_create.c \ + mbedtls/x509_crl.c \ + mbedtls/x509_crt.c \ + mbedtls/x509_csr.c \ + mbedtls/x509write_crt.c \ + mbedtls/x509write_csr.c \ + mbedtls/xtea.c \ + related/logic.cpp \ + sqlite/sqlite3.c \ + ldap/logic.cpp \ + quill/logic.cpp \ + rss/logic.cpp \ + rss/feed.cpp \ + microtar/microtar.c \ + miniz/miniz.c \ + nmt/index.cpp \ + nmt/logic.cpp \ + tbsx/text.cpp \ + read/index.cpp \ + read/load.cpp \ + read/verse.cpp \ + resource/divider.cpp \ + session/confirm.cpp \ + sources/abbott-smith.cpp \ + database/abbottsmith.cpp \ + resource/comparative9edit.cpp \ + resource/comparative1edit.cpp \ + resource/translated9edit.cpp \ + resource/translated1edit.cpp \ + developer/delay.cpp \ + images/index.cpp \ + images/view.cpp \ + images/fetch.cpp \ + images/logic.cpp \ + database/bibleimages.cpp \ + filter/image.cpp \ + mimetic098/header.cxx \ + mimetic098/contentid.cxx \ + mimetic098/contenttransferencoding.cxx \ + mimetic098/contentdisposition.cxx \ + mimetic098/contentdescription.cxx \ + mimetic098/mimeversion.cxx \ + mimetic098/contenttype.cxx \ + mimetic098/version.cxx \ + mimetic098/fieldparam.cxx \ + mimetic098/mimeentity.cxx \ + mimetic098/strutils.cxx \ + mimetic098/body.cxx \ + mimetic098/utils.cxx \ + mimetic098/rfc822/field.cxx \ + mimetic098/rfc822/header.cxx \ + mimetic098/rfc822/message.cxx \ + mimetic098/rfc822/addresslist.cxx \ + mimetic098/rfc822/fieldvalue.cxx \ + mimetic098/rfc822/mailbox.cxx \ + mimetic098/rfc822/messageid.cxx \ + mimetic098/rfc822/datetime.cxx \ + mimetic098/rfc822/group.cxx \ + mimetic098/rfc822/mailboxlist.cxx \ + mimetic098/rfc822/address.cxx \ + mimetic098/os/utils.cxx \ + mimetic098/os/file_iterator.cxx \ + mimetic098/os/mmfile.cxx \ + mimetic098/codec/base64.cxx \ + system/googletranslate.cpp \ + filter/google.cpp \ + i18n/logic.cpp \ + tidy/access.c \ + tidy/alloc.c \ + tidy/attrdict.c \ + tidy/attrs.c \ + tidy/buffio.c \ + tidy/charsets.c \ + tidy/clean.c \ + tidy/config.c \ + tidy/entities.c \ + tidy/fileio.c \ + tidy/gdoc.c \ + tidy/istack.c \ + tidy/language.c \ + tidy/lexer.c \ + tidy/mappedio.c \ + tidy/message.c \ + tidy/messageobj.c \ + tidy/parser.c \ + tidy/pprint.c \ + tidy/sprtf.c \ + tidy/streamio.c \ + tidy/tagask.c \ + tidy/tags.c \ + tidy/tidylib.c \ + tidy/tmbstr.c \ + tidy/utf8.c + +server_SOURCES = executable/bibledit.cpp +server_LDADD = libbibledit.a +unittest_SOURCES = \ + unittests/unittest.cpp \ + unittests/utilities.cpp \ + unittests/sqlite.cpp \ + unittests/session.cpp \ + unittests/folders.cpp \ + unittests/flate.cpp \ + unittests/checksum.cpp \ + unittests/bibles.cpp \ + unittests/html2usfm.cpp \ + unittests/usfm2html.cpp \ + unittests/usfm2html2usfm.cpp \ + unittests/workspaces.cpp \ + unittests/client.cpp \ + unittests/sentences.cpp \ + unittests/versification.cpp \ + unittests/usfm.cpp \ + unittests/verses.cpp \ + unittests/pairs.cpp \ + unittests/paratext.cpp \ + unittests/hyphenate.cpp \ + unittests/search.cpp \ + unittests/json.cpp \ + unittests/related.cpp \ + unittests/editone.cpp \ + unittests/http.cpp \ + unittests/memory.cpp \ + unittests/tasks.cpp \ + unittests/biblegateway.cpp \ + unittests/rss.cpp \ + unittests/space.cpp \ + unittests/roles.cpp \ + unittests/md5.cpp \ + unittests/string.cpp \ + unittests/users.cpp \ + unittests/date.cpp \ + unittests/export.cpp \ + unittests/html.cpp \ + unittests/archive.cpp \ + unittests/odf.cpp \ + unittests/text.cpp \ + unittests/url.cpp \ + unittests/passage.cpp \ + unittests/styles.cpp \ + unittests/diff.cpp \ + unittests/git.cpp \ + unittests/ipc.cpp \ + unittests/shell.cpp \ + unittests/ldap.cpp \ + unittests/dev.cpp \ + unittests/sample.cpp \ + unittests/config.cpp \ + unittests/log.cpp \ + unittests/books.cpp \ + unittests/check.cpp \ + unittests/localization.cpp \ + unittests/confirm.cpp \ + unittests/jobs.cpp \ + unittests/kjv.cpp \ + unittests/oshb.cpp \ + unittests/sblgnt.cpp \ + unittests/sprint.cpp \ + unittests/mail.cpp \ + unittests/navigation.cpp \ + unittests/resources.cpp \ + unittests/notes.cpp \ + unittests/modifications.cpp \ + unittests/volatile.cpp \ + unittests/state.cpp \ + unittests/strong.cpp \ + unittests/morphgnt.cpp \ + unittests/etcbc4.cpp \ + unittests/lexicon.cpp \ + unittests/cache.cpp \ + unittests/login.cpp \ + unittests/privileges.cpp \ + unittests/statistics.cpp \ + unittests/webview.cpp \ + unittests/javascript.cpp \ + unittests/french.cpp \ + unittests/merge.cpp \ + unittests/nmt.cpp \ + unittests/html2format.cpp \ + unittests/studylight.cpp \ + unittests/gbs.cpp \ + unittests/bibleimages.cpp \ + unittests/image.cpp \ + unittests/easyenglishbible.cpp + +unittest_LDADD = libbibledit.a +generate_SOURCES = \ + executable/generate.cpp \ + sources/styles.cpp + +generate_LDADD = libbibledit.a +AM_CFLAGS = -g $(OPENSSL_CFLAGS) $(am__append_1) $(am__append_5) +AM_CXXFLAGS = -fno-var-tracking -g $(am__append_2) $(am__append_3) \ + $(CURL_CFLAGS) $(OPENSSL_CFLAGS) $(GTK_CFLAGS) \ + $(WEBKIT2GTK_CFLAGS) $(ICU_CFLAGS) $(XML2_CFLAGS) \ + $(am__append_4) +# LIBS += $(TIDY_LIBS) + +# The core library compiles and embeds the mbedtls library. +# On Debian this gives a lintian error: +# E: bibledit: embedded-library usr/bin/bibledit: mbedtls +# Solve this on Debian by omitting that library from the core, +# and by linking to the mbed TLS library provided by the system. +# For other platforms, the library remains in the core. +# debian LIBS += -lmbedtls -lmbedcrypto -lmbedx509 +EXTRA_DIST = a* bb bibledit bibles book bootstrap c* d* D* e* f* g* h* i* j* l* m* n* o* p* q* r* s* t* u* v* w* +CLEANFILES = bibledit*.gz *~ +man_MANS = man/bibledit.1 man/bibledit-cloud.1 +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .cxx .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +library/$(am__dirstamp): + @$(MKDIR_P) library + @: > library/$(am__dirstamp) +library/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) library/$(DEPDIR) + @: > library/$(DEPDIR)/$(am__dirstamp) +library/bibledit.$(OBJEXT): library/$(am__dirstamp) \ + library/$(DEPDIR)/$(am__dirstamp) +library/locks.$(OBJEXT): library/$(am__dirstamp) \ + library/$(DEPDIR)/$(am__dirstamp) +webserver/$(am__dirstamp): + @$(MKDIR_P) webserver + @: > webserver/$(am__dirstamp) +webserver/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) webserver/$(DEPDIR) + @: > webserver/$(DEPDIR)/$(am__dirstamp) +webserver/webserver.$(OBJEXT): webserver/$(am__dirstamp) \ + webserver/$(DEPDIR)/$(am__dirstamp) +webserver/http.$(OBJEXT): webserver/$(am__dirstamp) \ + webserver/$(DEPDIR)/$(am__dirstamp) +webserver/request.$(OBJEXT): webserver/$(am__dirstamp) \ + webserver/$(DEPDIR)/$(am__dirstamp) +bootstrap/$(am__dirstamp): + @$(MKDIR_P) bootstrap + @: > bootstrap/$(am__dirstamp) +bootstrap/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) bootstrap/$(DEPDIR) + @: > bootstrap/$(DEPDIR)/$(am__dirstamp) +bootstrap/bootstrap.$(OBJEXT): bootstrap/$(am__dirstamp) \ + bootstrap/$(DEPDIR)/$(am__dirstamp) +filter/$(am__dirstamp): + @$(MKDIR_P) filter + @: > filter/$(am__dirstamp) +filter/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) filter/$(DEPDIR) + @: > filter/$(DEPDIR)/$(am__dirstamp) +filter/url.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/string.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/roles.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/md5.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/usfm.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/archive.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/text.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/passage.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/css.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/git.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/html.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/diff.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/shell.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/merge.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/date.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/memory.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/webview.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/mail.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +filter/note.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +flate/$(am__dirstamp): + @$(MKDIR_P) flate + @: > flate/$(am__dirstamp) +flate/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) flate/$(DEPDIR) + @: > flate/$(DEPDIR)/$(am__dirstamp) +flate/flate.$(OBJEXT): flate/$(am__dirstamp) \ + flate/$(DEPDIR)/$(am__dirstamp) +assets/$(am__dirstamp): + @$(MKDIR_P) assets + @: > assets/$(am__dirstamp) +assets/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) assets/$(DEPDIR) + @: > assets/$(DEPDIR)/$(am__dirstamp) +assets/view.$(OBJEXT): assets/$(am__dirstamp) \ + assets/$(DEPDIR)/$(am__dirstamp) +assets/page.$(OBJEXT): assets/$(am__dirstamp) \ + assets/$(DEPDIR)/$(am__dirstamp) +assets/header.$(OBJEXT): assets/$(am__dirstamp) \ + assets/$(DEPDIR)/$(am__dirstamp) +assets/external.$(OBJEXT): assets/$(am__dirstamp) \ + assets/$(DEPDIR)/$(am__dirstamp) +index/$(am__dirstamp): + @$(MKDIR_P) index + @: > index/$(am__dirstamp) +index/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) index/$(DEPDIR) + @: > index/$(DEPDIR)/$(am__dirstamp) +index/index.$(OBJEXT): index/$(am__dirstamp) \ + index/$(DEPDIR)/$(am__dirstamp) +index/listing.$(OBJEXT): index/$(am__dirstamp) \ + index/$(DEPDIR)/$(am__dirstamp) +config/$(am__dirstamp): + @$(MKDIR_P) config + @: > config/$(am__dirstamp) +config/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) config/$(DEPDIR) + @: > config/$(DEPDIR)/$(am__dirstamp) +config/globals.$(OBJEXT): config/$(am__dirstamp) \ + config/$(DEPDIR)/$(am__dirstamp) +menu/$(am__dirstamp): + @$(MKDIR_P) menu + @: > menu/$(am__dirstamp) +menu/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) menu/$(DEPDIR) + @: > menu/$(DEPDIR)/$(am__dirstamp) +menu/logic.$(OBJEXT): menu/$(am__dirstamp) \ + menu/$(DEPDIR)/$(am__dirstamp) +menu/index.$(OBJEXT): menu/$(am__dirstamp) \ + menu/$(DEPDIR)/$(am__dirstamp) +locale/$(am__dirstamp): + @$(MKDIR_P) locale + @: > locale/$(am__dirstamp) +locale/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) locale/$(DEPDIR) + @: > locale/$(DEPDIR)/$(am__dirstamp) +locale/translate.$(OBJEXT): locale/$(am__dirstamp) \ + locale/$(DEPDIR)/$(am__dirstamp) +locale/logic.$(OBJEXT): locale/$(am__dirstamp) \ + locale/$(DEPDIR)/$(am__dirstamp) +database/config/$(am__dirstamp): + @$(MKDIR_P) database/config + @: > database/config/$(am__dirstamp) +database/config/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) database/config/$(DEPDIR) + @: > database/config/$(DEPDIR)/$(am__dirstamp) +database/config/general.$(OBJEXT): database/config/$(am__dirstamp) \ + database/config/$(DEPDIR)/$(am__dirstamp) +database/config/bible.$(OBJEXT): database/config/$(am__dirstamp) \ + database/config/$(DEPDIR)/$(am__dirstamp) +database/config/user.$(OBJEXT): database/config/$(am__dirstamp) \ + database/config/$(DEPDIR)/$(am__dirstamp) +database/$(am__dirstamp): + @$(MKDIR_P) database + @: > database/$(am__dirstamp) +database/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) database/$(DEPDIR) + @: > database/$(DEPDIR)/$(am__dirstamp) +database/users.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/logs.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/sqlite.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/styles.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/bibles.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/books.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/bibleactions.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/check.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/localization.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/confirm.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/ipc.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/jobs.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/kjv.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/logic.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/oshb.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/sblgnt.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/sprint.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/mail.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/navigation.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/usfmresources.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/mappings.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/noteactions.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/versifications.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/modifications.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/notes.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/volatile.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/maintenance.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/imageresources.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/state.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/noteassignment.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/strong.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/morphgnt.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/etcbc4.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/hebrewlexicon.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/cache.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/login.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/privileges.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/git.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/userresources.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/statistics.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +database/sample.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +session/$(am__dirstamp): + @$(MKDIR_P) session + @: > session/$(am__dirstamp) +session/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) session/$(DEPDIR) + @: > session/$(DEPDIR)/$(am__dirstamp) +session/logic.$(OBJEXT): session/$(am__dirstamp) \ + session/$(DEPDIR)/$(am__dirstamp) +session/login.$(OBJEXT): session/$(am__dirstamp) \ + session/$(DEPDIR)/$(am__dirstamp) +session/logout.$(OBJEXT): session/$(am__dirstamp) \ + session/$(DEPDIR)/$(am__dirstamp) +session/password.$(OBJEXT): session/$(am__dirstamp) \ + session/$(DEPDIR)/$(am__dirstamp) +session/signup.$(OBJEXT): session/$(am__dirstamp) \ + session/$(DEPDIR)/$(am__dirstamp) +session/switch.$(OBJEXT): session/$(am__dirstamp) \ + session/$(DEPDIR)/$(am__dirstamp) +parsewebdata/$(am__dirstamp): + @$(MKDIR_P) parsewebdata + @: > parsewebdata/$(am__dirstamp) +parsewebdata/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) parsewebdata/$(DEPDIR) + @: > parsewebdata/$(DEPDIR)/$(am__dirstamp) +parsewebdata/ParseMultipartFormData.$(OBJEXT): \ + parsewebdata/$(am__dirstamp) \ + parsewebdata/$(DEPDIR)/$(am__dirstamp) +parsewebdata/ParseWebData.$(OBJEXT): parsewebdata/$(am__dirstamp) \ + parsewebdata/$(DEPDIR)/$(am__dirstamp) +setup/$(am__dirstamp): + @$(MKDIR_P) setup + @: > setup/$(am__dirstamp) +setup/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) setup/$(DEPDIR) + @: > setup/$(DEPDIR)/$(am__dirstamp) +setup/index.$(OBJEXT): setup/$(am__dirstamp) \ + setup/$(DEPDIR)/$(am__dirstamp) +setup/logic.$(OBJEXT): setup/$(am__dirstamp) \ + setup/$(DEPDIR)/$(am__dirstamp) +journal/$(am__dirstamp): + @$(MKDIR_P) journal + @: > journal/$(am__dirstamp) +journal/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) journal/$(DEPDIR) + @: > journal/$(DEPDIR)/$(am__dirstamp) +journal/index.$(OBJEXT): journal/$(am__dirstamp) \ + journal/$(DEPDIR)/$(am__dirstamp) +journal/logic.$(OBJEXT): journal/$(am__dirstamp) \ + journal/$(DEPDIR)/$(am__dirstamp) +styles/$(am__dirstamp): + @$(MKDIR_P) styles + @: > styles/$(am__dirstamp) +styles/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) styles/$(DEPDIR) + @: > styles/$(DEPDIR)/$(am__dirstamp) +styles/logic.$(OBJEXT): styles/$(am__dirstamp) \ + styles/$(DEPDIR)/$(am__dirstamp) +styles/indexm.$(OBJEXT): styles/$(am__dirstamp) \ + styles/$(DEPDIR)/$(am__dirstamp) +styles/sheetm.$(OBJEXT): styles/$(am__dirstamp) \ + styles/$(DEPDIR)/$(am__dirstamp) +styles/view.$(OBJEXT): styles/$(am__dirstamp) \ + styles/$(DEPDIR)/$(am__dirstamp) +styles/css.$(OBJEXT): styles/$(am__dirstamp) \ + styles/$(DEPDIR)/$(am__dirstamp) +styles/sheets.$(OBJEXT): styles/$(am__dirstamp) \ + styles/$(DEPDIR)/$(am__dirstamp) +text/$(am__dirstamp): + @$(MKDIR_P) text + @: > text/$(am__dirstamp) +text/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) text/$(DEPDIR) + @: > text/$(DEPDIR)/$(am__dirstamp) +text/text.$(OBJEXT): text/$(am__dirstamp) \ + text/$(DEPDIR)/$(am__dirstamp) +esword/$(am__dirstamp): + @$(MKDIR_P) esword + @: > esword/$(am__dirstamp) +esword/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) esword/$(DEPDIR) + @: > esword/$(DEPDIR)/$(am__dirstamp) +esword/text.$(OBJEXT): esword/$(am__dirstamp) \ + esword/$(DEPDIR)/$(am__dirstamp) +olb/$(am__dirstamp): + @$(MKDIR_P) olb + @: > olb/$(am__dirstamp) +olb/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) olb/$(DEPDIR) + @: > olb/$(DEPDIR)/$(am__dirstamp) +olb/text.$(OBJEXT): olb/$(am__dirstamp) olb/$(DEPDIR)/$(am__dirstamp) +html/$(am__dirstamp): + @$(MKDIR_P) html + @: > html/$(am__dirstamp) +html/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) html/$(DEPDIR) + @: > html/$(DEPDIR)/$(am__dirstamp) +html/text.$(OBJEXT): html/$(am__dirstamp) \ + html/$(DEPDIR)/$(am__dirstamp) +html/header.$(OBJEXT): html/$(am__dirstamp) \ + html/$(DEPDIR)/$(am__dirstamp) +odf/$(am__dirstamp): + @$(MKDIR_P) odf + @: > odf/$(am__dirstamp) +odf/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) odf/$(DEPDIR) + @: > odf/$(DEPDIR)/$(am__dirstamp) +odf/text.$(OBJEXT): odf/$(am__dirstamp) odf/$(DEPDIR)/$(am__dirstamp) +timer/$(am__dirstamp): + @$(MKDIR_P) timer + @: > timer/$(am__dirstamp) +timer/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) timer/$(DEPDIR) + @: > timer/$(DEPDIR)/$(am__dirstamp) +timer/index.$(OBJEXT): timer/$(am__dirstamp) \ + timer/$(DEPDIR)/$(am__dirstamp) +tasks/$(am__dirstamp): + @$(MKDIR_P) tasks + @: > tasks/$(am__dirstamp) +tasks/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) tasks/$(DEPDIR) + @: > tasks/$(DEPDIR)/$(am__dirstamp) +tasks/logic.$(OBJEXT): tasks/$(am__dirstamp) \ + tasks/$(DEPDIR)/$(am__dirstamp) +tasks/run.$(OBJEXT): tasks/$(am__dirstamp) \ + tasks/$(DEPDIR)/$(am__dirstamp) +config/logic.$(OBJEXT): config/$(am__dirstamp) \ + config/$(DEPDIR)/$(am__dirstamp) +bb/$(am__dirstamp): + @$(MKDIR_P) bb + @: > bb/$(am__dirstamp) +bb/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) bb/$(DEPDIR) + @: > bb/$(DEPDIR)/$(am__dirstamp) +bb/logic.$(OBJEXT): bb/$(am__dirstamp) bb/$(DEPDIR)/$(am__dirstamp) +bb/manage.$(OBJEXT): bb/$(am__dirstamp) bb/$(DEPDIR)/$(am__dirstamp) +bb/settings.$(OBJEXT): bb/$(am__dirstamp) bb/$(DEPDIR)/$(am__dirstamp) +bb/book.$(OBJEXT): bb/$(am__dirstamp) bb/$(DEPDIR)/$(am__dirstamp) +bb/chapter.$(OBJEXT): bb/$(am__dirstamp) bb/$(DEPDIR)/$(am__dirstamp) +bb/import_run.$(OBJEXT): bb/$(am__dirstamp) \ + bb/$(DEPDIR)/$(am__dirstamp) +bb/import.$(OBJEXT): bb/$(am__dirstamp) bb/$(DEPDIR)/$(am__dirstamp) +bb/order.$(OBJEXT): bb/$(am__dirstamp) bb/$(DEPDIR)/$(am__dirstamp) +bb/css.$(OBJEXT): bb/$(am__dirstamp) bb/$(DEPDIR)/$(am__dirstamp) +notes/$(am__dirstamp): + @$(MKDIR_P) notes + @: > notes/$(am__dirstamp) +notes/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) notes/$(DEPDIR) + @: > notes/$(DEPDIR)/$(am__dirstamp) +notes/logic.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/actions.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/note.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/status-1.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/assign-1.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/notes.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/status-n.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/assign-n.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/click.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/poll.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/summary.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/bb-1.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/comment.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/select.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/unassign-n.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/bb-n.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/create.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/severity-1.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/verses.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/bulk.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/edit.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/index.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +notes/severity-n.$(OBJEXT): notes/$(am__dirstamp) \ + notes/$(DEPDIR)/$(am__dirstamp) +trash/$(am__dirstamp): + @$(MKDIR_P) trash + @: > trash/$(am__dirstamp) +trash/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) trash/$(DEPDIR) + @: > trash/$(DEPDIR)/$(am__dirstamp) +trash/handler.$(OBJEXT): trash/$(am__dirstamp) \ + trash/$(DEPDIR)/$(am__dirstamp) +help/$(am__dirstamp): + @$(MKDIR_P) help + @: > help/$(am__dirstamp) +help/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) help/$(DEPDIR) + @: > help/$(DEPDIR)/$(am__dirstamp) +help/index.$(OBJEXT): help/$(am__dirstamp) \ + help/$(DEPDIR)/$(am__dirstamp) +confirm/$(am__dirstamp): + @$(MKDIR_P) confirm + @: > confirm/$(am__dirstamp) +confirm/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) confirm/$(DEPDIR) + @: > confirm/$(DEPDIR)/$(am__dirstamp) +confirm/worker.$(OBJEXT): confirm/$(am__dirstamp) \ + confirm/$(DEPDIR)/$(am__dirstamp) +email/$(am__dirstamp): + @$(MKDIR_P) email + @: > email/$(am__dirstamp) +email/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) email/$(DEPDIR) + @: > email/$(DEPDIR)/$(am__dirstamp) +email/index.$(OBJEXT): email/$(am__dirstamp) \ + email/$(DEPDIR)/$(am__dirstamp) +email/send.$(OBJEXT): email/$(am__dirstamp) \ + email/$(DEPDIR)/$(am__dirstamp) +email/receive.$(OBJEXT): email/$(am__dirstamp) \ + email/$(DEPDIR)/$(am__dirstamp) +user/$(am__dirstamp): + @$(MKDIR_P) user + @: > user/$(am__dirstamp) +user/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) user/$(DEPDIR) + @: > user/$(DEPDIR)/$(am__dirstamp) +user/notifications.$(OBJEXT): user/$(am__dirstamp) \ + user/$(DEPDIR)/$(am__dirstamp) +user/account.$(OBJEXT): user/$(am__dirstamp) \ + user/$(DEPDIR)/$(am__dirstamp) +user/logic.$(OBJEXT): user/$(am__dirstamp) \ + user/$(DEPDIR)/$(am__dirstamp) +manage/$(am__dirstamp): + @$(MKDIR_P) manage + @: > manage/$(am__dirstamp) +manage/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) manage/$(DEPDIR) + @: > manage/$(DEPDIR)/$(am__dirstamp) +manage/index.$(OBJEXT): manage/$(am__dirstamp) \ + manage/$(DEPDIR)/$(am__dirstamp) +manage/users.$(OBJEXT): manage/$(am__dirstamp) \ + manage/$(DEPDIR)/$(am__dirstamp) +manage/accounts.$(OBJEXT): manage/$(am__dirstamp) \ + manage/$(DEPDIR)/$(am__dirstamp) +manage/exports.$(OBJEXT): manage/$(am__dirstamp) \ + manage/$(DEPDIR)/$(am__dirstamp) +manage/hyphenation.$(OBJEXT): manage/$(am__dirstamp) \ + manage/$(DEPDIR)/$(am__dirstamp) +manage/hyphenate.$(OBJEXT): manage/$(am__dirstamp) \ + manage/$(DEPDIR)/$(am__dirstamp) +manage/write.$(OBJEXT): manage/$(am__dirstamp) \ + manage/$(DEPDIR)/$(am__dirstamp) +manage/privileges.$(OBJEXT): manage/$(am__dirstamp) \ + manage/$(DEPDIR)/$(am__dirstamp) +system/$(am__dirstamp): + @$(MKDIR_P) system + @: > system/$(am__dirstamp) +system/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) system/$(DEPDIR) + @: > system/$(DEPDIR)/$(am__dirstamp) +system/index.$(OBJEXT): system/$(am__dirstamp) \ + system/$(DEPDIR)/$(am__dirstamp) +system/logic.$(OBJEXT): system/$(am__dirstamp) \ + system/$(DEPDIR)/$(am__dirstamp) +collaboration/$(am__dirstamp): + @$(MKDIR_P) collaboration + @: > collaboration/$(am__dirstamp) +collaboration/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) collaboration/$(DEPDIR) + @: > collaboration/$(DEPDIR)/$(am__dirstamp) +collaboration/index.$(OBJEXT): collaboration/$(am__dirstamp) \ + collaboration/$(DEPDIR)/$(am__dirstamp) +collaboration/link.$(OBJEXT): collaboration/$(am__dirstamp) \ + collaboration/$(DEPDIR)/$(am__dirstamp) +collaboration/settings.$(OBJEXT): collaboration/$(am__dirstamp) \ + collaboration/$(DEPDIR)/$(am__dirstamp) +search/$(am__dirstamp): + @$(MKDIR_P) search + @: > search/$(am__dirstamp) +search/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) search/$(DEPDIR) + @: > search/$(DEPDIR)/$(am__dirstamp) +search/rebibles.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/renotes.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +access/$(am__dirstamp): + @$(MKDIR_P) access + @: > access/$(am__dirstamp) +access/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) access/$(DEPDIR) + @: > access/$(DEPDIR)/$(am__dirstamp) +access/user.$(OBJEXT): access/$(am__dirstamp) \ + access/$(DEPDIR)/$(am__dirstamp) +access/bible.$(OBJEXT): access/$(am__dirstamp) \ + access/$(DEPDIR)/$(am__dirstamp) +access/logic.$(OBJEXT): access/$(am__dirstamp) \ + access/$(DEPDIR)/$(am__dirstamp) +dialog/$(am__dirstamp): + @$(MKDIR_P) dialog + @: > dialog/$(am__dirstamp) +dialog/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) dialog/$(DEPDIR) + @: > dialog/$(DEPDIR)/$(am__dirstamp) +dialog/entry.$(OBJEXT): dialog/$(am__dirstamp) \ + dialog/$(DEPDIR)/$(am__dirstamp) +dialog/list.$(OBJEXT): dialog/$(am__dirstamp) \ + dialog/$(DEPDIR)/$(am__dirstamp) +dialog/list2.$(OBJEXT): dialog/$(am__dirstamp) \ + dialog/$(DEPDIR)/$(am__dirstamp) +dialog/yes.$(OBJEXT): dialog/$(am__dirstamp) \ + dialog/$(DEPDIR)/$(am__dirstamp) +dialog/color.$(OBJEXT): dialog/$(am__dirstamp) \ + dialog/$(DEPDIR)/$(am__dirstamp) +dialog/books.$(OBJEXT): dialog/$(am__dirstamp) \ + dialog/$(DEPDIR)/$(am__dirstamp) +dialog/upload.$(OBJEXT): dialog/$(am__dirstamp) \ + dialog/$(DEPDIR)/$(am__dirstamp) +fonts/$(am__dirstamp): + @$(MKDIR_P) fonts + @: > fonts/$(am__dirstamp) +fonts/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) fonts/$(DEPDIR) + @: > fonts/$(DEPDIR)/$(am__dirstamp) +fonts/logic.$(OBJEXT): fonts/$(am__dirstamp) \ + fonts/$(DEPDIR)/$(am__dirstamp) +versification/$(am__dirstamp): + @$(MKDIR_P) versification + @: > versification/$(am__dirstamp) +versification/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) versification/$(DEPDIR) + @: > versification/$(DEPDIR)/$(am__dirstamp) +versification/index.$(OBJEXT): versification/$(am__dirstamp) \ + versification/$(DEPDIR)/$(am__dirstamp) +versification/system.$(OBJEXT): versification/$(am__dirstamp) \ + versification/$(DEPDIR)/$(am__dirstamp) +versification/logic.$(OBJEXT): versification/$(am__dirstamp) \ + versification/$(DEPDIR)/$(am__dirstamp) +book/$(am__dirstamp): + @$(MKDIR_P) book + @: > book/$(am__dirstamp) +book/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) book/$(DEPDIR) + @: > book/$(DEPDIR)/$(am__dirstamp) +book/create.$(OBJEXT): book/$(am__dirstamp) \ + book/$(DEPDIR)/$(am__dirstamp) +compare/$(am__dirstamp): + @$(MKDIR_P) compare + @: > compare/$(am__dirstamp) +compare/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) compare/$(DEPDIR) + @: > compare/$(DEPDIR)/$(am__dirstamp) +compare/index.$(OBJEXT): compare/$(am__dirstamp) \ + compare/$(DEPDIR)/$(am__dirstamp) +compare/compare.$(OBJEXT): compare/$(am__dirstamp) \ + compare/$(DEPDIR)/$(am__dirstamp) +jobs/$(am__dirstamp): + @$(MKDIR_P) jobs + @: > jobs/$(am__dirstamp) +jobs/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) jobs/$(DEPDIR) + @: > jobs/$(DEPDIR)/$(am__dirstamp) +jobs/index.$(OBJEXT): jobs/$(am__dirstamp) \ + jobs/$(DEPDIR)/$(am__dirstamp) +redirect/$(am__dirstamp): + @$(MKDIR_P) redirect + @: > redirect/$(am__dirstamp) +redirect/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) redirect/$(DEPDIR) + @: > redirect/$(DEPDIR)/$(am__dirstamp) +redirect/index.$(OBJEXT): redirect/$(am__dirstamp) \ + redirect/$(DEPDIR)/$(am__dirstamp) +editone2/$(am__dirstamp): + @$(MKDIR_P) editone2 + @: > editone2/$(am__dirstamp) +editone2/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) editone2/$(DEPDIR) + @: > editone2/$(DEPDIR)/$(am__dirstamp) +editone2/index.$(OBJEXT): editone2/$(am__dirstamp) \ + editone2/$(DEPDIR)/$(am__dirstamp) +editone2/load.$(OBJEXT): editone2/$(am__dirstamp) \ + editone2/$(DEPDIR)/$(am__dirstamp) +editone2/save.$(OBJEXT): editone2/$(am__dirstamp) \ + editone2/$(DEPDIR)/$(am__dirstamp) +editone2/verse.$(OBJEXT): editone2/$(am__dirstamp) \ + editone2/$(DEPDIR)/$(am__dirstamp) +editone2/logic.$(OBJEXT): editone2/$(am__dirstamp) \ + editone2/$(DEPDIR)/$(am__dirstamp) +editone2/update.$(OBJEXT): editone2/$(am__dirstamp) \ + editone2/$(DEPDIR)/$(am__dirstamp) +navigation/$(am__dirstamp): + @$(MKDIR_P) navigation + @: > navigation/$(am__dirstamp) +navigation/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) navigation/$(DEPDIR) + @: > navigation/$(DEPDIR)/$(am__dirstamp) +navigation/passage.$(OBJEXT): navigation/$(am__dirstamp) \ + navigation/$(DEPDIR)/$(am__dirstamp) +navigation/update.$(OBJEXT): navigation/$(am__dirstamp) \ + navigation/$(DEPDIR)/$(am__dirstamp) +navigation/poll.$(OBJEXT): navigation/$(am__dirstamp) \ + navigation/$(DEPDIR)/$(am__dirstamp) +navigation/paratext.$(OBJEXT): navigation/$(am__dirstamp) \ + navigation/$(DEPDIR)/$(am__dirstamp) +ipc/$(am__dirstamp): + @$(MKDIR_P) ipc + @: > ipc/$(am__dirstamp) +ipc/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ipc/$(DEPDIR) + @: > ipc/$(DEPDIR)/$(am__dirstamp) +ipc/focus.$(OBJEXT): ipc/$(am__dirstamp) ipc/$(DEPDIR)/$(am__dirstamp) +ipc/notes.$(OBJEXT): ipc/$(am__dirstamp) ipc/$(DEPDIR)/$(am__dirstamp) +checksum/$(am__dirstamp): + @$(MKDIR_P) checksum + @: > checksum/$(am__dirstamp) +checksum/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) checksum/$(DEPDIR) + @: > checksum/$(DEPDIR)/$(am__dirstamp) +checksum/logic.$(OBJEXT): checksum/$(am__dirstamp) \ + checksum/$(DEPDIR)/$(am__dirstamp) +editusfm/$(am__dirstamp): + @$(MKDIR_P) editusfm + @: > editusfm/$(am__dirstamp) +editusfm/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) editusfm/$(DEPDIR) + @: > editusfm/$(DEPDIR)/$(am__dirstamp) +editusfm/focus.$(OBJEXT): editusfm/$(am__dirstamp) \ + editusfm/$(DEPDIR)/$(am__dirstamp) +editusfm/index.$(OBJEXT): editusfm/$(am__dirstamp) \ + editusfm/$(DEPDIR)/$(am__dirstamp) +editusfm/load.$(OBJEXT): editusfm/$(am__dirstamp) \ + editusfm/$(DEPDIR)/$(am__dirstamp) +editusfm/offset.$(OBJEXT): editusfm/$(am__dirstamp) \ + editusfm/$(DEPDIR)/$(am__dirstamp) +editusfm/save.$(OBJEXT): editusfm/$(am__dirstamp) \ + editusfm/$(DEPDIR)/$(am__dirstamp) +editor/$(am__dirstamp): + @$(MKDIR_P) editor + @: > editor/$(am__dirstamp) +editor/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) editor/$(DEPDIR) + @: > editor/$(DEPDIR)/$(am__dirstamp) +editor/styles.$(OBJEXT): editor/$(am__dirstamp) \ + editor/$(DEPDIR)/$(am__dirstamp) +editor/html2usfm.$(OBJEXT): editor/$(am__dirstamp) \ + editor/$(DEPDIR)/$(am__dirstamp) +editor/usfm2html.$(OBJEXT): editor/$(am__dirstamp) \ + editor/$(DEPDIR)/$(am__dirstamp) +editor/select.$(OBJEXT): editor/$(am__dirstamp) \ + editor/$(DEPDIR)/$(am__dirstamp) +editor/html2format.$(OBJEXT): editor/$(am__dirstamp) \ + editor/$(DEPDIR)/$(am__dirstamp) +editor/id.$(OBJEXT): editor/$(am__dirstamp) \ + editor/$(DEPDIR)/$(am__dirstamp) +editor/style.$(OBJEXT): editor/$(am__dirstamp) \ + editor/$(DEPDIR)/$(am__dirstamp) +edit/$(am__dirstamp): + @$(MKDIR_P) edit + @: > edit/$(am__dirstamp) +edit/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) edit/$(DEPDIR) + @: > edit/$(DEPDIR)/$(am__dirstamp) +edit/edit.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +edit/id.$(OBJEXT): edit/$(am__dirstamp) edit/$(DEPDIR)/$(am__dirstamp) +edit/index.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +edit/load.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +edit/save.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +edit/styles.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +edit/logic.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +edit/preview.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +edit/position.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +edit/navigate.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +edit/update.$(OBJEXT): edit/$(am__dirstamp) \ + edit/$(DEPDIR)/$(am__dirstamp) +search/all.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/index.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/replace.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/getids.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/replacepre.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/replacego.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/search2.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/replace2.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/replacepre2.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/getids2.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/replacego2.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/similar.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/strongs.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/strong.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +search/originals.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +tmp/$(am__dirstamp): + @$(MKDIR_P) tmp + @: > tmp/$(am__dirstamp) +tmp/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) tmp/$(DEPDIR) + @: > tmp/$(DEPDIR)/$(am__dirstamp) +tmp/tmp.$(OBJEXT): tmp/$(am__dirstamp) tmp/$(DEPDIR)/$(am__dirstamp) +workspace/$(am__dirstamp): + @$(MKDIR_P) workspace + @: > workspace/$(am__dirstamp) +workspace/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) workspace/$(DEPDIR) + @: > workspace/$(DEPDIR)/$(am__dirstamp) +workspace/index.$(OBJEXT): workspace/$(am__dirstamp) \ + workspace/$(DEPDIR)/$(am__dirstamp) +workspace/logic.$(OBJEXT): workspace/$(am__dirstamp) \ + workspace/$(DEPDIR)/$(am__dirstamp) +workspace/settings.$(OBJEXT): workspace/$(am__dirstamp) \ + workspace/$(DEPDIR)/$(am__dirstamp) +workspace/organize.$(OBJEXT): workspace/$(am__dirstamp) \ + workspace/$(DEPDIR)/$(am__dirstamp) +sendreceive/$(am__dirstamp): + @$(MKDIR_P) sendreceive + @: > sendreceive/$(am__dirstamp) +sendreceive/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) sendreceive/$(DEPDIR) + @: > sendreceive/$(DEPDIR)/$(am__dirstamp) +sendreceive/logic.$(OBJEXT): sendreceive/$(am__dirstamp) \ + sendreceive/$(DEPDIR)/$(am__dirstamp) +sendreceive/index.$(OBJEXT): sendreceive/$(am__dirstamp) \ + sendreceive/$(DEPDIR)/$(am__dirstamp) +sendreceive/sendreceive.$(OBJEXT): sendreceive/$(am__dirstamp) \ + sendreceive/$(DEPDIR)/$(am__dirstamp) +sendreceive/settings.$(OBJEXT): sendreceive/$(am__dirstamp) \ + sendreceive/$(DEPDIR)/$(am__dirstamp) +sendreceive/bibles.$(OBJEXT): sendreceive/$(am__dirstamp) \ + sendreceive/$(DEPDIR)/$(am__dirstamp) +sendreceive/notes.$(OBJEXT): sendreceive/$(am__dirstamp) \ + sendreceive/$(DEPDIR)/$(am__dirstamp) +sendreceive/changes.$(OBJEXT): sendreceive/$(am__dirstamp) \ + sendreceive/$(DEPDIR)/$(am__dirstamp) +sendreceive/files.$(OBJEXT): sendreceive/$(am__dirstamp) \ + sendreceive/$(DEPDIR)/$(am__dirstamp) +sendreceive/resources.$(OBJEXT): sendreceive/$(am__dirstamp) \ + sendreceive/$(DEPDIR)/$(am__dirstamp) +demo/$(am__dirstamp): + @$(MKDIR_P) demo + @: > demo/$(am__dirstamp) +demo/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) demo/$(DEPDIR) + @: > demo/$(DEPDIR)/$(am__dirstamp) +demo/logic.$(OBJEXT): demo/$(am__dirstamp) \ + demo/$(DEPDIR)/$(am__dirstamp) +client/$(am__dirstamp): + @$(MKDIR_P) client + @: > client/$(am__dirstamp) +client/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) client/$(DEPDIR) + @: > client/$(DEPDIR)/$(am__dirstamp) +client/index.$(OBJEXT): client/$(am__dirstamp) \ + client/$(DEPDIR)/$(am__dirstamp) +client/logic.$(OBJEXT): client/$(am__dirstamp) \ + client/$(DEPDIR)/$(am__dirstamp) +sync/$(am__dirstamp): + @$(MKDIR_P) sync + @: > sync/$(am__dirstamp) +sync/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) sync/$(DEPDIR) + @: > sync/$(DEPDIR)/$(am__dirstamp) +sync/logic.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +sync/setup.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +sync/settings.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +sync/bibles.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +sync/usfmresources.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +sync/notes.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +sync/changes.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +sync/files.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +sync/resources.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +sync/mail.$(OBJEXT): sync/$(am__dirstamp) \ + sync/$(DEPDIR)/$(am__dirstamp) +resource/$(am__dirstamp): + @$(MKDIR_P) resource + @: > resource/$(am__dirstamp) +resource/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) resource/$(DEPDIR) + @: > resource/$(DEPDIR)/$(am__dirstamp) +resource/index.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/organize.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/logic.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/get.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/external.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/bb2resource.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/convert2resource.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/convert2bible.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/manage.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/print.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/download.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/images.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/image.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/img.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/imagefetch.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/sword.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/select.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/cache.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/user9edit.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/user1edit.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/user9view.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/user1view.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/bbgateway.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/studylight.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/unload.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +jsonxx/$(am__dirstamp): + @$(MKDIR_P) jsonxx + @: > jsonxx/$(am__dirstamp) +jsonxx/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) jsonxx/$(DEPDIR) + @: > jsonxx/$(DEPDIR)/$(am__dirstamp) +jsonxx/jsonxx.$(OBJEXT): jsonxx/$(am__dirstamp) \ + jsonxx/$(DEPDIR)/$(am__dirstamp) +mapping/$(am__dirstamp): + @$(MKDIR_P) mapping + @: > mapping/$(am__dirstamp) +mapping/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) mapping/$(DEPDIR) + @: > mapping/$(DEPDIR)/$(am__dirstamp) +mapping/index.$(OBJEXT): mapping/$(am__dirstamp) \ + mapping/$(DEPDIR)/$(am__dirstamp) +mapping/map.$(OBJEXT): mapping/$(am__dirstamp) \ + mapping/$(DEPDIR)/$(am__dirstamp) +statistics/$(am__dirstamp): + @$(MKDIR_P) statistics + @: > statistics/$(am__dirstamp) +statistics/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) statistics/$(DEPDIR) + @: > statistics/$(DEPDIR)/$(am__dirstamp) +statistics/statistics.$(OBJEXT): statistics/$(am__dirstamp) \ + statistics/$(DEPDIR)/$(am__dirstamp) +changes/$(am__dirstamp): + @$(MKDIR_P) changes + @: > changes/$(am__dirstamp) +changes/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) changes/$(DEPDIR) + @: > changes/$(DEPDIR)/$(am__dirstamp) +changes/change.$(OBJEXT): changes/$(am__dirstamp) \ + changes/$(DEPDIR)/$(am__dirstamp) +changes/changes.$(OBJEXT): changes/$(am__dirstamp) \ + changes/$(DEPDIR)/$(am__dirstamp) +changes/logic.$(OBJEXT): changes/$(am__dirstamp) \ + changes/$(DEPDIR)/$(am__dirstamp) +changes/manage.$(OBJEXT): changes/$(am__dirstamp) \ + changes/$(DEPDIR)/$(am__dirstamp) +changes/modifications.$(OBJEXT): changes/$(am__dirstamp) \ + changes/$(DEPDIR)/$(am__dirstamp) +changes/statistics.$(OBJEXT): changes/$(am__dirstamp) \ + changes/$(DEPDIR)/$(am__dirstamp) +sprint/$(am__dirstamp): + @$(MKDIR_P) sprint + @: > sprint/$(am__dirstamp) +sprint/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) sprint/$(DEPDIR) + @: > sprint/$(DEPDIR)/$(am__dirstamp) +sprint/burndown.$(OBJEXT): sprint/$(am__dirstamp) \ + sprint/$(DEPDIR)/$(am__dirstamp) +sprint/index.$(OBJEXT): sprint/$(am__dirstamp) \ + sprint/$(DEPDIR)/$(am__dirstamp) +checks/$(am__dirstamp): + @$(MKDIR_P) checks + @: > checks/$(am__dirstamp) +checks/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) checks/$(DEPDIR) + @: > checks/$(DEPDIR)/$(am__dirstamp) +checks/run.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/headers.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/index.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/logic.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/sentences.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/settings.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/settingspatterns.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/settingssentences.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/space.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/suppress.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/usfm.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/verses.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/versification.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/pairs.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/settingspairs.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +checks/french.$(OBJEXT): checks/$(am__dirstamp) \ + checks/$(DEPDIR)/$(am__dirstamp) +consistency/$(am__dirstamp): + @$(MKDIR_P) consistency + @: > consistency/$(am__dirstamp) +consistency/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) consistency/$(DEPDIR) + @: > consistency/$(DEPDIR)/$(am__dirstamp) +consistency/index.$(OBJEXT): consistency/$(am__dirstamp) \ + consistency/$(DEPDIR)/$(am__dirstamp) +consistency/input.$(OBJEXT): consistency/$(am__dirstamp) \ + consistency/$(DEPDIR)/$(am__dirstamp) +consistency/logic.$(OBJEXT): consistency/$(am__dirstamp) \ + consistency/$(DEPDIR)/$(am__dirstamp) +consistency/poll.$(OBJEXT): consistency/$(am__dirstamp) \ + consistency/$(DEPDIR)/$(am__dirstamp) +export/$(am__dirstamp): + @$(MKDIR_P) export + @: > export/$(am__dirstamp) +export/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) export/$(DEPDIR) + @: > export/$(DEPDIR)/$(am__dirstamp) +export/esword.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/html.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/index.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/info.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/logic.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/odt.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/onlinebible.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/textusfm.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/usfm.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/web.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +export/bibledropbox.$(OBJEXT): export/$(am__dirstamp) \ + export/$(DEPDIR)/$(am__dirstamp) +webbb/$(am__dirstamp): + @$(MKDIR_P) webbb + @: > webbb/$(am__dirstamp) +webbb/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) webbb/$(DEPDIR) + @: > webbb/$(DEPDIR)/$(am__dirstamp) +webbb/search.$(OBJEXT): webbb/$(am__dirstamp) \ + webbb/$(DEPDIR)/$(am__dirstamp) +developer/$(am__dirstamp): + @$(MKDIR_P) developer + @: > developer/$(am__dirstamp) +developer/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) developer/$(DEPDIR) + @: > developer/$(DEPDIR)/$(am__dirstamp) +developer/index.$(OBJEXT): developer/$(am__dirstamp) \ + developer/$(DEPDIR)/$(am__dirstamp) +developer/logic.$(OBJEXT): developer/$(am__dirstamp) \ + developer/$(DEPDIR)/$(am__dirstamp) +paratext/$(am__dirstamp): + @$(MKDIR_P) paratext + @: > paratext/$(am__dirstamp) +paratext/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) paratext/$(DEPDIR) + @: > paratext/$(DEPDIR)/$(am__dirstamp) +paratext/logic.$(OBJEXT): paratext/$(am__dirstamp) \ + paratext/$(DEPDIR)/$(am__dirstamp) +paratext/index.$(OBJEXT): paratext/$(am__dirstamp) \ + paratext/$(DEPDIR)/$(am__dirstamp) +personalize/$(am__dirstamp): + @$(MKDIR_P) personalize + @: > personalize/$(am__dirstamp) +personalize/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) personalize/$(DEPDIR) + @: > personalize/$(DEPDIR)/$(am__dirstamp) +personalize/index.$(OBJEXT): personalize/$(am__dirstamp) \ + personalize/$(DEPDIR)/$(am__dirstamp) +lexicon/$(am__dirstamp): + @$(MKDIR_P) lexicon + @: > lexicon/$(am__dirstamp) +lexicon/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) lexicon/$(DEPDIR) + @: > lexicon/$(DEPDIR)/$(am__dirstamp) +lexicon/logic.$(OBJEXT): lexicon/$(am__dirstamp) \ + lexicon/$(DEPDIR)/$(am__dirstamp) +lexicon/definition.$(OBJEXT): lexicon/$(am__dirstamp) \ + lexicon/$(DEPDIR)/$(am__dirstamp) +sources/$(am__dirstamp): + @$(MKDIR_P) sources + @: > sources/$(am__dirstamp) +sources/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) sources/$(DEPDIR) + @: > sources/$(DEPDIR)/$(am__dirstamp) +sources/etcbc4.$(OBJEXT): sources/$(am__dirstamp) \ + sources/$(DEPDIR)/$(am__dirstamp) +sources/kjv.$(OBJEXT): sources/$(am__dirstamp) \ + sources/$(DEPDIR)/$(am__dirstamp) +sources/morphhb.$(OBJEXT): sources/$(am__dirstamp) \ + sources/$(DEPDIR)/$(am__dirstamp) +sources/morphgnt.$(OBJEXT): sources/$(am__dirstamp) \ + sources/$(DEPDIR)/$(am__dirstamp) +sources/hebrewlexicon.$(OBJEXT): sources/$(am__dirstamp) \ + sources/$(DEPDIR)/$(am__dirstamp) +sources/oshb.$(OBJEXT): sources/$(am__dirstamp) \ + sources/$(DEPDIR)/$(am__dirstamp) +sword/$(am__dirstamp): + @$(MKDIR_P) sword + @: > sword/$(am__dirstamp) +sword/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) sword/$(DEPDIR) + @: > sword/$(DEPDIR)/$(am__dirstamp) +sword/logic.$(OBJEXT): sword/$(am__dirstamp) \ + sword/$(DEPDIR)/$(am__dirstamp) +pugixml/$(am__dirstamp): + @$(MKDIR_P) pugixml + @: > pugixml/$(am__dirstamp) +pugixml/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) pugixml/$(DEPDIR) + @: > pugixml/$(DEPDIR)/$(am__dirstamp) +pugixml/pugixml.$(OBJEXT): pugixml/$(am__dirstamp) \ + pugixml/$(DEPDIR)/$(am__dirstamp) +pugixml/utils.$(OBJEXT): pugixml/$(am__dirstamp) \ + pugixml/$(DEPDIR)/$(am__dirstamp) +public/$(am__dirstamp): + @$(MKDIR_P) public + @: > public/$(am__dirstamp) +public/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) public/$(DEPDIR) + @: > public/$(DEPDIR)/$(am__dirstamp) +public/index.$(OBJEXT): public/$(am__dirstamp) \ + public/$(DEPDIR)/$(am__dirstamp) +public/logic.$(OBJEXT): public/$(am__dirstamp) \ + public/$(DEPDIR)/$(am__dirstamp) +public/login.$(OBJEXT): public/$(am__dirstamp) \ + public/$(DEPDIR)/$(am__dirstamp) +public/chapter.$(OBJEXT): public/$(am__dirstamp) \ + public/$(DEPDIR)/$(am__dirstamp) +public/notes.$(OBJEXT): public/$(am__dirstamp) \ + public/$(DEPDIR)/$(am__dirstamp) +public/new.$(OBJEXT): public/$(am__dirstamp) \ + public/$(DEPDIR)/$(am__dirstamp) +public/create.$(OBJEXT): public/$(am__dirstamp) \ + public/$(DEPDIR)/$(am__dirstamp) +public/note.$(OBJEXT): public/$(am__dirstamp) \ + public/$(DEPDIR)/$(am__dirstamp) +public/comment.$(OBJEXT): public/$(am__dirstamp) \ + public/$(DEPDIR)/$(am__dirstamp) +utf8proc/$(am__dirstamp): + @$(MKDIR_P) utf8proc + @: > utf8proc/$(am__dirstamp) +utf8proc/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) utf8proc/$(DEPDIR) + @: > utf8proc/$(DEPDIR)/$(am__dirstamp) +utf8proc/utf8proc.$(OBJEXT): utf8proc/$(am__dirstamp) \ + utf8proc/$(DEPDIR)/$(am__dirstamp) +search/logic.$(OBJEXT): search/$(am__dirstamp) \ + search/$(DEPDIR)/$(am__dirstamp) +mbedtls/$(am__dirstamp): + @$(MKDIR_P) mbedtls + @: > mbedtls/$(am__dirstamp) +mbedtls/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) mbedtls/$(DEPDIR) + @: > mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/aes.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/arc4.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/asn1parse.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/asn1write.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/base64.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/bignum.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/blowfish.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/camellia.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ccm.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/certs.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/chacha20.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/chachapoly.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/cipher.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/cipher_wrap.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ctr_drbg.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/debug.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/des.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/dhm.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ecdh.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ecdsa.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ecp.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ecp_curves.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/entropy.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/entropy_poll.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/error.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/gcm.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/hmac_drbg.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/md.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/md5.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/md_wrap.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/net_sockets.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/oid.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/pem.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/pk.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/pk_wrap.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/pkcs12.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/pkcs5.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/pkparse.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/pkwrite.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/platform_util.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/platform.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/poly1305.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ripemd160.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/rsa.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/rsa_internal.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/sha1.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/sha256.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/sha512.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ssl_cache.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ssl_ciphersuites.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ssl_cli.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ssl_cookie.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ssl_srv.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ssl_ticket.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/ssl_tls.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/threading.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/timing.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/version.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/version_features.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/x509.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/x509_create.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/x509_crl.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/x509_crt.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/x509_csr.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/x509write_crt.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/x509write_csr.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +mbedtls/xtea.$(OBJEXT): mbedtls/$(am__dirstamp) \ + mbedtls/$(DEPDIR)/$(am__dirstamp) +related/$(am__dirstamp): + @$(MKDIR_P) related + @: > related/$(am__dirstamp) +related/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) related/$(DEPDIR) + @: > related/$(DEPDIR)/$(am__dirstamp) +related/logic.$(OBJEXT): related/$(am__dirstamp) \ + related/$(DEPDIR)/$(am__dirstamp) +sqlite/$(am__dirstamp): + @$(MKDIR_P) sqlite + @: > sqlite/$(am__dirstamp) +sqlite/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) sqlite/$(DEPDIR) + @: > sqlite/$(DEPDIR)/$(am__dirstamp) +sqlite/sqlite3.$(OBJEXT): sqlite/$(am__dirstamp) \ + sqlite/$(DEPDIR)/$(am__dirstamp) +ldap/$(am__dirstamp): + @$(MKDIR_P) ldap + @: > ldap/$(am__dirstamp) +ldap/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ldap/$(DEPDIR) + @: > ldap/$(DEPDIR)/$(am__dirstamp) +ldap/logic.$(OBJEXT): ldap/$(am__dirstamp) \ + ldap/$(DEPDIR)/$(am__dirstamp) +quill/$(am__dirstamp): + @$(MKDIR_P) quill + @: > quill/$(am__dirstamp) +quill/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) quill/$(DEPDIR) + @: > quill/$(DEPDIR)/$(am__dirstamp) +quill/logic.$(OBJEXT): quill/$(am__dirstamp) \ + quill/$(DEPDIR)/$(am__dirstamp) +rss/$(am__dirstamp): + @$(MKDIR_P) rss + @: > rss/$(am__dirstamp) +rss/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) rss/$(DEPDIR) + @: > rss/$(DEPDIR)/$(am__dirstamp) +rss/logic.$(OBJEXT): rss/$(am__dirstamp) rss/$(DEPDIR)/$(am__dirstamp) +rss/feed.$(OBJEXT): rss/$(am__dirstamp) rss/$(DEPDIR)/$(am__dirstamp) +microtar/$(am__dirstamp): + @$(MKDIR_P) microtar + @: > microtar/$(am__dirstamp) +microtar/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) microtar/$(DEPDIR) + @: > microtar/$(DEPDIR)/$(am__dirstamp) +microtar/microtar.$(OBJEXT): microtar/$(am__dirstamp) \ + microtar/$(DEPDIR)/$(am__dirstamp) +miniz/$(am__dirstamp): + @$(MKDIR_P) miniz + @: > miniz/$(am__dirstamp) +miniz/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) miniz/$(DEPDIR) + @: > miniz/$(DEPDIR)/$(am__dirstamp) +miniz/miniz.$(OBJEXT): miniz/$(am__dirstamp) \ + miniz/$(DEPDIR)/$(am__dirstamp) +nmt/$(am__dirstamp): + @$(MKDIR_P) nmt + @: > nmt/$(am__dirstamp) +nmt/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) nmt/$(DEPDIR) + @: > nmt/$(DEPDIR)/$(am__dirstamp) +nmt/index.$(OBJEXT): nmt/$(am__dirstamp) nmt/$(DEPDIR)/$(am__dirstamp) +nmt/logic.$(OBJEXT): nmt/$(am__dirstamp) nmt/$(DEPDIR)/$(am__dirstamp) +tbsx/$(am__dirstamp): + @$(MKDIR_P) tbsx + @: > tbsx/$(am__dirstamp) +tbsx/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) tbsx/$(DEPDIR) + @: > tbsx/$(DEPDIR)/$(am__dirstamp) +tbsx/text.$(OBJEXT): tbsx/$(am__dirstamp) \ + tbsx/$(DEPDIR)/$(am__dirstamp) +read/$(am__dirstamp): + @$(MKDIR_P) read + @: > read/$(am__dirstamp) +read/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) read/$(DEPDIR) + @: > read/$(DEPDIR)/$(am__dirstamp) +read/index.$(OBJEXT): read/$(am__dirstamp) \ + read/$(DEPDIR)/$(am__dirstamp) +read/load.$(OBJEXT): read/$(am__dirstamp) \ + read/$(DEPDIR)/$(am__dirstamp) +read/verse.$(OBJEXT): read/$(am__dirstamp) \ + read/$(DEPDIR)/$(am__dirstamp) +resource/divider.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +session/confirm.$(OBJEXT): session/$(am__dirstamp) \ + session/$(DEPDIR)/$(am__dirstamp) +sources/abbott-smith.$(OBJEXT): sources/$(am__dirstamp) \ + sources/$(DEPDIR)/$(am__dirstamp) +database/abbottsmith.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +resource/comparative9edit.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/comparative1edit.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/translated9edit.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +resource/translated1edit.$(OBJEXT): resource/$(am__dirstamp) \ + resource/$(DEPDIR)/$(am__dirstamp) +developer/delay.$(OBJEXT): developer/$(am__dirstamp) \ + developer/$(DEPDIR)/$(am__dirstamp) +images/$(am__dirstamp): + @$(MKDIR_P) images + @: > images/$(am__dirstamp) +images/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) images/$(DEPDIR) + @: > images/$(DEPDIR)/$(am__dirstamp) +images/index.$(OBJEXT): images/$(am__dirstamp) \ + images/$(DEPDIR)/$(am__dirstamp) +images/view.$(OBJEXT): images/$(am__dirstamp) \ + images/$(DEPDIR)/$(am__dirstamp) +images/fetch.$(OBJEXT): images/$(am__dirstamp) \ + images/$(DEPDIR)/$(am__dirstamp) +images/logic.$(OBJEXT): images/$(am__dirstamp) \ + images/$(DEPDIR)/$(am__dirstamp) +database/bibleimages.$(OBJEXT): database/$(am__dirstamp) \ + database/$(DEPDIR)/$(am__dirstamp) +filter/image.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +mimetic098/$(am__dirstamp): + @$(MKDIR_P) mimetic098 + @: > mimetic098/$(am__dirstamp) +mimetic098/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) mimetic098/$(DEPDIR) + @: > mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/header.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/contentid.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/contenttransferencoding.$(OBJEXT): \ + mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/contentdisposition.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/contentdescription.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/mimeversion.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/contenttype.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/version.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/fieldparam.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/mimeentity.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/strutils.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/body.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/utils.$(OBJEXT): mimetic098/$(am__dirstamp) \ + mimetic098/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/$(am__dirstamp): + @$(MKDIR_P) mimetic098/rfc822 + @: > mimetic098/rfc822/$(am__dirstamp) +mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) mimetic098/rfc822/$(DEPDIR) + @: > mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/field.$(OBJEXT): mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/header.$(OBJEXT): mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/message.$(OBJEXT): \ + mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/addresslist.$(OBJEXT): \ + mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/fieldvalue.$(OBJEXT): \ + mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/mailbox.$(OBJEXT): \ + mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/messageid.$(OBJEXT): \ + mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/datetime.$(OBJEXT): \ + mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/group.$(OBJEXT): mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/mailboxlist.$(OBJEXT): \ + mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/rfc822/address.$(OBJEXT): \ + mimetic098/rfc822/$(am__dirstamp) \ + mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) +mimetic098/os/$(am__dirstamp): + @$(MKDIR_P) mimetic098/os + @: > mimetic098/os/$(am__dirstamp) +mimetic098/os/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) mimetic098/os/$(DEPDIR) + @: > mimetic098/os/$(DEPDIR)/$(am__dirstamp) +mimetic098/os/utils.$(OBJEXT): mimetic098/os/$(am__dirstamp) \ + mimetic098/os/$(DEPDIR)/$(am__dirstamp) +mimetic098/os/file_iterator.$(OBJEXT): mimetic098/os/$(am__dirstamp) \ + mimetic098/os/$(DEPDIR)/$(am__dirstamp) +mimetic098/os/mmfile.$(OBJEXT): mimetic098/os/$(am__dirstamp) \ + mimetic098/os/$(DEPDIR)/$(am__dirstamp) +mimetic098/codec/$(am__dirstamp): + @$(MKDIR_P) mimetic098/codec + @: > mimetic098/codec/$(am__dirstamp) +mimetic098/codec/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) mimetic098/codec/$(DEPDIR) + @: > mimetic098/codec/$(DEPDIR)/$(am__dirstamp) +mimetic098/codec/base64.$(OBJEXT): mimetic098/codec/$(am__dirstamp) \ + mimetic098/codec/$(DEPDIR)/$(am__dirstamp) +system/googletranslate.$(OBJEXT): system/$(am__dirstamp) \ + system/$(DEPDIR)/$(am__dirstamp) +filter/google.$(OBJEXT): filter/$(am__dirstamp) \ + filter/$(DEPDIR)/$(am__dirstamp) +i18n/$(am__dirstamp): + @$(MKDIR_P) i18n + @: > i18n/$(am__dirstamp) +i18n/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) i18n/$(DEPDIR) + @: > i18n/$(DEPDIR)/$(am__dirstamp) +i18n/logic.$(OBJEXT): i18n/$(am__dirstamp) \ + i18n/$(DEPDIR)/$(am__dirstamp) +tidy/$(am__dirstamp): + @$(MKDIR_P) tidy + @: > tidy/$(am__dirstamp) +tidy/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) tidy/$(DEPDIR) + @: > tidy/$(DEPDIR)/$(am__dirstamp) +tidy/access.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/alloc.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/attrdict.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/attrs.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/buffio.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/charsets.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/clean.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/config.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/entities.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/fileio.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/gdoc.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/istack.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/language.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/lexer.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/mappedio.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/message.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/messageobj.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/parser.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/pprint.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/sprtf.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/streamio.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/tagask.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/tags.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/tidylib.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/tmbstr.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) +tidy/utf8.$(OBJEXT): tidy/$(am__dirstamp) \ + tidy/$(DEPDIR)/$(am__dirstamp) + +libbibledit.a: $(libbibledit_a_OBJECTS) $(libbibledit_a_DEPENDENCIES) $(EXTRA_libbibledit_a_DEPENDENCIES) + $(AM_V_at)-rm -f libbibledit.a + $(AM_V_AR)$(libbibledit_a_AR) libbibledit.a $(libbibledit_a_OBJECTS) $(libbibledit_a_LIBADD) + $(AM_V_at)$(RANLIB) libbibledit.a +executable/$(am__dirstamp): + @$(MKDIR_P) executable + @: > executable/$(am__dirstamp) +executable/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) executable/$(DEPDIR) + @: > executable/$(DEPDIR)/$(am__dirstamp) +executable/generate.$(OBJEXT): executable/$(am__dirstamp) \ + executable/$(DEPDIR)/$(am__dirstamp) +sources/styles.$(OBJEXT): sources/$(am__dirstamp) \ + sources/$(DEPDIR)/$(am__dirstamp) + +generate$(EXEEXT): $(generate_OBJECTS) $(generate_DEPENDENCIES) $(EXTRA_generate_DEPENDENCIES) + @rm -f generate$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(generate_OBJECTS) $(generate_LDADD) $(LIBS) +executable/bibledit.$(OBJEXT): executable/$(am__dirstamp) \ + executable/$(DEPDIR)/$(am__dirstamp) + +server$(EXEEXT): $(server_OBJECTS) $(server_DEPENDENCIES) $(EXTRA_server_DEPENDENCIES) + @rm -f server$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(server_OBJECTS) $(server_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f access/*.$(OBJEXT) + -rm -f assets/*.$(OBJEXT) + -rm -f bb/*.$(OBJEXT) + -rm -f book/*.$(OBJEXT) + -rm -f bootstrap/*.$(OBJEXT) + -rm -f changes/*.$(OBJEXT) + -rm -f checks/*.$(OBJEXT) + -rm -f checksum/*.$(OBJEXT) + -rm -f client/*.$(OBJEXT) + -rm -f collaboration/*.$(OBJEXT) + -rm -f compare/*.$(OBJEXT) + -rm -f config/*.$(OBJEXT) + -rm -f confirm/*.$(OBJEXT) + -rm -f consistency/*.$(OBJEXT) + -rm -f database/*.$(OBJEXT) + -rm -f database/config/*.$(OBJEXT) + -rm -f demo/*.$(OBJEXT) + -rm -f developer/*.$(OBJEXT) + -rm -f dialog/*.$(OBJEXT) + -rm -f edit/*.$(OBJEXT) + -rm -f editone2/*.$(OBJEXT) + -rm -f editor/*.$(OBJEXT) + -rm -f editusfm/*.$(OBJEXT) + -rm -f email/*.$(OBJEXT) + -rm -f esword/*.$(OBJEXT) + -rm -f executable/*.$(OBJEXT) + -rm -f export/*.$(OBJEXT) + -rm -f filter/*.$(OBJEXT) + -rm -f flate/*.$(OBJEXT) + -rm -f fonts/*.$(OBJEXT) + -rm -f help/*.$(OBJEXT) + -rm -f html/*.$(OBJEXT) + -rm -f i18n/*.$(OBJEXT) + -rm -f images/*.$(OBJEXT) + -rm -f index/*.$(OBJEXT) + -rm -f ipc/*.$(OBJEXT) + -rm -f jobs/*.$(OBJEXT) + -rm -f journal/*.$(OBJEXT) + -rm -f jsonxx/*.$(OBJEXT) + -rm -f ldap/*.$(OBJEXT) + -rm -f lexicon/*.$(OBJEXT) + -rm -f library/*.$(OBJEXT) + -rm -f locale/*.$(OBJEXT) + -rm -f manage/*.$(OBJEXT) + -rm -f mapping/*.$(OBJEXT) + -rm -f mbedtls/*.$(OBJEXT) + -rm -f menu/*.$(OBJEXT) + -rm -f microtar/*.$(OBJEXT) + -rm -f mimetic098/*.$(OBJEXT) + -rm -f mimetic098/codec/*.$(OBJEXT) + -rm -f mimetic098/os/*.$(OBJEXT) + -rm -f mimetic098/rfc822/*.$(OBJEXT) + -rm -f miniz/*.$(OBJEXT) + -rm -f navigation/*.$(OBJEXT) + -rm -f nmt/*.$(OBJEXT) + -rm -f notes/*.$(OBJEXT) + -rm -f odf/*.$(OBJEXT) + -rm -f olb/*.$(OBJEXT) + -rm -f paratext/*.$(OBJEXT) + -rm -f parsewebdata/*.$(OBJEXT) + -rm -f personalize/*.$(OBJEXT) + -rm -f public/*.$(OBJEXT) + -rm -f pugixml/*.$(OBJEXT) + -rm -f quill/*.$(OBJEXT) + -rm -f read/*.$(OBJEXT) + -rm -f redirect/*.$(OBJEXT) + -rm -f related/*.$(OBJEXT) + -rm -f resource/*.$(OBJEXT) + -rm -f rss/*.$(OBJEXT) + -rm -f search/*.$(OBJEXT) + -rm -f sendreceive/*.$(OBJEXT) + -rm -f session/*.$(OBJEXT) + -rm -f setup/*.$(OBJEXT) + -rm -f sources/*.$(OBJEXT) + -rm -f sprint/*.$(OBJEXT) + -rm -f sqlite/*.$(OBJEXT) + -rm -f statistics/*.$(OBJEXT) + -rm -f styles/*.$(OBJEXT) + -rm -f sword/*.$(OBJEXT) + -rm -f sync/*.$(OBJEXT) + -rm -f system/*.$(OBJEXT) + -rm -f tasks/*.$(OBJEXT) + -rm -f tbsx/*.$(OBJEXT) + -rm -f text/*.$(OBJEXT) + -rm -f tidy/*.$(OBJEXT) + -rm -f timer/*.$(OBJEXT) + -rm -f tmp/*.$(OBJEXT) + -rm -f trash/*.$(OBJEXT) + -rm -f user/*.$(OBJEXT) + -rm -f utf8proc/*.$(OBJEXT) + -rm -f versification/*.$(OBJEXT) + -rm -f webbb/*.$(OBJEXT) + -rm -f webserver/*.$(OBJEXT) + -rm -f workspace/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include access/$(DEPDIR)/bible.Po # am--include-marker +include access/$(DEPDIR)/logic.Po # am--include-marker +include access/$(DEPDIR)/user.Po # am--include-marker +include assets/$(DEPDIR)/external.Po # am--include-marker +include assets/$(DEPDIR)/header.Po # am--include-marker +include assets/$(DEPDIR)/page.Po # am--include-marker +include assets/$(DEPDIR)/view.Po # am--include-marker +include bb/$(DEPDIR)/book.Po # am--include-marker +include bb/$(DEPDIR)/chapter.Po # am--include-marker +include bb/$(DEPDIR)/css.Po # am--include-marker +include bb/$(DEPDIR)/import.Po # am--include-marker +include bb/$(DEPDIR)/import_run.Po # am--include-marker +include bb/$(DEPDIR)/logic.Po # am--include-marker +include bb/$(DEPDIR)/manage.Po # am--include-marker +include bb/$(DEPDIR)/order.Po # am--include-marker +include bb/$(DEPDIR)/settings.Po # am--include-marker +include book/$(DEPDIR)/create.Po # am--include-marker +include bootstrap/$(DEPDIR)/bootstrap.Po # am--include-marker +include changes/$(DEPDIR)/change.Po # am--include-marker +include changes/$(DEPDIR)/changes.Po # am--include-marker +include changes/$(DEPDIR)/logic.Po # am--include-marker +include changes/$(DEPDIR)/manage.Po # am--include-marker +include changes/$(DEPDIR)/modifications.Po # am--include-marker +include changes/$(DEPDIR)/statistics.Po # am--include-marker +include checks/$(DEPDIR)/french.Po # am--include-marker +include checks/$(DEPDIR)/headers.Po # am--include-marker +include checks/$(DEPDIR)/index.Po # am--include-marker +include checks/$(DEPDIR)/logic.Po # am--include-marker +include checks/$(DEPDIR)/pairs.Po # am--include-marker +include checks/$(DEPDIR)/run.Po # am--include-marker +include checks/$(DEPDIR)/sentences.Po # am--include-marker +include checks/$(DEPDIR)/settings.Po # am--include-marker +include checks/$(DEPDIR)/settingspairs.Po # am--include-marker +include checks/$(DEPDIR)/settingspatterns.Po # am--include-marker +include checks/$(DEPDIR)/settingssentences.Po # am--include-marker +include checks/$(DEPDIR)/space.Po # am--include-marker +include checks/$(DEPDIR)/suppress.Po # am--include-marker +include checks/$(DEPDIR)/usfm.Po # am--include-marker +include checks/$(DEPDIR)/verses.Po # am--include-marker +include checks/$(DEPDIR)/versification.Po # am--include-marker +include checksum/$(DEPDIR)/logic.Po # am--include-marker +include client/$(DEPDIR)/index.Po # am--include-marker +include client/$(DEPDIR)/logic.Po # am--include-marker +include collaboration/$(DEPDIR)/index.Po # am--include-marker +include collaboration/$(DEPDIR)/link.Po # am--include-marker +include collaboration/$(DEPDIR)/settings.Po # am--include-marker +include compare/$(DEPDIR)/compare.Po # am--include-marker +include compare/$(DEPDIR)/index.Po # am--include-marker +include config/$(DEPDIR)/globals.Po # am--include-marker +include config/$(DEPDIR)/logic.Po # am--include-marker +include confirm/$(DEPDIR)/worker.Po # am--include-marker +include consistency/$(DEPDIR)/index.Po # am--include-marker +include consistency/$(DEPDIR)/input.Po # am--include-marker +include consistency/$(DEPDIR)/logic.Po # am--include-marker +include consistency/$(DEPDIR)/poll.Po # am--include-marker +include database/$(DEPDIR)/abbottsmith.Po # am--include-marker +include database/$(DEPDIR)/bibleactions.Po # am--include-marker +include database/$(DEPDIR)/bibleimages.Po # am--include-marker +include database/$(DEPDIR)/bibles.Po # am--include-marker +include database/$(DEPDIR)/books.Po # am--include-marker +include database/$(DEPDIR)/cache.Po # am--include-marker +include database/$(DEPDIR)/check.Po # am--include-marker +include database/$(DEPDIR)/confirm.Po # am--include-marker +include database/$(DEPDIR)/etcbc4.Po # am--include-marker +include database/$(DEPDIR)/git.Po # am--include-marker +include database/$(DEPDIR)/hebrewlexicon.Po # am--include-marker +include database/$(DEPDIR)/imageresources.Po # am--include-marker +include database/$(DEPDIR)/ipc.Po # am--include-marker +include database/$(DEPDIR)/jobs.Po # am--include-marker +include database/$(DEPDIR)/kjv.Po # am--include-marker +include database/$(DEPDIR)/localization.Po # am--include-marker +include database/$(DEPDIR)/logic.Po # am--include-marker +include database/$(DEPDIR)/login.Po # am--include-marker +include database/$(DEPDIR)/logs.Po # am--include-marker +include database/$(DEPDIR)/mail.Po # am--include-marker +include database/$(DEPDIR)/maintenance.Po # am--include-marker +include database/$(DEPDIR)/mappings.Po # am--include-marker +include database/$(DEPDIR)/modifications.Po # am--include-marker +include database/$(DEPDIR)/morphgnt.Po # am--include-marker +include database/$(DEPDIR)/navigation.Po # am--include-marker +include database/$(DEPDIR)/noteactions.Po # am--include-marker +include database/$(DEPDIR)/noteassignment.Po # am--include-marker +include database/$(DEPDIR)/notes.Po # am--include-marker +include database/$(DEPDIR)/oshb.Po # am--include-marker +include database/$(DEPDIR)/privileges.Po # am--include-marker +include database/$(DEPDIR)/sample.Po # am--include-marker +include database/$(DEPDIR)/sblgnt.Po # am--include-marker +include database/$(DEPDIR)/sprint.Po # am--include-marker +include database/$(DEPDIR)/sqlite.Po # am--include-marker +include database/$(DEPDIR)/state.Po # am--include-marker +include database/$(DEPDIR)/statistics.Po # am--include-marker +include database/$(DEPDIR)/strong.Po # am--include-marker +include database/$(DEPDIR)/styles.Po # am--include-marker +include database/$(DEPDIR)/userresources.Po # am--include-marker +include database/$(DEPDIR)/users.Po # am--include-marker +include database/$(DEPDIR)/usfmresources.Po # am--include-marker +include database/$(DEPDIR)/versifications.Po # am--include-marker +include database/$(DEPDIR)/volatile.Po # am--include-marker +include database/config/$(DEPDIR)/bible.Po # am--include-marker +include database/config/$(DEPDIR)/general.Po # am--include-marker +include database/config/$(DEPDIR)/user.Po # am--include-marker +include demo/$(DEPDIR)/logic.Po # am--include-marker +include developer/$(DEPDIR)/delay.Po # am--include-marker +include developer/$(DEPDIR)/index.Po # am--include-marker +include developer/$(DEPDIR)/logic.Po # am--include-marker +include dialog/$(DEPDIR)/books.Po # am--include-marker +include dialog/$(DEPDIR)/color.Po # am--include-marker +include dialog/$(DEPDIR)/entry.Po # am--include-marker +include dialog/$(DEPDIR)/list.Po # am--include-marker +include dialog/$(DEPDIR)/list2.Po # am--include-marker +include dialog/$(DEPDIR)/upload.Po # am--include-marker +include dialog/$(DEPDIR)/yes.Po # am--include-marker +include edit/$(DEPDIR)/edit.Po # am--include-marker +include edit/$(DEPDIR)/id.Po # am--include-marker +include edit/$(DEPDIR)/index.Po # am--include-marker +include edit/$(DEPDIR)/load.Po # am--include-marker +include edit/$(DEPDIR)/logic.Po # am--include-marker +include edit/$(DEPDIR)/navigate.Po # am--include-marker +include edit/$(DEPDIR)/position.Po # am--include-marker +include edit/$(DEPDIR)/preview.Po # am--include-marker +include edit/$(DEPDIR)/save.Po # am--include-marker +include edit/$(DEPDIR)/styles.Po # am--include-marker +include edit/$(DEPDIR)/update.Po # am--include-marker +include editone2/$(DEPDIR)/index.Po # am--include-marker +include editone2/$(DEPDIR)/load.Po # am--include-marker +include editone2/$(DEPDIR)/logic.Po # am--include-marker +include editone2/$(DEPDIR)/save.Po # am--include-marker +include editone2/$(DEPDIR)/update.Po # am--include-marker +include editone2/$(DEPDIR)/verse.Po # am--include-marker +include editor/$(DEPDIR)/html2format.Po # am--include-marker +include editor/$(DEPDIR)/html2usfm.Po # am--include-marker +include editor/$(DEPDIR)/id.Po # am--include-marker +include editor/$(DEPDIR)/select.Po # am--include-marker +include editor/$(DEPDIR)/style.Po # am--include-marker +include editor/$(DEPDIR)/styles.Po # am--include-marker +include editor/$(DEPDIR)/usfm2html.Po # am--include-marker +include editusfm/$(DEPDIR)/focus.Po # am--include-marker +include editusfm/$(DEPDIR)/index.Po # am--include-marker +include editusfm/$(DEPDIR)/load.Po # am--include-marker +include editusfm/$(DEPDIR)/offset.Po # am--include-marker +include editusfm/$(DEPDIR)/save.Po # am--include-marker +include email/$(DEPDIR)/index.Po # am--include-marker +include email/$(DEPDIR)/receive.Po # am--include-marker +include email/$(DEPDIR)/send.Po # am--include-marker +include esword/$(DEPDIR)/text.Po # am--include-marker +include executable/$(DEPDIR)/bibledit.Po # am--include-marker +include executable/$(DEPDIR)/generate.Po # am--include-marker +include export/$(DEPDIR)/bibledropbox.Po # am--include-marker +include export/$(DEPDIR)/esword.Po # am--include-marker +include export/$(DEPDIR)/html.Po # am--include-marker +include export/$(DEPDIR)/index.Po # am--include-marker +include export/$(DEPDIR)/info.Po # am--include-marker +include export/$(DEPDIR)/logic.Po # am--include-marker +include export/$(DEPDIR)/odt.Po # am--include-marker +include export/$(DEPDIR)/onlinebible.Po # am--include-marker +include export/$(DEPDIR)/textusfm.Po # am--include-marker +include export/$(DEPDIR)/usfm.Po # am--include-marker +include export/$(DEPDIR)/web.Po # am--include-marker +include filter/$(DEPDIR)/archive.Po # am--include-marker +include filter/$(DEPDIR)/css.Po # am--include-marker +include filter/$(DEPDIR)/date.Po # am--include-marker +include filter/$(DEPDIR)/diff.Po # am--include-marker +include filter/$(DEPDIR)/git.Po # am--include-marker +include filter/$(DEPDIR)/google.Po # am--include-marker +include filter/$(DEPDIR)/html.Po # am--include-marker +include filter/$(DEPDIR)/image.Po # am--include-marker +include filter/$(DEPDIR)/mail.Po # am--include-marker +include filter/$(DEPDIR)/md5.Po # am--include-marker +include filter/$(DEPDIR)/memory.Po # am--include-marker +include filter/$(DEPDIR)/merge.Po # am--include-marker +include filter/$(DEPDIR)/note.Po # am--include-marker +include filter/$(DEPDIR)/passage.Po # am--include-marker +include filter/$(DEPDIR)/roles.Po # am--include-marker +include filter/$(DEPDIR)/shell.Po # am--include-marker +include filter/$(DEPDIR)/string.Po # am--include-marker +include filter/$(DEPDIR)/text.Po # am--include-marker +include filter/$(DEPDIR)/url.Po # am--include-marker +include filter/$(DEPDIR)/usfm.Po # am--include-marker +include filter/$(DEPDIR)/webview.Po # am--include-marker +include flate/$(DEPDIR)/flate.Po # am--include-marker +include fonts/$(DEPDIR)/logic.Po # am--include-marker +include help/$(DEPDIR)/index.Po # am--include-marker +include html/$(DEPDIR)/header.Po # am--include-marker +include html/$(DEPDIR)/text.Po # am--include-marker +include i18n/$(DEPDIR)/logic.Po # am--include-marker +include images/$(DEPDIR)/fetch.Po # am--include-marker +include images/$(DEPDIR)/index.Po # am--include-marker +include images/$(DEPDIR)/logic.Po # am--include-marker +include images/$(DEPDIR)/view.Po # am--include-marker +include index/$(DEPDIR)/index.Po # am--include-marker +include index/$(DEPDIR)/listing.Po # am--include-marker +include ipc/$(DEPDIR)/focus.Po # am--include-marker +include ipc/$(DEPDIR)/notes.Po # am--include-marker +include jobs/$(DEPDIR)/index.Po # am--include-marker +include journal/$(DEPDIR)/index.Po # am--include-marker +include journal/$(DEPDIR)/logic.Po # am--include-marker +include jsonxx/$(DEPDIR)/jsonxx.Po # am--include-marker +include ldap/$(DEPDIR)/logic.Po # am--include-marker +include lexicon/$(DEPDIR)/definition.Po # am--include-marker +include lexicon/$(DEPDIR)/logic.Po # am--include-marker +include library/$(DEPDIR)/bibledit.Po # am--include-marker +include library/$(DEPDIR)/locks.Po # am--include-marker +include locale/$(DEPDIR)/logic.Po # am--include-marker +include locale/$(DEPDIR)/translate.Po # am--include-marker +include manage/$(DEPDIR)/accounts.Po # am--include-marker +include manage/$(DEPDIR)/exports.Po # am--include-marker +include manage/$(DEPDIR)/hyphenate.Po # am--include-marker +include manage/$(DEPDIR)/hyphenation.Po # am--include-marker +include manage/$(DEPDIR)/index.Po # am--include-marker +include manage/$(DEPDIR)/privileges.Po # am--include-marker +include manage/$(DEPDIR)/users.Po # am--include-marker +include manage/$(DEPDIR)/write.Po # am--include-marker +include mapping/$(DEPDIR)/index.Po # am--include-marker +include mapping/$(DEPDIR)/map.Po # am--include-marker +include mbedtls/$(DEPDIR)/aes.Po # am--include-marker +include mbedtls/$(DEPDIR)/arc4.Po # am--include-marker +include mbedtls/$(DEPDIR)/asn1parse.Po # am--include-marker +include mbedtls/$(DEPDIR)/asn1write.Po # am--include-marker +include mbedtls/$(DEPDIR)/base64.Po # am--include-marker +include mbedtls/$(DEPDIR)/bignum.Po # am--include-marker +include mbedtls/$(DEPDIR)/blowfish.Po # am--include-marker +include mbedtls/$(DEPDIR)/camellia.Po # am--include-marker +include mbedtls/$(DEPDIR)/ccm.Po # am--include-marker +include mbedtls/$(DEPDIR)/certs.Po # am--include-marker +include mbedtls/$(DEPDIR)/chacha20.Po # am--include-marker +include mbedtls/$(DEPDIR)/chachapoly.Po # am--include-marker +include mbedtls/$(DEPDIR)/cipher.Po # am--include-marker +include mbedtls/$(DEPDIR)/cipher_wrap.Po # am--include-marker +include mbedtls/$(DEPDIR)/ctr_drbg.Po # am--include-marker +include mbedtls/$(DEPDIR)/debug.Po # am--include-marker +include mbedtls/$(DEPDIR)/des.Po # am--include-marker +include mbedtls/$(DEPDIR)/dhm.Po # am--include-marker +include mbedtls/$(DEPDIR)/ecdh.Po # am--include-marker +include mbedtls/$(DEPDIR)/ecdsa.Po # am--include-marker +include mbedtls/$(DEPDIR)/ecp.Po # am--include-marker +include mbedtls/$(DEPDIR)/ecp_curves.Po # am--include-marker +include mbedtls/$(DEPDIR)/entropy.Po # am--include-marker +include mbedtls/$(DEPDIR)/entropy_poll.Po # am--include-marker +include mbedtls/$(DEPDIR)/error.Po # am--include-marker +include mbedtls/$(DEPDIR)/gcm.Po # am--include-marker +include mbedtls/$(DEPDIR)/hmac_drbg.Po # am--include-marker +include mbedtls/$(DEPDIR)/md.Po # am--include-marker +include mbedtls/$(DEPDIR)/md5.Po # am--include-marker +include mbedtls/$(DEPDIR)/md_wrap.Po # am--include-marker +include mbedtls/$(DEPDIR)/net_sockets.Po # am--include-marker +include mbedtls/$(DEPDIR)/oid.Po # am--include-marker +include mbedtls/$(DEPDIR)/pem.Po # am--include-marker +include mbedtls/$(DEPDIR)/pk.Po # am--include-marker +include mbedtls/$(DEPDIR)/pk_wrap.Po # am--include-marker +include mbedtls/$(DEPDIR)/pkcs12.Po # am--include-marker +include mbedtls/$(DEPDIR)/pkcs5.Po # am--include-marker +include mbedtls/$(DEPDIR)/pkparse.Po # am--include-marker +include mbedtls/$(DEPDIR)/pkwrite.Po # am--include-marker +include mbedtls/$(DEPDIR)/platform.Po # am--include-marker +include mbedtls/$(DEPDIR)/platform_util.Po # am--include-marker +include mbedtls/$(DEPDIR)/poly1305.Po # am--include-marker +include mbedtls/$(DEPDIR)/ripemd160.Po # am--include-marker +include mbedtls/$(DEPDIR)/rsa.Po # am--include-marker +include mbedtls/$(DEPDIR)/rsa_internal.Po # am--include-marker +include mbedtls/$(DEPDIR)/sha1.Po # am--include-marker +include mbedtls/$(DEPDIR)/sha256.Po # am--include-marker +include mbedtls/$(DEPDIR)/sha512.Po # am--include-marker +include mbedtls/$(DEPDIR)/ssl_cache.Po # am--include-marker +include mbedtls/$(DEPDIR)/ssl_ciphersuites.Po # am--include-marker +include mbedtls/$(DEPDIR)/ssl_cli.Po # am--include-marker +include mbedtls/$(DEPDIR)/ssl_cookie.Po # am--include-marker +include mbedtls/$(DEPDIR)/ssl_srv.Po # am--include-marker +include mbedtls/$(DEPDIR)/ssl_ticket.Po # am--include-marker +include mbedtls/$(DEPDIR)/ssl_tls.Po # am--include-marker +include mbedtls/$(DEPDIR)/threading.Po # am--include-marker +include mbedtls/$(DEPDIR)/timing.Po # am--include-marker +include mbedtls/$(DEPDIR)/version.Po # am--include-marker +include mbedtls/$(DEPDIR)/version_features.Po # am--include-marker +include mbedtls/$(DEPDIR)/x509.Po # am--include-marker +include mbedtls/$(DEPDIR)/x509_create.Po # am--include-marker +include mbedtls/$(DEPDIR)/x509_crl.Po # am--include-marker +include mbedtls/$(DEPDIR)/x509_crt.Po # am--include-marker +include mbedtls/$(DEPDIR)/x509_csr.Po # am--include-marker +include mbedtls/$(DEPDIR)/x509write_crt.Po # am--include-marker +include mbedtls/$(DEPDIR)/x509write_csr.Po # am--include-marker +include mbedtls/$(DEPDIR)/xtea.Po # am--include-marker +include menu/$(DEPDIR)/index.Po # am--include-marker +include menu/$(DEPDIR)/logic.Po # am--include-marker +include microtar/$(DEPDIR)/microtar.Po # am--include-marker +include mimetic098/$(DEPDIR)/body.Po # am--include-marker +include mimetic098/$(DEPDIR)/contentdescription.Po # am--include-marker +include mimetic098/$(DEPDIR)/contentdisposition.Po # am--include-marker +include mimetic098/$(DEPDIR)/contentid.Po # am--include-marker +include mimetic098/$(DEPDIR)/contenttransferencoding.Po # am--include-marker +include mimetic098/$(DEPDIR)/contenttype.Po # am--include-marker +include mimetic098/$(DEPDIR)/fieldparam.Po # am--include-marker +include mimetic098/$(DEPDIR)/header.Po # am--include-marker +include mimetic098/$(DEPDIR)/mimeentity.Po # am--include-marker +include mimetic098/$(DEPDIR)/mimeversion.Po # am--include-marker +include mimetic098/$(DEPDIR)/strutils.Po # am--include-marker +include mimetic098/$(DEPDIR)/utils.Po # am--include-marker +include mimetic098/$(DEPDIR)/version.Po # am--include-marker +include mimetic098/codec/$(DEPDIR)/base64.Po # am--include-marker +include mimetic098/os/$(DEPDIR)/file_iterator.Po # am--include-marker +include mimetic098/os/$(DEPDIR)/mmfile.Po # am--include-marker +include mimetic098/os/$(DEPDIR)/utils.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/address.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/addresslist.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/datetime.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/field.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/fieldvalue.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/group.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/header.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/mailbox.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/mailboxlist.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/message.Po # am--include-marker +include mimetic098/rfc822/$(DEPDIR)/messageid.Po # am--include-marker +include miniz/$(DEPDIR)/miniz.Po # am--include-marker +include navigation/$(DEPDIR)/paratext.Po # am--include-marker +include navigation/$(DEPDIR)/passage.Po # am--include-marker +include navigation/$(DEPDIR)/poll.Po # am--include-marker +include navigation/$(DEPDIR)/update.Po # am--include-marker +include nmt/$(DEPDIR)/index.Po # am--include-marker +include nmt/$(DEPDIR)/logic.Po # am--include-marker +include notes/$(DEPDIR)/actions.Po # am--include-marker +include notes/$(DEPDIR)/assign-1.Po # am--include-marker +include notes/$(DEPDIR)/assign-n.Po # am--include-marker +include notes/$(DEPDIR)/bb-1.Po # am--include-marker +include notes/$(DEPDIR)/bb-n.Po # am--include-marker +include notes/$(DEPDIR)/bulk.Po # am--include-marker +include notes/$(DEPDIR)/click.Po # am--include-marker +include notes/$(DEPDIR)/comment.Po # am--include-marker +include notes/$(DEPDIR)/create.Po # am--include-marker +include notes/$(DEPDIR)/edit.Po # am--include-marker +include notes/$(DEPDIR)/index.Po # am--include-marker +include notes/$(DEPDIR)/logic.Po # am--include-marker +include notes/$(DEPDIR)/note.Po # am--include-marker +include notes/$(DEPDIR)/notes.Po # am--include-marker +include notes/$(DEPDIR)/poll.Po # am--include-marker +include notes/$(DEPDIR)/select.Po # am--include-marker +include notes/$(DEPDIR)/severity-1.Po # am--include-marker +include notes/$(DEPDIR)/severity-n.Po # am--include-marker +include notes/$(DEPDIR)/status-1.Po # am--include-marker +include notes/$(DEPDIR)/status-n.Po # am--include-marker +include notes/$(DEPDIR)/summary.Po # am--include-marker +include notes/$(DEPDIR)/unassign-n.Po # am--include-marker +include notes/$(DEPDIR)/verses.Po # am--include-marker +include odf/$(DEPDIR)/text.Po # am--include-marker +include olb/$(DEPDIR)/text.Po # am--include-marker +include paratext/$(DEPDIR)/index.Po # am--include-marker +include paratext/$(DEPDIR)/logic.Po # am--include-marker +include parsewebdata/$(DEPDIR)/ParseMultipartFormData.Po # am--include-marker +include parsewebdata/$(DEPDIR)/ParseWebData.Po # am--include-marker +include personalize/$(DEPDIR)/index.Po # am--include-marker +include public/$(DEPDIR)/chapter.Po # am--include-marker +include public/$(DEPDIR)/comment.Po # am--include-marker +include public/$(DEPDIR)/create.Po # am--include-marker +include public/$(DEPDIR)/index.Po # am--include-marker +include public/$(DEPDIR)/logic.Po # am--include-marker +include public/$(DEPDIR)/login.Po # am--include-marker +include public/$(DEPDIR)/new.Po # am--include-marker +include public/$(DEPDIR)/note.Po # am--include-marker +include public/$(DEPDIR)/notes.Po # am--include-marker +include pugixml/$(DEPDIR)/pugixml.Po # am--include-marker +include pugixml/$(DEPDIR)/utils.Po # am--include-marker +include quill/$(DEPDIR)/logic.Po # am--include-marker +include read/$(DEPDIR)/index.Po # am--include-marker +include read/$(DEPDIR)/load.Po # am--include-marker +include read/$(DEPDIR)/verse.Po # am--include-marker +include redirect/$(DEPDIR)/index.Po # am--include-marker +include related/$(DEPDIR)/logic.Po # am--include-marker +include resource/$(DEPDIR)/bb2resource.Po # am--include-marker +include resource/$(DEPDIR)/bbgateway.Po # am--include-marker +include resource/$(DEPDIR)/cache.Po # am--include-marker +include resource/$(DEPDIR)/comparative1edit.Po # am--include-marker +include resource/$(DEPDIR)/comparative9edit.Po # am--include-marker +include resource/$(DEPDIR)/convert2bible.Po # am--include-marker +include resource/$(DEPDIR)/convert2resource.Po # am--include-marker +include resource/$(DEPDIR)/divider.Po # am--include-marker +include resource/$(DEPDIR)/download.Po # am--include-marker +include resource/$(DEPDIR)/external.Po # am--include-marker +include resource/$(DEPDIR)/get.Po # am--include-marker +include resource/$(DEPDIR)/image.Po # am--include-marker +include resource/$(DEPDIR)/imagefetch.Po # am--include-marker +include resource/$(DEPDIR)/images.Po # am--include-marker +include resource/$(DEPDIR)/img.Po # am--include-marker +include resource/$(DEPDIR)/index.Po # am--include-marker +include resource/$(DEPDIR)/logic.Po # am--include-marker +include resource/$(DEPDIR)/manage.Po # am--include-marker +include resource/$(DEPDIR)/organize.Po # am--include-marker +include resource/$(DEPDIR)/print.Po # am--include-marker +include resource/$(DEPDIR)/select.Po # am--include-marker +include resource/$(DEPDIR)/studylight.Po # am--include-marker +include resource/$(DEPDIR)/sword.Po # am--include-marker +include resource/$(DEPDIR)/translated1edit.Po # am--include-marker +include resource/$(DEPDIR)/translated9edit.Po # am--include-marker +include resource/$(DEPDIR)/unload.Po # am--include-marker +include resource/$(DEPDIR)/user1edit.Po # am--include-marker +include resource/$(DEPDIR)/user1view.Po # am--include-marker +include resource/$(DEPDIR)/user9edit.Po # am--include-marker +include resource/$(DEPDIR)/user9view.Po # am--include-marker +include rss/$(DEPDIR)/feed.Po # am--include-marker +include rss/$(DEPDIR)/logic.Po # am--include-marker +include search/$(DEPDIR)/all.Po # am--include-marker +include search/$(DEPDIR)/getids.Po # am--include-marker +include search/$(DEPDIR)/getids2.Po # am--include-marker +include search/$(DEPDIR)/index.Po # am--include-marker +include search/$(DEPDIR)/logic.Po # am--include-marker +include search/$(DEPDIR)/originals.Po # am--include-marker +include search/$(DEPDIR)/rebibles.Po # am--include-marker +include search/$(DEPDIR)/renotes.Po # am--include-marker +include search/$(DEPDIR)/replace.Po # am--include-marker +include search/$(DEPDIR)/replace2.Po # am--include-marker +include search/$(DEPDIR)/replacego.Po # am--include-marker +include search/$(DEPDIR)/replacego2.Po # am--include-marker +include search/$(DEPDIR)/replacepre.Po # am--include-marker +include search/$(DEPDIR)/replacepre2.Po # am--include-marker +include search/$(DEPDIR)/search2.Po # am--include-marker +include search/$(DEPDIR)/similar.Po # am--include-marker +include search/$(DEPDIR)/strong.Po # am--include-marker +include search/$(DEPDIR)/strongs.Po # am--include-marker +include sendreceive/$(DEPDIR)/bibles.Po # am--include-marker +include sendreceive/$(DEPDIR)/changes.Po # am--include-marker +include sendreceive/$(DEPDIR)/files.Po # am--include-marker +include sendreceive/$(DEPDIR)/index.Po # am--include-marker +include sendreceive/$(DEPDIR)/logic.Po # am--include-marker +include sendreceive/$(DEPDIR)/notes.Po # am--include-marker +include sendreceive/$(DEPDIR)/resources.Po # am--include-marker +include sendreceive/$(DEPDIR)/sendreceive.Po # am--include-marker +include sendreceive/$(DEPDIR)/settings.Po # am--include-marker +include session/$(DEPDIR)/confirm.Po # am--include-marker +include session/$(DEPDIR)/logic.Po # am--include-marker +include session/$(DEPDIR)/login.Po # am--include-marker +include session/$(DEPDIR)/logout.Po # am--include-marker +include session/$(DEPDIR)/password.Po # am--include-marker +include session/$(DEPDIR)/signup.Po # am--include-marker +include session/$(DEPDIR)/switch.Po # am--include-marker +include setup/$(DEPDIR)/index.Po # am--include-marker +include setup/$(DEPDIR)/logic.Po # am--include-marker +include sources/$(DEPDIR)/abbott-smith.Po # am--include-marker +include sources/$(DEPDIR)/etcbc4.Po # am--include-marker +include sources/$(DEPDIR)/hebrewlexicon.Po # am--include-marker +include sources/$(DEPDIR)/kjv.Po # am--include-marker +include sources/$(DEPDIR)/morphgnt.Po # am--include-marker +include sources/$(DEPDIR)/morphhb.Po # am--include-marker +include sources/$(DEPDIR)/oshb.Po # am--include-marker +include sources/$(DEPDIR)/styles.Po # am--include-marker +include sprint/$(DEPDIR)/burndown.Po # am--include-marker +include sprint/$(DEPDIR)/index.Po # am--include-marker +include sqlite/$(DEPDIR)/sqlite3.Po # am--include-marker +include statistics/$(DEPDIR)/statistics.Po # am--include-marker +include styles/$(DEPDIR)/css.Po # am--include-marker +include styles/$(DEPDIR)/indexm.Po # am--include-marker +include styles/$(DEPDIR)/logic.Po # am--include-marker +include styles/$(DEPDIR)/sheetm.Po # am--include-marker +include styles/$(DEPDIR)/sheets.Po # am--include-marker +include styles/$(DEPDIR)/view.Po # am--include-marker +include sword/$(DEPDIR)/logic.Po # am--include-marker +include sync/$(DEPDIR)/bibles.Po # am--include-marker +include sync/$(DEPDIR)/changes.Po # am--include-marker +include sync/$(DEPDIR)/files.Po # am--include-marker +include sync/$(DEPDIR)/logic.Po # am--include-marker +include sync/$(DEPDIR)/mail.Po # am--include-marker +include sync/$(DEPDIR)/notes.Po # am--include-marker +include sync/$(DEPDIR)/resources.Po # am--include-marker +include sync/$(DEPDIR)/settings.Po # am--include-marker +include sync/$(DEPDIR)/setup.Po # am--include-marker +include sync/$(DEPDIR)/usfmresources.Po # am--include-marker +include system/$(DEPDIR)/googletranslate.Po # am--include-marker +include system/$(DEPDIR)/index.Po # am--include-marker +include system/$(DEPDIR)/logic.Po # am--include-marker +include tasks/$(DEPDIR)/logic.Po # am--include-marker +include tasks/$(DEPDIR)/run.Po # am--include-marker +include tbsx/$(DEPDIR)/text.Po # am--include-marker +include text/$(DEPDIR)/text.Po # am--include-marker +include tidy/$(DEPDIR)/access.Po # am--include-marker +include tidy/$(DEPDIR)/alloc.Po # am--include-marker +include tidy/$(DEPDIR)/attrdict.Po # am--include-marker +include tidy/$(DEPDIR)/attrs.Po # am--include-marker +include tidy/$(DEPDIR)/buffio.Po # am--include-marker +include tidy/$(DEPDIR)/charsets.Po # am--include-marker +include tidy/$(DEPDIR)/clean.Po # am--include-marker +include tidy/$(DEPDIR)/config.Po # am--include-marker +include tidy/$(DEPDIR)/entities.Po # am--include-marker +include tidy/$(DEPDIR)/fileio.Po # am--include-marker +include tidy/$(DEPDIR)/gdoc.Po # am--include-marker +include tidy/$(DEPDIR)/istack.Po # am--include-marker +include tidy/$(DEPDIR)/language.Po # am--include-marker +include tidy/$(DEPDIR)/lexer.Po # am--include-marker +include tidy/$(DEPDIR)/mappedio.Po # am--include-marker +include tidy/$(DEPDIR)/message.Po # am--include-marker +include tidy/$(DEPDIR)/messageobj.Po # am--include-marker +include tidy/$(DEPDIR)/parser.Po # am--include-marker +include tidy/$(DEPDIR)/pprint.Po # am--include-marker +include tidy/$(DEPDIR)/sprtf.Po # am--include-marker +include tidy/$(DEPDIR)/streamio.Po # am--include-marker +include tidy/$(DEPDIR)/tagask.Po # am--include-marker +include tidy/$(DEPDIR)/tags.Po # am--include-marker +include tidy/$(DEPDIR)/tidylib.Po # am--include-marker +include tidy/$(DEPDIR)/tmbstr.Po # am--include-marker +include tidy/$(DEPDIR)/utf8.Po # am--include-marker +include timer/$(DEPDIR)/index.Po # am--include-marker +include tmp/$(DEPDIR)/tmp.Po # am--include-marker +include trash/$(DEPDIR)/handler.Po # am--include-marker +include user/$(DEPDIR)/account.Po # am--include-marker +include user/$(DEPDIR)/logic.Po # am--include-marker +include user/$(DEPDIR)/notifications.Po # am--include-marker +include utf8proc/$(DEPDIR)/utf8proc.Po # am--include-marker +include versification/$(DEPDIR)/index.Po # am--include-marker +include versification/$(DEPDIR)/logic.Po # am--include-marker +include versification/$(DEPDIR)/system.Po # am--include-marker +include webbb/$(DEPDIR)/search.Po # am--include-marker +include webserver/$(DEPDIR)/http.Po # am--include-marker +include webserver/$(DEPDIR)/request.Po # am--include-marker +include webserver/$(DEPDIR)/webserver.Po # am--include-marker +include workspace/$(DEPDIR)/index.Po # am--include-marker +include workspace/$(DEPDIR)/logic.Po # am--include-marker +include workspace/$(DEPDIR)/organize.Po # am--include-marker +include workspace/$(DEPDIR)/settings.Po # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: + $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ + $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# $(AM_V_CC)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(AM_V_CC_no)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ + $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# $(AM_V_CC)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.o: + $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ + $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# $(AM_V_CXX)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: + $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ + $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# $(AM_V_CXX)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cxx.o: + $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ + $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# $(AM_V_CXX)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: + $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ + $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# $(AM_V_CXX)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(LIBRARIES) $(MANS) config.h all-local +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f access/$(DEPDIR)/$(am__dirstamp) + -rm -f access/$(am__dirstamp) + -rm -f assets/$(DEPDIR)/$(am__dirstamp) + -rm -f assets/$(am__dirstamp) + -rm -f bb/$(DEPDIR)/$(am__dirstamp) + -rm -f bb/$(am__dirstamp) + -rm -f book/$(DEPDIR)/$(am__dirstamp) + -rm -f book/$(am__dirstamp) + -rm -f bootstrap/$(DEPDIR)/$(am__dirstamp) + -rm -f bootstrap/$(am__dirstamp) + -rm -f changes/$(DEPDIR)/$(am__dirstamp) + -rm -f changes/$(am__dirstamp) + -rm -f checks/$(DEPDIR)/$(am__dirstamp) + -rm -f checks/$(am__dirstamp) + -rm -f checksum/$(DEPDIR)/$(am__dirstamp) + -rm -f checksum/$(am__dirstamp) + -rm -f client/$(DEPDIR)/$(am__dirstamp) + -rm -f client/$(am__dirstamp) + -rm -f collaboration/$(DEPDIR)/$(am__dirstamp) + -rm -f collaboration/$(am__dirstamp) + -rm -f compare/$(DEPDIR)/$(am__dirstamp) + -rm -f compare/$(am__dirstamp) + -rm -f config/$(DEPDIR)/$(am__dirstamp) + -rm -f config/$(am__dirstamp) + -rm -f confirm/$(DEPDIR)/$(am__dirstamp) + -rm -f confirm/$(am__dirstamp) + -rm -f consistency/$(DEPDIR)/$(am__dirstamp) + -rm -f consistency/$(am__dirstamp) + -rm -f database/$(DEPDIR)/$(am__dirstamp) + -rm -f database/$(am__dirstamp) + -rm -f database/config/$(DEPDIR)/$(am__dirstamp) + -rm -f database/config/$(am__dirstamp) + -rm -f demo/$(DEPDIR)/$(am__dirstamp) + -rm -f demo/$(am__dirstamp) + -rm -f developer/$(DEPDIR)/$(am__dirstamp) + -rm -f developer/$(am__dirstamp) + -rm -f dialog/$(DEPDIR)/$(am__dirstamp) + -rm -f dialog/$(am__dirstamp) + -rm -f edit/$(DEPDIR)/$(am__dirstamp) + -rm -f edit/$(am__dirstamp) + -rm -f editone2/$(DEPDIR)/$(am__dirstamp) + -rm -f editone2/$(am__dirstamp) + -rm -f editor/$(DEPDIR)/$(am__dirstamp) + -rm -f editor/$(am__dirstamp) + -rm -f editusfm/$(DEPDIR)/$(am__dirstamp) + -rm -f editusfm/$(am__dirstamp) + -rm -f email/$(DEPDIR)/$(am__dirstamp) + -rm -f email/$(am__dirstamp) + -rm -f esword/$(DEPDIR)/$(am__dirstamp) + -rm -f esword/$(am__dirstamp) + -rm -f executable/$(DEPDIR)/$(am__dirstamp) + -rm -f executable/$(am__dirstamp) + -rm -f export/$(DEPDIR)/$(am__dirstamp) + -rm -f export/$(am__dirstamp) + -rm -f filter/$(DEPDIR)/$(am__dirstamp) + -rm -f filter/$(am__dirstamp) + -rm -f flate/$(DEPDIR)/$(am__dirstamp) + -rm -f flate/$(am__dirstamp) + -rm -f fonts/$(DEPDIR)/$(am__dirstamp) + -rm -f fonts/$(am__dirstamp) + -rm -f help/$(DEPDIR)/$(am__dirstamp) + -rm -f help/$(am__dirstamp) + -rm -f html/$(DEPDIR)/$(am__dirstamp) + -rm -f html/$(am__dirstamp) + -rm -f i18n/$(DEPDIR)/$(am__dirstamp) + -rm -f i18n/$(am__dirstamp) + -rm -f images/$(DEPDIR)/$(am__dirstamp) + -rm -f images/$(am__dirstamp) + -rm -f index/$(DEPDIR)/$(am__dirstamp) + -rm -f index/$(am__dirstamp) + -rm -f ipc/$(DEPDIR)/$(am__dirstamp) + -rm -f ipc/$(am__dirstamp) + -rm -f jobs/$(DEPDIR)/$(am__dirstamp) + -rm -f jobs/$(am__dirstamp) + -rm -f journal/$(DEPDIR)/$(am__dirstamp) + -rm -f journal/$(am__dirstamp) + -rm -f jsonxx/$(DEPDIR)/$(am__dirstamp) + -rm -f jsonxx/$(am__dirstamp) + -rm -f ldap/$(DEPDIR)/$(am__dirstamp) + -rm -f ldap/$(am__dirstamp) + -rm -f lexicon/$(DEPDIR)/$(am__dirstamp) + -rm -f lexicon/$(am__dirstamp) + -rm -f library/$(DEPDIR)/$(am__dirstamp) + -rm -f library/$(am__dirstamp) + -rm -f locale/$(DEPDIR)/$(am__dirstamp) + -rm -f locale/$(am__dirstamp) + -rm -f manage/$(DEPDIR)/$(am__dirstamp) + -rm -f manage/$(am__dirstamp) + -rm -f mapping/$(DEPDIR)/$(am__dirstamp) + -rm -f mapping/$(am__dirstamp) + -rm -f mbedtls/$(DEPDIR)/$(am__dirstamp) + -rm -f mbedtls/$(am__dirstamp) + -rm -f menu/$(DEPDIR)/$(am__dirstamp) + -rm -f menu/$(am__dirstamp) + -rm -f microtar/$(DEPDIR)/$(am__dirstamp) + -rm -f microtar/$(am__dirstamp) + -rm -f mimetic098/$(DEPDIR)/$(am__dirstamp) + -rm -f mimetic098/$(am__dirstamp) + -rm -f mimetic098/codec/$(DEPDIR)/$(am__dirstamp) + -rm -f mimetic098/codec/$(am__dirstamp) + -rm -f mimetic098/os/$(DEPDIR)/$(am__dirstamp) + -rm -f mimetic098/os/$(am__dirstamp) + -rm -f mimetic098/rfc822/$(DEPDIR)/$(am__dirstamp) + -rm -f mimetic098/rfc822/$(am__dirstamp) + -rm -f miniz/$(DEPDIR)/$(am__dirstamp) + -rm -f miniz/$(am__dirstamp) + -rm -f navigation/$(DEPDIR)/$(am__dirstamp) + -rm -f navigation/$(am__dirstamp) + -rm -f nmt/$(DEPDIR)/$(am__dirstamp) + -rm -f nmt/$(am__dirstamp) + -rm -f notes/$(DEPDIR)/$(am__dirstamp) + -rm -f notes/$(am__dirstamp) + -rm -f odf/$(DEPDIR)/$(am__dirstamp) + -rm -f odf/$(am__dirstamp) + -rm -f olb/$(DEPDIR)/$(am__dirstamp) + -rm -f olb/$(am__dirstamp) + -rm -f paratext/$(DEPDIR)/$(am__dirstamp) + -rm -f paratext/$(am__dirstamp) + -rm -f parsewebdata/$(DEPDIR)/$(am__dirstamp) + -rm -f parsewebdata/$(am__dirstamp) + -rm -f personalize/$(DEPDIR)/$(am__dirstamp) + -rm -f personalize/$(am__dirstamp) + -rm -f public/$(DEPDIR)/$(am__dirstamp) + -rm -f public/$(am__dirstamp) + -rm -f pugixml/$(DEPDIR)/$(am__dirstamp) + -rm -f pugixml/$(am__dirstamp) + -rm -f quill/$(DEPDIR)/$(am__dirstamp) + -rm -f quill/$(am__dirstamp) + -rm -f read/$(DEPDIR)/$(am__dirstamp) + -rm -f read/$(am__dirstamp) + -rm -f redirect/$(DEPDIR)/$(am__dirstamp) + -rm -f redirect/$(am__dirstamp) + -rm -f related/$(DEPDIR)/$(am__dirstamp) + -rm -f related/$(am__dirstamp) + -rm -f resource/$(DEPDIR)/$(am__dirstamp) + -rm -f resource/$(am__dirstamp) + -rm -f rss/$(DEPDIR)/$(am__dirstamp) + -rm -f rss/$(am__dirstamp) + -rm -f search/$(DEPDIR)/$(am__dirstamp) + -rm -f search/$(am__dirstamp) + -rm -f sendreceive/$(DEPDIR)/$(am__dirstamp) + -rm -f sendreceive/$(am__dirstamp) + -rm -f session/$(DEPDIR)/$(am__dirstamp) + -rm -f session/$(am__dirstamp) + -rm -f setup/$(DEPDIR)/$(am__dirstamp) + -rm -f setup/$(am__dirstamp) + -rm -f sources/$(DEPDIR)/$(am__dirstamp) + -rm -f sources/$(am__dirstamp) + -rm -f sprint/$(DEPDIR)/$(am__dirstamp) + -rm -f sprint/$(am__dirstamp) + -rm -f sqlite/$(DEPDIR)/$(am__dirstamp) + -rm -f sqlite/$(am__dirstamp) + -rm -f statistics/$(DEPDIR)/$(am__dirstamp) + -rm -f statistics/$(am__dirstamp) + -rm -f styles/$(DEPDIR)/$(am__dirstamp) + -rm -f styles/$(am__dirstamp) + -rm -f sword/$(DEPDIR)/$(am__dirstamp) + -rm -f sword/$(am__dirstamp) + -rm -f sync/$(DEPDIR)/$(am__dirstamp) + -rm -f sync/$(am__dirstamp) + -rm -f system/$(DEPDIR)/$(am__dirstamp) + -rm -f system/$(am__dirstamp) + -rm -f tasks/$(DEPDIR)/$(am__dirstamp) + -rm -f tasks/$(am__dirstamp) + -rm -f tbsx/$(DEPDIR)/$(am__dirstamp) + -rm -f tbsx/$(am__dirstamp) + -rm -f text/$(DEPDIR)/$(am__dirstamp) + -rm -f text/$(am__dirstamp) + -rm -f tidy/$(DEPDIR)/$(am__dirstamp) + -rm -f tidy/$(am__dirstamp) + -rm -f timer/$(DEPDIR)/$(am__dirstamp) + -rm -f timer/$(am__dirstamp) + -rm -f tmp/$(DEPDIR)/$(am__dirstamp) + -rm -f tmp/$(am__dirstamp) + -rm -f trash/$(DEPDIR)/$(am__dirstamp) + -rm -f trash/$(am__dirstamp) + -rm -f user/$(DEPDIR)/$(am__dirstamp) + -rm -f user/$(am__dirstamp) + -rm -f utf8proc/$(DEPDIR)/$(am__dirstamp) + -rm -f utf8proc/$(am__dirstamp) + -rm -f versification/$(DEPDIR)/$(am__dirstamp) + -rm -f versification/$(am__dirstamp) + -rm -f webbb/$(DEPDIR)/$(am__dirstamp) + -rm -f webbb/$(am__dirstamp) + -rm -f webserver/$(DEPDIR)/$(am__dirstamp) + -rm -f webserver/$(am__dirstamp) + -rm -f workspace/$(DEPDIR)/$(am__dirstamp) + -rm -f workspace/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f access/$(DEPDIR)/bible.Po + -rm -f access/$(DEPDIR)/logic.Po + -rm -f access/$(DEPDIR)/user.Po + -rm -f assets/$(DEPDIR)/external.Po + -rm -f assets/$(DEPDIR)/header.Po + -rm -f assets/$(DEPDIR)/page.Po + -rm -f assets/$(DEPDIR)/view.Po + -rm -f bb/$(DEPDIR)/book.Po + -rm -f bb/$(DEPDIR)/chapter.Po + -rm -f bb/$(DEPDIR)/css.Po + -rm -f bb/$(DEPDIR)/import.Po + -rm -f bb/$(DEPDIR)/import_run.Po + -rm -f bb/$(DEPDIR)/logic.Po + -rm -f bb/$(DEPDIR)/manage.Po + -rm -f bb/$(DEPDIR)/order.Po + -rm -f bb/$(DEPDIR)/settings.Po + -rm -f book/$(DEPDIR)/create.Po + -rm -f bootstrap/$(DEPDIR)/bootstrap.Po + -rm -f changes/$(DEPDIR)/change.Po + -rm -f changes/$(DEPDIR)/changes.Po + -rm -f changes/$(DEPDIR)/logic.Po + -rm -f changes/$(DEPDIR)/manage.Po + -rm -f changes/$(DEPDIR)/modifications.Po + -rm -f changes/$(DEPDIR)/statistics.Po + -rm -f checks/$(DEPDIR)/french.Po + -rm -f checks/$(DEPDIR)/headers.Po + -rm -f checks/$(DEPDIR)/index.Po + -rm -f checks/$(DEPDIR)/logic.Po + -rm -f checks/$(DEPDIR)/pairs.Po + -rm -f checks/$(DEPDIR)/run.Po + -rm -f checks/$(DEPDIR)/sentences.Po + -rm -f checks/$(DEPDIR)/settings.Po + -rm -f checks/$(DEPDIR)/settingspairs.Po + -rm -f checks/$(DEPDIR)/settingspatterns.Po + -rm -f checks/$(DEPDIR)/settingssentences.Po + -rm -f checks/$(DEPDIR)/space.Po + -rm -f checks/$(DEPDIR)/suppress.Po + -rm -f checks/$(DEPDIR)/usfm.Po + -rm -f checks/$(DEPDIR)/verses.Po + -rm -f checks/$(DEPDIR)/versification.Po + -rm -f checksum/$(DEPDIR)/logic.Po + -rm -f client/$(DEPDIR)/index.Po + -rm -f client/$(DEPDIR)/logic.Po + -rm -f collaboration/$(DEPDIR)/index.Po + -rm -f collaboration/$(DEPDIR)/link.Po + -rm -f collaboration/$(DEPDIR)/settings.Po + -rm -f compare/$(DEPDIR)/compare.Po + -rm -f compare/$(DEPDIR)/index.Po + -rm -f config/$(DEPDIR)/globals.Po + -rm -f config/$(DEPDIR)/logic.Po + -rm -f confirm/$(DEPDIR)/worker.Po + -rm -f consistency/$(DEPDIR)/index.Po + -rm -f consistency/$(DEPDIR)/input.Po + -rm -f consistency/$(DEPDIR)/logic.Po + -rm -f consistency/$(DEPDIR)/poll.Po + -rm -f database/$(DEPDIR)/abbottsmith.Po + -rm -f database/$(DEPDIR)/bibleactions.Po + -rm -f database/$(DEPDIR)/bibleimages.Po + -rm -f database/$(DEPDIR)/bibles.Po + -rm -f database/$(DEPDIR)/books.Po + -rm -f database/$(DEPDIR)/cache.Po + -rm -f database/$(DEPDIR)/check.Po + -rm -f database/$(DEPDIR)/confirm.Po + -rm -f database/$(DEPDIR)/etcbc4.Po + -rm -f database/$(DEPDIR)/git.Po + -rm -f database/$(DEPDIR)/hebrewlexicon.Po + -rm -f database/$(DEPDIR)/imageresources.Po + -rm -f database/$(DEPDIR)/ipc.Po + -rm -f database/$(DEPDIR)/jobs.Po + -rm -f database/$(DEPDIR)/kjv.Po + -rm -f database/$(DEPDIR)/localization.Po + -rm -f database/$(DEPDIR)/logic.Po + -rm -f database/$(DEPDIR)/login.Po + -rm -f database/$(DEPDIR)/logs.Po + -rm -f database/$(DEPDIR)/mail.Po + -rm -f database/$(DEPDIR)/maintenance.Po + -rm -f database/$(DEPDIR)/mappings.Po + -rm -f database/$(DEPDIR)/modifications.Po + -rm -f database/$(DEPDIR)/morphgnt.Po + -rm -f database/$(DEPDIR)/navigation.Po + -rm -f database/$(DEPDIR)/noteactions.Po + -rm -f database/$(DEPDIR)/noteassignment.Po + -rm -f database/$(DEPDIR)/notes.Po + -rm -f database/$(DEPDIR)/oshb.Po + -rm -f database/$(DEPDIR)/privileges.Po + -rm -f database/$(DEPDIR)/sample.Po + -rm -f database/$(DEPDIR)/sblgnt.Po + -rm -f database/$(DEPDIR)/sprint.Po + -rm -f database/$(DEPDIR)/sqlite.Po + -rm -f database/$(DEPDIR)/state.Po + -rm -f database/$(DEPDIR)/statistics.Po + -rm -f database/$(DEPDIR)/strong.Po + -rm -f database/$(DEPDIR)/styles.Po + -rm -f database/$(DEPDIR)/userresources.Po + -rm -f database/$(DEPDIR)/users.Po + -rm -f database/$(DEPDIR)/usfmresources.Po + -rm -f database/$(DEPDIR)/versifications.Po + -rm -f database/$(DEPDIR)/volatile.Po + -rm -f database/config/$(DEPDIR)/bible.Po + -rm -f database/config/$(DEPDIR)/general.Po + -rm -f database/config/$(DEPDIR)/user.Po + -rm -f demo/$(DEPDIR)/logic.Po + -rm -f developer/$(DEPDIR)/delay.Po + -rm -f developer/$(DEPDIR)/index.Po + -rm -f developer/$(DEPDIR)/logic.Po + -rm -f dialog/$(DEPDIR)/books.Po + -rm -f dialog/$(DEPDIR)/color.Po + -rm -f dialog/$(DEPDIR)/entry.Po + -rm -f dialog/$(DEPDIR)/list.Po + -rm -f dialog/$(DEPDIR)/list2.Po + -rm -f dialog/$(DEPDIR)/upload.Po + -rm -f dialog/$(DEPDIR)/yes.Po + -rm -f edit/$(DEPDIR)/edit.Po + -rm -f edit/$(DEPDIR)/id.Po + -rm -f edit/$(DEPDIR)/index.Po + -rm -f edit/$(DEPDIR)/load.Po + -rm -f edit/$(DEPDIR)/logic.Po + -rm -f edit/$(DEPDIR)/navigate.Po + -rm -f edit/$(DEPDIR)/position.Po + -rm -f edit/$(DEPDIR)/preview.Po + -rm -f edit/$(DEPDIR)/save.Po + -rm -f edit/$(DEPDIR)/styles.Po + -rm -f edit/$(DEPDIR)/update.Po + -rm -f editone2/$(DEPDIR)/index.Po + -rm -f editone2/$(DEPDIR)/load.Po + -rm -f editone2/$(DEPDIR)/logic.Po + -rm -f editone2/$(DEPDIR)/save.Po + -rm -f editone2/$(DEPDIR)/update.Po + -rm -f editone2/$(DEPDIR)/verse.Po + -rm -f editor/$(DEPDIR)/html2format.Po + -rm -f editor/$(DEPDIR)/html2usfm.Po + -rm -f editor/$(DEPDIR)/id.Po + -rm -f editor/$(DEPDIR)/select.Po + -rm -f editor/$(DEPDIR)/style.Po + -rm -f editor/$(DEPDIR)/styles.Po + -rm -f editor/$(DEPDIR)/usfm2html.Po + -rm -f editusfm/$(DEPDIR)/focus.Po + -rm -f editusfm/$(DEPDIR)/index.Po + -rm -f editusfm/$(DEPDIR)/load.Po + -rm -f editusfm/$(DEPDIR)/offset.Po + -rm -f editusfm/$(DEPDIR)/save.Po + -rm -f email/$(DEPDIR)/index.Po + -rm -f email/$(DEPDIR)/receive.Po + -rm -f email/$(DEPDIR)/send.Po + -rm -f esword/$(DEPDIR)/text.Po + -rm -f executable/$(DEPDIR)/bibledit.Po + -rm -f executable/$(DEPDIR)/generate.Po + -rm -f export/$(DEPDIR)/bibledropbox.Po + -rm -f export/$(DEPDIR)/esword.Po + -rm -f export/$(DEPDIR)/html.Po + -rm -f export/$(DEPDIR)/index.Po + -rm -f export/$(DEPDIR)/info.Po + -rm -f export/$(DEPDIR)/logic.Po + -rm -f export/$(DEPDIR)/odt.Po + -rm -f export/$(DEPDIR)/onlinebible.Po + -rm -f export/$(DEPDIR)/textusfm.Po + -rm -f export/$(DEPDIR)/usfm.Po + -rm -f export/$(DEPDIR)/web.Po + -rm -f filter/$(DEPDIR)/archive.Po + -rm -f filter/$(DEPDIR)/css.Po + -rm -f filter/$(DEPDIR)/date.Po + -rm -f filter/$(DEPDIR)/diff.Po + -rm -f filter/$(DEPDIR)/git.Po + -rm -f filter/$(DEPDIR)/google.Po + -rm -f filter/$(DEPDIR)/html.Po + -rm -f filter/$(DEPDIR)/image.Po + -rm -f filter/$(DEPDIR)/mail.Po + -rm -f filter/$(DEPDIR)/md5.Po + -rm -f filter/$(DEPDIR)/memory.Po + -rm -f filter/$(DEPDIR)/merge.Po + -rm -f filter/$(DEPDIR)/note.Po + -rm -f filter/$(DEPDIR)/passage.Po + -rm -f filter/$(DEPDIR)/roles.Po + -rm -f filter/$(DEPDIR)/shell.Po + -rm -f filter/$(DEPDIR)/string.Po + -rm -f filter/$(DEPDIR)/text.Po + -rm -f filter/$(DEPDIR)/url.Po + -rm -f filter/$(DEPDIR)/usfm.Po + -rm -f filter/$(DEPDIR)/webview.Po + -rm -f flate/$(DEPDIR)/flate.Po + -rm -f fonts/$(DEPDIR)/logic.Po + -rm -f help/$(DEPDIR)/index.Po + -rm -f html/$(DEPDIR)/header.Po + -rm -f html/$(DEPDIR)/text.Po + -rm -f i18n/$(DEPDIR)/logic.Po + -rm -f images/$(DEPDIR)/fetch.Po + -rm -f images/$(DEPDIR)/index.Po + -rm -f images/$(DEPDIR)/logic.Po + -rm -f images/$(DEPDIR)/view.Po + -rm -f index/$(DEPDIR)/index.Po + -rm -f index/$(DEPDIR)/listing.Po + -rm -f ipc/$(DEPDIR)/focus.Po + -rm -f ipc/$(DEPDIR)/notes.Po + -rm -f jobs/$(DEPDIR)/index.Po + -rm -f journal/$(DEPDIR)/index.Po + -rm -f journal/$(DEPDIR)/logic.Po + -rm -f jsonxx/$(DEPDIR)/jsonxx.Po + -rm -f ldap/$(DEPDIR)/logic.Po + -rm -f lexicon/$(DEPDIR)/definition.Po + -rm -f lexicon/$(DEPDIR)/logic.Po + -rm -f library/$(DEPDIR)/bibledit.Po + -rm -f library/$(DEPDIR)/locks.Po + -rm -f locale/$(DEPDIR)/logic.Po + -rm -f locale/$(DEPDIR)/translate.Po + -rm -f manage/$(DEPDIR)/accounts.Po + -rm -f manage/$(DEPDIR)/exports.Po + -rm -f manage/$(DEPDIR)/hyphenate.Po + -rm -f manage/$(DEPDIR)/hyphenation.Po + -rm -f manage/$(DEPDIR)/index.Po + -rm -f manage/$(DEPDIR)/privileges.Po + -rm -f manage/$(DEPDIR)/users.Po + -rm -f manage/$(DEPDIR)/write.Po + -rm -f mapping/$(DEPDIR)/index.Po + -rm -f mapping/$(DEPDIR)/map.Po + -rm -f mbedtls/$(DEPDIR)/aes.Po + -rm -f mbedtls/$(DEPDIR)/arc4.Po + -rm -f mbedtls/$(DEPDIR)/asn1parse.Po + -rm -f mbedtls/$(DEPDIR)/asn1write.Po + -rm -f mbedtls/$(DEPDIR)/base64.Po + -rm -f mbedtls/$(DEPDIR)/bignum.Po + -rm -f mbedtls/$(DEPDIR)/blowfish.Po + -rm -f mbedtls/$(DEPDIR)/camellia.Po + -rm -f mbedtls/$(DEPDIR)/ccm.Po + -rm -f mbedtls/$(DEPDIR)/certs.Po + -rm -f mbedtls/$(DEPDIR)/chacha20.Po + -rm -f mbedtls/$(DEPDIR)/chachapoly.Po + -rm -f mbedtls/$(DEPDIR)/cipher.Po + -rm -f mbedtls/$(DEPDIR)/cipher_wrap.Po + -rm -f mbedtls/$(DEPDIR)/ctr_drbg.Po + -rm -f mbedtls/$(DEPDIR)/debug.Po + -rm -f mbedtls/$(DEPDIR)/des.Po + -rm -f mbedtls/$(DEPDIR)/dhm.Po + -rm -f mbedtls/$(DEPDIR)/ecdh.Po + -rm -f mbedtls/$(DEPDIR)/ecdsa.Po + -rm -f mbedtls/$(DEPDIR)/ecp.Po + -rm -f mbedtls/$(DEPDIR)/ecp_curves.Po + -rm -f mbedtls/$(DEPDIR)/entropy.Po + -rm -f mbedtls/$(DEPDIR)/entropy_poll.Po + -rm -f mbedtls/$(DEPDIR)/error.Po + -rm -f mbedtls/$(DEPDIR)/gcm.Po + -rm -f mbedtls/$(DEPDIR)/hmac_drbg.Po + -rm -f mbedtls/$(DEPDIR)/md.Po + -rm -f mbedtls/$(DEPDIR)/md5.Po + -rm -f mbedtls/$(DEPDIR)/md_wrap.Po + -rm -f mbedtls/$(DEPDIR)/net_sockets.Po + -rm -f mbedtls/$(DEPDIR)/oid.Po + -rm -f mbedtls/$(DEPDIR)/pem.Po + -rm -f mbedtls/$(DEPDIR)/pk.Po + -rm -f mbedtls/$(DEPDIR)/pk_wrap.Po + -rm -f mbedtls/$(DEPDIR)/pkcs12.Po + -rm -f mbedtls/$(DEPDIR)/pkcs5.Po + -rm -f mbedtls/$(DEPDIR)/pkparse.Po + -rm -f mbedtls/$(DEPDIR)/pkwrite.Po + -rm -f mbedtls/$(DEPDIR)/platform.Po + -rm -f mbedtls/$(DEPDIR)/platform_util.Po + -rm -f mbedtls/$(DEPDIR)/poly1305.Po + -rm -f mbedtls/$(DEPDIR)/ripemd160.Po + -rm -f mbedtls/$(DEPDIR)/rsa.Po + -rm -f mbedtls/$(DEPDIR)/rsa_internal.Po + -rm -f mbedtls/$(DEPDIR)/sha1.Po + -rm -f mbedtls/$(DEPDIR)/sha256.Po + -rm -f mbedtls/$(DEPDIR)/sha512.Po + -rm -f mbedtls/$(DEPDIR)/ssl_cache.Po + -rm -f mbedtls/$(DEPDIR)/ssl_ciphersuites.Po + -rm -f mbedtls/$(DEPDIR)/ssl_cli.Po + -rm -f mbedtls/$(DEPDIR)/ssl_cookie.Po + -rm -f mbedtls/$(DEPDIR)/ssl_srv.Po + -rm -f mbedtls/$(DEPDIR)/ssl_ticket.Po + -rm -f mbedtls/$(DEPDIR)/ssl_tls.Po + -rm -f mbedtls/$(DEPDIR)/threading.Po + -rm -f mbedtls/$(DEPDIR)/timing.Po + -rm -f mbedtls/$(DEPDIR)/version.Po + -rm -f mbedtls/$(DEPDIR)/version_features.Po + -rm -f mbedtls/$(DEPDIR)/x509.Po + -rm -f mbedtls/$(DEPDIR)/x509_create.Po + -rm -f mbedtls/$(DEPDIR)/x509_crl.Po + -rm -f mbedtls/$(DEPDIR)/x509_crt.Po + -rm -f mbedtls/$(DEPDIR)/x509_csr.Po + -rm -f mbedtls/$(DEPDIR)/x509write_crt.Po + -rm -f mbedtls/$(DEPDIR)/x509write_csr.Po + -rm -f mbedtls/$(DEPDIR)/xtea.Po + -rm -f menu/$(DEPDIR)/index.Po + -rm -f menu/$(DEPDIR)/logic.Po + -rm -f microtar/$(DEPDIR)/microtar.Po + -rm -f mimetic098/$(DEPDIR)/body.Po + -rm -f mimetic098/$(DEPDIR)/contentdescription.Po + -rm -f mimetic098/$(DEPDIR)/contentdisposition.Po + -rm -f mimetic098/$(DEPDIR)/contentid.Po + -rm -f mimetic098/$(DEPDIR)/contenttransferencoding.Po + -rm -f mimetic098/$(DEPDIR)/contenttype.Po + -rm -f mimetic098/$(DEPDIR)/fieldparam.Po + -rm -f mimetic098/$(DEPDIR)/header.Po + -rm -f mimetic098/$(DEPDIR)/mimeentity.Po + -rm -f mimetic098/$(DEPDIR)/mimeversion.Po + -rm -f mimetic098/$(DEPDIR)/strutils.Po + -rm -f mimetic098/$(DEPDIR)/utils.Po + -rm -f mimetic098/$(DEPDIR)/version.Po + -rm -f mimetic098/codec/$(DEPDIR)/base64.Po + -rm -f mimetic098/os/$(DEPDIR)/file_iterator.Po + -rm -f mimetic098/os/$(DEPDIR)/mmfile.Po + -rm -f mimetic098/os/$(DEPDIR)/utils.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/address.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/addresslist.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/datetime.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/field.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/fieldvalue.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/group.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/header.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/mailbox.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/mailboxlist.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/message.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/messageid.Po + -rm -f miniz/$(DEPDIR)/miniz.Po + -rm -f navigation/$(DEPDIR)/paratext.Po + -rm -f navigation/$(DEPDIR)/passage.Po + -rm -f navigation/$(DEPDIR)/poll.Po + -rm -f navigation/$(DEPDIR)/update.Po + -rm -f nmt/$(DEPDIR)/index.Po + -rm -f nmt/$(DEPDIR)/logic.Po + -rm -f notes/$(DEPDIR)/actions.Po + -rm -f notes/$(DEPDIR)/assign-1.Po + -rm -f notes/$(DEPDIR)/assign-n.Po + -rm -f notes/$(DEPDIR)/bb-1.Po + -rm -f notes/$(DEPDIR)/bb-n.Po + -rm -f notes/$(DEPDIR)/bulk.Po + -rm -f notes/$(DEPDIR)/click.Po + -rm -f notes/$(DEPDIR)/comment.Po + -rm -f notes/$(DEPDIR)/create.Po + -rm -f notes/$(DEPDIR)/edit.Po + -rm -f notes/$(DEPDIR)/index.Po + -rm -f notes/$(DEPDIR)/logic.Po + -rm -f notes/$(DEPDIR)/note.Po + -rm -f notes/$(DEPDIR)/notes.Po + -rm -f notes/$(DEPDIR)/poll.Po + -rm -f notes/$(DEPDIR)/select.Po + -rm -f notes/$(DEPDIR)/severity-1.Po + -rm -f notes/$(DEPDIR)/severity-n.Po + -rm -f notes/$(DEPDIR)/status-1.Po + -rm -f notes/$(DEPDIR)/status-n.Po + -rm -f notes/$(DEPDIR)/summary.Po + -rm -f notes/$(DEPDIR)/unassign-n.Po + -rm -f notes/$(DEPDIR)/verses.Po + -rm -f odf/$(DEPDIR)/text.Po + -rm -f olb/$(DEPDIR)/text.Po + -rm -f paratext/$(DEPDIR)/index.Po + -rm -f paratext/$(DEPDIR)/logic.Po + -rm -f parsewebdata/$(DEPDIR)/ParseMultipartFormData.Po + -rm -f parsewebdata/$(DEPDIR)/ParseWebData.Po + -rm -f personalize/$(DEPDIR)/index.Po + -rm -f public/$(DEPDIR)/chapter.Po + -rm -f public/$(DEPDIR)/comment.Po + -rm -f public/$(DEPDIR)/create.Po + -rm -f public/$(DEPDIR)/index.Po + -rm -f public/$(DEPDIR)/logic.Po + -rm -f public/$(DEPDIR)/login.Po + -rm -f public/$(DEPDIR)/new.Po + -rm -f public/$(DEPDIR)/note.Po + -rm -f public/$(DEPDIR)/notes.Po + -rm -f pugixml/$(DEPDIR)/pugixml.Po + -rm -f pugixml/$(DEPDIR)/utils.Po + -rm -f quill/$(DEPDIR)/logic.Po + -rm -f read/$(DEPDIR)/index.Po + -rm -f read/$(DEPDIR)/load.Po + -rm -f read/$(DEPDIR)/verse.Po + -rm -f redirect/$(DEPDIR)/index.Po + -rm -f related/$(DEPDIR)/logic.Po + -rm -f resource/$(DEPDIR)/bb2resource.Po + -rm -f resource/$(DEPDIR)/bbgateway.Po + -rm -f resource/$(DEPDIR)/cache.Po + -rm -f resource/$(DEPDIR)/comparative1edit.Po + -rm -f resource/$(DEPDIR)/comparative9edit.Po + -rm -f resource/$(DEPDIR)/convert2bible.Po + -rm -f resource/$(DEPDIR)/convert2resource.Po + -rm -f resource/$(DEPDIR)/divider.Po + -rm -f resource/$(DEPDIR)/download.Po + -rm -f resource/$(DEPDIR)/external.Po + -rm -f resource/$(DEPDIR)/get.Po + -rm -f resource/$(DEPDIR)/image.Po + -rm -f resource/$(DEPDIR)/imagefetch.Po + -rm -f resource/$(DEPDIR)/images.Po + -rm -f resource/$(DEPDIR)/img.Po + -rm -f resource/$(DEPDIR)/index.Po + -rm -f resource/$(DEPDIR)/logic.Po + -rm -f resource/$(DEPDIR)/manage.Po + -rm -f resource/$(DEPDIR)/organize.Po + -rm -f resource/$(DEPDIR)/print.Po + -rm -f resource/$(DEPDIR)/select.Po + -rm -f resource/$(DEPDIR)/studylight.Po + -rm -f resource/$(DEPDIR)/sword.Po + -rm -f resource/$(DEPDIR)/translated1edit.Po + -rm -f resource/$(DEPDIR)/translated9edit.Po + -rm -f resource/$(DEPDIR)/unload.Po + -rm -f resource/$(DEPDIR)/user1edit.Po + -rm -f resource/$(DEPDIR)/user1view.Po + -rm -f resource/$(DEPDIR)/user9edit.Po + -rm -f resource/$(DEPDIR)/user9view.Po + -rm -f rss/$(DEPDIR)/feed.Po + -rm -f rss/$(DEPDIR)/logic.Po + -rm -f search/$(DEPDIR)/all.Po + -rm -f search/$(DEPDIR)/getids.Po + -rm -f search/$(DEPDIR)/getids2.Po + -rm -f search/$(DEPDIR)/index.Po + -rm -f search/$(DEPDIR)/logic.Po + -rm -f search/$(DEPDIR)/originals.Po + -rm -f search/$(DEPDIR)/rebibles.Po + -rm -f search/$(DEPDIR)/renotes.Po + -rm -f search/$(DEPDIR)/replace.Po + -rm -f search/$(DEPDIR)/replace2.Po + -rm -f search/$(DEPDIR)/replacego.Po + -rm -f search/$(DEPDIR)/replacego2.Po + -rm -f search/$(DEPDIR)/replacepre.Po + -rm -f search/$(DEPDIR)/replacepre2.Po + -rm -f search/$(DEPDIR)/search2.Po + -rm -f search/$(DEPDIR)/similar.Po + -rm -f search/$(DEPDIR)/strong.Po + -rm -f search/$(DEPDIR)/strongs.Po + -rm -f sendreceive/$(DEPDIR)/bibles.Po + -rm -f sendreceive/$(DEPDIR)/changes.Po + -rm -f sendreceive/$(DEPDIR)/files.Po + -rm -f sendreceive/$(DEPDIR)/index.Po + -rm -f sendreceive/$(DEPDIR)/logic.Po + -rm -f sendreceive/$(DEPDIR)/notes.Po + -rm -f sendreceive/$(DEPDIR)/resources.Po + -rm -f sendreceive/$(DEPDIR)/sendreceive.Po + -rm -f sendreceive/$(DEPDIR)/settings.Po + -rm -f session/$(DEPDIR)/confirm.Po + -rm -f session/$(DEPDIR)/logic.Po + -rm -f session/$(DEPDIR)/login.Po + -rm -f session/$(DEPDIR)/logout.Po + -rm -f session/$(DEPDIR)/password.Po + -rm -f session/$(DEPDIR)/signup.Po + -rm -f session/$(DEPDIR)/switch.Po + -rm -f setup/$(DEPDIR)/index.Po + -rm -f setup/$(DEPDIR)/logic.Po + -rm -f sources/$(DEPDIR)/abbott-smith.Po + -rm -f sources/$(DEPDIR)/etcbc4.Po + -rm -f sources/$(DEPDIR)/hebrewlexicon.Po + -rm -f sources/$(DEPDIR)/kjv.Po + -rm -f sources/$(DEPDIR)/morphgnt.Po + -rm -f sources/$(DEPDIR)/morphhb.Po + -rm -f sources/$(DEPDIR)/oshb.Po + -rm -f sources/$(DEPDIR)/styles.Po + -rm -f sprint/$(DEPDIR)/burndown.Po + -rm -f sprint/$(DEPDIR)/index.Po + -rm -f sqlite/$(DEPDIR)/sqlite3.Po + -rm -f statistics/$(DEPDIR)/statistics.Po + -rm -f styles/$(DEPDIR)/css.Po + -rm -f styles/$(DEPDIR)/indexm.Po + -rm -f styles/$(DEPDIR)/logic.Po + -rm -f styles/$(DEPDIR)/sheetm.Po + -rm -f styles/$(DEPDIR)/sheets.Po + -rm -f styles/$(DEPDIR)/view.Po + -rm -f sword/$(DEPDIR)/logic.Po + -rm -f sync/$(DEPDIR)/bibles.Po + -rm -f sync/$(DEPDIR)/changes.Po + -rm -f sync/$(DEPDIR)/files.Po + -rm -f sync/$(DEPDIR)/logic.Po + -rm -f sync/$(DEPDIR)/mail.Po + -rm -f sync/$(DEPDIR)/notes.Po + -rm -f sync/$(DEPDIR)/resources.Po + -rm -f sync/$(DEPDIR)/settings.Po + -rm -f sync/$(DEPDIR)/setup.Po + -rm -f sync/$(DEPDIR)/usfmresources.Po + -rm -f system/$(DEPDIR)/googletranslate.Po + -rm -f system/$(DEPDIR)/index.Po + -rm -f system/$(DEPDIR)/logic.Po + -rm -f tasks/$(DEPDIR)/logic.Po + -rm -f tasks/$(DEPDIR)/run.Po + -rm -f tbsx/$(DEPDIR)/text.Po + -rm -f text/$(DEPDIR)/text.Po + -rm -f tidy/$(DEPDIR)/access.Po + -rm -f tidy/$(DEPDIR)/alloc.Po + -rm -f tidy/$(DEPDIR)/attrdict.Po + -rm -f tidy/$(DEPDIR)/attrs.Po + -rm -f tidy/$(DEPDIR)/buffio.Po + -rm -f tidy/$(DEPDIR)/charsets.Po + -rm -f tidy/$(DEPDIR)/clean.Po + -rm -f tidy/$(DEPDIR)/config.Po + -rm -f tidy/$(DEPDIR)/entities.Po + -rm -f tidy/$(DEPDIR)/fileio.Po + -rm -f tidy/$(DEPDIR)/gdoc.Po + -rm -f tidy/$(DEPDIR)/istack.Po + -rm -f tidy/$(DEPDIR)/language.Po + -rm -f tidy/$(DEPDIR)/lexer.Po + -rm -f tidy/$(DEPDIR)/mappedio.Po + -rm -f tidy/$(DEPDIR)/message.Po + -rm -f tidy/$(DEPDIR)/messageobj.Po + -rm -f tidy/$(DEPDIR)/parser.Po + -rm -f tidy/$(DEPDIR)/pprint.Po + -rm -f tidy/$(DEPDIR)/sprtf.Po + -rm -f tidy/$(DEPDIR)/streamio.Po + -rm -f tidy/$(DEPDIR)/tagask.Po + -rm -f tidy/$(DEPDIR)/tags.Po + -rm -f tidy/$(DEPDIR)/tidylib.Po + -rm -f tidy/$(DEPDIR)/tmbstr.Po + -rm -f tidy/$(DEPDIR)/utf8.Po + -rm -f timer/$(DEPDIR)/index.Po + -rm -f tmp/$(DEPDIR)/tmp.Po + -rm -f trash/$(DEPDIR)/handler.Po + -rm -f user/$(DEPDIR)/account.Po + -rm -f user/$(DEPDIR)/logic.Po + -rm -f user/$(DEPDIR)/notifications.Po + -rm -f utf8proc/$(DEPDIR)/utf8proc.Po + -rm -f versification/$(DEPDIR)/index.Po + -rm -f versification/$(DEPDIR)/logic.Po + -rm -f versification/$(DEPDIR)/system.Po + -rm -f webbb/$(DEPDIR)/search.Po + -rm -f webserver/$(DEPDIR)/http.Po + -rm -f webserver/$(DEPDIR)/request.Po + -rm -f webserver/$(DEPDIR)/webserver.Po + -rm -f workspace/$(DEPDIR)/index.Po + -rm -f workspace/$(DEPDIR)/logic.Po + -rm -f workspace/$(DEPDIR)/organize.Po + -rm -f workspace/$(DEPDIR)/settings.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f access/$(DEPDIR)/bible.Po + -rm -f access/$(DEPDIR)/logic.Po + -rm -f access/$(DEPDIR)/user.Po + -rm -f assets/$(DEPDIR)/external.Po + -rm -f assets/$(DEPDIR)/header.Po + -rm -f assets/$(DEPDIR)/page.Po + -rm -f assets/$(DEPDIR)/view.Po + -rm -f bb/$(DEPDIR)/book.Po + -rm -f bb/$(DEPDIR)/chapter.Po + -rm -f bb/$(DEPDIR)/css.Po + -rm -f bb/$(DEPDIR)/import.Po + -rm -f bb/$(DEPDIR)/import_run.Po + -rm -f bb/$(DEPDIR)/logic.Po + -rm -f bb/$(DEPDIR)/manage.Po + -rm -f bb/$(DEPDIR)/order.Po + -rm -f bb/$(DEPDIR)/settings.Po + -rm -f book/$(DEPDIR)/create.Po + -rm -f bootstrap/$(DEPDIR)/bootstrap.Po + -rm -f changes/$(DEPDIR)/change.Po + -rm -f changes/$(DEPDIR)/changes.Po + -rm -f changes/$(DEPDIR)/logic.Po + -rm -f changes/$(DEPDIR)/manage.Po + -rm -f changes/$(DEPDIR)/modifications.Po + -rm -f changes/$(DEPDIR)/statistics.Po + -rm -f checks/$(DEPDIR)/french.Po + -rm -f checks/$(DEPDIR)/headers.Po + -rm -f checks/$(DEPDIR)/index.Po + -rm -f checks/$(DEPDIR)/logic.Po + -rm -f checks/$(DEPDIR)/pairs.Po + -rm -f checks/$(DEPDIR)/run.Po + -rm -f checks/$(DEPDIR)/sentences.Po + -rm -f checks/$(DEPDIR)/settings.Po + -rm -f checks/$(DEPDIR)/settingspairs.Po + -rm -f checks/$(DEPDIR)/settingspatterns.Po + -rm -f checks/$(DEPDIR)/settingssentences.Po + -rm -f checks/$(DEPDIR)/space.Po + -rm -f checks/$(DEPDIR)/suppress.Po + -rm -f checks/$(DEPDIR)/usfm.Po + -rm -f checks/$(DEPDIR)/verses.Po + -rm -f checks/$(DEPDIR)/versification.Po + -rm -f checksum/$(DEPDIR)/logic.Po + -rm -f client/$(DEPDIR)/index.Po + -rm -f client/$(DEPDIR)/logic.Po + -rm -f collaboration/$(DEPDIR)/index.Po + -rm -f collaboration/$(DEPDIR)/link.Po + -rm -f collaboration/$(DEPDIR)/settings.Po + -rm -f compare/$(DEPDIR)/compare.Po + -rm -f compare/$(DEPDIR)/index.Po + -rm -f config/$(DEPDIR)/globals.Po + -rm -f config/$(DEPDIR)/logic.Po + -rm -f confirm/$(DEPDIR)/worker.Po + -rm -f consistency/$(DEPDIR)/index.Po + -rm -f consistency/$(DEPDIR)/input.Po + -rm -f consistency/$(DEPDIR)/logic.Po + -rm -f consistency/$(DEPDIR)/poll.Po + -rm -f database/$(DEPDIR)/abbottsmith.Po + -rm -f database/$(DEPDIR)/bibleactions.Po + -rm -f database/$(DEPDIR)/bibleimages.Po + -rm -f database/$(DEPDIR)/bibles.Po + -rm -f database/$(DEPDIR)/books.Po + -rm -f database/$(DEPDIR)/cache.Po + -rm -f database/$(DEPDIR)/check.Po + -rm -f database/$(DEPDIR)/confirm.Po + -rm -f database/$(DEPDIR)/etcbc4.Po + -rm -f database/$(DEPDIR)/git.Po + -rm -f database/$(DEPDIR)/hebrewlexicon.Po + -rm -f database/$(DEPDIR)/imageresources.Po + -rm -f database/$(DEPDIR)/ipc.Po + -rm -f database/$(DEPDIR)/jobs.Po + -rm -f database/$(DEPDIR)/kjv.Po + -rm -f database/$(DEPDIR)/localization.Po + -rm -f database/$(DEPDIR)/logic.Po + -rm -f database/$(DEPDIR)/login.Po + -rm -f database/$(DEPDIR)/logs.Po + -rm -f database/$(DEPDIR)/mail.Po + -rm -f database/$(DEPDIR)/maintenance.Po + -rm -f database/$(DEPDIR)/mappings.Po + -rm -f database/$(DEPDIR)/modifications.Po + -rm -f database/$(DEPDIR)/morphgnt.Po + -rm -f database/$(DEPDIR)/navigation.Po + -rm -f database/$(DEPDIR)/noteactions.Po + -rm -f database/$(DEPDIR)/noteassignment.Po + -rm -f database/$(DEPDIR)/notes.Po + -rm -f database/$(DEPDIR)/oshb.Po + -rm -f database/$(DEPDIR)/privileges.Po + -rm -f database/$(DEPDIR)/sample.Po + -rm -f database/$(DEPDIR)/sblgnt.Po + -rm -f database/$(DEPDIR)/sprint.Po + -rm -f database/$(DEPDIR)/sqlite.Po + -rm -f database/$(DEPDIR)/state.Po + -rm -f database/$(DEPDIR)/statistics.Po + -rm -f database/$(DEPDIR)/strong.Po + -rm -f database/$(DEPDIR)/styles.Po + -rm -f database/$(DEPDIR)/userresources.Po + -rm -f database/$(DEPDIR)/users.Po + -rm -f database/$(DEPDIR)/usfmresources.Po + -rm -f database/$(DEPDIR)/versifications.Po + -rm -f database/$(DEPDIR)/volatile.Po + -rm -f database/config/$(DEPDIR)/bible.Po + -rm -f database/config/$(DEPDIR)/general.Po + -rm -f database/config/$(DEPDIR)/user.Po + -rm -f demo/$(DEPDIR)/logic.Po + -rm -f developer/$(DEPDIR)/delay.Po + -rm -f developer/$(DEPDIR)/index.Po + -rm -f developer/$(DEPDIR)/logic.Po + -rm -f dialog/$(DEPDIR)/books.Po + -rm -f dialog/$(DEPDIR)/color.Po + -rm -f dialog/$(DEPDIR)/entry.Po + -rm -f dialog/$(DEPDIR)/list.Po + -rm -f dialog/$(DEPDIR)/list2.Po + -rm -f dialog/$(DEPDIR)/upload.Po + -rm -f dialog/$(DEPDIR)/yes.Po + -rm -f edit/$(DEPDIR)/edit.Po + -rm -f edit/$(DEPDIR)/id.Po + -rm -f edit/$(DEPDIR)/index.Po + -rm -f edit/$(DEPDIR)/load.Po + -rm -f edit/$(DEPDIR)/logic.Po + -rm -f edit/$(DEPDIR)/navigate.Po + -rm -f edit/$(DEPDIR)/position.Po + -rm -f edit/$(DEPDIR)/preview.Po + -rm -f edit/$(DEPDIR)/save.Po + -rm -f edit/$(DEPDIR)/styles.Po + -rm -f edit/$(DEPDIR)/update.Po + -rm -f editone2/$(DEPDIR)/index.Po + -rm -f editone2/$(DEPDIR)/load.Po + -rm -f editone2/$(DEPDIR)/logic.Po + -rm -f editone2/$(DEPDIR)/save.Po + -rm -f editone2/$(DEPDIR)/update.Po + -rm -f editone2/$(DEPDIR)/verse.Po + -rm -f editor/$(DEPDIR)/html2format.Po + -rm -f editor/$(DEPDIR)/html2usfm.Po + -rm -f editor/$(DEPDIR)/id.Po + -rm -f editor/$(DEPDIR)/select.Po + -rm -f editor/$(DEPDIR)/style.Po + -rm -f editor/$(DEPDIR)/styles.Po + -rm -f editor/$(DEPDIR)/usfm2html.Po + -rm -f editusfm/$(DEPDIR)/focus.Po + -rm -f editusfm/$(DEPDIR)/index.Po + -rm -f editusfm/$(DEPDIR)/load.Po + -rm -f editusfm/$(DEPDIR)/offset.Po + -rm -f editusfm/$(DEPDIR)/save.Po + -rm -f email/$(DEPDIR)/index.Po + -rm -f email/$(DEPDIR)/receive.Po + -rm -f email/$(DEPDIR)/send.Po + -rm -f esword/$(DEPDIR)/text.Po + -rm -f executable/$(DEPDIR)/bibledit.Po + -rm -f executable/$(DEPDIR)/generate.Po + -rm -f export/$(DEPDIR)/bibledropbox.Po + -rm -f export/$(DEPDIR)/esword.Po + -rm -f export/$(DEPDIR)/html.Po + -rm -f export/$(DEPDIR)/index.Po + -rm -f export/$(DEPDIR)/info.Po + -rm -f export/$(DEPDIR)/logic.Po + -rm -f export/$(DEPDIR)/odt.Po + -rm -f export/$(DEPDIR)/onlinebible.Po + -rm -f export/$(DEPDIR)/textusfm.Po + -rm -f export/$(DEPDIR)/usfm.Po + -rm -f export/$(DEPDIR)/web.Po + -rm -f filter/$(DEPDIR)/archive.Po + -rm -f filter/$(DEPDIR)/css.Po + -rm -f filter/$(DEPDIR)/date.Po + -rm -f filter/$(DEPDIR)/diff.Po + -rm -f filter/$(DEPDIR)/git.Po + -rm -f filter/$(DEPDIR)/google.Po + -rm -f filter/$(DEPDIR)/html.Po + -rm -f filter/$(DEPDIR)/image.Po + -rm -f filter/$(DEPDIR)/mail.Po + -rm -f filter/$(DEPDIR)/md5.Po + -rm -f filter/$(DEPDIR)/memory.Po + -rm -f filter/$(DEPDIR)/merge.Po + -rm -f filter/$(DEPDIR)/note.Po + -rm -f filter/$(DEPDIR)/passage.Po + -rm -f filter/$(DEPDIR)/roles.Po + -rm -f filter/$(DEPDIR)/shell.Po + -rm -f filter/$(DEPDIR)/string.Po + -rm -f filter/$(DEPDIR)/text.Po + -rm -f filter/$(DEPDIR)/url.Po + -rm -f filter/$(DEPDIR)/usfm.Po + -rm -f filter/$(DEPDIR)/webview.Po + -rm -f flate/$(DEPDIR)/flate.Po + -rm -f fonts/$(DEPDIR)/logic.Po + -rm -f help/$(DEPDIR)/index.Po + -rm -f html/$(DEPDIR)/header.Po + -rm -f html/$(DEPDIR)/text.Po + -rm -f i18n/$(DEPDIR)/logic.Po + -rm -f images/$(DEPDIR)/fetch.Po + -rm -f images/$(DEPDIR)/index.Po + -rm -f images/$(DEPDIR)/logic.Po + -rm -f images/$(DEPDIR)/view.Po + -rm -f index/$(DEPDIR)/index.Po + -rm -f index/$(DEPDIR)/listing.Po + -rm -f ipc/$(DEPDIR)/focus.Po + -rm -f ipc/$(DEPDIR)/notes.Po + -rm -f jobs/$(DEPDIR)/index.Po + -rm -f journal/$(DEPDIR)/index.Po + -rm -f journal/$(DEPDIR)/logic.Po + -rm -f jsonxx/$(DEPDIR)/jsonxx.Po + -rm -f ldap/$(DEPDIR)/logic.Po + -rm -f lexicon/$(DEPDIR)/definition.Po + -rm -f lexicon/$(DEPDIR)/logic.Po + -rm -f library/$(DEPDIR)/bibledit.Po + -rm -f library/$(DEPDIR)/locks.Po + -rm -f locale/$(DEPDIR)/logic.Po + -rm -f locale/$(DEPDIR)/translate.Po + -rm -f manage/$(DEPDIR)/accounts.Po + -rm -f manage/$(DEPDIR)/exports.Po + -rm -f manage/$(DEPDIR)/hyphenate.Po + -rm -f manage/$(DEPDIR)/hyphenation.Po + -rm -f manage/$(DEPDIR)/index.Po + -rm -f manage/$(DEPDIR)/privileges.Po + -rm -f manage/$(DEPDIR)/users.Po + -rm -f manage/$(DEPDIR)/write.Po + -rm -f mapping/$(DEPDIR)/index.Po + -rm -f mapping/$(DEPDIR)/map.Po + -rm -f mbedtls/$(DEPDIR)/aes.Po + -rm -f mbedtls/$(DEPDIR)/arc4.Po + -rm -f mbedtls/$(DEPDIR)/asn1parse.Po + -rm -f mbedtls/$(DEPDIR)/asn1write.Po + -rm -f mbedtls/$(DEPDIR)/base64.Po + -rm -f mbedtls/$(DEPDIR)/bignum.Po + -rm -f mbedtls/$(DEPDIR)/blowfish.Po + -rm -f mbedtls/$(DEPDIR)/camellia.Po + -rm -f mbedtls/$(DEPDIR)/ccm.Po + -rm -f mbedtls/$(DEPDIR)/certs.Po + -rm -f mbedtls/$(DEPDIR)/chacha20.Po + -rm -f mbedtls/$(DEPDIR)/chachapoly.Po + -rm -f mbedtls/$(DEPDIR)/cipher.Po + -rm -f mbedtls/$(DEPDIR)/cipher_wrap.Po + -rm -f mbedtls/$(DEPDIR)/ctr_drbg.Po + -rm -f mbedtls/$(DEPDIR)/debug.Po + -rm -f mbedtls/$(DEPDIR)/des.Po + -rm -f mbedtls/$(DEPDIR)/dhm.Po + -rm -f mbedtls/$(DEPDIR)/ecdh.Po + -rm -f mbedtls/$(DEPDIR)/ecdsa.Po + -rm -f mbedtls/$(DEPDIR)/ecp.Po + -rm -f mbedtls/$(DEPDIR)/ecp_curves.Po + -rm -f mbedtls/$(DEPDIR)/entropy.Po + -rm -f mbedtls/$(DEPDIR)/entropy_poll.Po + -rm -f mbedtls/$(DEPDIR)/error.Po + -rm -f mbedtls/$(DEPDIR)/gcm.Po + -rm -f mbedtls/$(DEPDIR)/hmac_drbg.Po + -rm -f mbedtls/$(DEPDIR)/md.Po + -rm -f mbedtls/$(DEPDIR)/md5.Po + -rm -f mbedtls/$(DEPDIR)/md_wrap.Po + -rm -f mbedtls/$(DEPDIR)/net_sockets.Po + -rm -f mbedtls/$(DEPDIR)/oid.Po + -rm -f mbedtls/$(DEPDIR)/pem.Po + -rm -f mbedtls/$(DEPDIR)/pk.Po + -rm -f mbedtls/$(DEPDIR)/pk_wrap.Po + -rm -f mbedtls/$(DEPDIR)/pkcs12.Po + -rm -f mbedtls/$(DEPDIR)/pkcs5.Po + -rm -f mbedtls/$(DEPDIR)/pkparse.Po + -rm -f mbedtls/$(DEPDIR)/pkwrite.Po + -rm -f mbedtls/$(DEPDIR)/platform.Po + -rm -f mbedtls/$(DEPDIR)/platform_util.Po + -rm -f mbedtls/$(DEPDIR)/poly1305.Po + -rm -f mbedtls/$(DEPDIR)/ripemd160.Po + -rm -f mbedtls/$(DEPDIR)/rsa.Po + -rm -f mbedtls/$(DEPDIR)/rsa_internal.Po + -rm -f mbedtls/$(DEPDIR)/sha1.Po + -rm -f mbedtls/$(DEPDIR)/sha256.Po + -rm -f mbedtls/$(DEPDIR)/sha512.Po + -rm -f mbedtls/$(DEPDIR)/ssl_cache.Po + -rm -f mbedtls/$(DEPDIR)/ssl_ciphersuites.Po + -rm -f mbedtls/$(DEPDIR)/ssl_cli.Po + -rm -f mbedtls/$(DEPDIR)/ssl_cookie.Po + -rm -f mbedtls/$(DEPDIR)/ssl_srv.Po + -rm -f mbedtls/$(DEPDIR)/ssl_ticket.Po + -rm -f mbedtls/$(DEPDIR)/ssl_tls.Po + -rm -f mbedtls/$(DEPDIR)/threading.Po + -rm -f mbedtls/$(DEPDIR)/timing.Po + -rm -f mbedtls/$(DEPDIR)/version.Po + -rm -f mbedtls/$(DEPDIR)/version_features.Po + -rm -f mbedtls/$(DEPDIR)/x509.Po + -rm -f mbedtls/$(DEPDIR)/x509_create.Po + -rm -f mbedtls/$(DEPDIR)/x509_crl.Po + -rm -f mbedtls/$(DEPDIR)/x509_crt.Po + -rm -f mbedtls/$(DEPDIR)/x509_csr.Po + -rm -f mbedtls/$(DEPDIR)/x509write_crt.Po + -rm -f mbedtls/$(DEPDIR)/x509write_csr.Po + -rm -f mbedtls/$(DEPDIR)/xtea.Po + -rm -f menu/$(DEPDIR)/index.Po + -rm -f menu/$(DEPDIR)/logic.Po + -rm -f microtar/$(DEPDIR)/microtar.Po + -rm -f mimetic098/$(DEPDIR)/body.Po + -rm -f mimetic098/$(DEPDIR)/contentdescription.Po + -rm -f mimetic098/$(DEPDIR)/contentdisposition.Po + -rm -f mimetic098/$(DEPDIR)/contentid.Po + -rm -f mimetic098/$(DEPDIR)/contenttransferencoding.Po + -rm -f mimetic098/$(DEPDIR)/contenttype.Po + -rm -f mimetic098/$(DEPDIR)/fieldparam.Po + -rm -f mimetic098/$(DEPDIR)/header.Po + -rm -f mimetic098/$(DEPDIR)/mimeentity.Po + -rm -f mimetic098/$(DEPDIR)/mimeversion.Po + -rm -f mimetic098/$(DEPDIR)/strutils.Po + -rm -f mimetic098/$(DEPDIR)/utils.Po + -rm -f mimetic098/$(DEPDIR)/version.Po + -rm -f mimetic098/codec/$(DEPDIR)/base64.Po + -rm -f mimetic098/os/$(DEPDIR)/file_iterator.Po + -rm -f mimetic098/os/$(DEPDIR)/mmfile.Po + -rm -f mimetic098/os/$(DEPDIR)/utils.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/address.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/addresslist.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/datetime.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/field.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/fieldvalue.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/group.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/header.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/mailbox.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/mailboxlist.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/message.Po + -rm -f mimetic098/rfc822/$(DEPDIR)/messageid.Po + -rm -f miniz/$(DEPDIR)/miniz.Po + -rm -f navigation/$(DEPDIR)/paratext.Po + -rm -f navigation/$(DEPDIR)/passage.Po + -rm -f navigation/$(DEPDIR)/poll.Po + -rm -f navigation/$(DEPDIR)/update.Po + -rm -f nmt/$(DEPDIR)/index.Po + -rm -f nmt/$(DEPDIR)/logic.Po + -rm -f notes/$(DEPDIR)/actions.Po + -rm -f notes/$(DEPDIR)/assign-1.Po + -rm -f notes/$(DEPDIR)/assign-n.Po + -rm -f notes/$(DEPDIR)/bb-1.Po + -rm -f notes/$(DEPDIR)/bb-n.Po + -rm -f notes/$(DEPDIR)/bulk.Po + -rm -f notes/$(DEPDIR)/click.Po + -rm -f notes/$(DEPDIR)/comment.Po + -rm -f notes/$(DEPDIR)/create.Po + -rm -f notes/$(DEPDIR)/edit.Po + -rm -f notes/$(DEPDIR)/index.Po + -rm -f notes/$(DEPDIR)/logic.Po + -rm -f notes/$(DEPDIR)/note.Po + -rm -f notes/$(DEPDIR)/notes.Po + -rm -f notes/$(DEPDIR)/poll.Po + -rm -f notes/$(DEPDIR)/select.Po + -rm -f notes/$(DEPDIR)/severity-1.Po + -rm -f notes/$(DEPDIR)/severity-n.Po + -rm -f notes/$(DEPDIR)/status-1.Po + -rm -f notes/$(DEPDIR)/status-n.Po + -rm -f notes/$(DEPDIR)/summary.Po + -rm -f notes/$(DEPDIR)/unassign-n.Po + -rm -f notes/$(DEPDIR)/verses.Po + -rm -f odf/$(DEPDIR)/text.Po + -rm -f olb/$(DEPDIR)/text.Po + -rm -f paratext/$(DEPDIR)/index.Po + -rm -f paratext/$(DEPDIR)/logic.Po + -rm -f parsewebdata/$(DEPDIR)/ParseMultipartFormData.Po + -rm -f parsewebdata/$(DEPDIR)/ParseWebData.Po + -rm -f personalize/$(DEPDIR)/index.Po + -rm -f public/$(DEPDIR)/chapter.Po + -rm -f public/$(DEPDIR)/comment.Po + -rm -f public/$(DEPDIR)/create.Po + -rm -f public/$(DEPDIR)/index.Po + -rm -f public/$(DEPDIR)/logic.Po + -rm -f public/$(DEPDIR)/login.Po + -rm -f public/$(DEPDIR)/new.Po + -rm -f public/$(DEPDIR)/note.Po + -rm -f public/$(DEPDIR)/notes.Po + -rm -f pugixml/$(DEPDIR)/pugixml.Po + -rm -f pugixml/$(DEPDIR)/utils.Po + -rm -f quill/$(DEPDIR)/logic.Po + -rm -f read/$(DEPDIR)/index.Po + -rm -f read/$(DEPDIR)/load.Po + -rm -f read/$(DEPDIR)/verse.Po + -rm -f redirect/$(DEPDIR)/index.Po + -rm -f related/$(DEPDIR)/logic.Po + -rm -f resource/$(DEPDIR)/bb2resource.Po + -rm -f resource/$(DEPDIR)/bbgateway.Po + -rm -f resource/$(DEPDIR)/cache.Po + -rm -f resource/$(DEPDIR)/comparative1edit.Po + -rm -f resource/$(DEPDIR)/comparative9edit.Po + -rm -f resource/$(DEPDIR)/convert2bible.Po + -rm -f resource/$(DEPDIR)/convert2resource.Po + -rm -f resource/$(DEPDIR)/divider.Po + -rm -f resource/$(DEPDIR)/download.Po + -rm -f resource/$(DEPDIR)/external.Po + -rm -f resource/$(DEPDIR)/get.Po + -rm -f resource/$(DEPDIR)/image.Po + -rm -f resource/$(DEPDIR)/imagefetch.Po + -rm -f resource/$(DEPDIR)/images.Po + -rm -f resource/$(DEPDIR)/img.Po + -rm -f resource/$(DEPDIR)/index.Po + -rm -f resource/$(DEPDIR)/logic.Po + -rm -f resource/$(DEPDIR)/manage.Po + -rm -f resource/$(DEPDIR)/organize.Po + -rm -f resource/$(DEPDIR)/print.Po + -rm -f resource/$(DEPDIR)/select.Po + -rm -f resource/$(DEPDIR)/studylight.Po + -rm -f resource/$(DEPDIR)/sword.Po + -rm -f resource/$(DEPDIR)/translated1edit.Po + -rm -f resource/$(DEPDIR)/translated9edit.Po + -rm -f resource/$(DEPDIR)/unload.Po + -rm -f resource/$(DEPDIR)/user1edit.Po + -rm -f resource/$(DEPDIR)/user1view.Po + -rm -f resource/$(DEPDIR)/user9edit.Po + -rm -f resource/$(DEPDIR)/user9view.Po + -rm -f rss/$(DEPDIR)/feed.Po + -rm -f rss/$(DEPDIR)/logic.Po + -rm -f search/$(DEPDIR)/all.Po + -rm -f search/$(DEPDIR)/getids.Po + -rm -f search/$(DEPDIR)/getids2.Po + -rm -f search/$(DEPDIR)/index.Po + -rm -f search/$(DEPDIR)/logic.Po + -rm -f search/$(DEPDIR)/originals.Po + -rm -f search/$(DEPDIR)/rebibles.Po + -rm -f search/$(DEPDIR)/renotes.Po + -rm -f search/$(DEPDIR)/replace.Po + -rm -f search/$(DEPDIR)/replace2.Po + -rm -f search/$(DEPDIR)/replacego.Po + -rm -f search/$(DEPDIR)/replacego2.Po + -rm -f search/$(DEPDIR)/replacepre.Po + -rm -f search/$(DEPDIR)/replacepre2.Po + -rm -f search/$(DEPDIR)/search2.Po + -rm -f search/$(DEPDIR)/similar.Po + -rm -f search/$(DEPDIR)/strong.Po + -rm -f search/$(DEPDIR)/strongs.Po + -rm -f sendreceive/$(DEPDIR)/bibles.Po + -rm -f sendreceive/$(DEPDIR)/changes.Po + -rm -f sendreceive/$(DEPDIR)/files.Po + -rm -f sendreceive/$(DEPDIR)/index.Po + -rm -f sendreceive/$(DEPDIR)/logic.Po + -rm -f sendreceive/$(DEPDIR)/notes.Po + -rm -f sendreceive/$(DEPDIR)/resources.Po + -rm -f sendreceive/$(DEPDIR)/sendreceive.Po + -rm -f sendreceive/$(DEPDIR)/settings.Po + -rm -f session/$(DEPDIR)/confirm.Po + -rm -f session/$(DEPDIR)/logic.Po + -rm -f session/$(DEPDIR)/login.Po + -rm -f session/$(DEPDIR)/logout.Po + -rm -f session/$(DEPDIR)/password.Po + -rm -f session/$(DEPDIR)/signup.Po + -rm -f session/$(DEPDIR)/switch.Po + -rm -f setup/$(DEPDIR)/index.Po + -rm -f setup/$(DEPDIR)/logic.Po + -rm -f sources/$(DEPDIR)/abbott-smith.Po + -rm -f sources/$(DEPDIR)/etcbc4.Po + -rm -f sources/$(DEPDIR)/hebrewlexicon.Po + -rm -f sources/$(DEPDIR)/kjv.Po + -rm -f sources/$(DEPDIR)/morphgnt.Po + -rm -f sources/$(DEPDIR)/morphhb.Po + -rm -f sources/$(DEPDIR)/oshb.Po + -rm -f sources/$(DEPDIR)/styles.Po + -rm -f sprint/$(DEPDIR)/burndown.Po + -rm -f sprint/$(DEPDIR)/index.Po + -rm -f sqlite/$(DEPDIR)/sqlite3.Po + -rm -f statistics/$(DEPDIR)/statistics.Po + -rm -f styles/$(DEPDIR)/css.Po + -rm -f styles/$(DEPDIR)/indexm.Po + -rm -f styles/$(DEPDIR)/logic.Po + -rm -f styles/$(DEPDIR)/sheetm.Po + -rm -f styles/$(DEPDIR)/sheets.Po + -rm -f styles/$(DEPDIR)/view.Po + -rm -f sword/$(DEPDIR)/logic.Po + -rm -f sync/$(DEPDIR)/bibles.Po + -rm -f sync/$(DEPDIR)/changes.Po + -rm -f sync/$(DEPDIR)/files.Po + -rm -f sync/$(DEPDIR)/logic.Po + -rm -f sync/$(DEPDIR)/mail.Po + -rm -f sync/$(DEPDIR)/notes.Po + -rm -f sync/$(DEPDIR)/resources.Po + -rm -f sync/$(DEPDIR)/settings.Po + -rm -f sync/$(DEPDIR)/setup.Po + -rm -f sync/$(DEPDIR)/usfmresources.Po + -rm -f system/$(DEPDIR)/googletranslate.Po + -rm -f system/$(DEPDIR)/index.Po + -rm -f system/$(DEPDIR)/logic.Po + -rm -f tasks/$(DEPDIR)/logic.Po + -rm -f tasks/$(DEPDIR)/run.Po + -rm -f tbsx/$(DEPDIR)/text.Po + -rm -f text/$(DEPDIR)/text.Po + -rm -f tidy/$(DEPDIR)/access.Po + -rm -f tidy/$(DEPDIR)/alloc.Po + -rm -f tidy/$(DEPDIR)/attrdict.Po + -rm -f tidy/$(DEPDIR)/attrs.Po + -rm -f tidy/$(DEPDIR)/buffio.Po + -rm -f tidy/$(DEPDIR)/charsets.Po + -rm -f tidy/$(DEPDIR)/clean.Po + -rm -f tidy/$(DEPDIR)/config.Po + -rm -f tidy/$(DEPDIR)/entities.Po + -rm -f tidy/$(DEPDIR)/fileio.Po + -rm -f tidy/$(DEPDIR)/gdoc.Po + -rm -f tidy/$(DEPDIR)/istack.Po + -rm -f tidy/$(DEPDIR)/language.Po + -rm -f tidy/$(DEPDIR)/lexer.Po + -rm -f tidy/$(DEPDIR)/mappedio.Po + -rm -f tidy/$(DEPDIR)/message.Po + -rm -f tidy/$(DEPDIR)/messageobj.Po + -rm -f tidy/$(DEPDIR)/parser.Po + -rm -f tidy/$(DEPDIR)/pprint.Po + -rm -f tidy/$(DEPDIR)/sprtf.Po + -rm -f tidy/$(DEPDIR)/streamio.Po + -rm -f tidy/$(DEPDIR)/tagask.Po + -rm -f tidy/$(DEPDIR)/tags.Po + -rm -f tidy/$(DEPDIR)/tidylib.Po + -rm -f tidy/$(DEPDIR)/tmbstr.Po + -rm -f tidy/$(DEPDIR)/utf8.Po + -rm -f timer/$(DEPDIR)/index.Po + -rm -f tmp/$(DEPDIR)/tmp.Po + -rm -f trash/$(DEPDIR)/handler.Po + -rm -f user/$(DEPDIR)/account.Po + -rm -f user/$(DEPDIR)/logic.Po + -rm -f user/$(DEPDIR)/notifications.Po + -rm -f utf8proc/$(DEPDIR)/utf8proc.Po + -rm -f versification/$(DEPDIR)/index.Po + -rm -f versification/$(DEPDIR)/logic.Po + -rm -f versification/$(DEPDIR)/system.Po + -rm -f webbb/$(DEPDIR)/search.Po + -rm -f webserver/$(DEPDIR)/http.Po + -rm -f webserver/$(DEPDIR)/request.Po + -rm -f webserver/$(DEPDIR)/webserver.Po + -rm -f workspace/$(DEPDIR)/index.Po + -rm -f workspace/$(DEPDIR)/logic.Po + -rm -f workspace/$(DEPDIR)/organize.Po + -rm -f workspace/$(DEPDIR)/settings.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-local uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: all install-am install-data-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am all-local am--depfiles am--refresh \ + check check-am clean clean-binPROGRAMS clean-cscope \ + clean-generic clean-noinstLIBRARIES cscope cscopelist-am ctags \ + ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \ + dist-lzip dist-shar dist-tarZ dist-xz dist-zip dist-zstd \ + distcheck distclean distclean-compile distclean-generic \ + distclean-hdr distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-data-hook install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-local uninstall-man uninstall-man1 + +.PRECIOUS: Makefile + + +dist-hook: + rm -rf `find $(distdir) -name *.o` + rm -rf `find $(distdir) -name *.a` + rm -rf `find $(distdir) -name autom4te.cache` + rm -f $(distdir)/server + rm -f $(distdir)/unittest + rm -rf `find $(distdir) -name .dirstamp` + rm -rf `find $(distdir) -name .deps` + rm -rf `find $(distdir) -name *~` + rm -f $(distdir)/config.h + rm -f $(distdir)/config.log + rm -f $(distdir)/config.status + +all-local: + pkgdata/create.sh + +install-data-hook: + $(srcdir)/pkgdata/install.sh $(srcdir) $(DESTDIR) $(pkgdatadir) + +uninstall-local: + rm -rf $(DESTDIR)$(pkgdatadir)/* + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/access/bible.cpp b/access/bible.cpp deleted file mode 100644 index d7597f58b..000000000 --- a/access/bible.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -namespace access_bible { - - -// Returns true if the $user has read access to the $bible. -// If no $user is given, it takes the currently logged-in user. -bool read (Webserver_Request& webserver_request, const string & bible, string user) -{ - // Client: User has access to all Bibles. -#ifdef HAVE_CLIENT - (void) webserver_request; - (void) bible; - (void) user; - return true; -#endif - -#ifdef HAVE_CLOUD - - // Get the level, that is the role, of the given user. - int role_level { 0 }; - if (user.empty ()) { - // Current user. - user = webserver_request.session_logic ()->currentUser (); - role_level = webserver_request.session_logic ()->currentLevel (); - } else { - // Take level belonging to user. - role_level = webserver_request.database_users ()->get_level (user); - } - - // Managers and higher have read access. - if (role_level >= Filter_Roles::manager ()) { - return true; - } - - // Read privileges for the user. - auto [ read, write ] = DatabasePrivileges::get_bible (user, bible); - if (read) { - return true; - } - - // No Bibles assigned: Consultant can view any Bible. - if (role_level >= Filter_Roles::consultant ()) { - if (int privileges_count = DatabasePrivileges::get_bible_book_count (); privileges_count == 0) { - return true; - } - } -#endif - - // Default. - return false; -} - - -// Returns true if the user has write access to the $bible. -bool write (Webserver_Request& webserver_request, const string & bible, string user) -{ -#ifdef HAVE_CLIENT - // Client: When not yet connected to the Cloud, the user has access to all Bibles. - // When connected to the Cloud, this no longer applies, - // since the client now receives the privileges from the Cloud. - if (!client_logic_client_enabled ()) { - return true; - } -#endif - - int level {0}; - if (user.empty ()) { - user = webserver_request.session_logic ()->currentUser (); - level = webserver_request.session_logic ()->currentLevel (); - } - if (level == 0) { - // Take level belonging to user. - level = webserver_request.database_users ()->get_level (user); - } - - // Managers and higher always have write access. - if (level >= Filter_Roles::manager ()) { - return true; - } - - // Read the privileges for the user. - auto [ read, write ] = DatabasePrivileges::get_bible (user, bible); - if (write) { - return true; - } - - // No Bibles assigned: Translator can write to any bible. - if (level >= Filter_Roles::translator ()) { - if (int privileges_count = DatabasePrivileges::get_bible_book_count (); privileges_count == 0) { - return true; - } - } - - // Default. - return false; -} - - -// Returns true if the $user has write access to the $bible and the $book. -// If no user is given, it takes the currently logged-in user. -// If the user has read-only access to even one book of the $bible, -// then the user is considered not to have write access to the entire $bible. -bool book_write (Webserver_Request& webserver_request, string user, const string & bible, int book) -{ -#ifdef HAVE_CLIENT - // Client: When not yet connected to the Cloud, the user has access to the book. - // When connected to the Cloud, this no longer applies, - // since the client now receives the privileges from the Cloud. - if (!client_logic_client_enabled ()) { - return true; - } -#endif - - // Get the user level (role). - int level {0}; - if (user.empty ()) { - user = webserver_request.session_logic ()->currentUser (); - level = webserver_request.session_logic ()->currentLevel (); - } - if (level == 0) { - // Take level belonging to user. - level = webserver_request.database_users ()->get_level (user); - } - - // Managers and higher always have write access. - if (level >= Filter_Roles::manager ()) { - return true; - } - - // Read the privileges for the user. - bool read {false}; - bool write {false}; - DatabasePrivileges::get_bible_book (user, bible, book, read, write); - if (write) { - return true; - } - - // No Bibles assigned: Translator can write to any bible. - if (level >= Filter_Roles::translator ()) { - if (int privileges_count = DatabasePrivileges::get_bible_book_count (); privileges_count == 0) { - return true; - } - } - - // Default. - return false; -} - - -// Returns an array of Bibles the user has read access to. -// If no user is given, it takes the currently logged-in user. -vector bibles (Webserver_Request& webserver_request, string user) -{ - vector allbibles = webserver_request.database_bibles()->get_bibles (); - vector bibles; - for (auto & bible : allbibles) { - if (read (webserver_request, bible, user)) { - bibles.push_back (bible); - } - } - return bibles; -} - - -// This function clamps bible. -// It returns the $bible if the currently logged-in user has access to it. -// Else it returns another accessible bible or nothing. -string clamp (Webserver_Request& webserver_request, string bible) -{ - if (!read (webserver_request, bible)) { - bible = string(); - vector bibles = access_bible::bibles (webserver_request); - if (!bibles.empty ()) bible = bibles [0]; - webserver_request.database_config_user ()->setBible (bible); - } - return bible; -} - - -// This function checks whether the user in the $webserver_request -// has $read or $write access to one or more Bibles. -// It returns a tuple . -tuple any (Webserver_Request& webserver_request) -{ - bool read {false}; - bool write {false}; - vector bibles = webserver_request.database_bibles()->get_bibles (); - for (auto & bible : bibles) { - if (access_bible::read (webserver_request, bible)) read = true; - if (access_bible::write (webserver_request, bible)) write = true; - } - // The results consists of . - return make_tuple(read, write); -} - - -} diff --git a/access/bible.h b/access/bible.h deleted file mode 100644 index 0b5dfecf4..000000000 --- a/access/bible.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -namespace access_bible { - -bool read (Webserver_Request& webserver_request, const std::string & bible, std::string user = std::string()); -bool write (Webserver_Request& webserver_request, const std::string & bible, std::string user = std::string()); -bool book_write (Webserver_Request& webserver_request, std::string user, const std::string & bible, int book); -std::vector bibles (Webserver_Request& webserver_request, std::string user = std::string()); -std::string clamp (Webserver_Request& webserver_request, std::string bible); -std::tuple any (Webserver_Request& webserver_request); - -} diff --git a/access/logic.cpp b/access/logic.cpp deleted file mode 100644 index 7a4df2e53..000000000 --- a/access/logic.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -namespace access_logic { - - -int view_resources_role () -{ - return Filter_Roles::consultant (); -} - - -bool privilege_view_resources (Webserver_Request& webserver_request, string user) -{ - int level {0}; - user_level (webserver_request, user, level); - if (level >= view_resources_role ()) return true; - return DatabasePrivileges::get_feature (user, PRIVILEGE_VIEW_RESOURCES); -} - - -int view_notes_role () -{ - return Filter_Roles::consultant (); -} - - -bool privilege_view_notes (Webserver_Request& webserver_request, string user) -{ - int level {0}; - user_level (webserver_request, user, level); - if (level >= view_notes_role ()) return true; - return DatabasePrivileges::get_feature (user, PRIVILEGE_VIEW_NOTES); -} - - -int create_comment_notes_role () -{ - return Filter_Roles::consultant (); -} - - -bool privilege_create_comment_notes (Webserver_Request& webserver_request, string user) -{ - int level {0}; - user_level (webserver_request, user, level); - if (level >= create_comment_notes_role ()) return true; - return DatabasePrivileges::get_feature (user, PRIVILEGE_CREATE_COMMENT_NOTES); -} - - -int delete_consultation_notes_role () -{ - return Filter_Roles::manager (); -} - - -bool privilege_delete_consultation_notes (Webserver_Request& webserver_request, string user) -{ - int level {0}; - user_level (webserver_request, user, level); - if (level >= delete_consultation_notes_role ()) return true; - return webserver_request.database_config_user ()->getPrivilegeDeleteConsultationNotesForUser (user); -} - - -int use_advanced_mode_role () -{ - return Filter_Roles::manager (); -} - - -bool privilege_use_advanced_mode (Webserver_Request& webserver_request, string user) -{ - int level {0}; - user_level (webserver_request, user, level); - if (level >= use_advanced_mode_role ()) return true; - return webserver_request.database_config_user ()->getPrivilegeUseAdvancedModeForUser (user); -} - - -int set_stylesheets_role () -{ - return Filter_Roles::manager (); -} - - -bool privilege_set_stylesheets (Webserver_Request& webserver_request, string user) -{ - int level {0}; - user_level (webserver_request, user, level); - if (level >= set_stylesheets_role ()) return true; - return webserver_request.database_config_user ()->getPrivilegeSetStylesheetsForUser (user); -} - - -void user_level (Webserver_Request& webserver_request, string & user, int & level) -{ - if (user.empty ()) { - // If no user is given, take the user from the session. - user = webserver_request.session_logic ()->currentUser (); - level = webserver_request.session_logic ()->currentLevel (); - } else { - // If a user is given, take the matching level from the database. - level = webserver_request.database_users ()->get_level (user); - } -} - - -void create_client_files () -{ - Database_Users database_users; - vector users = database_users.get_users (); - for (auto & user : users) { - // Only maintain the privilege file if it does not yet exist, - // to avoid unnecessary downloads by the clients. - database_privileges_client_create (user, false); - } -} - - -set default_privilege_usernames () -{ - return {"defaultguest", "defaultmember", "defaultconsultant", "defaulttranslator", "defaultmanager"}; -} - - -} diff --git a/access/logic.h b/access/logic.h deleted file mode 100644 index a5f3db8ff..000000000 --- a/access/logic.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -#define PRIVILEGE_VIEW_RESOURCES 1 - -namespace access_logic { - -int view_resources_role (); -bool privilege_view_resources (Webserver_Request& webserver_request, std::string user = std::string()); - -#define PRIVILEGE_VIEW_NOTES 2 -int view_notes_role (); -bool privilege_view_notes (Webserver_Request& webserver_request, std::string user = std::string()); - -#define PRIVILEGE_CREATE_COMMENT_NOTES 3 -int create_comment_notes_role (); -bool privilege_create_comment_notes (Webserver_Request& webserver_request, std::string user = std::string()); - -int delete_consultation_notes_role (); -bool privilege_delete_consultation_notes (Webserver_Request& webserver_request, std::string user = std::string()); - -int use_advanced_mode_role (); -bool privilege_use_advanced_mode (Webserver_Request& webserver_request, std::string user = std::string()); - -int set_stylesheets_role (); -bool privilege_set_stylesheets (Webserver_Request& webserver_request, std::string user = std::string()); - -void user_level (Webserver_Request& webserver_request, std::string& user, int& level); -void create_client_files (); - -std::set default_privilege_usernames (); - -} diff --git a/access/user.cpp b/access/user.cpp deleted file mode 100644 index 82e8eaa15..000000000 --- a/access/user.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// This function returns users assigned to the logged-in user. -vector access_user::assignees (Webserver_Request& webserver_request) -{ - const string myuser = webserver_request.session_logic ()->currentUser (); - const int mylevel = webserver_request.session_logic ()->currentLevel (); - - // This holds the assignees. - vector assignees {}; - - // Process all users. - vector users = webserver_request.database_users ()->get_users (); - sort (users.begin(), users.end()); - for (const auto & user : users) { - // Assignees should have a level less than or equal to mylevel. - if (webserver_request.database_users ()->get_level (user) <= mylevel) { - assignees.push_back (user); - } - } - - return assignees; -} diff --git a/access/user.h b/access/user.h deleted file mode 100644 index a9f7c545e..000000000 --- a/access/user.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -namespace access_user { - -std::vector assignees (Webserver_Request& webserver_request); - -} diff --git a/assets/external.cpp b/assets/external.cpp deleted file mode 100644 index 3e8881dac..000000000 --- a/assets/external.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -using namespace std; - - -string assets_external_url () -{ - return "assets/external"; -} - - -string assets_external (Webserver_Request& webserver_request) -{ - // Whether a URL was POSTed, that is, whether it was clicked by the user. - string href = webserver_request.post ["href"]; - if (!href.empty ()) { - config_globals_external_url = webserver_request.post ["href"]; - return string(); - } - - // Wait for some time till a URL is available. - int timer {100}; - while (timer) { - this_thread::sleep_for (chrono::milliseconds (100)); - timer--; - if (!config_globals_external_url.empty ()) { - href = config_globals_external_url; - config_globals_external_url.clear (); - timer = 0; - } - } - - // Return the URL, if it is there. - return href; -} - - -string assets_external_logic_link_addon () -{ - // Open an external link in an external browser on most clients. - // Open an external link in a new tab in some situations. - bool newtab {false}; -#ifdef HAVE_CLOUD - newtab = true; -#endif - string addon {}; - if (newtab) addon = R"(target="_blank")"; - else addon = R"(class="external")"; - // Done. - return addon; -} diff --git a/assets/external.h b/assets/external.h deleted file mode 100644 index f897c1114..000000000 --- a/assets/external.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string assets_external_url (); -std::string assets_external (Webserver_Request& webserver_request); - -std::string assets_external_logic_link_addon (); diff --git a/assets/header.cpp b/assets/header.cpp deleted file mode 100644 index 06ac16e70..000000000 --- a/assets/header.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -Assets_Header::Assets_Header (string title, Webserver_Request& webserver_request) : -m_webserver_request (webserver_request) -{ - m_view = new Assets_View (); - m_view->set_variable ("title", title); -} - - -Assets_Header::~Assets_Header () -{ - delete m_view; -} - - -void Assets_Header::jquery_touch_on () -{ - m_jquery_touch_on = true; -} - - -void Assets_Header::touch_css_on () -{ - m_touch_css_on = true; -} - - -void Assets_Header::notify_it_on () -{ - m_notify_it_on = true; -} - - -// Display the passage navigator. -void Assets_Header::set_navigator () -{ - m_display_navigator = true; -} - - -// Display the user's basic stylesheet.css. -void Assets_Header::set_stylesheet () -{ - const string bible = m_webserver_request.database_config_user()->getBible (); - const string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - m_included_stylesheet = stylesheet; -} - - -// Display the user's editor stylesheet.css. -void Assets_Header::set_editor_stylesheet () -{ - const string bible = m_webserver_request.database_config_user()->getBible (); - const string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - m_included_editor_stylesheet = stylesheet; -} - - -// Whether to display the topbar. -bool Assets_Header::display_topbar () -{ - // If the topbar is in the query: Don't display the top bar. - if (m_webserver_request.query.count ("topbar")) { - return false; - } - // Display the topbar. - return true; -} - - -// Sets the page to refresh after "seconds". -void Assets_Header::refresh (int seconds, string url) -{ - string content = filter::strings::convert_to_string (seconds); - if (!url.empty ()) content.append (";URL=" + url); - stringstream ss; - ss << ""; - m_head_lines.push_back (ss.str()); -} - - -// Adds a menu item to the fading menu. -void Assets_Header::set_fading_menu (string html) -{ - m_fading_menu = html; -} - - -// Add one breadcrumb $item with $text. -void Assets_Header::add_bread_crumb (string item, string text) -{ - m_bread_crumbs.push_back (pair (item, text)); -} - - -// Runs the header. -string Assets_Header::run () -{ - string page; - - // Include the software version number in the stylesheet and javascript URL - // to refresh the browser's cache after a software upgrade. - m_view->set_variable("VERSION", config::logic::version ()); - - if (m_jquery_touch_on) { - m_view->enable_zone ("include_jquery_touch"); - } - - if (m_webserver_request.session_logic ()->touchEnabled ()) { - touch_css_on(); - } - if (!m_webserver_request.session_logic ()->loggedIn ()) { - touch_css_on(); - } - if (m_touch_css_on) { - m_view->enable_zone ("include_touch_css"); - } else { - m_view->enable_zone ("include_mouse_css"); - } - - if (m_notify_it_on) { - m_view->enable_zone ("include_notif_it"); - } - - string headlines; - for (auto & headline : m_head_lines) { - if (!headlines.empty ()) headlines.append ("\n"); - headlines.append (headline); - } - m_view->set_variable ("head_lines", headlines); - - if (!m_included_stylesheet.empty ()) { - m_view->enable_zone ("include_stylesheet"); - m_view->set_variable ("included_stylesheet", m_included_stylesheet); - } - if (!m_included_editor_stylesheet.empty ()) { - m_view->enable_zone ("include_editor_stylesheet"); - m_view->set_variable ("included_editor_stylesheet", m_included_editor_stylesheet); - } - - bool basic_mode = config::logic::basic_mode (m_webserver_request); - string basicadvanced; - if (basic_mode) basicadvanced = "basic"; - else basicadvanced = "advanced"; - m_view->set_variable ("basicadvanced", basicadvanced); - - if (display_topbar ()) { - m_view->enable_zone ("display_topbar"); - - // In basic mode there's no back button in a bare browser. - if (basic_mode) { - m_view->disable_zone ("bare_browser"); - } - - // The start button to be displayed only when there's no menu. - bool start_button = true; - - // Whether tabbed mode is on. - bool tabbed_mode_on = menu_logic_can_do_tabbed_mode () && Database_Config_General::getMenuInTabbedViewOn (); - - string menublock; - string item = m_webserver_request.query ["item"]; - bool main_menu_always_on = false; - if (item.empty ()) - if (m_webserver_request.database_config_user ()->getMainMenuAlwaysVisible ()) { - main_menu_always_on = true; - // Add the main menu status as a Javascript variable. - m_view->set_variable ("mainmenualwayson", filter::strings::convert_to_string (main_menu_always_on)); - } - if ((item == "main") || main_menu_always_on) { - if (basic_mode) { - // Basic mode gives basic menu, but nothing in tabbed mode. - if (!tabbed_mode_on) { - menublock = menu_logic_basic_categories (m_webserver_request); - } - } else { - string devnull; - menublock = menu_logic_main_categories (m_webserver_request, devnull); - } - start_button = false; - } else if (item == menu_logic_translate_menu ()) { - menublock = menu_logic_translate_category (m_webserver_request); - } else if (item == menu_logic_search_menu ()) { - menublock = menu_logic_search_category (m_webserver_request); - } else if (item == menu_logic_tools_menu ()) { - menublock = menu_logic_tools_category (m_webserver_request); - } else if (item == menu_logic_settings_menu ()) { - menublock = menu_logic_settings_category (m_webserver_request); - } else if (item == menu_logic_settings_resources_menu ()) { - menublock = menu_logic_settings_resources_category (m_webserver_request); - } else if (item == "help") { - menublock = menu_logic_help_category (m_webserver_request); - } - m_view->set_variable ("mainmenu", menublock); - - // Not to display the "start button" in tabbed mode. - // That would take up screen space unnecessarily. - if (tabbed_mode_on) start_button = false; - - if (start_button) { - m_view->enable_zone ("start_button"); - string tooltip; - menu_logic_main_categories (m_webserver_request, tooltip); - m_view->set_variable ("starttooltip", tooltip); - } - - if (!m_fading_menu.empty ()) { - m_view->enable_zone ("fading_menu"); - m_view->set_variable ("fadingmenu", m_fading_menu); - string delay = filter::strings::convert_to_string (m_webserver_request.database_config_user ()->getWorkspaceMenuFadeoutDelay ()) + "000"; - m_view->set_variable ("fadingmenudelay", delay); - m_fading_menu.clear (); - } - - if (m_display_navigator) { - m_view->enable_zone ("display_navigator"); - // string bible = access_bible::clamp (request, m_webserver_request.database_config_user()->getBible ()); - // The clamping above does not work for public feedback as it would reset the Bible always. - string bible = m_webserver_request.database_config_user()->getBible (); - m_view->set_variable ("navigation_code", Navigation_Passage::code (bible)); - } - } - - vector embedded_css; - int fontsize = m_webserver_request.database_config_user ()->getGeneralFontSize (); - if (fontsize != 100) { - embedded_css.push_back ("body { font-size: " + filter::strings::convert_to_string (fontsize) + "%; }"); - } - fontsize = m_webserver_request.database_config_user ()->getMenuFontSize (); - string filename = menu_font_size_filebased_cache_filename (m_webserver_request.session_identifier); - if (fontsize != 100) { - embedded_css.push_back (".menu-advanced, .menu-basic { font-size: " + filter::strings::convert_to_string (fontsize) + "%; }"); - } - fontsize = m_webserver_request.database_config_user ()->getBibleEditorsFontSize (); - if (fontsize != 100) { - embedded_css.push_back (".bibleeditor { font-size: " + filter::strings::convert_to_string (fontsize) + "% !important; }"); - } - fontsize = m_webserver_request.database_config_user ()->getResourcesFontSize (); - filename = resource_font_size_filebased_cache_filename (m_webserver_request.session_identifier); - if (fontsize != 100) { - embedded_css.push_back (".resource { font-size: " + filter::strings::convert_to_string (fontsize) + "% !important; }"); - } - fontsize = m_webserver_request.database_config_user ()->getHebrewFontSize (); - if (fontsize != 100) { - embedded_css.push_back (".hebrew { font-size: " + filter::strings::convert_to_string (fontsize) + "%!important; }"); - } - fontsize = m_webserver_request.database_config_user ()->getGreekFontSize (); - filename = greek_font_size_filebased_cache_filename (m_webserver_request.session_identifier); - if (fontsize != 100) { - embedded_css.push_back (".greek { font-size: " + filter::strings::convert_to_string (fontsize) + "%!important; }"); - } - if (!embedded_css.empty ()) { - m_view->set_variable ("embedded_css", filter::strings::implode (embedded_css, "\n")); - } - - int current_theme_index = m_webserver_request.database_config_user ()->getCurrentTheme (); - filename = current_theme_filebased_cache_filename (m_webserver_request.session_identifier); - // Add the theme color css class selector name on the body element,.. - m_view->set_variable ("body_theme_color", Filter_Css::theme_picker (current_theme_index, 0)); - // ..workspacewrapper div element.. - m_view->set_variable ("workspace_theme_color", Filter_Css::theme_picker (current_theme_index, 4)); - // ..and as a variable for JavaScript. - m_view->set_variable ("themecolorfortabs", Filter_Css::theme_picker (current_theme_index, 1)); - - if (m_webserver_request.database_config_user ()->getDisplayBreadcrumbs ()) { - if (!m_bread_crumbs.empty ()) { - // No bread crumbs in basic mode. - // The crumbs would be incorrect anyway, because they show the trail of advanced mode. - if (!config::logic::basic_mode (m_webserver_request)) { - stringstream track; - track << ""; - track << menu_logic_menu_text ("") << ""; - for (auto & crumb : m_bread_crumbs) { - track << " » "; - if (!crumb.first.empty ()) { - track << ""; - } - track << crumb.second; - if (!crumb.first.empty ()) { - track << ""; - } - } - m_view->enable_zone("breadcrumbs"); - m_view->set_variable ("breadcrumbs", track.str()); - } - } - } - - page += m_view->render("assets", "xhtml_start"); - page += m_view->render("assets", "header"); - page += m_view->render("assets", "workspacewrapper_start"); - - return page; -} - - diff --git a/assets/header.h b/assets/header.h deleted file mode 100644 index 989cbd0b1..000000000 --- a/assets/header.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Webserver_Request; - -class Assets_Header -{ -public: - Assets_Header (std::string title, Webserver_Request& webserver_request_in); - ~Assets_Header (); - Assets_Header(const Assets_Header&) = delete; - Assets_Header operator=(const Assets_Header&) = delete; - void jquery_touch_on (); - void touch_css_on (); - void notify_it_on (); - void set_navigator (); - void set_stylesheet (); - void set_editor_stylesheet (); - bool display_topbar (); - void refresh (int seconds, std::string url = ""); - void set_fading_menu (std::string html); - void add_bread_crumb (std::string item, std::string text); - std::string run (); -private: - Assets_View * m_view {nullptr}; - bool m_jquery_touch_on {false}; - bool m_touch_css_on {false}; - bool m_notify_it_on {false}; - std::vector m_head_lines {}; - bool m_display_navigator {false}; - std::string m_included_stylesheet {}; - std::string m_included_editor_stylesheet {}; - Webserver_Request& m_webserver_request; - std::string m_fading_menu {}; - std::vector > m_bread_crumbs {}; -}; - diff --git a/assets/page.cpp b/assets/page.cpp deleted file mode 100644 index 0d3fc9a0b..000000000 --- a/assets/page.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - -namespace assets_page { - - -string header (const string & title, Webserver_Request& webserver_request) -{ - Assets_Header header = Assets_Header (title, webserver_request); - string page = header.run (); - return page; -} - - -string success (const string & message) -{ - Assets_View view {}; - view.set_variable ("message", message); - return view.render ("assets", "success"); -} - - -string error (const string & message) -{ - Assets_View view {}; - view.set_variable ("message", message); - return view.render ("assets", "error"); -} - - -string message (const string & message) -{ - Assets_View view {}; - view.set_variable ("message", message); - return view.render ("assets", "message"); -} - - -string footer () -{ - string page {}; - Assets_View view {}; - page += view.render ("assets", "workspacewrapper_finish"); - page += view.render ("assets", "footer"); - page += view.render ("assets", "xhtml_finish"); - return page; -} - - -} diff --git a/assets/page.h b/assets/page.h deleted file mode 100644 index 54d06641c..000000000 --- a/assets/page.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -namespace assets_page { - -std::string header (const std::string & title, Webserver_Request& webserver_request); -std::string success (const std::string & message); -std::string error (const std::string & message); -std::string message (const std::string & message); -std::string footer (); - -} diff --git a/assets/view.cpp b/assets/view.cpp deleted file mode 100644 index 7203ec459..000000000 --- a/assets/view.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -Assets_View::Assets_View () -{ - // On some installations like on iOS / Android / Mac, the browser has no controls. -#ifdef HAVE_BARE_BROWSER - enable_zone ("bare_browser"); -#endif - set_variable("VERSION", config::logic::version ()); -} - - -// Sets a variable (key and value) for the html template. -void Assets_View::set_variable (string key, string value) -{ - m_variables[key] = value; -} - - -// Enable displaying a zone in the html template. -void Assets_View::enable_zone (string zone) -{ - m_zones [zone] = true; -} - - -void Assets_View::disable_zone (string zone) -{ - m_zones.erase (zone); -} - - -void Assets_View::add_iteration (string key, map value) -{ - m_iterations[key].push_back (value); -} - - -// Renders the "tpl" template through the flate template engine. -// The "tpl" consists of two bits: -// 1: Relative folder -// 2: Basename of the html template without the .html extension. -// Setting the session variables in the template is postponed to the very last moment, -// since these could change during the course of the calling page. -string Assets_View::render (string tpl1, string tpl2) -{ - // Variable tpl is a relative path. Make it a full one. - string tpl = filter_url_create_root_path ({tpl1, tpl2 + ".html"}); - - // The flate engine crashes if the template does not exist, so be sure it exists. - if (!file_or_dir_exists (tpl)) { - Database_Logs::log ("Cannot find template file " + tpl); - return string(); - } - - // Instantiate and fill the template engine. - Flate flate; - - // Copy the variables and zones and iterations to the engine. - map ::iterator iter1; - for (iter1 = m_variables.begin (); iter1 != m_variables.end(); ++iter1) { - flate.set_variable (iter1->first, iter1->second); - } - map ::iterator iter2; - for (iter2 = m_zones.begin (); iter2 != m_zones.end(); ++iter2) { - flate.enable_zone (iter2->first); - } - flate.iterations = m_iterations; - - // Get and return the page contents. - string page = flate.render (tpl); - return page; -} diff --git a/assets/view.h b/assets/view.h deleted file mode 100644 index 9a49cce2c..000000000 --- a/assets/view.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Assets_View -{ -public: - Assets_View (); - void set_variable (std::string key, std::string value); - void enable_zone (std::string zone); - void disable_zone (std::string zone); - void add_iteration (std::string key, std::map value); - std::string render (std::string tpl1, std::string tpl2); -private: - std::map m_variables {}; - std::map m_zones {}; - std::map > > m_iterations {}; -}; diff --git a/bb/book.cpp b/bb/book.cpp deleted file mode 100644 index de187d4e8..000000000 --- a/bb/book.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string bible_book_url () -{ - return "bible/book"; -} - - -bool bible_book_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -std::string bible_book (Webserver_Request& webserver_request) -{ - std::string page {}; - - Assets_Header header = Assets_Header (translate("Book"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (bible_manage_url (), menu_logic_bible_manage_text ()); - page = header.run (); - - Assets_View view {}; - - std::string success_message {}; - std::string error_message {}; - - // The name of the Bible. - const std::string bible = access_bible::clamp (webserver_request, webserver_request.query["bible"]); - view.set_variable ("bible", filter::strings::escape_special_xml_characters (bible)); - - // The book. - const int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - view.set_variable ("book", filter::strings::convert_to_string (book)); - const std::string book_name = database::books::get_english_from_id (static_cast(book)); - view.set_variable ("book_name", filter::strings::escape_special_xml_characters (book_name)); - - // Whether the user has write access to this Bible book. - const bool write_access = access_bible::book_write (webserver_request, std::string(), bible, book); - if (write_access) view.enable_zone ("write_access"); - - // Delete chapter. - const std::string deletechapter = webserver_request.query ["deletechapter"]; - if (!deletechapter.empty()) { - const std::string confirm = webserver_request.query ["confirm"]; - if (confirm.empty()) { - Dialog_Yes dialog_yes = Dialog_Yes ("book", translate("Would you like to delete this chapter?")); - dialog_yes.add_query ("bible", bible); - dialog_yes.add_query ("book", filter::strings::convert_to_string (book)); - dialog_yes.add_query ("deletechapter", deletechapter); - page += dialog_yes.run (); - return page; - } if (confirm == "yes") { - if (write_access) bible_logic::delete_chapter (bible, book, filter::strings::convert_to_int (deletechapter)); - } - } - - // Add chapter. - if (webserver_request.query.count ("createchapter")) { - Dialog_Entry dialog_entry = Dialog_Entry ("book", translate("Please enter the number for the new chapter"), "", "createchapter", ""); - dialog_entry.add_query ("bible", bible); - dialog_entry.add_query ("book", filter::strings::convert_to_string (book)); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("createchapter")) { - const int createchapter = filter::strings::convert_to_int (webserver_request.post ["entry"]); - const std::vector chapters = webserver_request.database_bibles()->get_chapters (bible, book); - // Only create the chapters if it does not yet exist. - if (find (chapters.begin(), chapters.end(), createchapter) == chapters.end()) { - std::vector feedback{}; - bool result {true}; - if (write_access) result = book_create (bible, static_cast(book), createchapter, feedback); - const std::string message = filter::strings::implode (feedback, " "); - if (result) success_message = message; - else error_message = message; - } else { - error_message = translate ("This chapter already exists"); - } - } - - // Available chapters. - const std::vector chapters = webserver_request.database_bibles()->get_chapters (bible, book); - std::string chapterblock {}; - for (const auto& chapter : chapters) { - chapterblock.append (R"()"); - chapterblock.append (filter::strings::convert_to_string (chapter)); - chapterblock.append ("\n"); - } - view.set_variable ("chapterblock", chapterblock); - - view.set_variable ("success_message", success_message); - view.set_variable ("error_message", error_message); - - if (!client_logic_client_enabled ()) view.enable_zone ("server"); - - page += view.render ("bb", "book"); - - page += assets_page::footer (); - - return page; -} diff --git a/bb/book.h b/bb/book.h deleted file mode 100644 index a5226f14a..000000000 --- a/bb/book.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string bible_book_url (); -bool bible_book_acl (Webserver_Request& webserver_request); -std::string bible_book (Webserver_Request& webserver_request); diff --git a/bb/chapter.cpp b/bb/chapter.cpp deleted file mode 100644 index 8c9d10876..000000000 --- a/bb/chapter.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string bible_chapter_url () -{ - return "bible/chapter"; -} - - -bool bible_chapter_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -std::string bible_chapter (Webserver_Request& webserver_request) -{ - std::string page = assets_page::header (translate ("Chapter"), webserver_request); - - Assets_View view {}; - - std::string success_message {}; - std::string error_message {}; - - // The name of the Bible. - const std::string bible = access_bible::clamp (webserver_request, webserver_request.query["bible"]); - view.set_variable ("bible", filter::strings::escape_special_xml_characters (bible)); - - // The book. - const int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - view.set_variable ("book", filter::strings::convert_to_string (book)); - const std::string book_name = database::books::get_english_from_id (static_cast(book)); - view.set_variable ("book_name", filter::strings::escape_special_xml_characters (book_name)); - - // The chapter. - const std::string chapter = webserver_request.query ["chapter"]; - view.set_variable ("chapter", filter::strings::escape_special_xml_characters (chapter)); - - // Whether the user has write access to this Bible book. - if (bool write_access = access_bible::book_write (webserver_request, std::string(), bible, book); write_access) view.enable_zone ("write_access"); - - view.set_variable ("success_message", success_message); - view.set_variable ("error_message", error_message); - - if (!client_logic_client_enabled ()) view.enable_zone ("server"); - - page += view.render ("bb", "chapter"); - - page += assets_page::footer (); - - return page; -} diff --git a/bb/chapter.h b/bb/chapter.h deleted file mode 100644 index dada4bbca..000000000 --- a/bb/chapter.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string bible_chapter_url (); -bool bible_chapter_acl (Webserver_Request& webserver_request); -std::string bible_chapter (Webserver_Request& webserver_request); diff --git a/bb/css.cpp b/bb/css.cpp deleted file mode 100644 index c4ea80b7a..000000000 --- a/bb/css.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string bible_css_url () -{ - return "bible/css"; -} - - -bool bible_css_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -std::string bible_css (Webserver_Request& webserver_request) -{ - std::string page {}; - - Assets_Header header = Assets_Header (translate("Font and text direction"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (bible_manage_url (), menu_logic_bible_manage_text ()); - page = header.run (); - - Assets_View view {}; - - // The name of the Bible. - const std::string bible = access_bible::clamp (webserver_request, webserver_request.query ["bible"]); - view.set_variable ("bible", filter::strings::escape_special_xml_characters (bible)); - - // Data submission. - if (webserver_request.post.count ("submit")) { - - std::string font = webserver_request.post ["font"]; - font = filter::strings::trim (font); -#ifdef HAVE_CLIENT - // Bibledit client storage. - Database_Config_Bible::setTextFontClient (bible, font); -#else - // Bibledit Cloud storage. - Database_Config_Bible::setTextFont (bible, font); -#endif - - const std::string s_direction = webserver_request.post ["direction"]; - const int i_direction = Filter_Css::directionValue (s_direction); - - const std::string s_mode = webserver_request.post ["mode"]; - const int i_mode = Filter_Css::writingModeValue (s_mode); - - Database_Config_Bible::setTextDirection (bible, i_mode * 10 + i_direction); - - int lineheight = filter::strings::convert_to_int (webserver_request.post["lineheight"]); - if (lineheight < 50) lineheight = 50; - if (lineheight > 300) lineheight = 300; - Database_Config_Bible::setLineHeight (bible, lineheight); - - float letterspacing = filter::strings::convert_to_float (webserver_request.post["letterspacing"]); - if (letterspacing < -3) letterspacing = -3; - if (letterspacing > 3) letterspacing = 3; - Database_Config_Bible::setLetterSpacing (bible, static_cast(10 * letterspacing)); - - page += assets_page::success ("The information was saved."); - } - -#ifdef HAVE_CLIENT - view.enable_zone ("client"); -#endif - - const std::string font = fonts::logic::get_text_font (bible); - view.set_variable ("font", font); - - const int direction = Database_Config_Bible::getTextDirection (bible); - - view.set_variable ("direction_none", Filter_Css::directionUnspecified (direction)); - view.set_variable ("direction_ltr", Filter_Css::directionLeftToRight (direction)); - view.set_variable ("direction_rtl", Filter_Css::directionRightToLeft (direction)); - - view.set_variable ("mode_none", Filter_Css::writingModeUnspecified (direction)); - view.set_variable ("mode_tblr", Filter_Css::writingModeTopBottomLeftRight (direction)); - view.set_variable ("mode_tbrl", Filter_Css::writingModeTopBottomRightLeft (direction)); - view.set_variable ("mode_btlr", Filter_Css::writingModeBottomTopLeftRight (direction)); - view.set_variable ("mode_btrl", Filter_Css::writingModeBottomTopRightLeft (direction)); - - const int lineheight = Database_Config_Bible::getLineHeight (bible); - view.set_variable ("lineheight", filter::strings::convert_to_string (lineheight)); - - float letterspacing = static_cast (Database_Config_Bible::getLetterSpacing (bible)); - letterspacing /= 10; - view.set_variable ("letterspacing", filter::strings::convert_to_string (letterspacing)); - - const std::string custom_class = Filter_Css::getClass (bible); - view.set_variable ("custom_class", custom_class); - const std::string custom_css = Filter_Css::get_css (custom_class, - fonts::logic::get_font_path (font), direction, - lineheight, - Database_Config_Bible::getLetterSpacing (bible)); - view.set_variable ("custom_css", custom_css); - - page += view.render ("bb", "css"); - - page += assets_page::footer (); - - return page; -} diff --git a/bb/css.h b/bb/css.h deleted file mode 100644 index 4eee63026..000000000 --- a/bb/css.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string bible_css_url (); -bool bible_css_acl (Webserver_Request& webserver_request); -std::string bible_css (Webserver_Request& webserver_request); diff --git a/bb/import.cpp b/bb/import.cpp deleted file mode 100644 index beb41a0d6..000000000 --- a/bb/import.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string bible_import_url () -{ - return "bible/import"; -} - - -bool bible_import_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -std::string bible_import (Webserver_Request& webserver_request) -{ - std::string page {}; - - Assets_Header header = Assets_Header (translate("Import"), webserver_request); - header.set_navigator (); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (bible_manage_url (), menu_logic_bible_manage_text ()); - page = header.run (); - - Assets_View view {}; - - std::string success_message {}; - std::string error_message {}; - - // The name of the Bible. - const std::string bible = access_bible::clamp (webserver_request, webserver_request.query["bible"]); - view.set_variable ("bible", filter::strings::escape_special_xml_characters (bible)); - - const int book = Ipc_Focus::getBook (webserver_request); - const int chapter = Ipc_Focus::getChapter (webserver_request); - - // Whether the user has write access to this Bible. - if (bool write_access = access_bible::write (webserver_request, bible); write_access) { - view.enable_zone ("write_access"); - } - - // USFM data submission. - if (webserver_request.post.count ("submit")) { - // Submission may take long if there's a lot of data or the network is slow. - std::string data = webserver_request.post ["data"]; - data = filter_url_tag_to_plus (data); - data = filter::strings::trim (data); - if (!data.empty()) { - if (filter::strings::unicode_string_is_valid (data)) { - const std::string datafile = filter_url_tempfile (); - filter_url_file_put_contents (datafile, data); - success_message = translate("Import has started."); - view.set_variable ("journal", journal_logic_see_journal_for_progress ()); - tasks_logic_queue (IMPORTBIBLE, { datafile, bible, filter::strings::convert_to_string (book), filter::strings::convert_to_string (chapter) }); - } else { - error_message = translate("Please supply valid Unicode UTF-8 text."); - } - } else { - success_message = translate("Nothing was imported."); - } - // User imported something into this Bible: Set it as the default Bible. - webserver_request.database_config_user()->setBible (bible); - } - - // File upload. - if (webserver_request.post.count ("upload")) { - const std::string datafile = filter_url_tempfile () + webserver_request.post ["filename"]; - const std::string data = webserver_request.post ["data"]; - if (!data.empty ()) { - filter_url_file_put_contents (datafile, data); - success_message = translate("Import has started."); - view.set_variable ("journal", journal_logic_see_journal_for_progress ()); - tasks_logic_queue (IMPORTBIBLE, { datafile, bible, filter::strings::convert_to_string (book), filter::strings::convert_to_string (chapter) }); - } else { - error_message = translate ("Nothing was uploaded"); - } - // User imported something into this Bible: Set it as the default Bible. - webserver_request.database_config_user()->setBible (bible); - } - -#ifdef HAVE_UPLOAD - view.enable_zone ("enable_upload"); -#else - view.enable_zone ("disable_upload"); -#endif - - view.set_variable ("success_message", success_message); - view.set_variable ("error_message", error_message); - - view.set_variable ("external", assets_external_logic_link_addon ()); - - page += view.render ("bb", "import"); - - page += assets_page::footer (); - - return page; -} diff --git a/bb/import.h b/bb/import.h deleted file mode 100644 index 56c015a20..000000000 --- a/bb/import.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string bible_import_url (); -bool bible_import_acl (Webserver_Request& webserver_request); -std::string bible_import (Webserver_Request& webserver_request); diff --git a/bb/import_run.cpp b/bb/import_run.cpp deleted file mode 100644 index 8f23f0f0a..000000000 --- a/bb/import_run.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -void bible_import_run (std::string location, const std::string& bible, int book, int chapter) -{ - Database_Logs::log ("Importing Bible data from location " + location + " into Bible " + bible); - - const std::string folder = filter_archive_uncompress (location); - if (!folder.empty ()) location = folder; - std::vector files {}; - if (filter_url_is_dir (location)) { - filter_url_recursive_scandir (location, files); - } else { - files.push_back (location); - } - - for (const auto & file : files) { - if (filter_url_is_dir (file)) continue; - Database_Logs::log ("Examining file for import: " + file); - std::string success_message {}; - std::string error_message {}; - const std::string data = filter_url_file_get_contents (file); - if (!data.empty()) { - if (filter::strings::unicode_string_is_valid (data)) { - - // Check whether this is USFM data. - bool id = data.find ("\\id ") != std::string::npos; - bool c = data.find ("\\c ") != std::string::npos; - bool xml = data.find (" book_chapter_text = filter::usfm::usfm_import (data, stylesheet); - for (const auto& data2 : book_chapter_text) { - const int book_number = data2.m_book; - const int chapter_number = data2.m_chapter; - const std::string chapter_data = data2.m_data; - if (book_number > 0) { - bible_logic::store_chapter (bible, book_number, chapter_number, chapter_data); - const std::string book_name = database::books::get_usfm_from_id (static_cast(book_number)); - Database_Logs::log ("Imported " + book_name + " " + filter::strings::convert_to_string (chapter_number)); - } else { - Database_Logs::log ("Could not import this data: " + chapter_data.substr (0, 1000)); - } - } -} - - -// Import raw $text into $bible $book $chapter. -void bible_import_text (const std::string& text, const std::string& bible, int book, int chapter) -{ - // Consecutive discoveries. - bool discoveries_passed {true}; - - // Split the input text into separate lines. - std::vector lines = filter::strings::explode (text, '\n'); - - // Go through the lines. - for (size_t i = 0; i < lines.size(); i++) { - - // Trim the line. - lines[i] = filter::strings::trim (lines[i]); - - // Skip empty line. - if (lines[i].empty()) - continue; - - // Remove chapter markup. - if (lines[i].find("\\c") != std::string::npos) { - lines[i].clear(); - continue; - } - - // Skip line starting with a backslash. The rationale is that this line already has markup. - if (lines[i].substr(0, 1) == R"(\)") - continue; - - // If the line is a number on its own, and the number agrees with the chapter number - // that was set, it silently removes this line. But if it differs, an error comes up. - if (discoveries_passed) { - if (filter::strings::number_in_string(lines[i]) == lines[i]) { - const int number = filter::strings::convert_to_int (filter::strings::number_in_string (lines[i])); - if (number == chapter) { - lines[i].clear(); - continue; - } - const std::string msg = "The line that contains " + lines[i] + " looks like a chapter number, but the number differs from the chapter that was set"; - Database_Logs::log (msg); - discoveries_passed = false; - } - } - - // If the line has no number in it, - // and it ends with some type of punctuation, - // it is considered a a normal paragraph. - // If no punctuation at the end, it is a section heading. - if (discoveries_passed) { - if (filter::strings::number_in_string(lines[i]).empty()) { - const std::string last_character = lines[i].substr(lines[i].length() -1, 1); - if (filter::strings::unicode_string_is_punctuation (last_character)) { - lines[i].insert(0, "\\p "); - } else { - lines[i].insert(0, "\\s "); - } - continue; - } - } - - // If a number is found in the line, then this is considered a verse number. - // The first time a number is found, a \p is prefixed. - bool paragraph_open = false; - if (discoveries_passed) { - std::string output {}; - std::string number = filter::strings::number_in_string(lines[i]); - // Setting for having the number only at the start of the line. - bool treat_as_normal_paragraph {false}; - bool verses_at_start {true}; - if (verses_at_start) { - if (lines[i].find (number) != 0) { - number.clear(); - treat_as_normal_paragraph = true; - } - } - if (treat_as_normal_paragraph) { - - // Normal paragraph. - lines[i].insert(0, "\\p "); - - } else { - - // Find all verse numbers. - while (!number.empty()) { - if (!paragraph_open) { - output.append("\\p"); - paragraph_open = true; - } - size_t pos = lines[i].find(number); - if (pos > 0) { - output.append(" " + lines[i].substr(0, pos)); - lines[i].erase(0, pos); - } - output.append ("\n\\v "); - output.append (number); - output.append (" "); - lines[i].erase (0, number.length()); - lines[i] = filter::strings::trim (lines[i]); - number = filter::strings::number_in_string(lines[i]); - // Setting for discovering only first number in a paragraph. - if (verses_at_start) { - number.clear(); - } - } - - } - // Store line. - output.append(lines[i]); - lines[i] = output; - } - - } - - // Make one block of text. - std::string newtext {}; - for (unsigned int i = 0; i < lines.size(); i++) { - if (lines[i].empty()) - continue; - lines[i] = filter::strings::collapse_whitespace (lines[i]); - lines[i] = filter::strings::replace (" \n", "\n", lines[i]); - newtext.append(lines[i]); - newtext.append("\n"); - } - - // If no chapter marker is found, insert it at the top. - if (newtext.find("\\c") == std::string::npos) { - newtext.insert(0, "\\c " + filter::strings::convert_to_string(chapter) + "\n"); - } - - // Import the text as USFM. - bible_logic::store_chapter (bible, book, chapter, newtext); - const std::string book_name = database::books::get_usfm_from_id (static_cast(book)); - Database_Logs::log ("Imported " + book_name + " " + filter::strings::convert_to_string (chapter) + ": " + text); -} diff --git a/bb/import_run.h b/bb/import_run.h deleted file mode 100644 index ac42208d0..000000000 --- a/bb/import_run.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void bible_import_run (std::string location, const std::string& bible, int book, int chapter); -void bible_import_usfm (const std::string& data, const std::string& bible, int book, int chapter); -void bible_import_text (const std::string& text, const std::string& bible, int book, int chapter); diff --git a/bb/logic.cpp b/bb/logic.cpp deleted file mode 100644 index 963738e10..000000000 --- a/bb/logic.cpp +++ /dev/null @@ -1,1192 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void bible_logic::store_chapter (const string& bible, int book, int chapter, const string& usfm) -{ - Database_Bibles database_bibles {}; - - // Record data of the chapter to be stored prior to storing the new version. - // Both client and cloud follow this order. - -#ifdef HAVE_CLIENT - - // Client stores Bible action. - string oldusfm = database_bibles.get_chapter (bible, book, chapter); - Database_BibleActions database_bibleactions; - database_bibleactions.record (bible, book, chapter, oldusfm); - - // Kick the unsent-data timeout mechanism. - bible_logic::kick_unsent_data_timer (); - -#endif - -#ifdef HAVE_CLOUD - - // Server stores diff data. - Database_Modifications database_modifications; - database_modifications.storeTeamDiff (bible, book, chapter); - -#endif - - // Store the chapter in the database. - database_bibles.store_chapter (bible, book, chapter, usfm); -} - - -void bible_logic::delete_chapter (const string& bible, int book, int chapter) -{ - Database_Bibles database_bibles {}; - - // Cloud and client record data of the chapter to be deleted prior to deletion. - -#ifdef HAVE_CLIENT - - // Client stores Bible action. - string usfm = database_bibles.get_chapter (bible, book, chapter); - Database_BibleActions database_bibleactions; - database_bibleactions.record (bible, book, chapter, usfm); - - // Kick the unsent-data timeout mechanism. - bible_logic::kick_unsent_data_timer (); - -#endif - -#ifdef HAVE_CLOUD - - // Server stores diff data. - Database_Modifications database_modifications; - database_modifications.storeTeamDiff (bible, book, chapter); - -#endif - - // Delete the chapter from the database. - database_bibles.delete_chapter (bible, book, chapter); -} - - -void bible_logic::delete_book (const string& bible, int book) -{ - Database_Bibles database_bibles {}; - - // Both client and cloud record data of the book to be deleted prior to deletion. - -#ifdef HAVE_CLIENT - - // Client stores Bible actions. - Database_BibleActions database_bibleactions; - vector chapters = database_bibles.get_chapters (bible, book); - for (auto & chapter : chapters) { - string usfm = database_bibles.get_chapter (bible, book, chapter); - database_bibleactions.record (bible, book, chapter, usfm); - } - - // Kick the unsent-data timeout mechanism. - bible_logic::kick_unsent_data_timer (); - -#endif - -#ifdef HAVE_CLOUD - - // Server stores diff data. - Database_Modifications database_modifications; - database_modifications.storeTeamDiffBook (bible, book); - -#endif - - // Delete the book from the database. - database_bibles.delete_book (bible, book); -} - - -void bible_logic::delete_bible (const string& bible) -{ - Database_Bibles database_bibles {}; - - // The client and the cloud record data of the Bible to be deleted prior to deletion. - -#ifdef HAVE_CLIENT - - // Client stores Bible actions. - Database_BibleActions database_bibleactions {}; - vector books = database_bibles.get_books (bible); - for (const auto book : books) { - vector chapters = database_bibles.get_chapters (bible, book); - for (auto chapter : chapters) { - string usfm = database_bibles.get_chapter (bible, book, chapter); - database_bibleactions.record (bible, book, chapter, usfm); - } - } - - // Kick the unsent-data timeout mechanism. - bible_logic::kick_unsent_data_timer (); - -#endif - -#ifdef HAVE_CLOUD - - // Server stores diff data. - Database_Modifications database_modifications {}; - database_modifications.storeTeamDiffBible (bible); - - // Possible git repository. - string gitdirectory = filter_git_directory (bible); - if (file_or_dir_exists (gitdirectory)) { - filter_url_rmdir (gitdirectory); - } - -#endif - - // Delete the Bible from the database. - database_bibles.delete_bible (bible); - - // Delete the search index. - search_logic_delete_bible (bible); - - // Delete associated settings and privileges. - DatabasePrivileges::remove_bible (bible); - Database_Config_Bible::remove (bible); -} - - -void bible_logic::import_resource (string bible, string resource) -{ - Database_Logs::log ("Starting to import resource " + resource + " into Bible " + bible); - - Database_Versifications database_versifications {}; - Webserver_Request webserver_request {}; - - vector books = database_versifications.getMaximumBooks (); - for (const auto book : books) { - - string bookName = database::books::get_english_from_id (static_cast(book)); - - vector chapters = database_versifications.getMaximumChapters (book); - for (const auto chapter : chapters) { - - string message = "Importing " + resource + " " + bookName + " chapter " + filter::strings::convert_to_string (chapter); - Database_Logs::log (message, Filter_Roles::translator ()); - - vector usfm {}; - - if (chapter == 0) usfm.push_back ("\\id " + database::books::get_usfm_from_id (static_cast(book))); - - if (chapter) { - usfm.push_back ("\\c " + filter::strings::convert_to_string (chapter)); - usfm.push_back ("\\p"); - } - - vector verses = database_versifications.getMaximumVerses (book, chapter); - for (auto & verse : verses) { - - if (verse == 0) continue; - - // Fetch the text for the passage. - bool server_is_installing_module = false; - int wait_iterations = 0; - string html; - do { - // Fetch this resource from the server. - html = resource_logic_get_verse (webserver_request, resource, book, chapter, verse); - server_is_installing_module = (html == sword_logic_installing_module_text ()); - if (server_is_installing_module) { - Database_Logs::log (translate ("Waiting while Bibledit Cloud installs the requested SWORD module")); - this_thread::sleep_for (chrono::seconds (60)); - wait_iterations++; - } - } while (server_is_installing_module && (wait_iterations < 5)); - - // Remove all html markup. - html = filter::strings::html2text (html); - html = filter::strings::replace ("\n", " ", html); - - // Add the verse to the USFM. - usfm.push_back ("\\v " + filter::strings::convert_to_string (verse) + " " + filter::strings::trim (html)); - } - bible_logic::store_chapter (bible, book, chapter, filter::strings::implode (usfm, "\n")); - } - } - - Database_Logs::log ("Completed importing resource " + resource + " into Bible " + bible); -} - - -// This logs the change in the Bible text. -// When $force is given, it records the change on clients also. -void bible_logic::log_change (const string& bible, - int book, int chapter, - const string& usfm, - string user, - const string & summary, - [[maybe_unused]] bool force) -{ -#ifdef HAVE_CLIENT - if (!force) return; -#endif - - Database_Bibles database_bibles; - string existing_usfm = database_bibles.get_chapter (bible, book, chapter); - - // It used to calculate the percentage difference, but this took a relatively long time. - // In particular on low-power devices and on Windows, the time it took was excessive. - - string bookname = database::books::get_english_from_id (static_cast(book)); - string passage = bible + " " + bookname + " " + filter::strings::convert_to_string (chapter); - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - vector existing_verse_numbers = filter::usfm::get_verse_numbers (existing_usfm); - vector verse_numbers = filter::usfm::get_verse_numbers (usfm); - vector verses = existing_verse_numbers; - verses.insert (verses.end (), verse_numbers.begin (), verse_numbers.end ()); - verses = filter::strings::array_unique (verses); - sort (verses.begin (), verses.end ()); - - vector body; - - body.push_back ("Changes:"); - - for (auto verse : verses) { - string existing_verse_usfm = filter::usfm::get_verse_text (existing_usfm, verse); - string verse_usfm = filter::usfm::get_verse_text (usfm, verse); - if (existing_verse_usfm != verse_usfm) { - Filter_Text filter_text_old = Filter_Text (bible); - Filter_Text filter_text_new = Filter_Text (bible); - filter_text_old.text_text = new Text_Text (); - filter_text_new.text_text = new Text_Text (); - filter_text_old.add_usfm_code (existing_verse_usfm); - filter_text_new.add_usfm_code (verse_usfm); - filter_text_old.run (stylesheet); - filter_text_new.run (stylesheet); - string old_text = filter_text_old.text_text->get (); - string new_text = filter_text_new.text_text->get (); - if (old_text != new_text) { - body.push_back (string()); - body.push_back (filter_passage_display (book, chapter, filter::strings::convert_to_string (verse))); - body.push_back ("Old: " + old_text); - body.push_back ("New: " + new_text); - } - } - } - - body.push_back (string()); - body.push_back ("Old USFM:"); - body.push_back (existing_usfm); - - body.push_back (string()); - body.push_back ("New USFM:"); - body.push_back (usfm); - - if (!user.empty ()) user.append (" - "); - Database_Logs::log (user + summary + " - " + passage, filter::strings::implode (body, "\n")); -} - - -// This logs the change in the Bible text as a result of a merge operation. -// This is mostly for diagnostics as at times there's queries on how the merge was done. -void bible_logic::log_merge (string user, string bible, int book, int chapter, - string base, string change, string prioritized_change, string result) -{ - string bookname = database::books::get_english_from_id (static_cast(book)); - string passage = bible + " " + bookname + " " + filter::strings::convert_to_string (chapter); - - vector body {}; - - body.push_back ("This is a record of a merge operation after receiving an update on a chapter from a client."); - body.push_back (string()); - body.push_back ("Base:"); - body.push_back (base); - - body.push_back (string()); - body.push_back ("Change:"); - body.push_back (change); - - body.push_back (string()); - body.push_back ("Existing:"); - body.push_back (prioritized_change); - - body.push_back (string()); - body.push_back ("Result:"); - body.push_back (result); - - Database_Logs::log (user + " - merge record - " + passage, filter::strings::implode (body, "\n")); -} - - -void bible_logic::kick_unsent_data_timer () -{ - // The timer contains the oldest age of Bible data on a client not yet sent to the Cloud. - // If the timer has been set already, bail out. - if (Database_Config_General::getUnsentBibleDataTime () != 0) return; - - // Stamp with the current time. - Database_Config_General::setUnsentBibleDataTime (filter::date::seconds_since_epoch ()); -} - - -void bible_logic::kick_unreceived_data_timer () -{ - Database_Config_General::setUnreceivedBibleDataTime (filter::date::seconds_since_epoch ()); -} - - -// This returns a warning in case there's old Bible data not yet sent to the Cloud, -// or in case it has not received data from the Cloud for some days. -string bible_logic::unsent_unreceived_data_warning () -{ - string warning {}; - -#ifdef HAVE_CLIENT - - // Time-stamp for oldest unreceived Bible data. - int data_time = Database_Config_General::getUnreceivedBibleDataTime (); - // A value of 0 means that it is not relevant. - if (data_time) { - int now = filter::date::seconds_since_epoch (); - // Unreceived data warning after four days. - data_time += (4 * 24 * 3600); - if (now > data_time) { - warning.clear (); - warning.append (translate ("It has been some time ago that changes in the Bible text were received from the Cloud.")); - warning.append (" "); - warning.append (translate ("This will right itself in a little time if you are connected to the Internet.")); - warning.append (" "); - warning.append (translate ("If not please do a Send/receive action.")); - } - } - - // Time-stamp for oldest unsent Bible data. - data_time = Database_Config_General::getUnsentBibleDataTime (); - // A value of 0 means that there's no pending data. - if (data_time) { - int now = filter::date::seconds_since_epoch (); - // Unsent data warning after four days. - data_time += (4 * 24 * 3600); - if (now > data_time) { - warning.clear (); - warning.append (translate ("There are pending changes in the Bible text that have not yet been sent to the Cloud for some time.")); - warning.append (" "); - warning.append (translate ("This will right itself in a little time if you are connected to the Internet.")); - warning.append (" "); - warning.append (translate ("If not please do a Send/receive action.")); - } - } - -#endif - - return warning; -} - - -void bible_logic::merge_irregularity_mail (vector users, vector conflicts) -{ - if (conflicts.empty ()) return; - - for (const auto & conflict : conflicts) { - - // Add the passage to the subject. - string newsubject = conflict.subject; - if (conflict.book) newsubject.append (" | " + filter_passage_display (conflict.book, conflict.chapter, string())); - - // Create the body of the email. - xml_document document {}; - xml_node node {}; - node = document.append_child ("h3"); - node.text ().set (newsubject.c_str()); - - // Storage of the changes the user sent, and the result that was saved, in raw USFM, per verse. - vector change_usfm {}; - vector result_usfm {}; - - // Go through all verses available in the USFM, - // and make a record for each verse, - // where the USFM differs between the change that the user made and the result that was saved. - vector verses = filter::usfm::get_verse_numbers (conflict.result); - for (auto verse : verses) { - string change = filter::usfm::get_verse_text (conflict.change, verse); - string result = filter::usfm::get_verse_text (conflict.result, verse); - // When there's no change in the verse, skip it. - if (change == result) continue; - // Record the difference. - change_usfm.push_back (change); - result_usfm.push_back (result); - } - - // Add some information for the user. - node = document.append_child ("p"); - node.text ().set ("You sent changes to the Cloud. The changes were merged with other changes already in the Cloud. The crossed out parts below could not be merged. They were replaced with the bold text below. You may want to check the changes or resend them."); - - // Go over each verse where the change differs from the resulting text that was saved. - // For each verse, outline the difference between the change and the result. - // Clearly maark it up for the user. - // The purpose is that the user immediately can see what happened, - // and whether and how to correct it. - for (size_t i = 0; i < change_usfm.size(); i++) { - node = document.append_child ("p"); - string modification = filter_diff_diff (change_usfm[i], result_usfm[i]); - // Add raw html to the email's text buffer. - node.append_buffer (modification.c_str (), modification.size ()); - } - - // Add some information for the user. - document.append_child ("hr"); - document.append_child ("br"); - xml_node div_node {}; - div_node = document.append_child ("div"); - // Disabled: https://github.com/bibledit/cloud/issues/401 - // div_node.append_attribute ("style") = "font-size: 30%"; - - node = div_node.append_child ("p"); - node.text ().set ("Full details follow below."); - - // Add the base text. - div_node.append_child ("br"); - node = div_node.append_child ("p"); - node.text ().set ("Base text loaded in your editor"); - node = div_node.append_child ("pre"); - node.text ().set (conflict.base.c_str ()); - - // Add the changed text. - div_node.append_child ("br"); - node = div_node.append_child ("p"); - node.text ().set ("Changed text by you"); - node = div_node.append_child ("pre"); - node.text ().set (conflict.change.c_str ()); - - // Add the existing text. - div_node.append_child ("br"); - node = div_node.append_child ("p"); - node.text ().set ("Existing text in the Cloud"); - node = div_node.append_child ("pre"); - node.text ().set (conflict.prioritized_change.c_str ()); - - // Add the merge result. - div_node.append_child ("br"); - node = div_node.append_child ("p"); - node.text ().set ("The text that was actually saved to the chapter in the Cloud"); - node = div_node.append_child ("pre"); - node.text ().set (conflict.result.c_str ()); - - // Convert the document to a string. - stringstream output {}; - document.print (output, "", format_raw); - string html = output.str (); - - // Schedule the mail for sending to the user(s). - for (const auto & user : users) { - email_schedule (user, newsubject, html); - } - } -} - - -void bible_logic::unsafe_save_mail (string subject, const string & explanation, - const string & user, - const string & usfm, - int book, int chapter) -{ - if (subject.empty ()) return; - - // Add the passage to the subject for extra clarity. - // https://github.com/bibledit/cloud/issues/676 - subject.append (" | " + filter_passage_display (book, chapter, string())); - - // Create the body of the email. - xml_document document {}; - xml_node node {}; - node = document.append_child ("h3"); - node.text ().set (subject.c_str()); - - // Add some information for the user. - node = document.append_child ("p"); - node.text ().set (explanation.c_str ()); - node = document.append_child ("p"); - node.text ().set ("Failed to save the text below."); - - // Add the base text. - document.append_child ("br"); - node = document.append_child ("pre"); - node.text ().set (usfm.c_str ()); - - // Convert the document to a string. - stringstream output {}; - document.print (output, "", format_raw); - string html = output.str (); - - // Schedule the mail for sending to the user. - email_schedule (user, subject, html); -} - - -// This function sends an email -// if the USFM received from the client -// does not match the USFM that gets stored on the server. -void bible_logic::client_receive_merge_mail (const string & bible, int book, int chapter, - const string & user, - const string & client_old, - const string & client_new, - const string & server) -{ - // No difference: Done. - if (client_old == server) return; - - vector client_diff {}; - vector server_diff {}; - - // Go through all verses from the client, - // and make a record for each verse, - // where the USFM differs between client and server. - vector verses = filter::usfm::get_verse_numbers (client_old); - for (const auto verse : verses) { - string client_old_verse = filter::usfm::get_verse_text (client_old, verse); - string client_new_verse = filter::usfm::get_verse_text (client_new, verse); - // When there's no change in the verse as sent by the client, skip further checks. - if (client_old_verse == client_new_verse) continue; - // Check whether the client's change made it to the server. - string server_verse = filter::usfm::get_verse_text (server, verse); - if (client_new_verse == server_verse) continue; - // Record the difference. - client_diff.push_back (client_new_verse); - server_diff.push_back (server_verse); - } - - // No differences found: Done. - if (client_diff.empty ()) return; - - // Add the passage to the subject. - string subject = "Saved Bible text was merged"; - subject.append (" | " + filter_passage_display (book, chapter, string())); - - // Create the body of the email. - xml_document document {}; - xml_node node {}; - node = document.append_child ("h3"); - node.text ().set (subject.c_str()); - - // Add some information for the user. - node = document.append_child ("p"); - string information {}; - information.append (translate ("The Cloud already had some changes in this chapter.")); - information.append (" "); - information.append (translate ("You sent some changes for this chapter too.")); - information.append (" "); - information.append (translate ("The Cloud merged the two.")); - information.append (" "); - information.append (translate ("Most likely this is okay.")); - information.append (" "); - information.append (translate ("You may want to check the result of the merge, whether it is correct.")); - node.text ().set (information.c_str()); - node = document.append_child ("p"); - string location = bible + " " + filter_passage_display (book, chapter, "") + "."; - node.text ().set (location.c_str ()); - - for (unsigned int i = 0; i < client_diff.size(); i++) { - - document.append_child ("br"); - node = document.append_child ("p"); - node.text ().set ("You sent:"); - node = document.append_child ("p"); - node.text ().set (client_diff[i].c_str ()); - node = document.append_child ("p"); - node.text ().set ("The Cloud now has:"); - node = document.append_child ("p"); - node.text ().set (server_diff[i].c_str ()); - node = document.append_child ("p"); - node.text ().set ("The difference is:"); - node = document.append_child ("p"); - string difference = filter_diff_diff (client_diff[i], server_diff[i]); - node.append_buffer (difference.c_str (), difference.size ()); - } - - // Convert the document to a string. - stringstream output {}; - document.print (output, "", format_raw); - string html = output.str (); - - // Schedule the mail for sending to the user. - email_schedule (user, subject, html); -} - - -// This emails pending Bible updates to the user. -void bible_logic::client_mail_pending_bible_updates (string user) -{ - // Iterate over all the actions stored for all Bible data ready for sending to the Cloud. - Database_BibleActions database_bibleactions {}; - Database_Bibles database_bibles {}; - vector bibles = database_bibleactions.getBibles (); - for (string bible : bibles) { - // Skip the Sample Bible, for less clutter. - if (bible == demo_sample_bible_name ()) continue; - vector books = database_bibleactions.getBooks (bible); - for (const int book : books) { - vector chapters = database_bibleactions.getChapters (bible, book); - for (const int chapter : chapters) { - - // Get old and new USFM for this chapter. - string oldusfm = database_bibleactions.getUsfm (bible, book, chapter); - string newusfm = database_bibles.get_chapter (bible, book, chapter); - // If old USFM and new USFM are the same, or the new USFM is empty, skip it. - if (newusfm == oldusfm) continue; - if (newusfm.empty ()) continue; - - // Add the passage to the subject. - string subject = "Discarded text update"; - subject.append (" | " + filter_passage_display (book, chapter, string())); - - // Create the body of the email. - xml_document document {}; - xml_node node {}; - node = document.append_child ("h3"); - node.text ().set (subject.c_str()); - - // Add some information for the user. - node = document.append_child ("p"); - string information {}; - information.append (translate ("You have now connected to Bibledit Cloud.")); - information.append (" "); - information.append (translate ("While you were disconnected from Bibledit Cloud, you made some changes in the Bible text on your device.")); - information.append (" "); - information.append (translate ("These changes will not be saved to Bibledit Cloud.")); - information.append (" "); - information.append (translate ("The unsaved text is below.")); - node.text ().set (information.c_str()); - - // Add the passage. - node = document.append_child ("p"); - string location = bible + " " + filter_passage_display (book, chapter, "") + "."; - node.text ().set (location.c_str ()); - - // Add the text. - document.append_child ("br"); - node = document.append_child ("pre"); - node.text ().set (newusfm.c_str ()); - - // Convert the document to a string. - stringstream output; - document.print (output, "", format_raw); - string html = output.str (); - - // Schedule the mail for sending to the user. - email_schedule (user, subject, html); - } - } - } -} - - -void bible_logic::client_no_write_access_mail (const string & bible, int book, int chapter, - const string & user, - const string & oldusfm, const string & newusfm) -{ - // No difference: Done. - if (oldusfm == newusfm) return; - - vector client_new_diff {}; - vector client_old_diff {}; - - // Go through all verses from the client, - // and make a record for each verse, - // where the USFM differs between client and server. - vector verses = filter::usfm::get_verse_numbers (oldusfm); - for (const auto verse : verses) { - string client_old_verse = filter::usfm::get_verse_text (oldusfm, verse); - string client_new_verse = filter::usfm::get_verse_text (newusfm, verse); - // When there's no change in the verse as sent by the client, skip further checks. - if (client_old_verse == client_new_verse) continue; - // Record the difference. - client_new_diff.push_back (client_new_verse); - client_old_diff.push_back (client_old_verse); - } - - // No differences found: Done. - if (client_new_diff.empty ()) return; - - // Add the passage to the subject. - string subject = "No write access while sending Bible text"; - subject.append (" | " + filter_passage_display (book, chapter, "")); - - // Create the body of the email. - xml_document document {}; - xml_node node {}; - node = document.append_child ("h3"); - node.text ().set (subject.c_str()); - - // Add some information for the user. - node = document.append_child ("p"); - string information {}; - information.append (translate ("While sending Bible text to Bibledit Cloud, you did not have write access to this chapter.")); - information.append (" "); - information.append (translate ("You may want to check whether this is correct.")); - node.text ().set (information.c_str()); - node = document.append_child ("p"); - string location = bible + " " + filter_passage_display (book, chapter, "") + "."; - node.text ().set (location.c_str ()); - - for (unsigned int i = 0; i < client_new_diff.size(); i++) { - - document.append_child ("br"); - node = document.append_child ("p"); - node.text ().set ("You sent:"); - node = document.append_child ("p"); - node.text ().set (client_new_diff[i].c_str ()); - node = document.append_child ("p"); - node.text ().set ("The difference is:"); - node = document.append_child ("p"); - string difference = filter_diff_diff (client_old_diff[i], client_new_diff[i]); - node.append_buffer (difference.c_str (), difference.size ()); - } - - // Convert the document to a string. - stringstream output {}; - document.print (output, "", format_raw); - string html = output.str (); - - // Schedule the mail for sending to the user. - email_schedule (user, subject, html); -} - - -void bible_logic::recent_save_email (const string & bible, - int book, int chapter, - const string & user, - const string & old_usfm, const string & new_usfm) -{ - vector old_verses {}; - vector new_verses {}; - - // Go through all verses available in the USFM, - // and make a record for each verse, - // where the USFM differs between the old and the new USFM. - vector verses = filter::usfm::get_verse_numbers (new_usfm); - for (const auto verse : verses) { - string old_verse = filter::usfm::get_verse_text (old_usfm, verse); - string new_verse = filter::usfm::get_verse_text (new_usfm, verse); - // When there's no change in the verse, skip further checks. - if (old_verse == new_verse) continue; - // Record the difference. - old_verses.push_back (old_verse); - new_verses.push_back (new_verse); - } - - // No differences found: Done. - if (new_verses.empty ()) return; - - // Add the passage to the subject. - string subject = translate ("Check whether Bible text was saved"); - subject.append (" | " + filter_passage_display (book, chapter, "")); - - // Create the body of the email. - xml_document document {}; - xml_node node {}; - node = document.append_child ("h3"); - node.text ().set (subject.c_str()); - - // Add some information for the user. - node = document.append_child ("p"); - string information {}; - information.append (translate ("Bibledit saved the Bible text below.")); - information.append (" "); - information.append (translate ("But Bibledit is not entirely sure that all went well.")); - information.append (" "); - information.append (translate ("You may want to check whether the Bible text was saved correctly.")); - information.append (" "); - information.append (translate ("The text in bold was added.")); - information.append (" "); - information.append (translate ("The text in strikethrough was removed.")); - node.text ().set (information.c_str()); - node = document.append_child ("p"); - string location = bible + " " + filter_passage_display (book, chapter, "") + "."; - node.text ().set (location.c_str ()); - - bool differences_found {false}; - for (unsigned int i = 0; i < new_verses.size(); i++) { - Filter_Text filter_text_old = Filter_Text (bible); - Filter_Text filter_text_new = Filter_Text (bible); - filter_text_old.html_text_standard = new HtmlText (translate("Bible")); - filter_text_new.html_text_standard = new HtmlText (translate("Bible")); - filter_text_old.text_text = new Text_Text (); - filter_text_new.text_text = new Text_Text (); - filter_text_old.add_usfm_code (old_verses[i]); - filter_text_new.add_usfm_code (new_verses[i]); - filter_text_old.run (styles_logic_standard_sheet()); - filter_text_new.run (styles_logic_standard_sheet()); - string old_text = filter_text_old.text_text->get (); - string new_text = filter_text_new.text_text->get (); - if (old_text != new_text) { - node = document.append_child ("p"); - string modification = filter_diff_diff (old_text, new_text); - string fragment = /* filter::strings::convert_to_string (verse) + " " + */ modification; - node.append_buffer (fragment.c_str (), fragment.size ()); - differences_found = true; - } - } - // If no differences were found, bail out. - // This also handles differences in spacing. - // If the differences consist of whitespace only, bail out here. - // See issue https://github.com/bibledit/cloud/issues/413 - if (!differences_found) return; - - // Convert the document to a string. - stringstream output {}; - document.print (output, "", format_raw); - string html = output.str (); - - // Schedule the mail for sending to the user. - email_schedule (user, subject, html); -} - - -void bible_logic::optional_merge_irregularity_email (const string & bible, int book, int chapter, - const string & user, - const string & ancestor_usfm, - const string & edited_usfm, - const string & merged_usfm) -{ - // If the merged edited USFM is the same as the edited USFM, - // that means that the user's changes will get saved to the chapter. - if (edited_usfm == merged_usfm) return; - // But if the merged edited USFM differs from the original edited USFM, - // more checks need to be done to be sure that the user's edits made it. - - // Add the passage to the subject. - string subject = translate ("Check whether Bible text was saved"); - subject.append (" | " + filter_passage_display (book, chapter, "")); - - // Create the body of the email. - xml_document document {}; - xml_node node {}; - node = document.append_child ("h3"); - node.text ().set (subject.c_str()); - - // Add some information for the user. - node = document.append_child ("p"); - string information {}; - information.append (translate ("Bibledit saved the Bible text below.")); - information.append (" "); - information.append (translate ("But Bibledit is not entirely sure that all went well.")); - information.append (" "); - information.append (translate ("You may want to check whether the Bible text was saved correctly.")); - information.append (" "); - information.append (translate ("The text in bold was added.")); - information.append (" "); - information.append (translate ("The text in strikethrough was removed.")); - node.text ().set (information.c_str()); - node = document.append_child ("p"); - string location = bible + " " + filter_passage_display (book, chapter, "") + "."; - node.text ().set (location.c_str ()); - - bool anomalies_found {false}; - - // Go through all verses available in the USFM, - // and check the differences for each verse. - vector verses = filter::usfm::get_verse_numbers (merged_usfm); - for (const auto verse : verses) { - string ancestor_verse_usfm = filter::usfm::get_verse_text (ancestor_usfm, verse); - string edited_verse_usfm = filter::usfm::get_verse_text (edited_usfm, verse); - string merged_verse_usfm = filter::usfm::get_verse_text (merged_usfm, verse); - // There's going to be a check to find out that all the changes the user made, - // are available among the changes resulting from the merge. - // If all the changes are there, all is good. - // If not, then email the user about this. - bool anomaly_found {false}; - vector user_removals, user_additions, merged_removals, merged_additions; - filter_diff_diff (ancestor_verse_usfm, edited_verse_usfm, &user_removals, &user_additions); - filter_diff_diff (ancestor_verse_usfm, merged_verse_usfm, &merged_removals, &merged_additions); - for (auto user_removal : user_removals) { - if (!in_array (user_removal, merged_removals)) anomaly_found = true; - } - for (auto user_addition : user_additions) { - if (!in_array (user_addition, merged_additions)) anomaly_found = true; - } - if (!anomaly_found) continue; - Filter_Text filter_text_ancestor = Filter_Text (bible); - Filter_Text filter_text_edited = Filter_Text (bible); - Filter_Text filter_text_merged = Filter_Text (bible); - filter_text_ancestor.html_text_standard = new HtmlText (translate("Bible")); - filter_text_edited.html_text_standard = new HtmlText (translate("Bible")); - filter_text_merged.html_text_standard = new HtmlText (translate("Bible")); - filter_text_ancestor.text_text = new Text_Text (); - filter_text_edited.text_text = new Text_Text (); - filter_text_merged.text_text = new Text_Text (); - filter_text_ancestor.add_usfm_code (ancestor_verse_usfm); - filter_text_edited.add_usfm_code (edited_verse_usfm); - filter_text_merged.add_usfm_code (merged_verse_usfm); - filter_text_ancestor.run (styles_logic_standard_sheet()); - filter_text_edited.run (styles_logic_standard_sheet()); - filter_text_merged.run (styles_logic_standard_sheet()); - string ancestor_text = filter_text_ancestor.text_text->get (); - string edited_text = filter_text_edited.text_text->get (); - string merged_text = filter_text_merged.text_text->get (); - string modification_edited = filter_diff_diff (ancestor_text, edited_text); - string modification_saved = filter_diff_diff (ancestor_text, merged_text); - // If the edited and saved modifications are the same, do not email this. - // This keeps changes in footnotes and cross references out from consideration. - if (modification_saved == modification_edited) continue; - // Add labels to the modifications. - modification_edited.insert(0, translate ("You edited:") + " "); - modification_saved.insert(0, translate ("Bibledit saved:") + " "); - // Add the modifications to the email body. - node = document.append_child ("p"); - node.append_buffer (modification_edited.c_str (), modification_edited.size ()); - node = document.append_child ("p"); - node.append_buffer (modification_saved.c_str (), modification_saved.size ()); - anomalies_found = true; - } - - // If no differences were found, bail out. - // This also handles differences in spacing. - // If the differences consist of whitespace only, bail out here. - // See issue https://github.com/bibledit/cloud/issues/413 - if (!anomalies_found) return; - - // Convert the document to a string. - stringstream output {}; - document.print (output, "", format_raw); - string html = output.str (); - - // Schedule the mail for sending to the user. - email_schedule (user, subject, html); -} - - -const char * bible_logic::insert_operator () -{ - return "i"; -} -const char * bible_logic::delete_operator () -{ - return "d"; -} -const char * bible_logic::format_paragraph_operator () -{ - return "p"; -} -const char * bible_logic::format_character_operator () -{ - return "c"; -} - -// There are three containers with updating information. -// The function condenses this updating information. -// This condensed information works better for the Quill editor. -void bible_logic::condense_editor_updates (const vector & positions_in, - const vector & sizes_in, - const vector & additions_in, - const vector & content_in, - vector & positions_out, - vector & sizes_out, - vector & operators_out, - vector & content_out) -{ - positions_out.clear(); - sizes_out.clear(); - operators_out.clear(); - content_out.clear(); - - // https://stackoverflow.com/questions/40492414/why-does-stdnumeric-limitslong-longmax-fail - int previous_position = (numeric_limits::min)(); - bool previous_addition {false}; - string previous_character {}; - for (size_t i = 0; i < positions_in.size(); i++) { - const int position = positions_in[i]; - const int size = sizes_in[i]; - const bool addition = additions_in[i]; - const string character = content_in[i].substr (0, 1); - const string format = content_in[i].substr (1); - - // The following situation occurs when changing the style of a paragraph. - // Like for example changing a paragraph style from "p" to "s". - // The current sequence for this change is: - // 1. Delete a new line at a known position. - // 2. Insert a new line at the same position, with a given format. - // Condense this as follows: - // 1. Apply the given paragraph format to the given position. - // Without condensing this, the following would happen: - // 1. Delete the new line before the second line. - // Result: The first line gets the format of the second line. - // 2. Insert the new line before the second line again. - // 3. Appy formatting to the second line. - // The net result is that the first line remains with the paragraph format of the second line. - bool newlineflag = addition && !previous_addition && (character == "\n") && (character == previous_character) && (position == previous_position); - if (newlineflag) { - // Remove the previous "delete new line". - positions_out.pop_back(); - sizes_out.pop_back(); - operators_out.pop_back(); - content_out.pop_back(); - // Add the paragraph format operation data. - positions_out.push_back(position); - sizes_out.push_back(size); - operators_out.push_back(bible_logic::format_paragraph_operator()); - content_out.push_back(format); - } else { - positions_out.push_back(position); - sizes_out.push_back(size); - if (addition) operators_out.push_back(bible_logic::insert_operator()); - else operators_out.push_back(bible_logic::delete_operator()); - content_out.push_back(character + format); - } - - // Store data for the next iteration. - previous_position = position; - previous_addition = addition; - previous_character = character; - } - -} - - -void bible_logic::html_to_editor_updates (const string & editor_html, - const string & server_html, - vector & positions, - vector & sizes, - vector & operators, - vector & content) -{ - // Clear outputs. - positions.clear(); - sizes.clear(); - operators.clear(); - content.clear(); - - // Convert the html to formatted text. - Editor_Html2Format editor_format {}; - Editor_Html2Format server_format {}; - editor_format.load (editor_html); - server_format.load (server_html); - editor_format.run (); - server_format.run (); - - // Convert the formatted text fragments to formatted UTF-8 characters. - vector editor_formatted_character_content; - for (size_t i = 0; i < editor_format.texts.size(); i++) { - const string & text = editor_format.texts[i]; - const string & format = editor_format.formats[i]; - const size_t length = filter::strings::unicode_string_length (text); - for (size_t pos = 0; pos < length; pos++) { - const string utf8_character = filter::strings::unicode_string_substr (text, pos, 1); - editor_formatted_character_content.push_back (utf8_character + format); - } - } - vector server_formatted_character_content {}; - vector server_utf8_characters {}; - for (size_t i = 0; i < server_format.texts.size(); i++) { - const string & text = server_format.texts[i]; - const string & format = server_format.formats[i]; - const size_t length = filter::strings::unicode_string_length (text); - for (size_t pos = 0; pos < length; pos++) { - const string utf8_character = filter::strings::unicode_string_substr (text, pos, 1); - server_formatted_character_content.push_back (utf8_character + format); - server_utf8_characters.push_back(utf8_character); - } - } - - // Find the differences between the two sets of content. - vector positions_diff {}; - vector sizes_diff {}; - vector additions_diff {}; - vector content_diff {}; - int new_line_diff_count {}; - filter_diff_diff_utf16 (editor_formatted_character_content, server_formatted_character_content, - positions_diff, sizes_diff, additions_diff, content_diff, new_line_diff_count); - - // Condense the differences a bit and render them to another format. - bible_logic::condense_editor_updates (positions_diff, sizes_diff, additions_diff, content_diff, - positions, sizes, operators, content); - - // Problem description: - // User action: Remove the new line at the end of the current paragraph. - // Result: The current paragraph takes the style of the next paragraph. - // User actions: While removing notes, this goes wrong. - // Solution: - // If there's new line(s) added or removed, apply all paragraph styles again. - if (new_line_diff_count) { - int position {0}; - for (size_t i = 0; i < server_utf8_characters.size(); i++) { - const int size = static_cast(filter::strings::convert_to_u16string (server_utf8_characters[i]).length()); - if (server_utf8_characters[i] == "\n") { - positions.push_back(position); - sizes.push_back(size); - operators.push_back(bible_logic::format_paragraph_operator()); - content.push_back(server_formatted_character_content[i].substr (1)); - } - position += size; - } - } -} - - -void bible_logic::create_empty_bible (const string & name) -{ - Database_Logs::log (translate("Creating Bible") + " " + name); - - // Remove and create the empty Bible. - Database_Bibles database_bibles {}; - database_bibles.delete_bible (name); - database_bibles.create_bible (name); - - // Remove index for the Bible. - search_logic_delete_bible (name); - - // Create books with blank verses for the OT and NT. - vector books = database::books::get_ids (); - for (const auto book : books) { - const book_type type = database::books::get_type (book); - if ((type == book_type::old_testament) || (type == book_type::new_testament)) { - vector feedback {}; - book_create (name, book, -1, feedback); - } - } - - Database_Logs::log (translate("Created:") + " " + name); -} diff --git a/bb/logic.h b/bb/logic.h deleted file mode 100644 index 605409362..000000000 --- a/bb/logic.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -namespace bible_logic { - -void store_chapter (const std::string& bible, int book, int chapter, const std::string& usfm); -void delete_chapter (const std::string& bible, int book, int chapter); -void delete_book (const std::string& bible, int book); -void delete_bible (const std::string& bible); -void import_resource (std::string bible, std::string resource); -void log_change (const std::string& bible, int book, int chapter, const std::string& usfm, std::string user, const std::string & summary, bool force); -void log_merge (std::string user, std::string bible, int book, int chapter, - std::string base, std::string change, std::string prioritized_change, std::string result); -void kick_unsent_data_timer (); -void kick_unreceived_data_timer (); -std::string unsent_unreceived_data_warning (); -void merge_irregularity_mail (std::vector users, - std::vector conflicts); -void unsafe_save_mail (std::string subject, const std::string & explanation, - const std::string & user, - const std::string & usfm, - int book, int chapter); -void client_receive_merge_mail (const std::string & bible, int book, int chapter, - const std::string & user, - const std::string & client_old, - const std::string & client_new, - const std::string & server); -void client_mail_pending_bible_updates (std::string user); -void client_no_write_access_mail (const std::string & bible, int book, int chapter, - const std::string & user, - const std::string & oldusfm, const std::string & newusfm); -void recent_save_email (const std::string & bible, int book, int chapter, - const std::string & user, - const std::string & old_usfm, const std::string & new_usfm); -void optional_merge_irregularity_email (const std::string & bible, int book, int chapter, - const std::string & user, - const std::string & ancestor_usfm, - const std::string & edited_usfm, - const std::string & merged_usfm); -const char * insert_operator (); -const char * delete_operator (); -const char * format_paragraph_operator (); -const char * format_character_operator (); -void condense_editor_updates (const std::vector & positions_in, - const std::vector & sizes_in, - const std::vector & additions_in, - const std::vector & content_in, - std::vector & positions_out, - std::vector & sizes_out, - std::vector & operators_out, - std::vector & content_out); -void html_to_editor_updates (const std::string & editor_html, - const std::string & server_html, - std::vector & positions, - std::vector & sizes, - std::vector & operators, - std::vector & content); -void create_empty_bible (const std::string & name); - -} diff --git a/bb/manage.cpp b/bb/manage.cpp deleted file mode 100644 index 971a8c9dd..000000000 --- a/bb/manage.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop - - -std::string bible_manage_url () -{ - return "bible/manage"; -} - - -bool bible_manage_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -std::string bible_manage (Webserver_Request& webserver_request) -{ - std::string page {}; - - Assets_Header header = Assets_Header (translate("Bibles"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - page = header.run (); - - Assets_View view {}; - - std::string success_message {}; - std::string error_message {}; - - // New Bible handler. - if (webserver_request.query.count ("new")) { - Dialog_Entry dialog_entry = Dialog_Entry ("manage", translate("Please enter a name for the new empty Bible"), "", "new", ""); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("new")) { - std::string bible = webserver_request.post ["entry"]; - // No underscrore ( _ ) in the name of a Bible because the underscores are used in the searches to separate data. - bible = filter::strings::replace ("_", "", bible); - const std::vector bibles = webserver_request.database_bibles()->get_bibles (); - if (find (bibles.begin(), bibles.end(), bible) != bibles.end()) { - error_message = translate("This Bible already exists"); - } else { - webserver_request.database_bibles()->create_bible (bible); - // Check / grant access. - if (!access_bible::write (webserver_request, bible)) { - std::string me = webserver_request.session_logic()->currentUser (); - DatabasePrivileges::set_bible (me, bible, true); - } - success_message = translate("The Bible was created"); - // Creating a Bible removes any Sample Bible that might have been there. - if (!config::logic::demo_enabled ()) { - webserver_request.database_bibles()->delete_bible (demo_sample_bible_name ()); - search_logic_delete_bible (demo_sample_bible_name ()); - } - } - } - - // Copy Bible handler. - if (webserver_request.query.count ("copy")) { - const std::string copy = webserver_request.query["copy"]; - Dialog_Entry dialog_entry = Dialog_Entry ("manage", translate("Please enter a name for where to copy the Bible to"), "", "", "A new Bible will be created with the given name, and the current Bible copied to it"); - dialog_entry.add_query ("origin", copy); - page += dialog_entry.run (); - return page; - } - if (webserver_request.query.count ("origin")) { - const std::string origin = webserver_request.query["origin"]; - if (webserver_request.post.count ("entry")) { - std::string destination = webserver_request.post["entry"]; - destination = filter::strings::replace ("_", "", destination); // No underscores in the name. - const std::vector bibles = webserver_request.database_bibles()->get_bibles (); - if (find (bibles.begin(), bibles.end(), destination) != bibles.end()) { - error_message = translate("Cannot copy the Bible because the destination Bible already exists."); - } else { - // User needs read access to the original. - if (access_bible::read (webserver_request, origin)) { - // Copy the Bible data. - const std::string origin_folder = webserver_request.database_bibles()->bible_folder (origin); - const std::string destination_folder = webserver_request.database_bibles()->bible_folder (destination); - filter_url_dir_cp (origin_folder, destination_folder); - // Copy the Bible search index. - search_logic_copy_bible (origin, destination); - // Feedback. - success_message = translate("The Bible was copied."); - // Check / grant access to destination Bible. - if (!access_bible::write (webserver_request, destination)) { - const std::string me = webserver_request.session_logic ()->currentUser (); - DatabasePrivileges::set_bible (me, destination, true); - } - // Creating a Bible removes any Sample Bible that might have been there. - if (!config::logic::demo_enabled ()) { - webserver_request.database_bibles()->delete_bible (demo_sample_bible_name ()); - search_logic_delete_bible (demo_sample_bible_name ()); - } - } - } - } - } - - // Delete Bible handler. - if (webserver_request.query.count ("delete")) { - const std::string bible = webserver_request.query ["delete"]; - const std::string confirm = webserver_request.query ["confirm"]; - if (confirm == "yes") { - // User needs write access for delete operation. - if (access_bible::write (webserver_request, bible)) { - bible_logic::delete_bible (bible); - } else { - page += assets_page::error ("Insufficient privileges to complete action"); - } - } - if (confirm.empty()) { - Dialog_Yes dialog_yes = Dialog_Yes ("manage", translate("Would you like to delete this Bible?") + " (" + bible + ")"); - dialog_yes.add_query ("delete", bible); - page += dialog_yes.run (); - return page; - } - } - - view.set_variable ("success_message", success_message); - view.set_variable ("error_message", error_message); - const std::vector bibles = access_bible::bibles (webserver_request); - pugi::xml_document document{}; - for (const auto& bible : bibles) { - pugi::xml_node li_node = document.append_child ("li"); - pugi::xml_node a_node = li_node.append_child("a"); - const std::string href = filter_url_build_http_query ("settings", "bible", filter_url_urlencode(bible)); - a_node.append_attribute("href") = href.c_str(); - a_node.text().set(bible.c_str()); - } - std::stringstream bibleblock {}; - document.print(bibleblock, "", pugi::format_raw); - view.set_variable ("bibleblock", bibleblock.str()); - - if (!client_logic_client_enabled ()) - view.enable_zone ("server"); - - page += view.render ("bb", "manage"); - - page += assets_page::footer (); - - return page; -} diff --git a/bb/manage.h b/bb/manage.h deleted file mode 100644 index 828b1147d..000000000 --- a/bb/manage.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string bible_manage_url (); -bool bible_manage_acl (Webserver_Request& webserver_request); -std::string bible_manage (Webserver_Request& webserver_request); diff --git a/bb/order.cpp b/bb/order.cpp deleted file mode 100644 index 6c7858fba..000000000 --- a/bb/order.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string bible_order_url () -{ - return "bible/order"; -} - - -bool bible_order_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -std::string bible_order (Webserver_Request& webserver_request) -{ - std::string page {}; - - Assets_Header header = Assets_Header (translate("Order"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (bible_manage_url (), menu_logic_bible_manage_text ()); - page = header.run (); - - Assets_View view {}; - - // The name of the Bible. - const std::string bible = access_bible::clamp (webserver_request, webserver_request.query ["bible"]); - view.set_variable ("bible", filter::strings::escape_special_xml_characters (bible)); - - // The order the user wants for the Bibles. - const std::string order = webserver_request.query ["order"]; - - // Deuterocanonicals or Apocrypha interspersed among the books of the Hebrew Bible. - if (order == "interspersed") { - const std::vector interspersed = { - book_id::_front_matter, - book_id::_introduction_matter, - book_id::_genesis, - book_id::_exodus, - book_id::_leviticus, - book_id::_numbers, - book_id::_deuteronomy, - book_id::_joshua, - book_id::_judges, - book_id::_ruth, - book_id::_1_samuel, - book_id::_2_samuel, - book_id::_1_kings, - book_id::_2_kings, - book_id::_1_chronicles, - book_id::_2_chronicles, - book_id::_ezra, - book_id::_nehemiah, - book_id::_tobit, - book_id::_judith, - book_id::_esther, - book_id::_1_maccabees, - book_id::_2_maccabees, - book_id::_job, - book_id::_psalms, - book_id::_proverbs, - book_id::_ecclesiastes, - book_id::_song_of_solomon, - book_id::_wisdom_of_solomon, - book_id::_sirach, - book_id::_isaiah, - book_id::_jeremiah, - book_id::_lamentations, - book_id::_baruch, - book_id::_ezekiel, - book_id::_daniel, - book_id::_hosea, - book_id::_joel, - book_id::_amos, - book_id::_obadiah, - book_id::_jonah, - book_id::_micah, - book_id::_nahum, - book_id::_habakkuk, - book_id::_zephaniah, - book_id::_haggai, - book_id::_zechariah, - book_id::_malachi, - }; - std::vector v_book_order {}; - for (const auto book : interspersed) v_book_order.push_back (filter::strings::convert_to_string (static_cast(book))); - const std::string s_book_order = filter::strings::implode (v_book_order, " "); - Database_Config_Bible::setBookOrder (bible, s_book_order); - } - - - // Deuterocanonicals or Apocrypha between the Hebrew Bible and the New Testament. - if (order == "between") { - const std::vector interspersed = { - book_id::_front_matter, - book_id::_introduction_matter, - book_id::_genesis, - book_id::_exodus, - book_id::_leviticus, - book_id::_numbers, - book_id::_deuteronomy, - book_id::_joshua, - book_id::_judges, - book_id::_ruth, - book_id::_1_samuel, - book_id::_2_samuel, - book_id::_1_kings, - book_id::_2_kings, - book_id::_1_chronicles, - book_id::_2_chronicles, - book_id::_ezra, - book_id::_nehemiah, - book_id::_esther, - book_id::_job, - book_id::_psalms, - book_id::_proverbs, - book_id::_ecclesiastes, - book_id::_song_of_solomon, - book_id::_isaiah, - book_id::_jeremiah, - book_id::_lamentations, - book_id::_ezekiel, - book_id::_daniel, - book_id::_hosea, - book_id::_joel, - book_id::_amos, - book_id::_obadiah, - book_id::_jonah, - book_id::_micah, - book_id::_nahum, - book_id::_habakkuk, - book_id::_zephaniah, - book_id::_haggai, - book_id::_zechariah, - book_id::_malachi, - book_id::_tobit, - book_id::_judith, - book_id::_1_maccabees, - book_id::_2_maccabees, - book_id::_wisdom_of_solomon, - book_id::_sirach, - book_id::_baruch, - }; - std::vector v_book_order {}; - for (const auto book : interspersed) v_book_order.push_back (filter::strings::convert_to_string (static_cast(book))); - const std::string s_book_order = filter::strings::implode (v_book_order, " "); - Database_Config_Bible::setBookOrder (bible, s_book_order); - } - - - // Deuterocanonicals or Apocrypha at the end of the entire Bible. - if (order == "end") { - Database_Config_Bible::setBookOrder (bible, std::string()); - } - - // Handle updates to the custom book order. - const std::string moveup = webserver_request.query ["moveup"]; - const std::string movedown = webserver_request.query ["movedown"]; - if (!moveup.empty () || !movedown.empty ()) { - size_t move = static_cast(filter::strings::convert_to_int (moveup + movedown)); - const std::vector books = filter_passage_get_ordered_books (bible); - std::vector s_books; - for (const auto& book : books) - s_books.push_back (filter::strings::convert_to_string (book)); - filter::strings::array_move_up_down (s_books, move, !moveup.empty ()); - const std::string s_order = filter::strings::implode (s_books, " "); - Database_Config_Bible::setBookOrder (bible, s_order); - } - - const std::vector books = filter_passage_get_ordered_books (bible); - for (size_t i = 0; i < books.size (); i++) { - std::string bookname = database::books::get_english_from_id (static_cast(books[i])); - bookname = translate (bookname); - view.add_iteration ("order", { std::pair ("offset", filter::strings::convert_to_string (i)), std::pair ("bookname", bookname) } ); - } - - view.set_variable ("uparrow", filter::strings::unicode_black_up_pointing_triangle ()); - view.set_variable ("downarrow", filter::strings::unicode_black_down_pointing_triangle ()); - - page += view.render ("bb", "order"); - - page += assets_page::footer (); - - return page; -} diff --git a/bb/order.h b/bb/order.h deleted file mode 100644 index e64a53beb..000000000 --- a/bb/order.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string bible_order_url (); -bool bible_order_acl (Webserver_Request& webserver_request); -std::string bible_order (Webserver_Request& webserver_request); diff --git a/bb/settings.cpp b/bb/settings.cpp deleted file mode 100644 index 71b5ff686..000000000 --- a/bb/settings.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop - - -std::string bible_settings_url () -{ - return "bible/settings"; -} - - -bool bible_settings_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -std::string bible_settings (Webserver_Request& webserver_request) -{ - std::string page {}; - Assets_Header header = Assets_Header (translate("Bible"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (bible_manage_url (), menu_logic_bible_manage_text ()); - page = header.run (); - Assets_View view {}; - - - std::string success_message {}; - std::string error_message {}; - - - // The Bible. - std::string bible = webserver_request.query["bible"]; - if (bible.empty()) bible = webserver_request.post ["val1"]; - bible = access_bible::clamp (webserver_request, bible); - view.set_variable ("bible", filter::strings::escape_special_xml_characters (bible)); - view.set_variable ("urlbible", filter_url_urlencode(filter::strings::escape_special_xml_characters (bible))); - - - // Whether the user has write access to this Bible. - bool write_access = access_bible::write (webserver_request, bible); - if (write_access) view.enable_zone ("write_access"); - - - // Whether the user has the privilege to change the stylesheet. - const std::string current_user = webserver_request.session_logic()->currentUser (); - bool privilege_stylesheet = access_logic::privilege_set_stylesheets (webserver_request, current_user); - if (privilege_stylesheet) view.enable_zone ("privilege_stylesheet"); - - - // The state of the checkbox. - const std::string checkbox = webserver_request.post ["checkbox"]; - bool checked = filter::strings::convert_to_bool (webserver_request.post ["checked"]); - - - // Versification. - if (webserver_request.query.count ("versification")) { - const std::string versification = webserver_request.query["versification"]; - if (versification.empty()) { - Dialog_List dialog_list = Dialog_List ("settings", translate("Would you like to change the versification system?"), translate ("A versification system determines how many chapters are in each book, and how many verses are in each chapter. Please make your choice below."), ""); - dialog_list.add_query ("bible", bible); - Database_Versifications database_versifications; - const std::vector versification_names = database_versifications.getSystems (); - for (const auto& versification_name : versification_names) { - dialog_list.add_row (versification_name, "versification", versification_name); - } - page += dialog_list.run (); - return page; - } else { - if (write_access) Database_Config_Bible::setVersificationSystem (bible, versification); - } - } - const std::string versification = Database_Config_Bible::getVersificationSystem (bible); - view.set_variable ("versification", versification); - - - // Book creation. - if (webserver_request.query.count ("createbook")) { - const std::string createbook = webserver_request.query["createbook"]; - if (createbook.empty()) { - Dialog_Books dialog_books = Dialog_Books ("settings", translate("Create book"), "", "", "createbook", {}, webserver_request.database_bibles()->get_books (bible)); - dialog_books.add_query ("bible", bible); - page += dialog_books.run (); - return page; - } else { - std::vector feedback{}; - if (write_access) - book_create (bible, static_cast(filter::strings::convert_to_int (createbook)), -1, feedback); - } - // User creates a book in this Bible: Set it as the default Bible. - webserver_request.database_config_user()->setBible (bible); - } - - - // Book deletion. - const std::string deletebook = webserver_request.query["deletebook"]; - if (!deletebook.empty()) { - const std::string confirm = webserver_request.query["confirm"]; - if (confirm == "yes") { - if (write_access) bible_logic::delete_book (bible, filter::strings::convert_to_int (deletebook)); - } - else if (confirm == "cancel") { - } - else { - Dialog_Yes dialog_yes = Dialog_Yes ("settings", translate("Would you like to delete this book?")); - dialog_yes.add_query ("bible", bible); - dialog_yes.add_query ("deletebook", deletebook); - page += dialog_yes.run (); - return page; - } - } - - - // Importing text from a resource. - if (webserver_request.query.count ("resource")) { - Dialog_List dialog_list = Dialog_List ("settings", translate("Select a resource to import into the Bible"), translate ("The resource will be imported.") + " " + translate ("It will overwrite the content of the Bible."), "", true); - dialog_list.add_query ("bible", bible); - std::vector resources = resource_external_names (); - for (const auto& resource : resources) { - dialog_list.add_row (resource, "resource", resource); - } - resources = sword_logic_get_available (); - for (const auto& resource : resources) { - const std::string source = sword_logic_get_source (resource); - const std::string module = sword_logic_get_remote_module (resource); - const std::string name = sword_logic_get_resource_name (source, module); - dialog_list.add_row (resource, "resource", name); - } - page += dialog_list.run (); - return page; - } - // The resource should be POSTed. - // This is for the demo, where a GET request would allow search crawlers to regularly import resources. - const std::string resource = webserver_request.post["add"]; - if (!resource.empty ()) { - if (write_access) { - tasks_logic_queue (IMPORTRESOURCE, { bible, resource }); - success_message = translate ("The resource will be imported into the Bible.") + " " + translate ("The journal shows the progress."); - } - } - - - const int level = webserver_request.session_logic ()->currentLevel (); - const bool manager_level = (level >= Filter_Roles::manager ()); - if (manager_level) view.enable_zone ("manager"); - - - // Available books. - pugi::xml_document book_document {}; - const std::vector book_ids = filter_passage_get_ordered_books (bible); - for (const auto book: book_ids) { - std::string book_name = database::books::get_english_from_id (static_cast(book)); - book_name = translate(book_name); - pugi::xml_node a_or_span_node; - if (manager_level) { - a_or_span_node = book_document.append_child("a"); - std::string href = filter_url_build_http_query ("book", "bible", bible); - href = filter_url_build_http_query (href, "book", filter::strings::convert_to_string (book)); - a_or_span_node.append_attribute("href") = href.c_str(); - } else { - a_or_span_node = book_document.append_child("span"); - } - a_or_span_node.text().set(book_name.c_str()); - pugi::xml_node space_node = book_document.append_child("span"); - space_node.text().set(" "); - } - std::stringstream bookblock2 {}; - book_document.print (bookblock2, "", pugi::format_raw); - view.set_variable ("bookblock", bookblock2.str()); - view.set_variable ("book_count", filter::strings::convert_to_string (static_cast(book_ids.size()))); - - - // Public feedback. - if (checkbox == "public") { - if (write_access) Database_Config_Bible::setPublicFeedbackEnabled (bible, checked); - } - view.set_variable ("public", filter::strings::get_checkbox_status (Database_Config_Bible::getPublicFeedbackEnabled (bible))); - - - - // RSS feed. -#ifdef HAVE_CLOUD - if (checkbox == "rss") { - if (write_access) { - Database_Config_Bible::setSendChangesToRSS (bible, checked); - rss_logic_feed_on_off (); - } - } - view.set_variable ("rss", filter::strings::get_checkbox_status (Database_Config_Bible::getSendChangesToRSS (bible))); -#endif - - - // Stylesheet for editing. - if (webserver_request.query.count ("stylesheetediting")) { - const std::string stylesheet = webserver_request.query["stylesheetediting"]; - if (stylesheet.empty()) { - Dialog_List dialog_list = Dialog_List ("settings", translate("Would you like to change the stylesheet for editing?"), translate ("The stylesheet affects how the Bible text in the editor looks.") + " " + translate ("Please make your choice below."), ""); - dialog_list.add_query ("bible", bible); - Database_Styles database_styles = Database_Styles(); - const std::vector sheets = database_styles.getSheets(); - for (const auto& name : sheets) { - dialog_list.add_row (name, "stylesheetediting", name); - } - page += dialog_list.run (); - return page; - } else { - if (write_access) Database_Config_Bible::setEditorStylesheet (bible, stylesheet); - } - } - std::string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - view.set_variable ("stylesheetediting", stylesheet); - - - // Stylesheet for export. - if (webserver_request.query.count ("stylesheetexport")) { - const std::string export_stylesheet = webserver_request.query["stylesheetexport"]; - if (export_stylesheet.empty()) { - Dialog_List dialog_list = Dialog_List ("settings", translate("Would you like to change the stylesheet for export?"), translate ("The stylesheet affects how the Bible text looks when exported.") + " " + translate ("Please make your choice below."), ""); - dialog_list.add_query ("bible", bible); - Database_Styles database_styles = Database_Styles(); - const std::vector sheets = database_styles.getSheets(); - for (const auto& name : sheets) { - dialog_list.add_row (name, "stylesheetexport", name); - } - page += dialog_list.run (); - return page; - } else { - if (write_access) Database_Config_Bible::setExportStylesheet (bible, export_stylesheet); - } - } - stylesheet = Database_Config_Bible::getExportStylesheet (bible); - view.set_variable ("stylesheetexport", stylesheet); - - - // Automatic daily checks on text. -#ifdef HAVE_CLOUD - if (checkbox == "checks") { - if (write_access) { - Database_Config_Bible::setDailyChecksEnabled (bible, checked); - if (!checked) { - // If checking is switched off, also remove any existing checking results for this Bible. - Database_Check database_check; - database_check.truncateOutput(bible); - } - } - } - view.set_variable ("checks", filter::strings::get_checkbox_status (Database_Config_Bible::getDailyChecksEnabled (bible))); -#endif - - - view.set_variable ("systemindex", system_index_url()); - view.set_variable ("success_message", success_message); - view.set_variable ("error_message", error_message); - - - if (client_logic_client_enabled ()) { - view.enable_zone ("client"); - view.set_variable ("cloudlink", client_logic_link_to_cloud (bible_manage_url (), translate ("More operations in the Cloud"))); - } else { - view.enable_zone ("server"); - } - - - page += view.render ("bb", "settings"); - page += assets_page::footer (); - return page; -} diff --git a/bb/settings.h b/bb/settings.h deleted file mode 100644 index 4fd30c06b..000000000 --- a/bb/settings.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string bible_settings_url (); -bool bible_settings_acl (Webserver_Request& webserver_request); -std::string bible_settings (Webserver_Request& webserver_request); diff --git a/book/create.cpp b/book/create.cpp deleted file mode 100644 index 00aa7811a..000000000 --- a/book/create.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Creates book template with ID $book in Bible $bible. -// If a $chapter is given instead of -1, it creates that chapter only. -// If the $chapter is -1, it creates all chapters within that book. -bool book_create (const string & bible, const book_id book, const int chapter, vector & feedback) -{ - Database_Bibles database_bibles {}; - Database_Versifications database_versifications {}; - - vector bibles = database_bibles.get_bibles (); - if (!in_array (bible, bibles)) { - feedback.push_back (translate("Bible bible does not exist: Cannot create book")); - return false; - } - if (book == book_id::_unknown) { - feedback.push_back (translate("Invalid book while creating a book template")); - return false; - } - - // The chapters that have been created. - vector chapters_created {}; - - // The USFM created. - string data {}; - - // Chapter 0. - if (chapter <= 0) { - data = "\\id " + database::books::get_usfm_from_id(book) + "\n"; - data += "\\h " + database::books::get_english_from_id (book) + "\n"; - data += "\\toc2 " + database::books::get_english_from_id (book) + "\n"; - bible_logic::store_chapter (bible, static_cast(book), 0, data); - chapters_created.push_back (0); - } - - - // Subsequent chapters. - string versification = Database_Config_Bible::getVersificationSystem (bible); - vector versification_data = database_versifications.getBooksChaptersVerses (versification); - for (const auto & row : versification_data) { - if (book == static_cast(row.m_book)) { - int ch = row.m_chapter; - int verse = filter::strings::convert_to_int (row.m_verse); - if ((chapter < 0) || (chapter == ch)) { - data = "\\c " + filter::strings::convert_to_string (ch) + "\n"; - data += "\\p\n"; - for (int i = 1; i <= verse; i++) { - data += "\\v " + filter::strings::convert_to_string (i) + "\n"; - } - bible_logic::store_chapter (bible, static_cast(book), ch, data); - chapters_created.push_back (ch); - } - } - } - - // Done. - if (chapters_created.size () == 0) { - feedback.push_back (translate("No chapters have been created")); - return false; - } - string created; - for (auto & chapter_created : chapters_created) { - if (!created.empty ()) created.append (" "); - created.append (filter::strings::convert_to_string (chapter_created)); - } - feedback.push_back (translate("The following chapters have been created:") + " " + created); - return true; -} diff --git a/book/create.h b/book/create.h deleted file mode 100644 index e19fe6de5..000000000 --- a/book/create.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -enum class book_id; - -bool book_create (const std::string & bible, const book_id book, const int chapter, std::vector & feedback); diff --git a/bootstrap/bootstrap.cpp b/bootstrap/bootstrap.cpp deleted file mode 100644 index a662159be..000000000 --- a/bootstrap/bootstrap.cpp +++ /dev/null @@ -1,1245 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// Check whether a request coming from the browser is considered secure enough. -// It returns true if the security is okay. -bool browser_request_security_okay (Webserver_Request& webserver_request) -{ - // If the request is made via https, the security is OK. - if (webserver_request.secure) { - return true; - } - - // At this stage the request is made via plain http. - // If https is not enforced for the browser, the security is OK. - if (!config_globals_enforce_https_browser) { - return true; - } - - // Not secure enough: - return false; -} - - -// This function is the first function to be called after a client requests a page or file. -// Based on the request from the client, -// it decides which functions to call to obtain the response. -void bootstrap_index (Webserver_Request& webserver_request) -{ - std::shared_ptr developer_logic_tracer {nullptr}; - if (config_globals_log_network) { - developer_logic_tracer = std::make_shared(webserver_request); - } - - // Record the POST request made to the web server. - // This can be used for debugging. - /* - if (!webserver_request.post.empty () && config_logic_demo_enabled ()) { - string contents; - int seconds = filter::date::seconds_since_epoch (); - string rfc822time = filter::date::rfc822 (seconds); - contents.append (rfc822time + "\n"); - contents.append (webserver_request.get + "\n"); - string query; - for (auto element : webserver_request.query) { - query.append (element.first + "=" + element.second + " and "); - } - string post; - for (auto element : webserver_request.post) { - post.append (element.first + "=" + element.second + " and "); - } - contents.append ("query: " + query + "\n"); - contents.append ("post: " + post + "\n"); - string filename; - filename = filter_url_create_root_path (filter_url_temp_dir (), "http-post-trace.txt"); - filter_url_file_put_contents_append (filename, contents); - } - */ - - const std::string extension = filter_url_get_extension (webserver_request.get); - const std::string url = webserver_request.get.substr (1); - - - // Serve graphics, stylesheets, JavaScript, fonts, and so on. - // Use direct streaming for low memory usage. - if ( (extension == "ico") - || (filter_url_is_image (extension)) - || (extension == "css") - || (extension == "js") - || (fonts::logic::is_font (extension)) - || (extension == "sh") - || (extension == "map") - || (extension == "webmanifest") - ) { - http_stream_file (webserver_request, true); - return; - } - - if ((url == resource_imagefetch_url ()) && resource_imagefetch_acl (webserver_request)) { - webserver_request.reply = resource_imagefetch (webserver_request); - return; - } - - // Serve resource downloads. - if ((extension == "sqlite") && (webserver_request.get.find (Database_Cache::fragment ()) != std::string::npos)) { - http_stream_file (webserver_request, false); - return; - } - - // Serve initialization notice. - if (config::logic::version () != Database_Config_General::getInstalledDatabaseVersion ()) { - webserver_request.reply = setup_initialization_notice (); - return; - } - - // Force setup. - if (config::logic::version () != Database_Config_General::getInstalledInterfaceVersion ()) { - webserver_request.reply = setup_index (webserver_request); - return; - } - - // Home page and menu. - if ((url == index_index_url ()) && browser_request_security_okay (webserver_request) && index_index_acl (webserver_request)) { - webserver_request.reply = index_index (webserver_request); - return; - } - - if ((url == menu_index_url ()) && browser_request_security_okay (webserver_request) && menu_index_acl (webserver_request)) { - webserver_request.reply = menu_index (webserver_request); - return; - } - - // Login and logout. - if ((url == session_login_url ()) && browser_request_security_okay (webserver_request) && session_login_acl (webserver_request)) { - webserver_request.reply = session_login (webserver_request); - return; - } - - if ((url == session_logout_url ()) && browser_request_security_okay (webserver_request) && session_logout_acl (webserver_request)) { - webserver_request.reply = session_logout (webserver_request); - return; - } - - if ((url == session_password_url ()) && browser_request_security_okay (webserver_request) && session_password_acl (webserver_request)) { - webserver_request.reply = session_password (webserver_request); - return; - } - - if ((url == session_signup_url ()) && browser_request_security_okay (webserver_request) && session_signup_acl (webserver_request)) { - webserver_request.reply = session_signup (webserver_request); - return; - } - - if ((url == session_switch_url ()) && browser_request_security_okay (webserver_request) && session_switch_acl (webserver_request)) { - webserver_request.reply = session_switch (webserver_request); - return; - } - - // Bible menu. - if ((url == bible_manage_url ()) && browser_request_security_okay (webserver_request) && bible_manage_acl (webserver_request)) { - webserver_request.reply = bible_manage (webserver_request); - return; - } - - if ((url == bible_settings_url ()) && browser_request_security_okay (webserver_request) && bible_settings_acl (webserver_request)) { - webserver_request.reply = bible_settings (webserver_request); - return; - } - - if ((url == bible_book_url ()) && browser_request_security_okay (webserver_request) && bible_book_acl (webserver_request)) { - webserver_request.reply = bible_book (webserver_request); - return; - } - - if ((url == bible_chapter_url ()) && browser_request_security_okay (webserver_request) && bible_chapter_acl (webserver_request)) { - webserver_request.reply = bible_chapter (webserver_request); - return; - } - - if ((url == bible_import_url ()) && browser_request_security_okay (webserver_request) && bible_import_acl (webserver_request)) { - webserver_request.reply = bible_import (webserver_request); - return; - } - - if ((url == compare_index_url ()) && browser_request_security_okay (webserver_request) && compare_index_acl (webserver_request)) { - webserver_request.reply = compare_index (webserver_request); - return; - } - - if ((url == bible_order_url ()) && browser_request_security_okay (webserver_request) && bible_order_acl (webserver_request)) { - webserver_request.reply = bible_order (webserver_request); - return; - } - - if ((url == bible_css_url ()) && browser_request_security_okay (webserver_request) && bible_css_acl (webserver_request)) { - webserver_request.reply = bible_css (webserver_request); - return; - } - - if ((url == editone_index_url ()) && browser_request_security_okay (webserver_request) && editone_index_acl ()) { - webserver_request.reply = editone_index (webserver_request); - return; - } - - if ((url == editusfm_index_url ()) && browser_request_security_okay (webserver_request) && editusfm_index_acl (webserver_request)) { - webserver_request.reply = editusfm_index (webserver_request); - return; - } - - if ((url == edit_index_url ()) && browser_request_security_okay (webserver_request) && edit_index_acl (webserver_request)) { - webserver_request.reply = edit_index (webserver_request); - return; - } - - if ((url == edit_position_url ()) && browser_request_security_okay (webserver_request) && edit_position_acl (webserver_request)) { - webserver_request.reply = edit_position (webserver_request); - return; - } - - if ((url == edit_navigate_url ()) && browser_request_security_okay (webserver_request) && edit_navigate_acl (webserver_request)) { - webserver_request.reply = edit_navigate (webserver_request); - return; - } - - if ((url == search_index_url ()) && browser_request_security_okay (webserver_request) && search_index_acl (webserver_request)) { - webserver_request.reply = search_index (webserver_request); - return; - } - - if ((url == workspace_index_url ()) && browser_request_security_okay (webserver_request) && workspace_index_acl (webserver_request)) { - webserver_request.reply = workspace_index (webserver_request); - return; - } - - if ((url == workspace_organize_url ()) && browser_request_security_okay (webserver_request) && workspace_organize_acl (webserver_request)) { - webserver_request.reply = workspace_organize (webserver_request); - return; - } - - if ((url == resource_bible2resource_url ()) && browser_request_security_okay (webserver_request) && resource_bible2resource_acl (webserver_request)) { - webserver_request.reply = resource_bible2resource (webserver_request); - return; - } - - if ((url == checks_index_url ()) && browser_request_security_okay (webserver_request) && checks_index_acl (webserver_request)) { - webserver_request.reply = checks_index (webserver_request); - return; - } - - if ((url == checks_settings_url ()) && browser_request_security_okay (webserver_request) && checks_settings_acl (webserver_request)) { - webserver_request.reply = checks_settings (webserver_request); - return; - } - - if ((url == consistency_index_url ()) && browser_request_security_okay (webserver_request) && consistency_index_acl (webserver_request)) { - webserver_request.reply = consistency_index (webserver_request); - return; - } - - // Notes menu. - if ((url == notes_index_url ()) && browser_request_security_okay (webserver_request) && notes_index_acl (webserver_request)) { - webserver_request.reply = notes_index (webserver_request); - return; - } - - if ((url == notes_create_url ()) && browser_request_security_okay (webserver_request) && notes_create_acl (webserver_request)) { - webserver_request.reply = notes_create (webserver_request); - return; - } - - if ((url == notes_select_url ()) && browser_request_security_okay (webserver_request) && notes_select_acl (webserver_request)) { - webserver_request.reply = notes_select (webserver_request); - return; - } - - if ((url == notes_note_url ()) && browser_request_security_okay (webserver_request) && notes_note_acl (webserver_request)) { - webserver_request.reply = notes_note (webserver_request); - return; - } - - if ((url == notes_comment_url ()) && browser_request_security_okay (webserver_request) && notes_comment_acl (webserver_request)) { - webserver_request.reply = notes_comment (webserver_request); - return; - } - - if ((url == notes_actions_url ()) && browser_request_security_okay (webserver_request) && notes_actions_acl (webserver_request)) { - webserver_request.reply = notes_actions (webserver_request); - return; - } - - if ((url == notes_assign_1_url ()) && browser_request_security_okay (webserver_request) && notes_assign_1_acl (webserver_request)) { - webserver_request.reply = notes_assign_1 (webserver_request); - return; - } - - if ((url == notes_assign_n_url ()) && browser_request_security_okay (webserver_request) && notes_assign_n_acl (webserver_request)) { - webserver_request.reply = notes_assign_n (webserver_request); - return; - } - - if ((url == notes_unassign_n_url ()) && browser_request_security_okay (webserver_request) && notes_unassign_n_acl (webserver_request)) { - webserver_request.reply = notes_unassign_n (webserver_request); - return; - } - - if ((url == notes_status_1_url ()) && browser_request_security_okay (webserver_request) && notes_status_1_acl (webserver_request)) { - webserver_request.reply = notes_status_1 (webserver_request); - return; - } - - if ((url == notes_status_n_url ()) && browser_request_security_okay (webserver_request) && notes_status_n_acl (webserver_request)) { - webserver_request.reply = notes_status_n (webserver_request); - return; - } - - if ((url == notes_verses_url ()) && browser_request_security_okay (webserver_request) && notes_verses_acl (webserver_request)) { - webserver_request.reply = notes_verses (webserver_request); - return; - } - - if ((url == notes_severity_1_url ()) && browser_request_security_okay (webserver_request) && notes_severity_1_acl (webserver_request)) { - webserver_request.reply = notes_severity_1 (webserver_request); - return; - } - - if ((url == notes_severity_n_url ()) && browser_request_security_okay (webserver_request) && notes_severity_n_acl (webserver_request)) { - webserver_request.reply = notes_severity_n (webserver_request); - return; - } - - if ((url == notes_bible_1_url ()) && browser_request_security_okay (webserver_request) && notes_bible_1_acl (webserver_request)) { - webserver_request.reply = notes_bible_1 (webserver_request); - return; - } - - if ((url == notes_bible_n_url ()) && browser_request_security_okay (webserver_request) && notes_bible_n_acl (webserver_request)) { - webserver_request.reply = notes_bible_n (webserver_request); - return; - } - - if ((url == notes_bulk_url ()) && browser_request_security_okay (webserver_request) && notes_bulk_acl (webserver_request)) { - webserver_request.reply = notes_bulk (webserver_request); - return; - } - - if ((url == notes_edit_url ()) && browser_request_security_okay (webserver_request) && notes_edit_acl (webserver_request)) { - webserver_request.reply = notes_edit (webserver_request); - return; - } - - if ((url == notes_summary_url ()) && browser_request_security_okay (webserver_request) && notes_summary_acl (webserver_request)) { - webserver_request.reply = notes_summary (webserver_request); - return; - } - - // Resources menu. - if ((url == resource_index_url ()) && browser_request_security_okay (webserver_request) && resource_index_acl (webserver_request)) { - webserver_request.reply = resource_index (webserver_request); - return; - } - - if ((url == resource_organize_url ()) && browser_request_security_okay (webserver_request) && resource_organize_acl (webserver_request)) { - webserver_request.reply = resource_organize (webserver_request); - return; - } - - if ((url == resource_print_url ()) && browser_request_security_okay (webserver_request) && resource_print_acl (webserver_request)) { - webserver_request.reply = resource_print (webserver_request); - return; - } - - if ((url == resource_manage_url ()) && browser_request_security_okay (webserver_request) && resource_manage_acl (webserver_request)) { - webserver_request.reply = resource_manage (webserver_request); - return; - } - - if ((url == resource_download_url ()) && browser_request_security_okay (webserver_request) && resource_download_acl (webserver_request)) { - webserver_request.reply = resource_download (webserver_request); - return; - } - - if ((url == resource_images_url ()) && browser_request_security_okay (webserver_request) && resource_images_acl (webserver_request)) { - webserver_request.reply = resource_images (webserver_request); - return; - } - - if ((url == resource_sword_url ()) && browser_request_security_okay (webserver_request) && resource_sword_acl (webserver_request)) { - webserver_request.reply = resource_sword (webserver_request); - return; - } - - if ((url == resource_select_url ()) && browser_request_security_okay (webserver_request) && resource_select_acl (webserver_request)) { - webserver_request.reply = resource_select (webserver_request); - return; - } - - if ((url == resource_cache_url ()) && browser_request_security_okay (webserver_request) && resource_cache_acl (webserver_request)) { - webserver_request.reply = resource_cache (webserver_request); - return; - } - - if ((url == resource_user9edit_url ()) && browser_request_security_okay (webserver_request) && resource_user9edit_acl (webserver_request)) { - webserver_request.reply = resource_user9edit (webserver_request); - return; - } - - if ((url == resource_user1edit_url ()) && browser_request_security_okay (webserver_request) && resource_user1edit_acl (webserver_request)) { - webserver_request.reply = resource_user1edit (webserver_request); - return; - } - - if ((url == resource_user9view_url ()) && browser_request_security_okay (webserver_request) && resource_user9view_acl (webserver_request)) { - webserver_request.reply = resource_user9view (webserver_request); - return; - } - - if ((url == resource_user1view_url ()) && browser_request_security_okay (webserver_request) && resource_user1view_acl (webserver_request)) { - webserver_request.reply = resource_user1view (webserver_request); - return; - } - - if ((url == resource_biblegateway_url ()) && browser_request_security_okay (webserver_request) && resource_biblegateway_acl (webserver_request)) { - webserver_request.reply = resource_biblegateway (webserver_request); - return; - } - - if ((url == resource_studylight_url ()) && browser_request_security_okay (webserver_request) && resource_studylight_acl (webserver_request)) { - webserver_request.reply = resource_studylight (webserver_request); - return; - } - - if ((url == journal_index_url ()) && browser_request_security_okay (webserver_request) && journal_index_acl (webserver_request)) { - webserver_request.reply = journal_index (webserver_request); - return; - } - - if ((url == changes_changes_url ()) && browser_request_security_okay (webserver_request) && changes_changes_acl (webserver_request)) { - webserver_request.reply = changes_changes (webserver_request); - return; - } - - if ((url == changes_change_url ()) && browser_request_security_okay (webserver_request) && changes_change_acl (webserver_request)) { - webserver_request.reply = changes_change (webserver_request); - return; - } - - if ((url == changes_manage_url ()) && browser_request_security_okay (webserver_request) && changes_manage_acl (webserver_request)) { - webserver_request.reply = changes_manage (webserver_request); - return; - } - - if ((url == changes_statistics_url ()) && browser_request_security_okay (webserver_request) && changes_statistics_acl (webserver_request)) { - webserver_request.reply = changes_statistics (webserver_request); - return; - } - - // Planning menu. - if ((url == sprint_index_url ()) && browser_request_security_okay (webserver_request) && sprint_index_acl (webserver_request)) { - webserver_request.reply = sprint_index (webserver_request); - return; - } - - // Tools menu. - if ((url == sendreceive_index_url ()) && browser_request_security_okay (webserver_request) && sendreceive_index_acl (webserver_request)) { - webserver_request.reply = sendreceive_index (webserver_request); - return; - } - - if ((url == manage_exports_url ()) && browser_request_security_okay (webserver_request) && manage_exports_acl (webserver_request)) { - webserver_request.reply = manage_exports (webserver_request); - return; - } - - if ((url == manage_hyphenation_url ()) && browser_request_security_okay (webserver_request) && manage_hyphenation_acl (webserver_request)) { - webserver_request.reply = manage_hyphenation (webserver_request); - return; - } - - if ((url == developer_index_url ()) && browser_request_security_okay (webserver_request) && developer_index_acl (webserver_request)) { - webserver_request.reply = developer_index (webserver_request); - return; - } - - if ((url == personalize_index_url ()) && browser_request_security_okay (webserver_request) && personalize_index_acl (webserver_request)) { - webserver_request.reply = personalize_index (webserver_request); - return; - } - - if ((url == manage_users_url ()) && browser_request_security_okay (webserver_request) && manage_users_acl (webserver_request)) { - webserver_request.reply = manage_users (webserver_request); - return; - } - - if ((url == manage_accounts_url ()) && browser_request_security_okay (webserver_request) && manage_accounts_acl (webserver_request)) { - webserver_request.reply = manage_accounts (webserver_request); - return; - } - - if ((url == manage_index_url ()) && browser_request_security_okay (webserver_request) && manage_index_acl (webserver_request)) { - webserver_request.reply = manage_index (webserver_request); - return; - } - - if ((url == system_index_url ()) && browser_request_security_okay (webserver_request) && system_index_acl (webserver_request)) { - webserver_request.reply = system_index (webserver_request); - return; - } - - if ((url == system_googletranslate_url ()) && browser_request_security_okay (webserver_request) && system_googletranslate_acl (webserver_request)) { - webserver_request.reply = system_googletranslate (webserver_request); - return; - } - - if ((url == email_index_url ()) && browser_request_security_okay (webserver_request) && email_index_acl (webserver_request)) { - webserver_request.reply = email_index (webserver_request); - return; - } - - if ((url == styles_indexm_url ()) && browser_request_security_okay (webserver_request) && styles_indexm_acl (webserver_request)) { - webserver_request.reply = styles_indexm (webserver_request); - return; - } - - if ((url == styles_sheetm_url ()) && browser_request_security_okay (webserver_request) && styles_sheetm_acl (webserver_request)) { - webserver_request.reply = styles_sheetm (webserver_request); - return; - } - - if ((url == styles_view_url ()) && browser_request_security_okay (webserver_request) && styles_view_acl (webserver_request)) { - webserver_request.reply = styles_view (webserver_request); - return; - } - - if ((url == versification_index_url ()) && browser_request_security_okay (webserver_request) && versification_index_acl (webserver_request)) { - webserver_request.reply = versification_index (webserver_request); - return; - } - - if ((url == versification_system_url ()) && browser_request_security_okay (webserver_request) && versification_system_acl (webserver_request)) { - webserver_request.reply = versification_system (webserver_request); - return; - } - - if ((url == collaboration_index_url ()) && browser_request_security_okay (webserver_request) && collaboration_index_acl (webserver_request)) { - webserver_request.reply = collaboration_index (webserver_request); - return; - } - - if ((url == client_index_url ()) && browser_request_security_okay (webserver_request) && client_index_acl (webserver_request)) { - webserver_request.reply = client_index (webserver_request); - return; - } - - if ((url == mapping_index_url ()) && browser_request_security_okay (webserver_request) && mapping_index_acl (webserver_request)) { - webserver_request.reply = mapping_index (webserver_request); - return; - } - - if ((url == mapping_map_url ()) && browser_request_security_okay (webserver_request) && mapping_map_acl (webserver_request)) { - webserver_request.reply = mapping_map (webserver_request); - return; - } - - if ((url == paratext_index_url ()) && browser_request_security_okay (webserver_request) && paratext_index_acl (webserver_request)) { - webserver_request.reply = paratext_index (webserver_request); - return; - } - - // Help menu. - if ((help_index_url (url)) && browser_request_security_okay (webserver_request) && help_index_acl (webserver_request)) { - webserver_request.reply = help_index (webserver_request, url); - return; - } - - // User menu. - if ((url == user_notifications_url ()) && browser_request_security_okay (webserver_request) && user_notifications_acl (webserver_request)) { - webserver_request.reply = user_notifications (webserver_request); - return; - } - - if ((url == user_account_url ()) && browser_request_security_okay (webserver_request) && user_account_acl (webserver_request)) { - webserver_request.reply = user_account (webserver_request); - return; - } - - // Public feedback menu. - if ((url == public_index_url ()) && browser_request_security_okay (webserver_request) && public_index_acl (webserver_request)) { - webserver_request.reply = public_index (webserver_request); - return; - } - - if ((url == public_login_url ()) && browser_request_security_okay (webserver_request) && public_login_acl (webserver_request)) { - webserver_request.reply = public_login (webserver_request); - return; - } - - if ((url == public_chapter_url ()) && browser_request_security_okay (webserver_request) && public_chapter_acl (webserver_request)) { - webserver_request.reply = public_chapter (webserver_request); - return; - } - - if ((url == public_notes_url ()) && browser_request_security_okay (webserver_request) && public_notes_acl (webserver_request)) { - webserver_request.reply = public_notes (webserver_request); - return; - } - - if ((url == public_new_url ()) && browser_request_security_okay (webserver_request) && public_new_acl (webserver_request)) { - webserver_request.reply = public_new (webserver_request); - return; - } - - if ((url == public_create_url ()) && browser_request_security_okay (webserver_request) && public_create_acl (webserver_request)) { - webserver_request.reply = public_create (webserver_request); - return; - } - - if ((url == public_note_url ()) && browser_request_security_okay (webserver_request) && public_note_acl (webserver_request)) { - webserver_request.reply = public_note (webserver_request); - return; - } - - if ((url == public_comment_url ()) && browser_request_security_okay (webserver_request) && public_comment_acl (webserver_request)) { - webserver_request.reply = public_comment (webserver_request); - return; - } - - if ((url == jobs_index_url ()) && browser_request_security_okay (webserver_request) && jobs_index_acl (webserver_request)) { - webserver_request.reply = jobs_index (webserver_request); - return; - } - - if ((url == search_all_url ()) && browser_request_security_okay (webserver_request) && search_all_acl (webserver_request)) { - webserver_request.reply = search_all (webserver_request); - return; - } - - if ((url == search_replace_url ()) && browser_request_security_okay (webserver_request) && search_replace_acl (webserver_request)) { - webserver_request.reply = search_replace (webserver_request); - return; - } - - if ((url == search_search2_url ()) && browser_request_security_okay (webserver_request) && search_search2_acl (webserver_request)) { - webserver_request.reply = search_search2 (webserver_request); - return; - } - - if ((url == search_replace2_url ()) && browser_request_security_okay (webserver_request) && search_replace2_acl (webserver_request)) { - webserver_request.reply = search_replace2 (webserver_request); - return; - } - - if ((url == search_similar_url ()) && browser_request_security_okay (webserver_request) && search_similar_acl (webserver_request)) { - webserver_request.reply = search_similar (webserver_request); - return; - } - - if ((url == search_strongs_url ()) && browser_request_security_okay (webserver_request) && search_strongs_acl (webserver_request)) { - webserver_request.reply = search_strongs (webserver_request); - return; - } - - if ((url == search_strong_url ()) && browser_request_security_okay (webserver_request) && search_strong_acl (webserver_request)) { - webserver_request.reply = search_strong (webserver_request); - return; - } - - if ((url == search_originals_url ()) && browser_request_security_okay (webserver_request) && search_originals_acl (webserver_request)) { - webserver_request.reply = search_originals (webserver_request); - return; - } - - if ((url == workspace_settings_url ()) && browser_request_security_okay (webserver_request) && workspace_settings_acl (webserver_request)) { - webserver_request.reply = workspace_settings (webserver_request); - return; - } - - if ((url == collaboration_settings_url ()) && browser_request_security_okay (webserver_request) && collaboration_settings_acl (webserver_request)) { - webserver_request.reply = collaboration_settings (webserver_request); - return; - } - - if ((url == checks_settingspatterns_url ()) && browser_request_security_okay (webserver_request) && checks_settingspatterns_acl (webserver_request)) { - webserver_request.reply = checks_settingspatterns (webserver_request); - return; - } - - if ((url == checks_settingssentences_url ()) && browser_request_security_okay (webserver_request) && checks_settingssentences_acl (webserver_request)) { - webserver_request.reply = checks_settingssentences (webserver_request); - return; - } - - if ((url == checks_settingspairs_url ()) && browser_request_security_okay (webserver_request) && checks_settingspairs_acl (webserver_request)) { - webserver_request.reply = checks_settingspairs (webserver_request); - return; - } - - if ((url == checks_suppress_url ()) && browser_request_security_okay (webserver_request) && checks_suppress_acl (webserver_request)) { - webserver_request.reply = checks_suppress (webserver_request); - return; - } - - if ((url == webbible_search_url ()) && browser_request_security_okay (webserver_request) && webbible_search_acl (webserver_request)) { - webserver_request.reply = webbible_search (webserver_request); - return; - } - - if ((url == manage_write_url ()) && browser_request_security_okay (webserver_request) && manage_write_acl (webserver_request)) { - webserver_request.reply = manage_write (webserver_request); - return; - } - - if ((url == manage_privileges_url ()) && browser_request_security_okay (webserver_request) && manage_privileges_acl (webserver_request)) { - webserver_request.reply = manage_privileges (webserver_request); - return; - } - - if ((url == resource_image_url ()) && browser_request_security_okay (webserver_request) && resource_image_acl (webserver_request)) { - webserver_request.reply = resource_image (webserver_request); - return; - } - - if ((url == resource_img_url ()) && browser_request_security_okay (webserver_request) && resource_img_acl (webserver_request)) { - webserver_request.reply = resource_img (webserver_request); - return; - } - - if ((url == editor_select_url ()) && browser_request_security_okay (webserver_request) && editor_select_acl (webserver_request)) { - webserver_request.reply = editor_select (webserver_request); - return; - } - - // Downloads - if ((url == index_listing_url (url)) && browser_request_security_okay (webserver_request) && index_listing_acl (webserver_request, url)) { - webserver_request.reply = index_listing (webserver_request, url); - return; - } - -#ifdef HAVE_CLIENT - if (extension == "tar") { - http_stream_file (webserver_request, false); - return; - } -#endif - - if (url == sync_setup_url ()) { - webserver_request.reply = sync_setup (webserver_request); - return; - } - if (url == sync_settings_url ()) { - webserver_request.reply = sync_settings (webserver_request); - return; - } - if (url == sync_bibles_url ()) { - webserver_request.reply = sync_bibles (webserver_request); - return; - } - if (url == sync_notes_url ()) { - webserver_request.reply = sync_notes (webserver_request); - return; - } - if (extension == "sqlite") { - if (filter_url_dirname (url) == filter_url_temp_dir ()) { - http_stream_file (webserver_request, false); - return; - } - } - if (url == sync_usfmresources_url ()) { - webserver_request.reply = sync_usfmresources (webserver_request); - return; - } - if (url == sync_changes_url ()) { - webserver_request.reply = sync_changes (webserver_request); - return; - } - if (url == sync_files_url ()) { - webserver_request.reply = sync_files (webserver_request); - return; - } - if (url == sync_resources_url ()) { - webserver_request.reply = sync_resources (webserver_request); - return; - } - if (url == sync_mail_url ()) { - webserver_request.reply = sync_mail (webserver_request); - return; - } - - if ((url == navigation_update_url ()) && browser_request_security_okay (webserver_request) && navigation_update_acl (webserver_request)) { - webserver_request.reply = navigation_update (webserver_request); - return; - } - - if ((url == navigation_poll_url ()) && browser_request_security_okay (webserver_request) && navigation_poll_acl (webserver_request)) { - webserver_request.reply = navigation_poll (webserver_request); - return; - } - -#ifdef HAVE_WINDOWS - if (url == navigation_paratext_url ()) { - webserver_request.reply = navigation_paratext (webserver_request); - return; - } -#endif - - if ((url == edit_preview_url ()) && browser_request_security_okay (webserver_request) && edit_preview_acl (webserver_request)) { - webserver_request.reply = edit_preview (webserver_request); - return; - } - - if ((url == editusfm_focus_url ()) && browser_request_security_okay (webserver_request) && editusfm_focus_acl (webserver_request)) { - webserver_request.reply = editusfm_focus (webserver_request); - return; - } - - if ((url == editusfm_load_url ()) && browser_request_security_okay (webserver_request) && editusfm_load_acl (webserver_request)) { - webserver_request.reply = editusfm_load (webserver_request); - return; - } - - if ((url == editusfm_offset_url ()) && browser_request_security_okay (webserver_request) && editusfm_offset_acl (webserver_request)) { - webserver_request.reply = editusfm_offset (webserver_request); - return; - } - - if ((url == editusfm_save_url ()) && browser_request_security_okay (webserver_request) && editusfm_save_acl (webserver_request)) { - webserver_request.reply = editusfm_save (webserver_request); - return; - } - - if ((url == edit_edit_url ()) && browser_request_security_okay (webserver_request) && edit_edit_acl (webserver_request)) { - webserver_request.reply = edit_edit (webserver_request); - return; - } - - if ((url == edit_id_url ()) && browser_request_security_okay (webserver_request) && edit_id_acl (webserver_request)) { - webserver_request.reply = edit_id (webserver_request); - return; - } - - if ((url == edit_load_url ()) && browser_request_security_okay (webserver_request) && edit_load_acl (webserver_request)) { - webserver_request.reply = edit_load (webserver_request); - return; - } - - if ((url == edit_save_url ()) && browser_request_security_okay (webserver_request) && edit_save_acl (webserver_request)) { - webserver_request.reply = edit_save (webserver_request); - return; - } - - if ((url == edit_styles_url ()) && browser_request_security_okay (webserver_request) && edit_styles_acl (webserver_request)) { - webserver_request.reply = edit_styles (webserver_request); - return; - } - - if ((url == search_getids_url ()) && browser_request_security_okay (webserver_request) && search_getids_acl (webserver_request)) { - webserver_request.reply = search_getids (webserver_request); - return; - } - - if ((url == search_replacepre_url ()) && browser_request_security_okay (webserver_request) && search_replacepre_acl (webserver_request)) { - webserver_request.reply = search_replacepre (webserver_request); - return; - } - - if ((url == search_replacego_url ()) && browser_request_security_okay (webserver_request) && search_replacego_acl (webserver_request)) { - webserver_request.reply = search_replacego (webserver_request); - return; - } - - if ((url == search_replacepre2_url ()) && browser_request_security_okay (webserver_request) && search_replacepre2_acl (webserver_request)) { - webserver_request.reply = search_replacepre2 (webserver_request); - return; - } - - if ((url == search_getids2_url ()) && browser_request_security_okay (webserver_request) && search_getids2_acl (webserver_request)) { - webserver_request.reply = search_getids2 (webserver_request); - return; - } - - if ((url == search_replacego2_url ()) && browser_request_security_okay (webserver_request) && search_replacego2_acl (webserver_request)) { - webserver_request.reply = search_replacego2 (webserver_request); - return; - } - - if ((url == resource_get_url ()) && browser_request_security_okay (webserver_request) && resource_get_acl (webserver_request)) { - webserver_request.reply = resource_get (webserver_request); - return; - } - - if ((url == resource_unload_url ()) && browser_request_security_okay (webserver_request) && resource_unload_acl (webserver_request)) { - webserver_request.reply = resource_unload (webserver_request); - return; - } - - if ((url == notes_poll_url ()) && browser_request_security_okay (webserver_request) && notes_poll_acl (webserver_request)) { - webserver_request.reply = notes_poll (webserver_request); - return; - } - - if ((url == notes_notes_url ()) && browser_request_security_okay (webserver_request) && notes_notes_acl (webserver_request)) { - webserver_request.reply = notes_notes (webserver_request); - return; - } - - if ((url == notes_click_url ()) && browser_request_security_okay (webserver_request) && notes_click_acl (webserver_request)) { - webserver_request.reply = notes_click (webserver_request); - return; - } - - if ((url == consistency_poll_url ()) && browser_request_security_okay (webserver_request) && consistency_poll_acl (webserver_request)) { - webserver_request.reply = consistency_poll (webserver_request); - return; - } - - if ((url == consistency_input_url ()) && browser_request_security_okay (webserver_request) && consistency_input_acl (webserver_request)) { - webserver_request.reply = consistency_input (webserver_request); - return; - } - - if ((url == lexicon_definition_url ()) && browser_request_security_okay (webserver_request) && lexicon_definition_acl (webserver_request)) { - webserver_request.reply = lexicon_definition (webserver_request); - return; - } - -#ifdef HAVE_CLIENT - // For security reasons, this is only available in a client configuration. - if (url == assets_external_url ()) { - webserver_request.reply = assets_external (webserver_request); - return; - } -#endif - - if ((url == rss_feed_url ()) && browser_request_security_okay (webserver_request) && rss_feed_acl (webserver_request)) { - webserver_request.reply = rss_feed (webserver_request); - return; - } - - if ((url == nmt_index_url ()) && browser_request_security_okay (webserver_request) && nmt_index_acl (webserver_request)) { - webserver_request.reply = nmt_index (webserver_request); - return; - } - - if ((url == edit_update_url ()) && browser_request_security_okay (webserver_request) && edit_update_acl (webserver_request)) { - webserver_request.reply = edit_update (webserver_request); - return; - } - - if ((url == editor_id_url ()) && browser_request_security_okay (webserver_request) && editor_id_acl (webserver_request)) { - webserver_request.reply = editor_id (webserver_request); - return; - } - - if ((url == editor_style_url ()) && browser_request_security_okay (webserver_request) && editor_style_acl (webserver_request)) { - webserver_request.reply = editor_style (webserver_request); - return; - } - - if ((url == editone2_index_url ()) && browser_request_security_okay (webserver_request) && editone2_index_acl (webserver_request)) { - webserver_request.reply = editone2_index (webserver_request); - return; - } - - if ((url == editone2_load_url ()) && browser_request_security_okay (webserver_request) && editone2_load_acl (webserver_request)) { - webserver_request.reply = editone2_load (webserver_request); - return; - } - - if ((url == editone2_save_url ()) && browser_request_security_okay (webserver_request) && editone2_save_acl (webserver_request)) { - webserver_request.reply = editone2_save (webserver_request); - return; - } - - if ((url == editone2_verse_url ()) && browser_request_security_okay (webserver_request) && editone2_verse_acl (webserver_request)) { - webserver_request.reply = editone2_verse (webserver_request); - return; - } - - if ((url == editone2_update_url ()) && browser_request_security_okay (webserver_request) && editone2_update_acl (webserver_request)) { - webserver_request.reply = editone2_update (webserver_request); - return; - } - - if ((url == read_index_url ()) && browser_request_security_okay (webserver_request) && read_index_acl (webserver_request)) { - webserver_request.reply = read_index (webserver_request); - return; - } - - if ((url == read_load_url ()) && browser_request_security_okay (webserver_request) && read_load_acl (webserver_request)) { - webserver_request.reply = read_load (webserver_request); - return; - } - - if ((url == read_verse_url ()) && browser_request_security_okay (webserver_request) && read_verse_acl (webserver_request)) { - webserver_request.reply = read_verse (webserver_request); - return; - } - - if ((url == resource_divider_url ()) && browser_request_security_okay (webserver_request) && resource_divider_acl (webserver_request)) { - webserver_request.reply = resource_divider (webserver_request); - return; - } - - if ((url == session_confirm_url ()) && browser_request_security_okay (webserver_request) && session_confirm_acl (webserver_request)) { - webserver_request.reply = session_confirm (webserver_request); - return; - } - - if ((url == resource_comparative9edit_url ()) && browser_request_security_okay (webserver_request) && resource_comparative9edit_acl (webserver_request)) { - webserver_request.reply = resource_comparative9edit (webserver_request); - return; - } - - if ((url == resource_comparative1edit_url ()) && browser_request_security_okay (webserver_request) && resource_comparative1edit_acl (webserver_request)) { - webserver_request.reply = resource_comparative1edit (webserver_request); - return; - } - - if ((url == resource_translated9edit_url ()) && browser_request_security_okay (webserver_request) && resource_translated9edit_acl (webserver_request)) { - webserver_request.reply = resource_translated9edit (webserver_request); - return; - } - - if ((url == resource_translated1edit_url ()) && browser_request_security_okay (webserver_request) && resource_translated1edit_acl (webserver_request)) { - webserver_request.reply = resource_translated1edit (webserver_request); - return; - } - - if ((url == developer_delay_url ()) && developer_delay_acl (webserver_request)) { - webserver_request.reply = developer_delay (webserver_request); - return; - } - - if ((url == images_index_url ()) && browser_request_security_okay (webserver_request) && images_index_acl (webserver_request)) { - webserver_request.reply = images_index (webserver_request); - return; - } - - if ((url == images_view_url ()) && browser_request_security_okay (webserver_request) && images_view_acl (webserver_request)) { - webserver_request.reply = images_view (webserver_request); - return; - } - - if ((url == images_fetch_url ()) && browser_request_security_okay (webserver_request) && images_fetch_acl (webserver_request)) { - webserver_request.reply = images_fetch (webserver_request); - return; - } - - // Forward the browser to the default home page. - redirect_browser (webserver_request, index_index_url ()); -} diff --git a/bootstrap/bootstrap.h b/bootstrap/bootstrap.h deleted file mode 100644 index 1ba8c40fa..000000000 --- a/bootstrap/bootstrap.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -void bootstrap_index (Webserver_Request& webserver_request); diff --git a/build/config.h b/build/config.h deleted file mode 100644 index cbfa3fd04..000000000 --- a/build/config.h +++ /dev/null @@ -1,112 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define whether to compile for Android */ -/* #undef HAVE_ANDROID */ - -/* define if the compiler supports basic C++17 syntax */ -#define HAVE_CXX17 1 - -/* Define whether execinfo.h is present */ -#define HAVE_EXECINFO 1 - -/* Define whether ICU is available */ -#define HAVE_ICU 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define whether to compile for iOS */ -/* #undef HAVE_IOS */ - -/* Define to 1 if you have the `mbedtls' library (-lmbedtls). */ -/* #undef HAVE_LIBMBEDTLS */ - -/* Define whether libproc.h is present */ -#define HAVE_LIBPROC 1 - -/* Define whether to compile for Linux */ -/* #undef HAVE_LINUX */ - -/* Define whether to compile for Mac */ -/* #undef HAVE_MAC */ - -/* Define whether mach/mach.h is present */ -#define HAVE_MACH_MACH 1 - -/* Define whether pthread.h is present */ -#define HAVE_PTHREAD 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define whether function 'stoi' is available */ -#define HAVE_STOI 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define whether sys/sysctl.h is present */ -#define HAVE_SYS_SYSCTL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define whether utf8proc is available */ -#define HAVE_UTF8PROC 1 - -/* Define whether to compile on Windows */ -/* #undef HAVE_WINDOWS */ - -/* Name of package */ -#define PACKAGE "bibledit" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "http://bibledit.org" - -/* Package data directory */ -#define PACKAGE_DATA_DIR "/usr/share/bibledit" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "bibledit" - -/* Package prefix directory */ -#define PACKAGE_PREFIX_DIR "NONE" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "bibledit 5.0.990" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "bibledit" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "5.0.990" - -/* Define to 1 if all of the C90 standard headers exist (not just the ones - required in a freestanding environment). This macro is provided for - backward compatibility; new code need not use it. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "5.0.990" - -/* Define whether to compile on Windows */ -/* #undef WIN32 */ diff --git a/changes/change.cpp b/changes/change.cpp deleted file mode 100644 index 3efdf0cf8..000000000 --- a/changes/change.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -using namespace std; - - -string changes_change_url () -{ - return "changes/change"; -} - - -bool changes_change_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ()); -} - - -string changes_change (Webserver_Request& webserver_request) -{ - Database_Modifications database_modifications {}; - Database_Notes database_notes (webserver_request); - Notes_Logic notes_logic (webserver_request); - - - // Note unsubscribe handler. - if (webserver_request.post.count ("unsubscribe")) { - string unsubscribe = webserver_request.post["unsubscribe"]; - unsubscribe.erase (0, 11); - notes_logic.unsubscribe (filter::strings::convert_to_int (unsubscribe)); - return string(); - } - - - // Note unassign handler. - if (webserver_request.post.count ("unassign")) { - string unassign = webserver_request.post["unassign"]; - unassign.erase (0, 8); - notes_logic.unassignUser (filter::strings::convert_to_int (unassign), webserver_request.session_logic()->currentUser ()); - return string(); - } - - - // Note mark for deletion handler. - if (webserver_request.post.count("delete")) { - string erase = webserver_request.post["delete"]; - erase.erase (0, 6); - const int identifier {filter::strings::convert_to_int (erase)}; - notes_logic.markForDeletion (identifier); - return string(); - } - - - // From here on the script will produce output. - Assets_View view {}; - const string username {webserver_request.session_logic()->currentUser ()}; - const int level {webserver_request.session_logic ()->currentLevel ()}; - - - // The identifier of the change notification. - const int id {filter::strings::convert_to_int (webserver_request.query ["get"])}; - view.set_variable ("id", filter::strings::convert_to_string (id)); - - - // Get old text, modification, new text, date. - const string old_text {database_modifications.getNotificationOldText (id)}; - view.set_variable ("old_text", old_text); - const string modification {database_modifications.getNotificationModification (id)}; - view.set_variable ("modification", modification); - const string new_text {database_modifications.getNotificationNewText (id)}; - view.set_variable ("new_text", new_text); - const string date {locale_logic_date (database_modifications.getNotificationTimeStamp (id))}; - view.set_variable ("date", date); - - - // Bibles and passage. - const Passage passage {database_modifications.getNotificationPassage (id)}; - const vector bibles {access_bible::bibles (webserver_request)}; - - - // Get notes for the passage. - vector notes = database_notes.select_notes (bibles, // Bibles. - passage.m_book, passage.m_chapter, filter::strings::convert_to_int (passage.m_verse), - 0, // Passage selector. - 0, // Edit selector. - 0, // Non-edit selector. - "", // Status selector. - "", // Bible selector. - "", // Assignment selector. - 0, // Subscription selector. - -1, // Severity selector. - 0, // Text selector. - "", // Search text. - -1); // Limit. - - // Remove the ones marked for deletion. - { - vector notes2; - for (const auto note : notes) { - if (!database_notes.is_marked_for_deletion (note)) { - notes2.push_back (note); - } - } - notes = notes2; - } - - // Sort them, most recent notes first. - vector timestamps; - for (const auto note : notes) { - int timestap = database_notes.get_modified (note); - timestamps.push_back (timestap); - } - filter::strings::quick_sort (timestamps, notes, 0, static_cast (notes.size ())); - reverse (notes.begin(), notes.end()); - - - // Whether there"s a live notes editor available. - bool live_notes_editor = Ipc_Notes::alive (webserver_request, false); - if (live_notes_editor) - view.enable_zone ("alive"); - else - view.enable_zone ("dead"); - - - // Details for the notes. - pugi::xml_document notes_document {}; - for (const auto note : notes) { - string summary = database_notes.get_summary (note); - summary = filter::strings::escape_special_xml_characters (summary); - bool subscription = database_notes.is_subscribed (note, username); - bool assignment = database_notes.is_assigned (note, username); - pugi::xml_node tr_node = notes_document.append_child("tr"); - pugi::xml_node td_node = tr_node.append_child("td"); - pugi::xml_node a_node = td_node.append_child("a"); - string href {}; - if (live_notes_editor) { - a_node.append_attribute("class") = "opennote"; - href = filter::strings::convert_to_string (note); - } else { - href = "/notes/note?id=" + filter::strings::convert_to_string (note); - } - a_node.append_attribute("href") = href.c_str(); - a_node.text().set(summary.c_str()); - td_node = tr_node.append_child("td"); - if (subscription) { - pugi::xml_node a_node2 = td_node.append_child("a"); - a_node2.append_attribute("href") = ("unsubscribe" + filter::strings::convert_to_string (note)).c_str(); - a_node2.text().set(("[" + translate("unsubscribe") + "]").c_str()); - } - td_node = tr_node.append_child("td"); - if (assignment) { - pugi::xml_node a_node2 = td_node.append_child("a"); - a_node2.append_attribute("href") = ("unassign" + filter::strings::convert_to_string (note)).c_str(); - a_node2.text().set(("[" + translate("I have done my part on it") + "]").c_str()); - } - td_node = tr_node.append_child("td"); - if (level >= Filter_Roles::manager ()) { - pugi::xml_node a_node2 = td_node.append_child("a"); - a_node2.append_attribute("href") = ("delete" + filter::strings::convert_to_string (note)).c_str(); - a_node2.text().set(("[" + translate("mark for deletion") + "]").c_str()); - } - } - stringstream notesblock {}; - notes_document.print(notesblock, "", pugi::format_raw); - view.set_variable ("notesblock", notesblock.str()); - - - // Display page. - return view.render ("changes", "change"); -} diff --git a/changes/change.h b/changes/change.h deleted file mode 100644 index 9825d522a..000000000 --- a/changes/change.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string changes_change_url (); -bool changes_change_acl (Webserver_Request& webserver_request); -std::string changes_change (Webserver_Request& webserver_request); diff --git a/changes/changes.cpp b/changes/changes.cpp deleted file mode 100644 index 58f93144e..000000000 --- a/changes/changes.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -using namespace std; -using namespace pugi; - - -string changes_changes_url () -{ - return "changes/changes"; -} - - -bool changes_changes_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ()); -} - - -string changes_changes (Webserver_Request& webserver_request) -{ - Database_Modifications database_modifications; - - - // Handle AJAX call to load the summary of a change notification. - if (webserver_request.query.count ("load")) { - const int identifier = filter::strings::convert_to_int (webserver_request.query["load"]); - stringstream block {}; - const Passage passage = database_modifications.getNotificationPassage (identifier); - const string link = filter_passage_link_for_opening_editor_at (passage.m_book, passage.m_chapter, passage.m_verse); - string category = database_modifications.getNotificationCategory (identifier); - if (category == changes_personal_category ()) - category = filter::strings::emoji_smiling_face_with_smiling_eyes (); - if (category == changes_bible_category ()) - category = filter::strings::emoji_open_book (); - string modification = database_modifications.getNotificationModification (identifier); - block << "
\n"; - block << "" << filter::strings::emoji_file_folder () << "\n"; - block << "" << filter::strings::emoji_wastebasket () << "\n"; - block << link << "\n"; - block << category << "\n"; - block << modification << "\n"; - block << "
\n"; - return block.str(); - } - - - // Handle AJAX call to remove a change notification. - if (webserver_request.post.count ("remove")) { - const int remove = filter::strings::convert_to_int (webserver_request.post["remove"]); - trash_change_notification (webserver_request, remove); - database_modifications.deleteNotification (remove); -#ifdef HAVE_CLIENT - webserver_request.database_config_user ()->addRemovedChange (remove); -#endif - webserver_request.database_config_user ()->setChangeNotificationsChecksum (""); - return string(); - } - - - // Handle AJAX call to navigate to the passage belonging to the change notification. - if (webserver_request.post.count ("navigate")) { - string navigate = webserver_request.post["navigate"]; - const int id = filter::strings::convert_to_int (navigate); - const Passage passage = database_modifications.getNotificationPassage (id); - if (passage.m_book) { - Ipc_Focus::set (webserver_request, passage.m_book, passage.m_chapter, filter::strings::convert_to_int (passage.m_verse)); - Navigation_Passage::record_history (webserver_request, passage.m_book, passage.m_chapter, filter::strings::convert_to_int (passage.m_verse)); - } - // Set the correct default Bible for the user. - const string bible = database_modifications.getNotificationBible (id); - if (!bible.empty ()) - webserver_request.database_config_user()->setBible (bible); - return string(); - } - - - // Handle query to update the sorting order. - const string sort = webserver_request.query ["sort"]; - if (sort == "verse") { - webserver_request.database_config_user ()->setOrderChangesByAuthor (false); - } - if (sort == "author") { - webserver_request.database_config_user ()->setOrderChangesByAuthor (true); - } - - - const string username = webserver_request.session_logic()->currentUser (); - const bool touch = webserver_request.session_logic ()->touchEnabled (); - - - string page {}; - Assets_Header header = Assets_Header (translate("Changes"), webserver_request); - header.set_stylesheet (); - header.add_bread_crumb (menu_logic_translate_menu (), menu_logic_translate_text ()); - if (touch) header.jquery_touch_on (); - page += header.run (); - Assets_View view {}; - - - // The selected Bible, that is, the Bible for which to show the change notifications. - string selectedbible = webserver_request.query ["selectedbible"]; - if (webserver_request.query.count ("selectbible")) { - selectedbible = webserver_request.query ["selectbible"]; - } - view.set_variable ("selectedbible", selectedbible); - - - // Remove a user's personal changes notifications and their matching change notifications in the Bible. - const string matching = webserver_request.query ["matching"]; - if (!matching.empty ()) { - vector ids = database_modifications.clearNotificationMatches (username, matching, changes_bible_category (), selectedbible); -#ifdef HAVE_CLIENT - // Client records deletions for sending to the Cloud. - for (const auto id : ids) { - webserver_request.database_config_user ()->addRemovedChange (id); - } -#endif - // Clear checksum cache. - webserver_request.database_config_user ()->setChangeNotificationsChecksum (""); - } - - - // Remove all the personal change notifications. - if (webserver_request.query.count ("personal")) { - vector ids = database_modifications.getNotificationTeamIdentifiers (username, changes_personal_category (), selectedbible); - for (const auto id : ids) { - trash_change_notification (webserver_request, id); - database_modifications.deleteNotification (id); -#ifdef HAVE_CLIENT - webserver_request.database_config_user ()->addRemovedChange (id); -#endif - webserver_request.database_config_user ()->setChangeNotificationsChecksum (""); - } - } - - - // Remove all the Bible change notifications. - if (webserver_request.query.count ("bible")) { - vector ids = database_modifications.getNotificationTeamIdentifiers (username, changes_bible_category (), selectedbible); - for (const auto id : ids) { - trash_change_notification (webserver_request, id); - database_modifications.deleteNotification (id); -#ifdef HAVE_CLIENT - webserver_request.database_config_user ()->addRemovedChange (id); -#endif - webserver_request.database_config_user ()->setChangeNotificationsChecksum (""); - } - } - - - // Remove all the change notifications made by a certain user. - if (webserver_request.query.count ("dismiss")) { - string user = webserver_request.query ["dismiss"]; - vector ids = database_modifications.getNotificationTeamIdentifiers (username, user, selectedbible); - for (auto id : ids) { - trash_change_notification (webserver_request, id); - database_modifications.deleteNotification (id); -#ifdef HAVE_CLIENT - webserver_request.database_config_user ()->addRemovedChange (id); -#endif - webserver_request.database_config_user ()->setChangeNotificationsChecksum (""); - } - } - - - // Read the identifiers, optionally sorted on author (that is, category). - bool sort_on_author = webserver_request.database_config_user ()->getOrderChangesByAuthor (); - vector notification_ids = database_modifications.getNotificationIdentifiers (username, selectedbible, sort_on_author); - // Send the identifiers to the browser for download there. - string pendingidentifiers {}; - for (auto id : notification_ids) { - if (!pendingidentifiers.empty ()) pendingidentifiers.append (" "); - pendingidentifiers.append (filter::strings::convert_to_string (id)); - } - view.set_variable ("pendingidentifiers", pendingidentifiers); - - - stringstream loading {}; - loading << "var loading = " << quoted(translate("Loading ...")) << ";"; - string script = loading.str(); - config::logic::swipe_enabled (webserver_request, script); - view.set_variable ("script", script); - - - // Add links to enable the user to show the change notifications for one Bible or for all Bibles. - vector distinct_bibles = database_modifications.getNotificationDistinctBibles (username); - // Show the Bible selector if there's more than one distinct Bible. - bool show_bible_selector = distinct_bibles.size () > 1; - // Also show the Bible selector if there's no change notifications to display, yet there's at least one distinct Bible. - // This situation often occurs after clearing a Bible's notifications, so there's no notifications after clearing them, - // yet there's notifications for other Bibles. - // Showing the Bible selector in this situation enables the user to select the other Bible(s). - if (notification_ids.empty () && !distinct_bibles.empty ()) show_bible_selector = true; - // Show the Bible selector if needed. - if (show_bible_selector) { - // If there's more than one distinct Bible, add the "All Bibles" selector. - if (distinct_bibles.size () > 1) distinct_bibles.insert (distinct_bibles.begin(), ""); - // Iterate over the Bibles and make them all selectable. - for (const auto & bible : distinct_bibles) { - string cssclass {}; - if (selectedbible == bible) cssclass = "active"; - string name (bible); - if (name.empty ()) name = translate ("All Bibles"); - view.add_iteration ("bibleselector", { pair ("selectbible", bible), pair ("biblename", name), pair ("class", cssclass) } ); - } - } - - - // Enable links to dismiss categories of notifications depending on whether there's anything to dismiss. - // And give details about the number of changes. - vector personal_ids = database_modifications.getNotificationTeamIdentifiers (username, changes_personal_category (), selectedbible); - if (!personal_ids.empty ()) { - view.enable_zone ("personal"); - view.set_variable ("personalcount", filter::strings::convert_to_string (personal_ids.size ())); - } - vector bible_ids = database_modifications.getNotificationTeamIdentifiers (username, changes_bible_category (), selectedbible); - if (!bible_ids.empty ()) { - view.enable_zone ("bible"); - view.set_variable ("teamcount", filter::strings::convert_to_string (bible_ids.size ())); - } - - - // Add links to clear the notifications from the individual contributors. - vector categories = database_modifications.getCategories (); - for (const auto & category : categories) { - if (category == changes_personal_category ()) continue; - if (category == changes_bible_category ()) continue; - const string & user = category; - vector ids = database_modifications.getNotificationTeamIdentifiers (username, user, selectedbible); - if (!ids.empty ()) { - view.add_iteration ("individual", { - pair ("user", user), - pair ("selectedbible", selectedbible), - pair ("count", filter::strings::convert_to_string(ids.size())) - }); - } - } - - - // Add links to clear matching notifications of the various users. - for (const auto & category : categories) { - if (category == changes_bible_category ()) continue; - const string & user = category; - vector personal_ids2 = database_modifications.getNotificationTeamIdentifiers (username, user, selectedbible); - string user_and_icon = translate ("user") + " " + category; - if (category == changes_personal_category ()) { - user_and_icon = translate ("me") + " " + filter::strings::emoji_smiling_face_with_smiling_eyes (); - } - if (!personal_ids2.empty () && !bible_ids.empty ()) { - view.add_iteration ("matching", { pair ("user", user), pair ("icon", user_and_icon) } ); - } - } - - - view.set_variable ("VERSION", config::logic::version ()); - - - if (touch) view.enable_zone ("touch"); - - - view.set_variable ("interlinks", changes_interlinks (webserver_request, changes_changes_url ())); - - - // Create data for the link for how to sort the change notifications. - string sortquery {}; - string sorttext {}; - if (webserver_request.database_config_user ()->getOrderChangesByAuthor ()) { - sortquery = "verse"; - sorttext = translate ("Sort on verse" ); - } else { - sortquery = "author"; - sorttext = translate ("Sort on author"); - } - view.set_variable ("sortquery", sortquery); - view.set_variable ("sorttext", sorttext); - - - // Whether to show the controls for dismissing the changes. - if (!notification_ids.empty ()) { - // Whether to put those controls at the bottom of the page, as the default location, - // or whether to put them at the top of the page. - if (webserver_request.database_config_user ()->getDismissChangesAtTop ()) { - view.enable_zone ("controlsattop"); - } else { - view.enable_zone ("controlsatbottom"); - } - } - - - page += view.render ("changes", "changes"); - - - page += assets_page::footer (); - return page; -} diff --git a/changes/changes.h b/changes/changes.h deleted file mode 100644 index 23dac60e4..000000000 --- a/changes/changes.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string changes_changes_url (); -bool changes_changes_acl (Webserver_Request& webserver_request); -std::string changes_changes (Webserver_Request& webserver_request); diff --git a/changes/logic.cpp b/changes/logic.cpp deleted file mode 100644 index 1503d7878..000000000 --- a/changes/logic.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -#include -#include -#include -#include -#include -#include -#include -using namespace std; -using namespace pugi; - - -void changes_logic_start () -{ - tasks_logic_queue (GENERATECHANGES); -} - - -const char * changes_personal_category () -{ - return "P"; -} - - -const char * changes_bible_category () -{ - return "B"; -} - - -string changes_interlinks (Webserver_Request& webserver_request, string my_url) -{ - // Storage the available links. - vector urls {}; - vector labels {}; - - // Handle situation that the user has permission to view the changes. - if (changes_changes_acl (webserver_request)) { - - // Handle situation that the user is not currently displaying the changes. - if (changes_changes_url () != my_url) { - urls.push_back (changes_changes_url ()); - labels.push_back (translate ("View")); - } - - } - -#ifndef HAVE_CLIENT - - if (changes_statistics_url () != my_url) { - if (changes_statistics_acl (webserver_request)) { - urls.push_back (changes_statistics_url ()); - labels.push_back (translate ("Statistics")); - } - } - - string revisions = "revisions"; - if (index_listing_url (revisions) != my_url) { - if (index_listing_acl (webserver_request, revisions)) { - urls.push_back (index_listing_url (revisions)); - labels.push_back (translate ("Download")); - } - } - - if (changes_manage_url () != my_url) { - if (changes_manage_acl (webserver_request)) { - urls.push_back (changes_manage_url ()); - labels.push_back (translate ("Manage")); - } - } - -#endif - - // Generate the links in XML. - xml_document document {}; - bool first {true}; - for (unsigned int i = 0; i < urls.size (); i++) { - if (!first) { - xml_node node = document.append_child ("span"); - node.text ().set (" | "); - } - first = false; - xml_node a = document.append_child ("a"); - string href = "/" + urls[i]; - a.append_attribute ("href") = href.c_str(); - a.text ().set (labels[i].c_str()); - } - - // Convert the document to a string. - stringstream output {}; - document.print (output, "", format_raw); - return output.str (); -} - - -void changes_clear_notifications_user (string jobid, string username) -{ - Database_Logs::log (translate ("Start clearing change notifications") + " " + username); - - Database_Modifications database_modifications {}; - Database_Jobs database_jobs {}; - - // Get the total amount of change notifications to clear for the user. - string any_bible {}; - vector identifiers = database_modifications.getNotificationIdentifiers (username, any_bible); - - // Total notes cleared. - int total_cleared {0}; - - // Feedback. - database_jobs.set_percentage (filter::strings::convert_to_int (jobid), 0); - database_jobs.set_progress (filter::strings::convert_to_int (jobid), translate ("Total:") + " " + filter::strings::convert_to_string (identifiers.size())); - - - // The amount of notifications it clears in the next iteration. - int cleared_count_in_one_go {0}; - do { - cleared_count_in_one_go = database_modifications.clearNotificationsUser (username); - total_cleared += cleared_count_in_one_go; - if (!identifiers.empty ()) { - database_jobs.set_percentage (filter::strings::convert_to_int (jobid), 100 * total_cleared / static_cast (identifiers.size())); - } - } while (cleared_count_in_one_go); - - Webserver_Request request; - request.database_config_user ()->setUserChangeNotificationsChecksum (username, ""); - - database_jobs.set_result (filter::strings::convert_to_int (jobid), translate ("Ready clearing change notifications")); - - Database_Logs::log (translate ("Ready clearing change notifications") + " " + username); -} diff --git a/changes/logic.h b/changes/logic.h deleted file mode 100644 index 1b839783f..000000000 --- a/changes/logic.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -void changes_logic_start (); -const char * changes_personal_category (); -const char * changes_bible_category (); -std::string changes_interlinks (Webserver_Request& webserver_request, std::string my_url); -void changes_clear_notifications_user (std::string jobid, std::string username); diff --git a/changes/manage.cpp b/changes/manage.cpp deleted file mode 100644 index 8bae97437..000000000 --- a/changes/manage.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string changes_manage_url () -{ - return "changes/manage"; -} - - -bool changes_manage_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -string changes_manage (Webserver_Request& webserver_request) -{ - Database_Modifications database_modifications {}; - - - string page {}; - Assets_Header header = Assets_Header (translate("Changes"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - page = header.run (); - Assets_View view {}; - - - if (webserver_request.query.count("clear")) { - string username = webserver_request.query["clear"]; - // This may take time in case there are many change notifications to clear. - // If there's 2000+ notifications, it takes a considerable time. - // For that reason, it starts a background job to clear the change notifications. - // The app will remain responsive to the user. - Database_Jobs database_jobs {}; - int jobId = database_jobs.get_new_id (); - database_jobs.set_level (jobId, Filter_Roles::manager ()); - database_jobs.set_start (jobId, translate ("Clearing change notifications.")); - tasks_logic_queue (DELETECHANGES, {filter::strings::convert_to_string (jobId), username}); - redirect_browser (webserver_request, jobs_index_url () + "?id=" + filter::strings::convert_to_string (jobId)); - return string(); - } - - - if (webserver_request.query.count("generate")) { - changes_logic_start (); - view.set_variable ("success", translate ("Will generate lists of changes")); - } - - - bool notifications {false}; - vector users = access_user::assignees (webserver_request); - for (const auto& user : users) { - string any_bible {}; - vector ids = database_modifications.getNotificationIdentifiers (user, any_bible); - if (!ids.empty ()) { - notifications = true; - map values {}; - values ["user"] = user; - values ["count"] = filter::strings::convert_to_string (ids.size ()); - view.add_iteration ("notifications", values); - } - } - if (notifications) view.enable_zone ("notifications"); - - - view.set_variable ("interlinks", changes_interlinks (webserver_request, changes_manage_url ())); - - - page += view.render ("changes", "manage"); - page += assets_page::footer (); - return page; -} diff --git a/changes/manage.h b/changes/manage.h deleted file mode 100644 index 9c7b4b770..000000000 --- a/changes/manage.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string changes_manage_url (); -bool changes_manage_acl (Webserver_Request& webserver_request); -std::string changes_manage (Webserver_Request& webserver_request); diff --git a/changes/modifications.cpp b/changes/modifications.cpp deleted file mode 100644 index 0f2a303f8..000000000 --- a/changes/modifications.cpp +++ /dev/null @@ -1,508 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Internal function declarations. -void changes_process_identifiers (Webserver_Request& webserver_request, - const string & user, - const vector & recipients, - const string & bible, - int book, int chapter, - const map > & bibles_per_user, - int oldId, int newId, - string & email, - int & change_count, float & time_total, int & time_count); - - -// Helper function. -// $user: The user whose changes are being processed. -// $recipients: The users who opted for receiving online notifications of any contributor. -void changes_process_identifiers (Webserver_Request& webserver_request, - const string & user, - const vector & recipients, - const string & bible, - int book, int chapter, - const map > & bibles_per_user, - int oldId, int newId, - string & email, - int & change_count, float & time_total, int & time_count) -{ - if (oldId != 0) { - Database_Modifications database_modifications {}; - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - Database_Modifications_Text old_chapter_text = database_modifications.getUserChapter (user, bible, book, chapter, oldId); - string old_chapter_usfm = old_chapter_text.oldtext; - Database_Modifications_Text new_chapter_text = database_modifications.getUserChapter (user, bible, book, chapter, newId); - string new_chapter_usfm = new_chapter_text.newtext; - vector old_verse_numbers = filter::usfm::get_verse_numbers (old_chapter_usfm); - vector new_verse_numbers = filter::usfm::get_verse_numbers (new_chapter_usfm); - vector verses = old_verse_numbers; - verses.insert (verses.end (), new_verse_numbers.begin (), new_verse_numbers.end ()); - verses = filter::strings::array_unique (verses); - sort (verses.begin(), verses.end()); - for (auto verse : verses) { - string old_verse_usfm = filter::usfm::get_verse_text (old_chapter_usfm, verse); - string new_verse_usfm = filter::usfm::get_verse_text (new_chapter_usfm, verse); - if (old_verse_usfm != new_verse_usfm) { - Filter_Text filter_text_old = Filter_Text (bible); - Filter_Text filter_text_new = Filter_Text (bible); - filter_text_old.html_text_standard = new HtmlText (translate("Bible")); - filter_text_new.html_text_standard = new HtmlText (translate("Bible")); - filter_text_old.text_text = new Text_Text (); - filter_text_new.text_text = new Text_Text (); - filter_text_old.add_usfm_code (old_verse_usfm); - filter_text_new.add_usfm_code (new_verse_usfm); - filter_text_old.run (stylesheet); - filter_text_new.run (stylesheet); - string old_html = filter_text_old.html_text_standard->get_inner_html (); - string new_html = filter_text_new.html_text_standard->get_inner_html (); - string old_text = filter_text_old.text_text->get (); - string new_text = filter_text_new.text_text->get (); - if (old_text != new_text) { - string modification = filter_diff_diff (old_text, new_text); - email += "
"; - email += filter_passage_display (book, chapter, filter::strings::convert_to_string (verse)); - email += " "; - email += modification; - email += "
"; - if (webserver_request.database_config_user()->getUserUserChangesNotificationsOnline (user)) { - database_modifications.recordNotification ({user}, changes_personal_category (), bible, book, chapter, verse, old_html, modification, new_html); - } - // Go over all the receipients to record the change for them. - for (auto recipient : recipients) { - // The author of this change does not get a notification for it. - if (recipient == user) continue; - // The recipient may have set which Bibles to get the change notifications for. - // This is stored like this: - // container [user] = list of bibles. - bool receive {true}; - try { - const vector & bibles = bibles_per_user.at(recipient); - receive = in_array(bible, bibles); - } catch (...) {} - if (!receive) continue; - // Store the notification. - database_modifications.recordNotification ({recipient}, user, bible, book, chapter, verse, old_html, modification, new_html); - } - } - // Statistics: Count yet another change made by this hard-working user! - change_count++; - int timestamp = database_modifications.getUserTimestamp (user, bible, book, chapter, newId); - time_total += static_cast(timestamp); - time_count++; - } - } - } -} - - -void changes_modifications () -{ - Database_Logs::log ("Change notifications: Generating", Filter_Roles::translator ()); - - - // Notifications are not available to clients to download while processing them. - config_globals_change_notifications_available = false; - - - // Data objects. - Webserver_Request webserver_request {}; - Database_Modifications database_modifications {}; - - - // Check on the health of the modifications database and (re)create it if needed. - if (!database_modifications.healthy ()) database_modifications.erase (); - database_modifications.create (); - - - // Get the users who will receive the changes entered by the named contributors. - vector recipients_named_contributors; - { - vector users = webserver_request.database_users ()->get_users (); - for (const auto & user : users) { - if (webserver_request.database_config_user ()->getContributorChangesNotificationsOnline (user)) { - recipients_named_contributors.push_back (user); - } - } - } - - // Storage for the statistics. - map user_change_statistics {}; - float modification_time_total {0.0f}; - int modification_time_count {0}; - - // There is a setting per user indicating which Bible(s) a user - // will get the change notifications from. - // This setting affects the changes made by all users. - // Note: A user will always receive notificatons of changes made by that same user. - map > notification_bibles_per_user {}; - { - vector users = webserver_request.database_users ()->get_users (); - for (const auto & user : users) { - vector bibles = webserver_request.database_config_user ()->getChangeNotificationsBiblesForUser (user); - notification_bibles_per_user [user] = bibles; - } - } - - - // Create online change notifications for users who made changes in Bibles. - // (The changes were made through the web editor or through a client). - // It runs before the team changes. - // This produces the desired order of the notifications in the GUI. - // At the same time, produce change statistics per user. - - vector users = database_modifications.getUserUsernames (); - if (!users.empty ()) Database_Logs::log ("Change notifications: Per user", Filter_Roles::translator ()); - for (const auto & user : users) { - - // Total changes made by this user. - int change_count {0}; - - // Go through the Bibles changed by the current user. - vector bibles = database_modifications.getUserBibles (user); - for (const auto & bible : bibles) { - - // Body of the email to be sent. - string email = "

" + translate("You have entered the changes below in a Bible editor.") + " " + translate ("You may check if it made its way into the Bible text.") + "

"; - size_t empty_email_length = email.length (); - - // Go through the books in that Bible. - vector books = database_modifications.getUserBooks (user, bible); - for (auto book : books) { - - // Go through the chapters in that book. - vector chapters = database_modifications.getUserChapters (user, bible, book); - for (auto chapter : chapters) { - - // Get the sets of identifiers for that chapter, and set some variables. - vector IdSets = database_modifications.getUserIdentifiers (user, bible, book, chapter); - int reference_new_id {0}; - int new_id {0}; - int last_new_id {0}; - bool restart = true; - - // Go through the sets of identifiers. - for (const auto & id_set : IdSets) { - - int oldId {id_set.oldid}; - new_id = id_set.newid; - - if (restart) { - changes_process_identifiers (webserver_request, user, recipients_named_contributors, bible, book, chapter, notification_bibles_per_user, reference_new_id, new_id, email, change_count, modification_time_total, modification_time_count); - reference_new_id = new_id; - last_new_id = new_id; - restart = false; - continue; - } - - if (oldId == last_new_id) { - last_new_id = new_id; - } else { - restart = true; - } - } - - // Process the last set of identifiers. - changes_process_identifiers (webserver_request, user, recipients_named_contributors, bible, book, chapter, notification_bibles_per_user, reference_new_id, new_id, email, change_count, modification_time_total, modification_time_count); - - } - } - - // Check whether there's any email to be sent. - if (email.length () != empty_email_length) { - // Send the user email with the user's personal changes if the user opted to receive it. - if (webserver_request.database_config_user()->getUserUserChangesNotification (user)) { - string subject = translate("Changes you entered in") + " " + bible; - if (!client_logic_client_enabled ()) email_schedule (user, subject, email); - } - } - } - - // Store change statistics for this user. - user_change_statistics [user] = change_count; - - // Clear the user's changes in the database. - database_modifications.clearUserUser (user); - - - // Clear checksum cache. - webserver_request.database_config_user ()->setUserChangeNotificationsChecksum (user, ""); - } - - - // Generate the notifications, online and by email, - // for the changes in the Bibles entered by anyone - // since the previous notifications were generated. - vector bibles = database_modifications.getTeamDiffBibles (); - for (const auto & bible : bibles) { - - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - vector changeNotificationUsers; - vector all_users = webserver_request.database_users ()->get_users (); - for (const auto & user : all_users) { - if (access_bible::read (webserver_request, bible, user)) { - if (webserver_request.database_config_user()->getUserGenerateChangeNotifications (user)) { - // The recipient may have set which Bibles to get the change notifications for. - // This is stored like this: - // container [user] = list of bibles. - bool receive {true}; - try { - const vector & user_bibles = notification_bibles_per_user.at(user); - receive = in_array(bible, user_bibles); - } catch (...) {} - if (receive) { - changeNotificationUsers.push_back (user); - } - } - } - } - all_users.clear (); - - - // The number of changes processed so far for this Bible. - int processedChangesCount = 0; - - - // The files get stored at http://site.org:/revisions// - int seconds = filter::date::seconds_since_epoch (); - string timepath; - timepath.append (filter::strings::convert_to_string (filter::date::numerical_year (seconds))); - timepath.append ("-"); - timepath.append (filter::strings::fill (filter::strings::convert_to_string (filter::date::numerical_month (seconds)), 2, '0')); - timepath.append ("-"); - timepath.append (filter::strings::fill (filter::strings::convert_to_string (filter::date::numerical_month_day (seconds)), 2, '0')); - timepath.append (" "); - timepath.append (filter::strings::fill (filter::strings::convert_to_string (filter::date::numerical_hour (seconds)), 2, '0')); - timepath.append (":"); - timepath.append (filter::strings::fill (filter::strings::convert_to_string (filter::date::numerical_minute (seconds)), 2, '0')); - timepath.append (":"); - timepath.append (filter::strings::fill (filter::strings::convert_to_string (filter::date::numerical_second (seconds)), 2, '0')); - string directory = filter_url_create_root_path ({"revisions", bible, timepath}); - filter_url_mkdir (directory); - - - // Produce the USFM and html files. - filter_diff_produce_verse_level (bible, directory); - - - // Create online page with changed verses. - string versesoutputfile = filter_url_create_path ({directory, "changed_verses.html"}); - filter_diff_run_file (filter_url_create_path ({directory, "verses_old.txt"}), filter_url_create_path ({directory, "verses_new.txt"}), versesoutputfile); - - - // Storage for body of the email with the changes. - vector email_changes {}; - - - // Generate the online change notifications. - vector books = database_modifications.getTeamDiffBooks (bible); - for (auto book : books) { - vector chapters = database_modifications.getTeamDiffChapters (bible, book); - for (auto chapter : chapters) { - Database_Logs::log ("Change notifications: " + bible + " " + filter_passage_display (book, chapter, ""), Filter_Roles::translator ()); - string old_chapter_usfm = database_modifications.getTeamDiff (bible, book, chapter); - string new_chapter_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - vector old_verse_numbers = filter::usfm::get_verse_numbers (old_chapter_usfm); - vector new_verse_numbers = filter::usfm::get_verse_numbers (new_chapter_usfm); - vector verses = old_verse_numbers; - verses.insert (verses.end (), new_verse_numbers.begin (), new_verse_numbers.end ()); - verses = filter::strings::array_unique (verses); - sort (verses.begin (), verses.end()); - for (auto verse : verses) { - string old_verse_usfm = filter::usfm::get_verse_text (old_chapter_usfm, verse); - string new_verse_usfm = filter::usfm::get_verse_text (new_chapter_usfm, verse); - if (old_verse_usfm != new_verse_usfm) { - processedChangesCount++; - // In case of too many change notifications, processing them would take too much time, so take a few shortcuts. - string old_html = "

" + old_verse_usfm + "

"; - string new_html = "

" + new_verse_usfm + "

"; - string old_text = old_verse_usfm; - string new_text = new_verse_usfm; - if (processedChangesCount < 800) { - Filter_Text filter_text_old = Filter_Text (bible); - Filter_Text filter_text_new = Filter_Text (bible); - filter_text_old.html_text_standard = new HtmlText (""); - filter_text_new.html_text_standard = new HtmlText (""); - filter_text_old.text_text = new Text_Text (); - filter_text_new.text_text = new Text_Text (); - filter_text_old.add_usfm_code (old_verse_usfm); - filter_text_new.add_usfm_code (new_verse_usfm); - filter_text_old.run (stylesheet); - filter_text_new.run (stylesheet); - old_html = filter_text_old.html_text_standard->get_inner_html (); - new_html = filter_text_new.html_text_standard->get_inner_html (); - old_text = filter_text_old.text_text->get (); - new_text = filter_text_new.text_text->get (); - } - string modification = filter_diff_diff (old_text, new_text); - database_modifications.recordNotification (changeNotificationUsers, changes_bible_category (), bible, book, chapter, verse, old_html, modification, new_html); - string passage = filter_passage_display (book, chapter, filter::strings::convert_to_string (verse)) + ": "; - if (old_text != new_text) { - email_changes.push_back (passage + modification); - } else { - email_changes.push_back (translate ("The following passage has no change in the text.") + " " + translate ("Only the formatting was changed.") + " " + translate ("The USFM code is given for reference.")); - email_changes.push_back (passage); - email_changes.push_back (translate ("Old code:") + " " + old_verse_usfm); - email_changes.push_back (translate ("New code:") + " " + new_verse_usfm); - } - } - } - // Delete the diff data for this chapter, for two reasons: - // 1. New diffs for this chapter can be stored straightaway. - // 2. In case of large amounts of diff data, and this function gets killed, - // then the next time it runs again, it will continue from where it was killed. - database_modifications.deleteTeamDiffChapter (bible, book, chapter); - } - } - - - // Email the changes to the subscribed users. - if (!email_changes.empty ()) { - // Split large emails up into parts. - // The size of the parts has been found by checking the maximum size that the emailer will send, - // then each part should remain well below that maximum size. - // The size was reduced even more later on: - // https://github.com/bibledit/cloud/issues/727 - vector bodies {}; - int counter {0}; - string body {}; - for (const auto & line : email_changes) { - body.append ("
"); - body.append (line); - body.append ("
\n"); - counter++; - if (counter >= 150) { - bodies.push_back (body); - body.clear (); - counter = 0; - } - } - if (!body.empty ()) bodies.push_back (body); - for (size_t b = 0; b < bodies.size (); b++) { - string subject = translate("Recent changes:") + " " + bible; - if (bodies.size () > 1) { - subject.append (" (" + filter::strings::convert_to_string (b + 1) + "/" + filter::strings::convert_to_string (bodies.size ()) + ")"); - } - vector all_users_2 = webserver_request.database_users ()->get_users (); - for (auto & user : all_users_2) { - if (webserver_request.database_config_user()->getUserBibleChangesNotification (user)) { - if (access_bible::read (webserver_request, bible, user)) { - if (!client_logic_client_enabled ()) { - email_schedule (user, subject, bodies[b]); - } - } - } - } - } - } - } - - - // Index the data and remove expired notifications. - Database_Logs::log ("Change notifications: Indexing", Filter_Roles::translator ()); - database_modifications.indexTrimAllNotifications (); - - - // Remove expired downloadable revisions. - string directory = filter_url_create_root_path ({"revisions"}); - int now = filter::date::seconds_since_epoch (); - bibles = filter_url_scandir (directory); - for (const auto & bible : bibles) { - string folder = filter_url_create_path ({directory, bible}); - int time = filter_url_file_modification_time (folder); - int days = (now - time) / 86400; - if (days > 31) { - filter_url_rmdir (folder); - } else { - vector revisions = filter_url_scandir (folder); - for (auto & revision : revisions) { - string path = filter_url_create_path ({folder, revision}); - int time2 = filter_url_file_modification_time (path); - int days2 = (now - time2) / 86400; - if (days2 > 31) { - filter_url_rmdir (path); - Database_Logs::log ("Removing expired downloadable revision notification: " + bible + " " + revision, Filter_Roles::translator ()); - } - } - } - } - - - // Clear checksum caches. - users = webserver_request.database_users ()->get_users (); - for (const auto & user : users) { - webserver_request.database_config_user ()->setUserChangeNotificationsChecksum (user, ""); - } - - - // Vacuum the modifications index, as it might have been updated. - database_modifications.vacuum (); - - - // Make the notifications available again to clients. - config_globals_change_notifications_available = true; - - -#ifdef HAVE_CLOUD - // Store the statistics in the database. - if (modification_time_count) { - // Take average timestamp of all timestamps. - int timestamp = static_cast (round (modification_time_total / static_cast(modification_time_count))); - for (auto & element : user_change_statistics) { - // Store dated change statistics per user. - string user = element.first; - int count = element.second; - Database_Statistics::store_changes (timestamp, user, count); - } - } -#endif - - - Database_Logs::log ("Change notifications: Ready", Filter_Roles::translator ()); -} diff --git a/changes/modifications.h b/changes/modifications.h deleted file mode 100644 index b630de054..000000000 --- a/changes/modifications.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void changes_modifications (); diff --git a/changes/statistics.cpp b/changes/statistics.cpp deleted file mode 100644 index 8a12e24e9..000000000 --- a/changes/statistics.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Internal function declarations. -void changes_statistics_add (Assets_View & view, const string & date, int count); - - -string changes_statistics_url () -{ - return "changes/statistics"; -} - - -bool changes_statistics_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ()); -} - - -void changes_statistics_add (Assets_View& view, const string& date, int count) -{ - if (count) { - map values; - values ["date"] = date; - values ["count"] = filter::strings::convert_to_string (count); - view.add_iteration ("statistics", values); - } -} - - -string changes_statistics ([[maybe_unused]] Webserver_Request& webserver_request) -{ -#ifdef HAVE_CLIENT - return string(); -#endif - -#ifdef HAVE_CLOUD - - string page {}; - Assets_Header header = Assets_Header (translate("Change statistics"), webserver_request); - page += header.run (); - Assets_View view {}; - - - string everyone = translate ("Everyone"); - string user = webserver_request.query["user"]; - if (user == everyone) user.clear (); - - - vector > changes = Database_Statistics::get_changes (user); - string last_date {}; - int last_count {0}; - for (const auto & element : changes) { - const string date = locale_logic_date (element.first); - const int count = element.second; - if (date == last_date) { - last_count += count; - } else { - changes_statistics_add (view, last_date, last_count); - last_date = date; - last_count = count; - } - } - if (last_count) { - changes_statistics_add (view, last_date, last_count); - } - - - vector users = Database_Statistics::get_users (); - users.push_back (everyone); - for (size_t i = 0; i < users.size (); i++) { - map values; - if (i) values ["divider"] = "|"; - values ["user"] = users[i]; - view.add_iteration ("users", values); - } - - - if (user.empty ()) user = everyone; - view.set_variable ("user", user); - - - page += view.render ("changes", "statistics"); - - - page += assets_page::footer (); - return page; -#endif -} diff --git a/changes/statistics.h b/changes/statistics.h deleted file mode 100644 index d0d907fa8..000000000 --- a/changes/statistics.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string changes_statistics_url (); -bool changes_statistics_acl (Webserver_Request& webserver_request); -std::string changes_statistics (Webserver_Request& webserver_request); diff --git a/checks/french.cpp b/checks/french.cpp deleted file mode 100644 index 22da43310..000000000 --- a/checks/french.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -using namespace std; - - -// In French there is a no-break space after the « and before the » ! ? : ; -// The Unicode value for the no-break space is U+00A0. -// Another type of non-breaking space will be acceptable too. -void checks_french::space_before_after_punctuation (const string & bible, int book, int chapter, - const map & texts) -{ - Database_Check database_check {}; - string nbsp = filter::strings::non_breaking_space_u00A0 (); - string nnbsp = filter::strings::narrow_non_breaking_space_u202F (); - vector right_punctuation = { right_guillemet(), "!", "?", ":", ";" }; - for (const auto & element : texts) { - int verse = element.first; - - { - string text = element.second; - size_t pos = text.find (left_guillemet ()); - while (pos != std::string::npos) { - text.erase (0, pos + left_guillemet ().size ()); - bool space_follows = text.find (" ") == 0; - bool nbsp_follows = text.find (nbsp) == 0; - bool nnbsp_follows = text.find (nnbsp) == 0; - if (space_follows) { - string message = left_guillemet () + " - " + translate ("Should be followed by a no-break space rather than a plain space in French"); - database_check.recordOutput (bible, book, chapter, verse, message); - } else if (!nbsp_follows && !nnbsp_follows) { - string message = left_guillemet () + " - " + translate ("Should be followed by a no-break space in French"); - database_check.recordOutput (bible, book, chapter, verse, message); - } - pos = text.find (left_guillemet ()); - } - } - - for (const auto & punctuation : right_punctuation) { - string text = element.second; - // The location of this punctuation character. - size_t pos = filter::strings::unicode_string_strpos (text, punctuation); - while (pos != std::string::npos) { - if (pos > 0) { - string preceding_character = filter::strings::unicode_string_substr (text, pos - 1, 1); - if (preceding_character == " ") { - string message = punctuation + " - " + translate ("Should be preceded by a no-break space rather than a plain space in French"); - database_check.recordOutput (bible, book, chapter, verse, message); - } - else if (preceding_character == nbsp) { /* This is OK. */ } - else if (preceding_character == nnbsp) { /* This is OK. */ } - else { - string message = punctuation + " - " + translate ("Should be preceded by a no-break space in French"); - database_check.recordOutput (bible, book, chapter, verse, message); - } - } - // Prepare for next iteration. - text = filter::strings::unicode_string_substr (text, pos + 1, filter::strings::unicode_string_length (text) - pos - 1); - pos = filter::strings::unicode_string_strpos (text, punctuation); - } - } - - } -} - - -// In French, if a citation starts with "«", all subsequent paragraphs within that citation, may begin with a new «. -// Example: -// « This is the text of the citation. -// « This is a new paragraph, and it ends the citation ». -// This checks on that style. -void checks_french::citation_style (const string & bible, int book, int chapter, - const vector > & verses_paragraphs) -{ - Database_Check database_check {}; - - // Store the state of the previous paragraph. - // It indicates whether any citation was left open at the end of the paragraph. - bool previous_paragraph_open_citation {false}; - - // Iterate over the paragraphs. - for (unsigned int paragraph_counter = 0; paragraph_counter < verses_paragraphs.size (); paragraph_counter++) { - - // Container with verse numbers as the keys, plus the text of the whole paragraph. - const map verses_paragraph = verses_paragraphs [paragraph_counter]; - - // Skip empty containers. - if (verses_paragraph.empty ()) continue; - - // If this the first paragraph in the chapter, leave it as it is. - // If it is not the first paragraph, and if the previous paragraph left an open citation, - // this new paragraph should start with the French citation marker. - if (paragraph_counter) { - if (previous_paragraph_open_citation) { - int verse = verses_paragraph.begin()->first; - string text = verses_paragraph.begin()->second; - if (!text.empty ()) { - string character = filter::strings::unicode_string_substr (text, 0, 1); - if (character != left_guillemet ()) { - string message = translate ("The previous paragraph contains a citation not closed with a » therefore the current paragraph is expected to start with a « to continue that citation in French"); - database_check.recordOutput (bible, book, chapter, verse, message); - } - } - } - } - - // Count the number of left and right guillements in the paragraph. - int last_verse {0}; - string paragraph {}; - for (const auto & element : verses_paragraph) { - paragraph.append (element.second); - last_verse = element.first; - } - int opener_count {0}; - filter::strings::replace (left_guillemet (), "", paragraph, &opener_count); - int closer_count {0}; - filter::strings::replace (right_guillemet (), "", paragraph, &closer_count); - - // Determine whether the current paragraph opens a citation and does not close it. - previous_paragraph_open_citation = (opener_count > closer_count); - - // Whether there's too many left guillements. - if (opener_count > (closer_count + 1)) { - string message = translate ("The paragraph contains more left guillements than needed"); - database_check.recordOutput (bible, book, chapter, last_verse, message); - } - - // Whether there's too many right guillements. - if (closer_count > opener_count) { - string message = translate ("The paragraph contains more right guillements than needed"); - database_check.recordOutput (bible, book, chapter, last_verse, message); - } - } -} - - -string checks_french::left_guillemet () -{ - return "«"; -} - - -string checks_french::right_guillemet () -{ - return "»"; -} diff --git a/checks/french.h b/checks/french.h deleted file mode 100644 index 6629cf230..000000000 --- a/checks/french.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -namespace checks_french { - -void space_before_after_punctuation (const std::string & bible, int book, int chapter, - const std::map & texts); -void citation_style (const std::string & bible, int book, int chapter, - const std::vector > & verses_paragraphs); -std::string left_guillemet (); -std::string right_guillemet (); - -} diff --git a/checks/headers.cpp b/checks/headers.cpp deleted file mode 100644 index 24cf15e02..000000000 --- a/checks/headers.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -using namespace std; - - -void checks_headers::no_punctuation_at_end (const string & bible, int book, int chapter, - const map & headings, - const string & centermarks, const string & endmarks) -{ - Database_Check database_check {}; - for (const auto & element : headings) { - int verse = element.first; - string heading = element.second; - // Full stops often occur in the inspired headings of many Psalms in verse 0. - // Skip these. - if ((book == 19) && (verse == 0)) continue; - string last_character {}; - if (!heading.empty ()) last_character = heading.substr (heading.size () - 1); - bool message {false}; - if (centermarks.find (last_character) != std::string::npos) message = true; - if (endmarks.find (last_character) != std::string::npos) message = true; - if (message) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Punctuation at end of heading:") + " " + heading); - } - } -} diff --git a/checks/headers.h b/checks/headers.h deleted file mode 100644 index 232437b3f..000000000 --- a/checks/headers.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - - -namespace checks_headers { - -void no_punctuation_at_end (const std::string & bible, int book, int chapter, - const std::map & headings, - const std::string & centermarks, const std::string & endmarks); - -} diff --git a/checks/index.cpp b/checks/index.cpp deleted file mode 100644 index 08e428009..000000000 --- a/checks/index.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string checks_index_url () -{ - return "checks/index"; -} - - -bool checks_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -std::string checks_index (Webserver_Request& webserver_request) -{ - Database_Check database_check {}; - - - std::string page {}; - Assets_Header header = Assets_Header (translate("Checks"), webserver_request); - header.add_bread_crumb (menu_logic_tools_menu (), menu_logic_tools_text ()); - page = header.run (); - Assets_View view {}; - - - if (webserver_request.query.count ("approve")) { - const int approve = filter::strings::convert_to_int (webserver_request.query["approve"]); - database_check.approve (approve); - view.set_variable ("success", translate("The entry was suppressed.")); - } - - - if (webserver_request.query.count ("delete")) { - const int erase = filter::strings::convert_to_int (webserver_request.query["delete"]); - database_check.erase (erase); - view.set_variable ("success", translate("The entry was deleted for just now.")); - } - - - // Get the Bibles the user has write-access to. - std::vector bibles {}; - { - const std::vector & all_bibles = webserver_request.database_bibles()->get_bibles (); - for (const auto& bible : all_bibles) { - if (access_bible::write (webserver_request, bible)) { - bibles.push_back (bible); - } - } - } - - - std::stringstream resultblock {}; - const std::vector & hits = database_check.getHits (); - for (const auto& hit : hits) { - std::string bible = hit.bible; - if (find (bibles.begin(), bibles.end (), bible) != bibles.end ()) { - const int id = hit.rowid; - bible = filter::strings::escape_special_xml_characters (bible); - int book = hit.book; - int chapter = hit.chapter; - int verse = hit.verse; - const std::string link = filter_passage_link_for_opening_editor_at (book, chapter, filter::strings::convert_to_string (verse)); - const std::string information = filter::strings::escape_special_xml_characters (hit.data); - resultblock << "

\n"; - resultblock << "\n"; - resultblock << "" << filter::strings::emoji_wastebasket () << "\n"; - resultblock << bible; - resultblock << " "; - resultblock << link; - resultblock << " "; - resultblock << information; - resultblock << "

\n"; - } - } - view.set_variable ("resultblock", resultblock.str()); - - - if (checks_settings_acl (webserver_request)) { - view.enable_zone ("can_enable"); - } else { - view.enable_zone ("cannot_enable"); - } - - - page += view.render ("checks", "index"); - page += assets_page::footer (); - return page; -} diff --git a/checks/index.h b/checks/index.h deleted file mode 100644 index 063e72f44..000000000 --- a/checks/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string checks_index_url (); -bool checks_index_acl (Webserver_Request& webserver_request); -std::string checks_index (Webserver_Request& webserver_request); diff --git a/checks/logic.cpp b/checks/logic.cpp deleted file mode 100644 index de4a53805..000000000 --- a/checks/logic.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -using namespace std; - - -void checks_logic_start_all () -{ - Database_Bibles database_bibles {}; - const vector & bibles = database_bibles.get_bibles (); - for (const auto & bible : bibles) { - bool enabled = Database_Config_Bible::getDailyChecksEnabled (bible); - if (enabled) checks_logic_start (bible); - } -} - - -void checks_logic_start (const string & bible) -{ - tasks_logic_queue (CHECKBIBLE, {bible}); -} diff --git a/checks/logic.h b/checks/logic.h deleted file mode 100644 index 186295a60..000000000 --- a/checks/logic.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void checks_logic_start_all (); -void checks_logic_start (const std::string & bible); diff --git a/checks/pairs.cpp b/checks/pairs.cpp deleted file mode 100644 index 55654ca72..000000000 --- a/checks/pairs.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -void checks_pairs::run (const string & bible, int book, int chapter, - const map & texts, - const vector > & pairs, - bool french_citation_style) -{ - // This holds the opener characters of the pairs which were opened in the text. - // For example, it may hold the "[". - vector verses {}; - vector opened {}; - - // Containers with the openers and the closers. - // If the check on the French citation style is active, - // skip the French guillemets. - vector openers {}; - vector closers {}; - for (const auto & element : pairs) { - string opener = element.first; - if (french_citation_style && (opener == checks_french::left_guillemet ())) continue; - string closer = element.second; - if (french_citation_style && (opener == checks_french::right_guillemet ())) continue; - openers.push_back (opener); - closers.push_back (closer); - } - - Database_Check database_check {}; - - // Go through the verses with their texts. - for (const auto & element : texts) { - int verse = element.first; - string text = element.second; - size_t length = filter::strings::unicode_string_length (text); - for (size_t pos = 0; pos < length; pos++) { - - string character = filter::strings::unicode_string_substr (text, pos, 1); - - if (in_array (character, openers)) { - verses.push_back (verse); - opened.push_back (character); - } - - if (in_array (character, closers)) { - - string opener = match (character, pairs); - bool mismatch = false; - if (opened.empty ()) { - mismatch = true; - } else if (opened.back () == opener) { - verses.pop_back (); - opened.pop_back (); - } else { - mismatch = true; - } - if (mismatch) { - string fragment1 = translate ("Closing character"); - string fragment2 = translate ("without its matching opening character"); - stringstream message; - message << fragment1 << " " << quoted(character) << " " << fragment2 << " " << quoted(opener); - database_check.recordOutput (bible, book, chapter, verse, message.str()); - } - } - } - } - - // Report unclosed openers. - for (size_t i = 0; i < verses.size (); i++) { - int verse = verses [i]; - string opener = opened [i]; - string closer = match (opener, pairs); - string fragment1 = translate ("Opening character"); - string fragment2 = translate ("without its matching closing character"); - stringstream message; - message << fragment1 << " " << quoted(opener) << " " << fragment2 << " " << quoted(closer); - database_check.recordOutput (bible, book, chapter, verse, message.str()); - } -} - - -string checks_pairs::match (const string & character, const vector > & pairs) -{ - for (auto & element : pairs) { - if (character == element.first) return element.second; - if (character == element.second) return element.first; - } - return string(); -} diff --git a/checks/pairs.h b/checks/pairs.h deleted file mode 100644 index d39c62337..000000000 --- a/checks/pairs.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -namespace checks_pairs { - -void run (const std::string & bible, int book, int chapter, - const std::map & texts, - const std::vector > & pairs, - bool french_citation_style); -std::string match (const std::string & character, const std::vector > & pairs); - -} diff --git a/checks/run.cpp b/checks/run.cpp deleted file mode 100644 index abdc9f156..000000000 --- a/checks/run.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void checks_run (string bible) -{ - Webserver_Request webserver_request {}; - Database_Check database_check {}; -#ifndef HAVE_CLIENT - Database_Modifications database_modifications {}; -#endif - - - if (bible.empty()) return; - - - Database_Logs::log ("Check " + bible + ": Start", Filter_Roles::translator ()); - - - database_check.truncateOutput (bible); - - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - bool check_double_spaces_usfm = Database_Config_Bible::getCheckDoubleSpacesUsfm (bible); - bool check_full_stop_in_headings = Database_Config_Bible::getCheckFullStopInHeadings (bible); - bool check_space_before_punctuation = Database_Config_Bible::getCheckSpaceBeforePunctuation (bible); - bool check_space_before_final_note_marker = Database_Config_Bible::getCheckSpaceBeforeFinalNoteMarker (bible); - bool check_sentence_structure = Database_Config_Bible::getCheckSentenceStructure (bible); - bool check_paragraph_structure = Database_Config_Bible::getCheckParagraphStructure (bible); - Checks_Sentences checks_sentences; - checks_sentences.enter_capitals (Database_Config_Bible::getSentenceStructureCapitals (bible)); - checks_sentences.enter_small_letters (Database_Config_Bible::getSentenceStructureSmallLetters (bible)); - string end_marks = Database_Config_Bible::getSentenceStructureEndPunctuation (bible); - checks_sentences.enter_end_marks (end_marks); - string center_marks = Database_Config_Bible::getSentenceStructureMiddlePunctuation (bible); - checks_sentences.enter_center_marks (center_marks); - string disregards = Database_Config_Bible::getSentenceStructureDisregards (bible); - checks_sentences.enter_disregards (disregards); - checks_sentences.enter_names (Database_Config_Bible::getSentenceStructureNames (bible)); - vector within_sentence_paragraph_markers = filter::strings::explode (Database_Config_Bible::getSentenceStructureWithinSentenceMarkers (bible), ' '); - bool check_books_versification = Database_Config_Bible::getCheckBooksVersification (bible); - bool check_chapters_verses_versification = Database_Config_Bible::getCheckChaptesVersesVersification (bible); - bool check_well_formed_usfm = Database_Config_Bible::getCheckWellFormedUsfm (bible); - Checks_Usfm checks_usfm = Checks_Usfm (bible); - bool check_missing_punctuation_end_verse = Database_Config_Bible::getCheckMissingPunctuationEndVerse (bible); - bool check_patterns = Database_Config_Bible::getCheckPatterns (bible); - string s_checking_patterns = Database_Config_Bible::getCheckingPatterns (bible); - vector checking_patterns = filter::strings::explode (s_checking_patterns, '\n'); - bool check_matching_pairs = Database_Config_Bible::getCheckMatchingPairs (bible); - vector > matching_pairs; - { - string fragment = Database_Config_Bible::getMatchingPairs (bible); - vector pairs = filter::strings::explode (fragment, ' '); - for (auto & pair : pairs) { - pair = filter::strings::trim (pair); - size_t length = filter::strings::unicode_string_length (pair); - if (length == 2) { - string opener = filter::strings::unicode_string_substr (pair, 0, 1); - string closer = filter::strings::unicode_string_substr (pair, 1, 1); - matching_pairs.push_back ({opener, closer}); - } - } - } - bool check_space_end_verse = Database_Config_Bible::getCheckSpaceEndVerse (bible); - bool check_french_punctuation = Database_Config_Bible::getCheckFrenchPunctuation (bible); - bool check_french_citation_style = Database_Config_Bible::getCheckFrenchCitationStyle (bible); - bool transpose_fix_space_in_notes = Database_Config_Bible::getTransposeFixSpacesNotes (bible); - bool check_valid_utf8_text = Database_Config_Bible::getCheckValidUTF8Text (bible); - - - vector books = webserver_request.database_bibles()->get_books (bible); - if (check_books_versification) checks_versification::books (bible, books); - - - for (auto book : books) { - - - vector chapters = webserver_request.database_bibles()->get_chapters (bible, book); - if (check_chapters_verses_versification) checks_versification::chapters (bible, book, chapters); - - - for (auto chapter : chapters) { - string chapterUsfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - - // Transpose and fix spacing around certain markers in footnotes and cross references. - if (transpose_fix_space_in_notes) { - string old_usfm (chapterUsfm); - bool transposed = checks::space::transpose_note_space (chapterUsfm); - if (transposed) { -#ifndef HAVE_CLIENT - int oldID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); -#endif - webserver_request.database_bibles()->store_chapter(bible, book, chapter, chapterUsfm); -#ifndef HAVE_CLIENT - int newID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - string username = "Bibledit"; - database_modifications.recordUserSave (username, bible, book, chapter, oldID, old_usfm, newID, chapterUsfm); - if (sendreceive_git_repository_linked (bible)) { - Database_Git::store_chapter (username, bible, book, chapter, old_usfm, chapterUsfm); - } - rss_logic_schedule_update (username, bible, book, chapter, old_usfm, chapterUsfm); -#endif - Database_Logs::log ("Transposed and fixed double spaces around markers in footnotes or cross references in " + filter_passage_display (book, chapter, "") + " in Bible " + bible); - } - } - - - vector verses = filter::usfm::get_verse_numbers (chapterUsfm); - if (check_chapters_verses_versification) checks_versification::verses (bible, book, chapter, verses); - - - for (auto verse : verses) { - string verseUsfm = filter::usfm::get_verse_text (chapterUsfm, verse); - if (check_double_spaces_usfm) { - checks::space::double_space_usfm (bible, book, chapter, verse, verseUsfm); - } - if (check_valid_utf8_text) { - if (!filter::strings::unicode_string_is_valid (verseUsfm)) { - string msg = "Invalid UTF-8 Unicode in verse text"; - database_check.recordOutput (bible, book, chapter, verse, msg); - } - } - if (check_space_before_final_note_marker) { - checks::space::space_before_final_note_markup(bible, book, chapter, verse, verseUsfm); - } - } - - - Filter_Text filter_text = Filter_Text (bible); - filter_text.initializeHeadingsAndTextPerVerse (false); - filter_text.add_usfm_code (chapterUsfm); - filter_text.run (stylesheet); - map verses_headings = filter_text.verses_headings; - map verses_text = filter_text.getVersesText (); - vector > verses_paragraphs = filter_text.verses_paragraphs; - if (check_full_stop_in_headings) { - checks_headers::no_punctuation_at_end (bible, book, chapter, verses_headings, center_marks, end_marks); - } - if (check_space_before_punctuation) { - checks::space::space_before_punctuation (bible, book, chapter, verses_text); - } - - if (check_sentence_structure || check_paragraph_structure) { - checks_sentences.initialize (); - if (check_sentence_structure) checks_sentences.check (verses_text); - if (check_paragraph_structure) { - checks_sentences.paragraphs (filter_text.paragraph_starting_markers, - within_sentence_paragraph_markers, - verses_paragraphs); - } - - vector > results = checks_sentences.get_results (); - for (auto result : results) { - int verse = result.first; - string msg = result.second; - database_check.recordOutput (bible, book, chapter, verse, msg); - } - } - - if (check_well_formed_usfm) { - checks_usfm.initialize (book, chapter); - checks_usfm.check (chapterUsfm); - checks_usfm.finalize (); - vector > results = checks_usfm.get_results (); - for (auto element : results) { - int verse = element.first; - string msg = element.second; - database_check.recordOutput (bible, book, chapter, verse, msg); - } - } - - if (check_missing_punctuation_end_verse) { - checks_verses::missing_punctuation_at_end (bible, book, chapter, verses_text, center_marks, end_marks, disregards); - } - - if (check_patterns) { - checks_verses::patterns (bible, book, chapter, verses_text, checking_patterns); - } - - if (check_matching_pairs) { - checks_pairs::run (bible, book, chapter, verses_text, matching_pairs, check_french_citation_style); - } - - if (check_space_end_verse) { - checks::space::space_end_verse (bible, book, chapter, chapterUsfm); - } - - if (check_french_punctuation) { - checks_french::space_before_after_punctuation (bible, book, chapter, verses_headings); - checks_french::space_before_after_punctuation (bible, book, chapter, verses_text); - } - - if (check_french_citation_style) { - checks_french::citation_style (bible, book, chapter, verses_paragraphs); - } - - } - } - - - // Create an email with the checking results for this bible. - vector emailBody; - vector hits = database_check.getHits (); - for (const auto & hit : hits) { - if (hit.bible == bible) { - string passage = filter_passage_display_inline ({Passage ("", hit.book, hit.chapter, filter::strings::convert_to_string (hit.verse))}); - string data = filter::strings::escape_special_xml_characters (hit.data); - string result = "

" + passage + " " + data + "

"; - emailBody.push_back (result); - } - } - - - // Add a link to the online checking results. - if (!emailBody.empty ()) { - Webserver_Request webserver_request; - string siteUrl = config::logic::site_url (webserver_request); - stringstream body1 {}; - body1 << "

" << translate("Checking results online") << "

"; - emailBody.push_back (body1.str()); - stringstream body2 {}; - body2 << "

" << translate ("Settings") << "

"; - emailBody.push_back (body2.str()); - } - - - // Send email to users with access to the Bible and a subscription to the notification. - if (!emailBody.empty ()) { - string subject = translate("Bible Checks") + " " + bible; - string body = filter::strings::implode (emailBody, "\n"); - vector users = webserver_request.database_users ()->get_users (); - for (auto user : users) { - if (webserver_request.database_config_user()->getUserBibleChecksNotification (user)) { - if (access_bible::read (webserver_request, bible, user)) { - if (!client_logic_client_enabled ()) { - email_schedule (user, subject, body); - } - } - } - } - } - - - Database_Logs::log ("Check " + bible + ": Complete", Filter_Roles::translator ()); -} diff --git a/checks/run.h b/checks/run.h deleted file mode 100644 index 169c2c6cb..000000000 --- a/checks/run.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void checks_run (std::string bible); diff --git a/checks/sentences.cpp b/checks/sentences.cpp deleted file mode 100644 index 8bada3dc3..000000000 --- a/checks/sentences.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -using namespace std; - - -void Checks_Sentences::enter_capitals (const string & capitals) -{ - m_capitals = filter::strings::explode (capitals, ' '); -} - - -void Checks_Sentences::enter_small_letters (const string & small_letters) -{ - m_small_letters = filter::strings::explode (small_letters, ' '); -} - - -void Checks_Sentences::enter_end_marks (const string & end_marks) -{ - m_end_marks = filter::strings::explode (end_marks, ' '); -} - - -void Checks_Sentences::enter_center_marks (const string & center_marks) -{ - m_center_marks = filter::strings::explode (center_marks, ' '); -} - - -void Checks_Sentences::enter_disregards (const string & disregards) -{ - m_disregards = filter::strings::explode (disregards, ' '); -} - - -void Checks_Sentences::enter_names (string names) -{ - m_names.clear (); - names = filter::strings::replace ("\n", " ", names); - vector names2 = filter::strings::explode (names, ' '); - for (auto name : names2) { - if (!name.empty()) { - // Limit the length to the left of the suffix in the test. - name = filter::strings::unicode_string_substr (name, 0, 11); - m_names.push_back (name); - } - } -} - - -void Checks_Sentences::initialize () -{ - current_position = 0; - space_position = 0; - capital_position = 0; - small_letter_position = 0; - end_mark_position = 0; - center_mark_position = 0; - punctuation_mark_position = 0; - previous_mark_position = 0; - checking_results.clear (); - full_text.clear (); -} - - -void Checks_Sentences::check (const map & texts) -{ - vector verse_numbers {}; - vector characters {}; - int iterations {0}; - for (const auto & element : texts) { - int verse = element.first; - string text = element.second; - // For the second and subsequent verse_numbers, add a space to the text, - // because this is what is supposed to happen in USFM. - if (iterations > 0) { - verse_numbers.push_back (verse); - characters.push_back (" "); - full_text += " "; - } - // Split the UTF-8 text into characters and add them to the arrays of verse_numbers / characters. - size_t count = filter::strings::unicode_string_length (text); - for (size_t i = 0; i < count; i++) { - character = filter::strings::unicode_string_substr (text, i, 1); - // Skip characters to be disregarded. - if (in_array (character, m_disregards)) continue; - // Store verse numbers and characters. - verse_numbers.push_back (verse); - characters.push_back (character); - full_text += character; - } - // Next iteration. - iterations++; - } - - // Go through the characters. - for (size_t i = 0; i < characters.size (); i++) { - // Store current verse number in the object. - verse_number = verse_numbers [i]; - // Get the current character. - character = characters [i]; - // Analyze the character. - analyze_characters (); - // Run the checks. - check_unknown_character (); - check_character (); - } -} - - -void Checks_Sentences::check_character () -{ - // Handle a capital after a comma: ... He said, Go ... - if (this->is_capital) - if (this->space_position > 0) - if (this->current_position == this->space_position + 1) - if (this->current_position == this->center_mark_position + 2) - this->add_result (translate ("Capital follows mid-sentence punctuation mark"), Checks_Sentences::skip_names); - - - // Handle a small letter straight after mid-sentence punctuation: ... He said,go ... - if (this->is_small_letter) - if (this->center_mark_position > 0) - if (this->current_position == this->center_mark_position + 1) - this->add_result (translate ("Small letter follows straight after a mid-sentence punctuation mark"), Checks_Sentences::display_context); - - - // Handle a capital straight after mid-sentence punctuation: ... He said,Go ... - if (this->is_capital) - if (this->center_mark_position > 0) - if (this->current_position == this->center_mark_position + 1) - this->add_result (translate ("Capital follows straight after a mid-sentence punctuation mark"), Checks_Sentences::display_context); - - - // Handle small letter or capital straight after end-sentence punctuation: He said.Go. // He said.go. - if ((this->is_small_letter) || (this->is_capital)) - if (this->end_mark_position > 0) - if (this->current_position == this->end_mark_position + 1) - this->add_result (translate ("A letter follows straight after an end-sentence punctuation mark"), Checks_Sentences::display_context); - - - // Handle case of no capital after end-sentence punctuation: He did that. he went. - if (this->is_small_letter) - if (this->end_mark_position > 0) - if (this->current_position == this->end_mark_position + 2) - this->add_result (translate ("No capital after an end-sentence punctuation mark"), Checks_Sentences::display_context); - - - // Handle two punctuation marks in sequence. - if (this->is_end_mark || this->is_center_mark) - if (this->current_position == this->previous_mark_position + 1) - this->add_result (translate ("Two punctuation marks in sequence"), Checks_Sentences::display_context); - -} - - -// Checks paragraphs of text whether they are start and end with correct capitalization and punctuation. -// $paragraph_start_markers: The USFM markers that started the new paragraphs. -// $within_sentence_paragraph_markers: -// The USFM markers that start paragraphs that do not need to start with the correct capitalization. -// Usually such markers are poetic markers like \q1 and so on. -// $verses_paragraphs: The entire paragraphs, with verse number as their keys. -void Checks_Sentences::paragraphs (const vector & paragraph_start_markers, - const vector & within_sentence_paragraph_markers, - const vector > & verses_paragraphs) -{ - // Iterate over the paragraphs. - for (unsigned int p = 0; p < verses_paragraphs.size (); p++) { - - // Container with verse numbers and the whole paragraph. - const map & verses_paragraph = verses_paragraphs [p]; - - // Skip empty container. - if (verses_paragraph.empty ()) continue; - - // Get the first character of the paragraph. - int verse = verses_paragraph.begin()->first; - string character2 = verses_paragraph.begin()->second; - if (!character2.empty ()) { - character2 = filter::strings::unicode_string_substr (character2, 0, 1); - } - - // Check that the paragraph starts with a capital. - is_capital = in_array (character2, m_capitals); - if (!is_capital) { - const string & paragraph_marker = paragraph_start_markers [p]; - if (!in_array (paragraph_marker, within_sentence_paragraph_markers)) { - string context = verses_paragraph.begin()->second; - context = filter::strings::unicode_string_substr (context, 0, 15); - checking_results.push_back (pair (verse, translate ("Paragraph does not start with a capital:") + " " + context)); - } - } - - // Get the last two characters of the paragraph. - verse = verses_paragraph.rbegin()->first; - character2 = verses_paragraph.rbegin()->second; - if (!character2.empty ()) { - size_t length = filter::strings::unicode_string_length (character2); - character2 = filter::strings::unicode_string_substr (character2, length - 1, 1); - } - string previous_character = verses_paragraph.rbegin()->second; - if (!previous_character.empty ()) { - size_t length = filter::strings::unicode_string_length (character2); - if (length >= 2) { - previous_character = filter::strings::unicode_string_substr (previous_character, length - 2, 1); - } else { - previous_character.clear (); - } - } - - // Check that the paragraph ends with correct punctuation. - is_end_mark = in_array (character2, this->m_end_marks) || in_array (previous_character, this->m_end_marks); - if (!is_end_mark) { - // If the next paragraph starts with a marker that indicates it should not necessarily be capitalized, - // then the current paragraph may have punctuation that would be incorrect otherwise. - string next_paragraph_marker {}; - size_t p2 = p + 1; - if (p2 < paragraph_start_markers.size ()) { - next_paragraph_marker = paragraph_start_markers [p2]; - } - if (next_paragraph_marker.empty () || (!in_array (next_paragraph_marker, within_sentence_paragraph_markers))) { - string context = verses_paragraph.rbegin()->second; - const size_t length = filter::strings::unicode_string_length (character2); - if (length >= 15) { - context = filter::strings::unicode_string_substr (context, length - 15, 15); - } - checking_results.push_back (pair (verse, translate ("Paragraph does not end with an end marker:") + " " + context)); - } - } - - } -} - - -vector > Checks_Sentences::get_results () -{ - return checking_results; -} - - -void Checks_Sentences::add_result (string text, int modifier) -{ - // Get previous and next text fragment. - int start = current_position - 25; - if (start < 0) start = 0; - string previousFragment = filter::strings::unicode_string_substr (full_text, static_cast (start), static_cast (current_position - start - 1)); - int iterations {5}; - while (iterations) { - const size_t pos = previousFragment.find (" "); - if (pos != std::string::npos) { - if ((previousFragment.length () - pos) > 10) { - previousFragment.erase (0, pos + 1); - } - } - iterations--; - } - string nextFragment = filter::strings::unicode_string_substr (full_text, static_cast (current_position), 25); - while (nextFragment.length () > 10) { - const size_t pos = nextFragment.rfind (" "); - if (pos == std::string::npos) nextFragment.erase (nextFragment.length () - 1, 1); - else nextFragment.erase (pos); - } - // Check whether the result can be skipped due to a name being involved. - if (modifier == skip_names) { - string haystack = character + nextFragment; - for (auto name : m_names) { - if (haystack.find (name) == 0) return; - } - } - // Assemble text for checking result. - if (modifier == display_character_only) { - text += ": " + character; - } - if ((modifier == display_context) || (modifier == skip_names)) { - text += ": " + previousFragment + character + nextFragment; - } - // Store checking result. - checking_results.push_back (pair (verse_number, text)); -} - - -void Checks_Sentences::check_unknown_character () -{ - if (is_space) return; - if (is_capital) return; - if (is_small_letter) return; - if (is_end_mark) return; - if (is_center_mark) return; - add_result (translate ("Unknown character"), Checks_Sentences::display_character_only); -} - - -void Checks_Sentences::analyze_characters () -{ - current_position++; - - is_space = (character == " "); - if (is_space) { - space_position = current_position; - } - - is_capital = in_array (character, m_capitals); - if (is_capital) { - capital_position = current_position; - } - - is_small_letter = in_array (character, m_small_letters); - if (is_small_letter) { - small_letter_position = current_position; - } - - is_end_mark = in_array (character, m_end_marks); - if (is_end_mark) { - end_mark_position = current_position; - previous_mark_position = punctuation_mark_position; - punctuation_mark_position = current_position; - } - - is_center_mark = in_array (character, m_center_marks); - if (is_center_mark) { - center_mark_position = current_position; - previous_mark_position = punctuation_mark_position; - punctuation_mark_position = current_position; - } -} diff --git a/checks/sentences.h b/checks/sentences.h deleted file mode 100644 index 28cce9bcd..000000000 --- a/checks/sentences.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Checks_Sentences -{ -public: - void enter_capitals (const std::string & capitals); - void enter_small_letters (const std::string & small_letters); - void enter_end_marks (const std::string & end_marks); - void enter_center_marks (const std::string & center_marks); - void enter_disregards (const std::string & disregards); - void enter_names (std::string names); - void initialize (); - std::vector > get_results (); - void check (const std::map & texts); - void paragraphs (const std::vector & paragraph_start_markers, - const std::vector & within_sentence_paragraph_markers, - const std::vector > & verses_paragraphs); - -private: - // Sentence structure parameters. - std::vector m_capitals {}; - std::vector m_small_letters {}; - std::vector m_end_marks {}; - std::vector m_center_marks {}; - std::vector m_disregards {}; - std::vector m_names {}; - - // State. - int verse_number {0}; - int current_position {0}; - - // Grapheme analysis. - std::string character {}; - bool is_space {false}; - int space_position {0}; - bool is_capital {false}; - int capital_position {0}; - bool is_small_letter {false}; - int small_letter_position {0}; - bool is_end_mark {false}; - int end_mark_position {0}; - bool is_center_mark {false}; - int center_mark_position {0}; - int punctuation_mark_position {0}; - int previous_mark_position {0}; - - // Context. - std::string full_text {}; - - // Results of the checks. - std::vector > checking_results {}; - static constexpr int display_character_only {1}; - static constexpr int display_context {2}; - static constexpr int skip_names {3}; - - void add_result (std::string text, int modifier); - void check_unknown_character (); - void analyze_characters (); - void check_character (); -}; diff --git a/checks/settings.cpp b/checks/settings.cpp deleted file mode 100644 index ab64af59a..000000000 --- a/checks/settings.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string checks_settings_url () -{ - return "checks/settings"; -} - - -bool checks_settings_acl ([[maybe_unused]] Webserver_Request& webserver_request) -{ -#ifdef HAVE_CLIENT - return true; -#else - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -#endif -} - - -string checks_settings (Webserver_Request& webserver_request) -{ - string page {}; - Assets_Header header = Assets_Header (translate("Manage Checks"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - page = header.run (); - Assets_View view {}; - - - if (webserver_request.query.count ("bible")) { - string bible = webserver_request.query["bible"]; - if (bible.empty()) { - Dialog_List dialog_list = Dialog_List ("settings", translate("Select which Bible to manage"), string(), string()); - vector bibles = access_bible::bibles (webserver_request); - for (const auto & selectable_bible : bibles) { - dialog_list.add_row (selectable_bible, "bible", selectable_bible); - } - page += dialog_list.run (); - return page; - } else { - webserver_request.database_config_user()->setBible (bible); - } - } - string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - - - if (webserver_request.query.count ("run")) { - checks_logic_start (bible); - view.set_variable ("success", translate("Will run the checks.")); - view.set_variable ("journal", journal_logic_see_journal_for_progress ()); - } - - - string checkbox = webserver_request.post ["checkbox"]; - bool checked = filter::strings::convert_to_bool (webserver_request.post ["checked"]); - - - if (checkbox == "doublespacesusfm") { - Database_Config_Bible::setCheckDoubleSpacesUsfm (bible, checked); - } - view.set_variable ("doublespacesusfm", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckDoubleSpacesUsfm (bible))); - - - if (checkbox == "fullstopheadings") { - Database_Config_Bible::setCheckFullStopInHeadings (bible, checked); - } - view.set_variable ("fullstopheadings", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckFullStopInHeadings (bible))); - - - if (checkbox == "spacebeforepunctuation") { - Database_Config_Bible::setCheckSpaceBeforePunctuation (bible, checked); - } - view.set_variable ("spacebeforepunctuation", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckSpaceBeforePunctuation (bible))); - - - if (checkbox == "spacebeforefinalnotemarkup") { - Database_Config_Bible::setCheckSpaceBeforeFinalNoteMarker (bible, checked); - } - view.set_variable ("spacebeforefinalnotemarkup", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckSpaceBeforeFinalNoteMarker (bible))); - - - if (checkbox == "sentencestructure") { - Database_Config_Bible::setCheckSentenceStructure (bible, checked); - } - view.set_variable ("sentencestructure", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckSentenceStructure (bible))); - - - if (checkbox == "paragraphstructure") { - Database_Config_Bible::setCheckParagraphStructure (bible, checked); - } - view.set_variable ("paragraphstructure", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckParagraphStructure (bible))); - - - if (checkbox == "booksversification") { - Database_Config_Bible::setCheckBooksVersification (bible, checked); - } - view.set_variable ("booksversification", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckBooksVersification (bible))); - - - if (checkbox == "chaptersversesversification") { - Database_Config_Bible::setCheckChaptesVersesVersification (bible, checked); - } - view.set_variable ("chaptersversesversification", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckChaptesVersesVersification (bible))); - - - if (checkbox == "wellformedusfm") { - Database_Config_Bible::setCheckWellFormedUsfm (bible, checked); - } - view.set_variable ("wellformedusfm", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckWellFormedUsfm (bible))); - - - if (checkbox == "punctuationatendverse") { - Database_Config_Bible::setCheckMissingPunctuationEndVerse (bible, checked); - } - view.set_variable ("punctuationatendverse", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckMissingPunctuationEndVerse (bible))); - - - if (checkbox == "patterns") { - Database_Config_Bible::setCheckPatterns (bible, checked); - } - view.set_variable ("patterns", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckPatterns (bible))); - - - if (checkbox == "pairs") { - Database_Config_Bible::setCheckMatchingPairs (bible, checked); - } - view.set_variable ("pairs", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckMatchingPairs (bible))); - - - if (checkbox == "spaceendverse") { - Database_Config_Bible::setCheckSpaceEndVerse (bible, checked); - } - view.set_variable ("spaceendverse", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckSpaceEndVerse (bible))); - - - if (checkbox == "frenchpunctuation") { - Database_Config_Bible::setCheckFrenchPunctuation (bible, checked); - } - view.set_variable ("frenchpunctuation", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckFrenchPunctuation (bible))); - - - if (checkbox == "frenchcitation") { - Database_Config_Bible::setCheckFrenchCitationStyle (bible, checked); - } - view.set_variable ("frenchcitation", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckFrenchCitationStyle (bible))); - - - if (checkbox == "transposenotes") { - Database_Config_Bible::setTransposeFixSpacesNotes (bible, checked); - } - view.set_variable ("transposenotes", filter::strings::get_checkbox_status (Database_Config_Bible::getTransposeFixSpacesNotes (bible))); - - - if (checkbox == "validutf8") { - Database_Config_Bible::setCheckValidUTF8Text (bible, checked); - } - view.set_variable ("validutf8", filter::strings::get_checkbox_status (Database_Config_Bible::getCheckValidUTF8Text (bible))); - - - view.set_variable ("bible", bible); - - -#ifdef HAVE_CLIENT - view.enable_zone ("client"); -#else - view.enable_zone ("cloud"); -#endif - - - page += view.render ("checks", "settings"); - page += assets_page::footer (); - return page; -} diff --git a/checks/settings.h b/checks/settings.h deleted file mode 100644 index caf2ae958..000000000 --- a/checks/settings.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string checks_settings_url (); -bool checks_settings_acl (Webserver_Request& webserver_request); -std::string checks_settings (Webserver_Request& webserver_request); diff --git a/checks/settingspairs.cpp b/checks/settingspairs.cpp deleted file mode 100644 index e26e63d48..000000000 --- a/checks/settingspairs.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string checks_settingspairs_url () -{ - return "checks/settingspairs"; -} - - -bool checks_settingspairs_acl ([[maybe_unused]] Webserver_Request& webserver_request) -{ -#ifdef HAVE_CLIENT - return true; -#else - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -#endif -} - - -string checks_settingspairs (Webserver_Request& webserver_request) -{ - string page {}; - Assets_Header header = Assets_Header (translate ("Matching pairs"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (checks_settings_url (), menu_logic_checks_settings_text ()); - page = header.run (); - Assets_View view {}; - - - string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - view.set_variable ("bible", bible); - - - if (webserver_request.post.count ("pairs")) { - string fragment = webserver_request.post["pairs"]; - vector errors {}; - vector pairs = filter::strings::explode (fragment, ' '); - bool okay {true}; - for (const auto & pair : pairs) { - const size_t length = filter::strings::unicode_string_length (pair); - if (length != 2) { - errors.push_back (translate ("A pair should consist of two characters:") + " " + pair); - okay = false; - } - } - if (okay) { - Database_Config_Bible::setMatchingPairs (bible, fragment); - view.set_variable ("success", translate("The pairs were saved")); - } else { - view.set_variable ("error", filter::strings::implode (errors, " | ")); - } - } - view.set_variable ("pairs", Database_Config_Bible::getMatchingPairs (bible)); - - - page += view.render ("checks", "settingspairs"); - page += assets_page::footer (); - return page; -} diff --git a/checks/settingspairs.h b/checks/settingspairs.h deleted file mode 100644 index 3d9ef31a1..000000000 --- a/checks/settingspairs.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string checks_settingspairs_url (); -bool checks_settingspairs_acl (Webserver_Request& webserver_request); -std::string checks_settingspairs (Webserver_Request& webserver_request); diff --git a/checks/settingspatterns.cpp b/checks/settingspatterns.cpp deleted file mode 100644 index 4827d2c90..000000000 --- a/checks/settingspatterns.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string checks_settingspatterns_url () -{ - return "checks/settingspatterns"; -} - - -bool checks_settingspatterns_acl ([[maybe_unused]] Webserver_Request& webserver_request) -{ -#ifdef HAVE_CLIENT - return true; -#else - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -#endif -} - - -string checks_settingspatterns (Webserver_Request& webserver_request) -{ - string page {}; - Assets_Header header = Assets_Header (translate ("Patterns"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (checks_settings_url (), menu_logic_checks_settings_text ()); - page = header.run (); - Assets_View view {}; - - - string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - - - if (webserver_request.post.count ("patterns")) { - string patterns = webserver_request.post ["patterns"]; - if (!bible.empty ()) Database_Config_Bible::setCheckingPatterns (bible, patterns); - view.set_variable ("success", translate("The patterns were saved")); - } - - - view.set_variable ("bible", bible); - view.set_variable ("patterns", Database_Config_Bible::getCheckingPatterns (bible)); - - - page += view.render ("checks", "settingspatterns"); - page += assets_page::footer (); - return page; -} diff --git a/checks/settingspatterns.h b/checks/settingspatterns.h deleted file mode 100644 index c9d04660f..000000000 --- a/checks/settingspatterns.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string checks_settingspatterns_url (); -bool checks_settingspatterns_acl (Webserver_Request& webserver_request); -std::string checks_settingspatterns (Webserver_Request& webserver_request); diff --git a/checks/settingssentences.cpp b/checks/settingssentences.cpp deleted file mode 100644 index 698908a45..000000000 --- a/checks/settingssentences.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string checks_settingssentences_url () -{ - return "checks/settingssentences"; -} - - -bool checks_settingssentences_acl ([[maybe_unused]] Webserver_Request& webserver_request) -{ -#ifdef HAVE_CLIENT - return true; -#else - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -#endif -} - - -string checks_settingssentences (Webserver_Request& webserver_request) -{ - string page {}; - Assets_Header header = Assets_Header (translate ("Sentence Structure"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (checks_settings_url (), menu_logic_checks_settings_text ()); - page = header.run (); - Assets_View view {}; - - - string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - - - if (webserver_request.post.count ("capitals")) { - Database_Config_Bible::setSentenceStructureCapitals (bible, webserver_request.post["capitals"]); - view.set_variable ("success", translate("The capitals were stored")); - } - - - if (webserver_request.post.count ("smallletters")) { - Database_Config_Bible::setSentenceStructureSmallLetters (bible, webserver_request.post["smallletters"]); - view.set_variable ("success", translate("The small letters were stored")); - } - - - if (webserver_request.post.count ("endpunctuationmarks")) { - Database_Config_Bible::setSentenceStructureEndPunctuation (bible, webserver_request.post["endpunctuationmarks"]); - view.set_variable ("success", translate("The punctuation marks at the ends of sentences were stored")); - } - - - if (webserver_request.post.count ("middlepunctuationmarks")) { - Database_Config_Bible::setSentenceStructureMiddlePunctuation (bible, webserver_request.post["middlepunctuationmarks"]); - view.set_variable ("success", translate("The punctuation marks within the sentences were stored")); - } - - - if (webserver_request.post.count ("disregards")) { - Database_Config_Bible::setSentenceStructureDisregards (bible, webserver_request.post["disregards"]); - view.set_variable ("success", translate("The characters that should be disregarded within the sentences were stored")); - } - - - if (webserver_request.post.count ("names")) { - Database_Config_Bible::setSentenceStructureNames (bible, webserver_request.post["names"]); - view.set_variable ("success", translate("The names that may occur after mid-sentence punctuation were stored")); - } - - - if (webserver_request.post.count ("within_sentence_paragraph_markers")) { - Database_Config_Bible::setSentenceStructureWithinSentenceMarkers (bible, webserver_request.post["within_sentence_paragraph_markers"]); - view.set_variable ("success", translate("The markers that start a new line but not necessarily a new sentence were saved")); - } - - - view.set_variable ("bible", bible); - view.set_variable ("capitals", filter::strings::escape_special_xml_characters (Database_Config_Bible::getSentenceStructureCapitals (bible))); - view.set_variable ("smallletters", filter::strings::escape_special_xml_characters (Database_Config_Bible::getSentenceStructureSmallLetters (bible))); - view.set_variable ("endpunctuationmarks", filter::strings::escape_special_xml_characters (Database_Config_Bible::getSentenceStructureEndPunctuation (bible))); - view.set_variable ("middlepunctuationmarks", filter::strings::escape_special_xml_characters (Database_Config_Bible::getSentenceStructureMiddlePunctuation (bible))); - view.set_variable ("disregards", filter::strings::escape_special_xml_characters (Database_Config_Bible::getSentenceStructureDisregards (bible))); - view.set_variable ("names", filter::strings::escape_special_xml_characters (Database_Config_Bible::getSentenceStructureNames (bible))); - view.set_variable ("within_sentence_paragraph_markers", filter::strings::escape_special_xml_characters (Database_Config_Bible::getSentenceStructureWithinSentenceMarkers (bible))); - - - page += view.render ("checks", "settingssentences"); - page += assets_page::footer (); - return page; -} diff --git a/checks/settingssentences.h b/checks/settingssentences.h deleted file mode 100644 index 370dc766d..000000000 --- a/checks/settingssentences.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string checks_settingssentences_url (); -bool checks_settingssentences_acl (Webserver_Request& webserver_request); -std::string checks_settingssentences (Webserver_Request& webserver_request); diff --git a/checks/space.cpp b/checks/space.cpp deleted file mode 100644 index 09e033af1..000000000 --- a/checks/space.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -using namespace std; - - -namespace checks::space { - - -void double_space_usfm (const string & bible, int book, int chapter, int verse, const string & data) -{ - const size_t pos = data.find (" "); - if (pos != std::string::npos) { - int start = static_cast(pos) - 10; - if (start < 0) start = 0; - string fragment = data.substr (static_cast (start), 20); - Database_Check database_check {}; - database_check.recordOutput (bible, book, chapter, verse, translate ("Double space:") + " ... " + fragment + " ..."); - } -} - - -void space_before_punctuation (const string & bible, int book, int chapter, const map & texts) -{ - Database_Check database_check {}; - for (const auto & element : texts) { - const int verse = element.first; - string text = element.second; - if (text.find (" ,") != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Space before a comma")); - } - if (text.find (" ;") != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Space before a semicolon")); - } - if (text.find (" :") != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Space before a colon")); - } - if (text.find (" .") != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Space before a full stop")); - } - if (text.find (" ?") != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Space before a question mark")); - } - if (text.find (" !") != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Space before an exclamation mark")); - } - } -} - - -void space_end_verse (const string & bible, int book, int chapter, const string & usfm) -{ - Database_Check database_check {}; - vector verses = filter::usfm::get_verse_numbers (usfm); - for (auto verse : verses) { - if (!verse) continue; - string text = filter::usfm::get_verse_text (usfm, verse); - vector items = filter::usfm::get_markers_and_text (text); - for (const auto & item : items) { - if (filter::usfm::is_usfm_marker (item)) { - text = filter::strings::replace (item, "", text); - } - } - bool hit {false}; - if (!text.empty ()) { - string trimmed = filter::strings::trim (text); - if (trimmed.empty ()) hit = true; - char lastchar = text.back (); - if (lastchar == ' ') hit = true; - } - if (hit) database_check.recordOutput (bible, book, chapter, verse, translate ("Space at the end of the verse")); - } -} - - -bool transpose_note_space (string & usfm) -{ - // Samples of footnote and cross reference markers that have spacing to be transposed. - // \v 1 Verse\f + \fr 3.1\fk keyword\ft Text.\f* one. - // \v 2 Verse\x + \xo 3.2\xt Text.\x* two. - - bool transposed {false}; - const size_t pos = usfm.find(" "); - if (pos != std::string::npos) { - map data = { - pair (R"(\fk )", R"( \fk )"), - pair (R"(\ft )", R"( \ft )"), - pair (R"(\xt )", R"( \xt )") - }; - for (const auto & search_replace : data) { - int count {0}; - usfm = filter::strings::replace (search_replace.first, search_replace.second, usfm, &count); - if (count) transposed = true; - } - } - return transposed; -} - - -void space_before_final_note_markup (const string & bible, int book, int chapter, int verse, const string & data) -{ - Database_Check database_check {}; - if (data.find (R"( \f*)") != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Space before final note markup")); - } - if (data.find (R"( \fe*)") != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Space before final note markup")); - } - if (data.find (R"( \x*)") != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Space before final cross reference markup")); - } -} - - -} diff --git a/checks/space.h b/checks/space.h deleted file mode 100644 index f4f0d9795..000000000 --- a/checks/space.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -namespace checks::space { - -void double_space_usfm (const std::string & bible, int book, int chapter, int verse, const std::string & data); -void space_before_punctuation (const std::string & bible, int book, int chapter, const std::map & texts); -void space_end_verse (const std::string & bible, int book, int chapter, const std::string & usfm); -bool transpose_note_space (std::string & usfm); -void space_before_final_note_markup (const std::string & bible, int book, int chapter, int verse, const std::string & data); - -} - diff --git a/checks/suppress.cpp b/checks/suppress.cpp deleted file mode 100644 index b501dc91d..000000000 --- a/checks/suppress.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string checks_suppress_url () -{ - return "checks/suppress"; -} - - -bool checks_suppress_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -string checks_suppress (Webserver_Request& webserver_request) -{ - Database_Check database_check {}; - - - string page {}; - page = assets_page::header (translate ("Suppressed checking results"), webserver_request); - Assets_View view {}; - - - if (webserver_request.query.count ("release")) { - int release = filter::strings::convert_to_int (webserver_request.query["release"]); - database_check.release (release); - view.set_variable ("success", translate ("The check result is no longer suppressed.")); - } - - - // Get the Bibles the user has write-access to. - vector bibles {}; - { - vector all_bibles = webserver_request.database_bibles()->get_bibles (); - for (const auto & bible : all_bibles) { - if (access_bible::write (webserver_request, bible)) { - bibles.push_back (bible); - } - } - } - - - string block {}; - const vector suppressions = database_check.getSuppressions (); - for (const auto & suppression : suppressions) { - string bible = suppression.bible; - // Only display entries for Bibles the user has write access to. - if (in_array (bible, bibles)) { - int id = suppression.rowid; - bible = filter::strings::escape_special_xml_characters (bible); - string passage = filter_passage_display_inline ({Passage ("", suppression.book, suppression.chapter, filter::strings::convert_to_string (suppression.verse))}); - string result = filter::strings::escape_special_xml_characters (suppression.data); - result.insert (0, bible + " " + passage + " "); - block.append (R"(

)"); - block.append (R"()"); - block.append (filter::strings::emoji_wastebasket ()); - block.append (""); - block.append (result); - block.append ("

\n"); - } - } - view.set_variable ("block", block); - - - page += view.render ("checks", "suppress"); - page += assets_page::footer (); - return page; -} diff --git a/checks/suppress.h b/checks/suppress.h deleted file mode 100644 index 03e9262a3..000000000 --- a/checks/suppress.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string checks_suppress_url (); -bool checks_suppress_acl (Webserver_Request& webserver_request); -std::string checks_suppress (Webserver_Request& webserver_request); diff --git a/checks/usfm.cpp b/checks/usfm.cpp deleted file mode 100644 index d44a18c7e..000000000 --- a/checks/usfm.cpp +++ /dev/null @@ -1,580 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -Checks_Usfm::Checks_Usfm (const string & bible) -{ - Database_Styles database_styles {}; - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - markers_stylesheet = database_styles.getMarkers (stylesheet); - for (const auto & marker : markers_stylesheet) { - Database_Styles_Item style = database_styles.getMarkerData (stylesheet, marker); - style_items [marker] = style; - int styleType = style.type; - int styleSubtype = style.subtype; - - // Find out which markers require an endmarker. - // And which markers are embeddable. - bool required_endmarker {false}; - bool embeddable_marker {false}; - if (styleType == StyleTypeIdentifier) { - if (styleSubtype == IdentifierSubtypePublishedVerseMarker) { - required_endmarker = true; - } - } - if (styleType == StyleTypeFootEndNote) { - if ((styleSubtype == FootEndNoteSubtypeFootnote) || (styleSubtype == FootEndNoteSubtypeEndnote)) { - required_endmarker = true; - } - } - if (styleType == StyleTypeCrossreference) { - if (styleSubtype == CrossreferenceSubtypeCrossreference) { - required_endmarker = true; - } - } - if (styleType == StyleTypeInlineText) { - required_endmarker = true; - embeddable_marker = true; - } - if (styleType == StyleTypeWordlistElement) { - required_endmarker = true; - embeddable_marker = true; - } - if (required_endmarker) { - markers_requiring_endmarkers.push_back (marker); - } - if (embeddable_marker) { - embeddable_markers.push_back (marker); - } - - // Look for the \toc[1-3] markers. - if (styleType == StyleTypeIdentifier) { - if (styleSubtype == IdentifierSubtypeLongTOC) long_toc1_marker = marker; - if (styleSubtype == IdentifierSubtypeShortTOC) short_toc2_marker = marker; - if (styleSubtype == IdentifierSubtypeBookAbbrev) abbrev_toc3_marker = marker; - } - } -} - - -void Checks_Usfm::initialize (int book, int chapter) -{ - checking_results.clear (); - usfm_markers_and_text.clear (); - usfm_markers_and_text_pointer = 0; - book_number = book; - chapter_number = chapter; - verse_number = 0; - open_matching_markers.clear (); - empty_markup_previous_item.clear(); -} - - -void Checks_Usfm::finalize () -{ - // Check on unclosed markers. - if (open_matching_markers.size () > 0) { - add_result (translate ("Unclosed markers:") + " " + filter::strings::implode (open_matching_markers, " "), display_nothing); - } -} - - -void Checks_Usfm::check (const string & usfm) -{ - new_line_in_usfm (usfm); - - forward_slash (usfm); - - toc (usfm); - - usfm_markers_and_text = filter::usfm::get_markers_and_text (usfm); - for (usfm_markers_and_text_pointer = 0; usfm_markers_and_text_pointer < usfm_markers_and_text.size(); usfm_markers_and_text_pointer++) { - usfm_item = usfm_markers_and_text [usfm_markers_and_text_pointer]; - if (filter::usfm::is_usfm_marker (usfm_item)) { - - // Get the current verse number. - if (usfm_item == R"(\v )") { - string verseCode = filter::usfm::peek_text_following_marker (usfm_markers_and_text, usfm_markers_and_text_pointer); - verse_number = filter::strings::convert_to_int (filter::usfm::peek_verse_number (verseCode)); - } - - malformed_verse_number (); - - marker_in_stylesheet (); - - malformed_id (); - - widow_back_slash (); - - matching_endmarker (); - - embedded_marker (); - - figure (); - - } - - empty_markup(); - - note(); - - } -} - - -void Checks_Usfm::malformed_verse_number () -{ - if (usfm_item == "\\v ") { - string code = filter::usfm::peek_text_following_marker (usfm_markers_and_text, usfm_markers_and_text_pointer); - string cleanVerseNumber = filter::usfm::peek_verse_number (code); - vector v_dirtyVerseNumber = filter::strings::explode (code, ' '); - string dirtyVerseNumber; - if (!v_dirtyVerseNumber.empty ()) dirtyVerseNumber = v_dirtyVerseNumber [0]; - if (cleanVerseNumber != dirtyVerseNumber) { - add_result (translate ("Malformed verse number"), display_full); - } - } -} - - -void Checks_Usfm::new_line_in_usfm (const string & usfm) -{ - size_t position {string::npos}; - size_t pos = usfm.find ("\\\n"); - if (pos != std::string::npos) { - position = pos; - } - pos = usfm.find ("\\ \n"); - if (pos != std::string::npos) { - position = pos; - } - if (position != std::string::npos) { - if (position == 0) position = 1; - string bit = usfm.substr (position - 1, 10); - bit = filter::strings::replace ("\n", " ", bit); - add_result (translate ("New line within USFM:") + " " + bit, display_nothing); - } -} - - -void Checks_Usfm::marker_in_stylesheet () -{ - string marker = usfm_item.substr (1); - marker = filter::strings::trim (marker); - if (!filter::usfm::is_opening_marker (marker)) { - if (!marker.empty ()) marker = marker.substr (0, marker.length () - 1); - } - if (filter::usfm::is_embedded_marker (marker)) { - if (!marker.empty ()) marker = marker.substr (1); - } - if (marker.empty()) return; - if (in_array (marker, markers_stylesheet)) return; - add_result (translate ("Marker not in stylesheet"), Checks_Usfm::display_current); -} - - -void Checks_Usfm::malformed_id () -{ - string item = usfm_item.substr (0, 3); - string ide = usfm_item.substr (0, 4); - if (ide == R"(\ide)") return; - if (item == R"(\id)") { - string code = filter::usfm::peek_text_following_marker (usfm_markers_and_text, usfm_markers_and_text_pointer); - string sid = code.substr (0, 3); - vector vid = filter::strings::explode (code, ' '); - string id {}; - if (!vid.empty ()) id = vid [0]; - book_id book = database::books::get_id_from_usfm (id); - if (book == book_id::_unknown) { - add_result (translate ("Unknown ID"), display_full); - } else { - if (filter::strings::unicode_string_uppercase (id) != id) { - add_result (translate ("ID is not in uppercase"), display_full); - } - } - } -} - - -void Checks_Usfm::forward_slash (const string & usfm) -{ - string code = filter::strings::replace ("\n", " ", usfm); - size_t pos = code.find ("/"); - string bit {}; - if (pos != std::string::npos) { - size_t pos2 = code.find (" ", pos); - if (pos2 != std::string::npos) { - bit = code.substr (pos, pos2 - pos); - } else { - bit = code.substr (pos, 100); - } - pos2 = bit.find ("*"); - if (pos2 != std::string::npos) { - bit = bit.substr (0, pos2); - } - string marker = bit.substr (1, 100); - if (find (markers_stylesheet.begin(), markers_stylesheet.end(), marker) != markers_stylesheet.end ()) { - add_result (translate ("Forward slash instead of backslash:") + " " + bit, display_nothing); - } - } -} - - -void Checks_Usfm::widow_back_slash () -{ - string marker = usfm_item; - marker = filter::strings::trim (marker); - if (marker.length() == 1) { - add_result (translate ("Widow backslash"), display_current); - } -} - - -void Checks_Usfm::matching_endmarker () -{ - string marker = usfm_item; - // Remove the initial backslash, e.g. '\add' becomes 'add'. - marker = marker.substr (1); - marker = filter::strings::trim (marker); - bool isOpener = filter::usfm::is_opening_marker (marker); - if (!isOpener) { - if (!marker.empty ()) marker = marker.substr (0, marker.length () - 1); - } - if (!in_array (marker, markers_requiring_endmarkers)) return; - if (isOpener) { - if (in_array (marker, open_matching_markers)) { - add_result (translate ("Repeating opening marker"), Checks_Usfm::display_current); - } else { - open_matching_markers.push_back (marker); - } - } else { - if (in_array (marker, open_matching_markers)) { - open_matching_markers = filter::strings::array_diff (open_matching_markers, {marker}); - } else { - add_result (translate ("Closing marker does not match opening marker") + " " + filter::strings::implode (open_matching_markers, " "), display_current); - } - } -} - - -void Checks_Usfm::embedded_marker () -{ - // The marker, e.g. '\add'. - string marker = usfm_item; - - // Remove the initial backslash, e.g. '\add' becomes 'add'. - marker = marker.substr (1); - marker = filter::strings::trim (marker); - - bool isOpener = filter::usfm::is_opening_marker (marker); - - // Clean a closing marker, e.g. '\add*' becomes '\add'. - if (!isOpener) { - if (!marker.empty ()) marker = marker.substr (0, marker.length () - 1); - } - - // If the marker is not relevant for this check, bail out. - if (!in_array (marker, embeddable_markers)) return; - - // Checking method is as follows: - // If there's no open embeddable markers, then the '+' sign is not needed. - // If there's open embeddable markers, and another marker is opened, - // then the '+' sign is needed. - // Example USFM: - // \v 1 This \add is an \+w embedded\+w* marker\add*. - // See the following URL for more information about embedding markers: - // https://ubsicap.github.io/usfm/characters/nesting.html - - bool checkEmbedding = false; - if (isOpener) { - if (!in_array (marker, open_embeddable_markers)) { - if (!open_embeddable_markers.empty ()) { - checkEmbedding = true; - } - open_embeddable_markers.push_back (marker); - } - } else { - if (in_array (marker, open_embeddable_markers)) { - open_embeddable_markers = filter::strings::array_diff (open_embeddable_markers, {marker}); - if (!open_embeddable_markers.empty ()) { - checkEmbedding = true; - } - } - } - - if (checkEmbedding) { - if (marker.substr (0, 1) != "+") { - add_result (translate ("Embedded marker requires a plus sign"), display_full); - } - } -} - - -void Checks_Usfm::toc (string usfm) -{ - // Only check the 66 canonical books. - // Skip any of the other books. - book_type type = database::books::get_type (static_cast(book_number)); - if ((type == book_type::old_testament) || (type == book_type::new_testament)) { - - // Check on the presence of the table of contents markers in this chapter. - bool toc1_present = usfm.find (filter::usfm::get_opening_usfm (long_toc1_marker)) != std::string::npos; - bool toc2_present = usfm.find (filter::usfm::get_opening_usfm (short_toc2_marker)) != std::string::npos; - bool toc3_present = usfm.find (filter::usfm::get_opening_usfm (abbrev_toc3_marker)) != std::string::npos; - - // The markers should be on chapter 0 only. - if (chapter_number == 0) { - // Required: \toc1 - if (!toc1_present) { - add_result (translate ("The book lacks the marker for the verbose book name:") + " " + filter::usfm::get_opening_usfm (long_toc1_marker), display_nothing); - } - // Required: \toc2 - if (!toc2_present) { - add_result (translate ("The book lacks the marker for the short book name:") + " " + filter::usfm::get_opening_usfm (short_toc2_marker), display_nothing); - } - } else { - string msg = translate ("The following marker belongs in chapter 0:") + " "; - // Required markers. - if (toc1_present) { - add_result (msg + filter::usfm::get_opening_usfm (long_toc1_marker), display_nothing); - } - if (toc2_present) { - add_result (msg + filter::usfm::get_opening_usfm (short_toc2_marker), display_nothing); - } - // Optional markers, but should not be anywhere else except in chapter 0. - if (toc3_present) { - add_result (msg + filter::usfm::get_opening_usfm (abbrev_toc3_marker), display_nothing); - } - } - } -} - - -void Checks_Usfm::figure () -{ - if (usfm_item == R"(\fig )") { - string usfm = filter::usfm::peek_text_following_marker (usfm_markers_and_text, usfm_markers_and_text_pointer); - string caption, alt, src, size, loc, copy, ref; - filter::usfm::extract_fig (usfm, caption, alt, src, size, loc, copy, ref); - if (src.empty()) { - add_result (translate ("Empty figure source:") + " " + usfm, display_nothing); - } else { - Database_BibleImages database_bibleimages; - string image_contents = database_bibleimages.get (src); - if (image_contents.empty()) { - add_result (translate ("Could not find Bible image:") + " " + src, display_nothing); - } - } - size_t pos = usfm.find("“"); - if (pos != std::string::npos) { - add_result (translate ("Unusual quotation mark found:") + " " + usfm, display_nothing); - } - } -} - - -vector > Checks_Usfm::get_results () -{ - return checking_results; -} - - -void Checks_Usfm::add_result (string text, int modifier) -{ - string current = usfm_item; - string next = filter::usfm::peek_text_following_marker (usfm_markers_and_text, usfm_markers_and_text_pointer); - next = next.substr (0, 20); - switch (modifier) { - case display_nothing: - break; - case display_current: - text += ": " + current; - break; - case display_next: - text += ": " + next; - break; - case Checks_Usfm::display_full: - text += ": " + current + next; - break; - default: - break; - } - checking_results.push_back (pair (verse_number, text)); -} - - -// Checks on markup without intervening text. -void Checks_Usfm::empty_markup () -{ - // Get the current item (markup or text). - string current_item = usfm_item; - - // Flags that will describe the current item. - // bool current_is_text = false; - // bool current_is_usfm = false; - // bool current_is_opener = false; - bool current_is_closer {false}; - // bool current_is_embedded = false; - - // Flags that will describe the previous item. - // bool previous_is_text = false; - // bool previous_is_usfm = false; - bool previous_is_opener {false}; - // bool previous_is_closer = false; - // bool previous_is_embedded = false; - - // Set the above set of flags. - if (filter::usfm::is_usfm_marker (current_item)) { - //current_is_usfm = true; - if (filter::usfm::is_opening_marker(current_item)) { - //current_is_opener = true; - } - else current_is_closer = true; - //if (usfm_is_embedded_marker(current_item)) current_is_embedded = true; - } else { - //current_is_text = true; - } - if (filter::usfm::is_usfm_marker (empty_markup_previous_item)) { - //previous_is_usfm = true; - if (filter::usfm::is_opening_marker(empty_markup_previous_item)) previous_is_opener = true; - //else previous_is_closer = true; - //if (usfm_is_embedded_marker(empty_markup_previous_item)) previous_is_embedded = true; - } else { - //previous_is_text = true; - } - - // Flag the following situation: - // An opener is followed by a closer without intervening text. - if (previous_is_opener && current_is_closer) { - add_result (translate ("Opening markup is followed by closing markup without intervening text:") + " " + empty_markup_previous_item + current_item, Checks_Usfm::display_nothing); - } - - // Save the current item (markup or text) into the object for next iteration. - empty_markup_previous_item = current_item; -} - - -// Flags a otherwise correctly formed footnote or cross reference that is blank -// Such a note has no content but has (all of) the markers. -void Checks_Usfm::note () -{ - // Flags that describe the current item. - bool current_is_text {false}; - //bool current_is_usfm = false; - bool current_is_opener {false}; - bool current_is_closer {false}; - //bool current_is_embedded = false; - if (filter::usfm::is_usfm_marker (usfm_item)) { - //current_is_usfm = true; - if (filter::usfm::is_opening_marker(usfm_item)) current_is_opener = true; - else current_is_closer = true; - //if (usfm_is_embedded_marker(usfm_item)) current_is_embedded = true; - } else { - current_is_text = true; - } - - // If the current item is text, then do no further checks on that. - if (current_is_text) return; - // From here on it is assumed that the current item is USFM, not text. - - // Get the plain marker, e.g. '\f ' becomes "f". - string current_marker = filter::usfm::get_marker (usfm_item); - - // Get this style's properties. - Database_Styles_Item style = style_items [current_marker]; - - // Set a flag if this USFM starts a footnote or an endnote or a crossreference. - // Clear this flag if it ends the note or xref. - bool note_border_marker {false}; - if (style.type == StyleTypeFootEndNote) { - if (style.subtype == FootEndNoteSubtypeFootnote) note_border_marker = true; - if (style.subtype == FootEndNoteSubtypeEndnote) note_border_marker = true; - } - if (style.type == StyleTypeCrossreference) { - if (style.subtype == CrossreferenceSubtypeCrossreference) note_border_marker = true; - } - if (note_border_marker) { - if (current_is_opener) within_note = true; - if (current_is_closer) within_note = false; - } - - // If the current location is not within a footnote / endnote / cross reference, - // then there is nothing to check for. - if (!within_note) return; - - // Get the next item, that is the item following the current item. - string next_item = filter::usfm::peek_text_following_marker (usfm_markers_and_text, usfm_markers_and_text_pointer); - - // Flags that describe the next item. - bool next_is_text {false}; - //bool next_is_usfm = false; - //bool next_is_opener = false; - //bool next_is_closer = false; - //bool next_is_embedded = false; - if (filter::usfm::is_usfm_marker (next_item)) { - //next_is_usfm = true; - //if (usfm_is_opening_marker(next_item)) next_is_opener = true; - //else next_is_closer = true; - //if (usfm_is_embedded_marker(next_item)) next_is_embedded = true; - } else { - next_is_text = true; - } - - // Change, e.g. '\f ' to '\f'. - // Remove the initial backslash, e.g. '\f' becomes 'f'. - string next_marker = filter::usfm::get_marker(next_item); - - // If the current item is opening markup ... - if (!current_is_opener) return; - // ... and not requiring an endmarker ... - if (in_array(current_marker, markers_requiring_endmarkers)) return; - // then the following item should be one of these: - // - a text item - if (next_is_text) return; - // - a marker requiring an endmarker, like e.g. \add - if (in_array(next_marker, markers_requiring_endmarkers)) return; - - // It has not passed the text for a correctly formatted note. - // So add a message. - add_result (translate ("This sequence in the note does not look right:") + " " + usfm_item + next_item, display_nothing); -} - - -/* - - The official usfm.sty from paratext.org shows where each marker occurs under. - That could be used to do a mechanical check on the position of the various markers. - But this is not implemented just now - because it is not the purpose of Bibledit to exactly check every aspect of USFM. - Rather Bibledit checks some important issues that may occur in daily USFM editing. - Checking every aspect of USFM is a bit of an overkill. - -*/ diff --git a/checks/usfm.h b/checks/usfm.h deleted file mode 100644 index 9d3d17473..000000000 --- a/checks/usfm.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include - -class Checks_Usfm -{ -public: - Checks_Usfm (const std::string & bible); - void initialize (int book, int chapter); - void finalize (); - void check (const std::string & usfm); - std::vector > get_results (); -private: - // USFM and text. - std::vector usfm_markers_and_text {}; - unsigned int usfm_markers_and_text_pointer {0}; - std::string usfm_item {}; - int book_number {0}; - int chapter_number {0}; - int verse_number {0}; - - // Results of the checks. - std::vector > checking_results {}; - static constexpr int display_nothing {0}; - static constexpr int display_current {1}; - static constexpr int display_next {2}; - static constexpr int display_full {3}; - - // Stylesheet. - std::vector markers_stylesheet {}; - std::map style_items {}; - - // Matching markers. - std::vector markers_requiring_endmarkers {}; - std::vector open_matching_markers {}; - - // Embedded markers. - std::vector embeddable_markers {}; - std::vector open_embeddable_markers {}; - - // Table of contents markers and flags. - std::string long_toc1_marker {}; - std::string short_toc2_marker {}; - std::string abbrev_toc3_marker {}; - - // Empty markup checking. - std::string empty_markup_previous_item {}; - - // Empty note checking. - bool within_note {false}; - - // Methods. - void malformed_verse_number (); - void new_line_in_usfm (const std::string & usfm); - void marker_in_stylesheet (); - void malformed_id (); - void forward_slash (const std::string & usfm); - void widow_back_slash (); - void matching_endmarker (); - void embedded_marker (); - void toc (std::string usfm); - void figure (); - void add_result (std::string text, int modifier); - void empty_markup (); - void note (); -}; diff --git a/checks/verses.cpp b/checks/verses.cpp deleted file mode 100644 index d7a3ae806..000000000 --- a/checks/verses.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void checks_verses::missing_punctuation_at_end (const string & bible, int book, int chapter, - const map & verses, - const string & center_marks, const string & end_marks, - const string & disregards) -{ - const vector centermarks = filter::strings::explode (center_marks, ' '); - const vector endmarks = filter::strings::explode (end_marks, ' '); - const vector ignores = filter::strings::explode (disregards, ' '); - Database_Check database_check {}; - for (const auto & element : verses) { - int verse = element.first; - string text = element.second; - if (verse == 0) continue; - if (text.empty ()) continue; - for (const auto & ignore_text : ignores) { - text = filter::strings::replace (ignore_text, string(), text); - } - const size_t text_length = filter::strings::unicode_string_length (text); - const string lastCharacter = filter::strings::unicode_string_substr (text, text_length - 1, 1); - if (in_array (lastCharacter, centermarks)) continue; - if (in_array (lastCharacter, endmarks)) continue; - database_check.recordOutput (bible, book, chapter, verse, translate ("No punctuation at end of verse:") + " " + lastCharacter); - } -} - - -void checks_verses::patterns (const string & bible, int book, int chapter, - const map & verses, const vector & patterns) -{ - Database_Check database_check {}; - for (const auto & element : verses) { - const int verse = element.first; - const string text = element.second; - for (const auto & pattern : patterns) { - if (pattern.empty ()) continue; - if (text.find (pattern) != std::string::npos) { - database_check.recordOutput (bible, book, chapter, verse, translate ("Pattern found in text:") + " " + pattern); - } - } - } -} diff --git a/checks/verses.h b/checks/verses.h deleted file mode 100644 index 981ca89b0..000000000 --- a/checks/verses.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -namespace checks_verses { - -void missing_punctuation_at_end (const std::string & bible, int book, int chapter, - const std::map & verses, - const std::string & center_marks, const std::string & end_marks, - const std::string & disregards); -void patterns (const std::string & bible, int book, int chapter, - const std::map & verses, const std::vector & patterns); - -} diff --git a/checks/versification.cpp b/checks/versification.cpp deleted file mode 100644 index 937d0c93c..000000000 --- a/checks/versification.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -void checks_versification::books (const string & bible, const vector & books) -{ - Database_Versifications database_versifications {}; - string versification = Database_Config_Bible::getVersificationSystem (bible); - if (versification.empty ()) versification = filter::strings::english (); - const vector standardBooks = database_versifications.getBooks (versification); - const vector absentBooks = filter::strings::array_diff (standardBooks, books); - const vector extraBooks = filter::strings::array_diff (books, standardBooks); - Database_Check database_check {}; - for (auto book : absentBooks) { - database_check.recordOutput (bible, book, 1, 1, translate ("This book is absent from the Bible")); - } - for (auto book : extraBooks) { - database_check.recordOutput (bible, book, 1, 1, translate ("This book is extra in the Bible")); - } -} - - -void checks_versification::chapters (const string & bible, int book, const vector & chapters) -{ - Database_Versifications database_versifications {}; - string versification = Database_Config_Bible::getVersificationSystem (bible); - if (versification.empty ()) versification = filter::strings::english (); - const vector standardChapters = database_versifications.getChapters (versification, book, true); - const vector absentChapters = filter::strings::array_diff (standardChapters, chapters); - const vector extraChapters = filter::strings::array_diff (chapters, standardChapters); - Database_Check database_check {}; - for (auto chapter : absentChapters) { - database_check.recordOutput (bible, book, chapter, 1, translate ("This chapter is missing")); - } - for (auto chapter : extraChapters) { - database_check.recordOutput (bible, book, chapter, 1, translate ("This chapter is extra")); - } -} - - -void checks_versification::verses (const string & bible, int book, int chapter, const vector & verses) -{ - // Get verses in this chapter according to the versification system for the Bible. - Database_Versifications database_versifications {}; - string versification = Database_Config_Bible::getVersificationSystem (bible); - if (versification.empty ()) versification = filter::strings::english (); - const vector standardVerses = database_versifications.getVerses (versification, book, chapter); - // Look for missing and extra verses. - const vector absentVerses = filter::strings::array_diff (standardVerses, verses); - const vector extraVerses = filter::strings::array_diff (verses, standardVerses); - Database_Check database_check {}; - for (auto verse : absentVerses) { - database_check.recordOutput (bible, book, chapter, verse, translate ("This verse is missing according to the versification system")); - } - for (auto verse : extraVerses) { - //if ((chapter == 0) && (verse == 0)) continue; - database_check.recordOutput (bible, book, chapter, verse, translate ("This verse is extra according to the versification system")); - } - // Look for verses out of order. - int previousVerse {0}; - for (size_t i = 0; i < verses.size(); i++) { - int verse = verses[i]; - if (i > 0) { - if (verse != (previousVerse + 1)) { - database_check.recordOutput (bible, book, chapter, verse, translate ("The verse is out of sequence")); - } - } - previousVerse = verse; - } -} diff --git a/checks/versification.h b/checks/versification.h deleted file mode 100644 index e23e58ecb..000000000 --- a/checks/versification.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -namespace checks_versification { - -void books (const std::string & bible, const std::vector & books); -void chapters (const std::string & bible, int book, const std::vector & chapters); -void verses (const std::string & bible, int book, int chapter, const std::vector & verses); - -} diff --git a/checksum/logic.cpp b/checksum/logic.cpp deleted file mode 100644 index b610684f1..000000000 --- a/checksum/logic.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -using namespace std; - - -// This function reads $data, -// calculates a checksum, -// adds $readwrite, -// and returns the result as follows: -// The first line contains the checksum. -// The second line contains the readwrite as 0 or 1. -// The rest contains the $data. -string checksum_logic::send (const string & data, bool readwrite) -{ - string checksum = get (data); - checksum.append ("\n"); - checksum.append (filter::strings::convert_to_string (readwrite)); - checksum.append ("\n"); - checksum.append (data); - return checksum; -} - - -// This function gets the checksum for $data, and returns it. -// It calculates the length of 'data' in bytes. -string checksum_logic::get (const string & data) -{ - return filter::strings::convert_to_string (data.length ()); -} - - -// This function gets the checksum for $data, and returns it. -// It calculates the length of vector 'data' in bytes. -string checksum_logic::get (const vector & data) -{ - int length = 0; - for (auto & bit : data) length += static_cast(bit.length ()); - return filter::strings::convert_to_string (length); -} - - -// Returns a proper checksum for the USFM in the chapter. -string checksum_logic::get_chapter (Webserver_Request& webserver_request, const string & bible, int book, int chapter) -{ - string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - string checksum = md5 (filter::strings::trim (usfm)); - return checksum; -} - - -// Returns a proper checksum for the USFM in the book. -string checksum_logic::get_book (Webserver_Request& webserver_request, const string & bible, int book) -{ - vector chapters = webserver_request.database_bibles()->get_chapters (bible, book); - vector checksums; - for (auto chapter : chapters) { - checksums.push_back (get_chapter (webserver_request, bible, book, chapter)); - } - string checksum = filter::strings::implode (checksums, string()); - checksum = md5 (checksum); - return checksum; -} - - -// Returns a proper checksum for the USFM in the $bible. -string checksum_logic::get_bible (Webserver_Request& webserver_request, const string & bible) -{ - vector books = webserver_request.database_bibles()->get_books (bible); - vector checksums; - for (auto book : books) { - checksums.push_back (get_book (webserver_request, bible, book)); - } - string checksum = filter::strings::implode (checksums, string()); - checksum = md5 (checksum); - return checksum; -} - - -// Returns a proper checksum for the USFM in the array of $bibles. -string checksum_logic::get_bibles (Webserver_Request& webserver_request, const vector & bibles) -{ - vector checksums; - for (const auto & bible : bibles) { - checksums.push_back (get_bible (webserver_request, bible)); - } - string checksum = filter::strings::implode (checksums, string()); - checksum = md5 (checksum); - return checksum; -} - diff --git a/checksum/logic.h b/checksum/logic.h deleted file mode 100644 index dbdc45035..000000000 --- a/checksum/logic.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -namespace checksum_logic { - -std::string send (const std::string & data, bool readwrite); -std::string get (const std::string & data); -std::string get (const std::vector & data); -std::string get_chapter (Webserver_Request& webserver_request, const std::string & bible, int book, int chapter); -std::string get_book (Webserver_Request& webserver_request, const std::string & bible, int book); -std::string get_bible (Webserver_Request& webserver_request, const std::string & bible); -std::string get_bibles (Webserver_Request& webserver_request, const std::vector & bibles); - -}; diff --git a/classes/merge.h b/classes/merge.h deleted file mode 100644 index 56e340009..000000000 --- a/classes/merge.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -struct Merge_Conflict -{ -public: - std::string base {}; - std::string change {}; - std::string prioritized_change {}; - std::string result {}; - std::string subject {}; - // The following shows the passage where the conflict occurred. - int book {0}; - int chapter {0}; -}; diff --git a/client/index.cpp b/client/index.cpp deleted file mode 100644 index e117c9f11..000000000 --- a/client/index.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string client_index_url () -{ - return "client/index"; -} - - -bool client_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::member ()); -} - - -void client_index_remove_all_users (Webserver_Request& webserver_request) -{ - const std::vector existing_users {webserver_request.database_users()->get_users ()}; - for (const auto& existing_user : existing_users) { - webserver_request.database_users()->removeUser (existing_user); - } -} - - -void client_index_enable_client (Webserver_Request& webserver_request, const std::string& username, const std::string& password, const int level) -{ - // Enable client mode upon a successful connection. - client_logic_enable_client (true); - - // Remove all users from the database, and add the current one. - client_index_remove_all_users (webserver_request); - webserver_request.database_users ()->add_user (username, password, level, std::string()); - - // Update the username and the level in the current session. - webserver_request.session_logic ()->set_username (username); - webserver_request.session_logic ()->currentLevel (true); - - // If there's pending Bible updates, send them off to the user. - bible_logic::client_mail_pending_bible_updates (username); - - // Clear all pending note actions and Bible actions and settings updates. - Database_NoteActions database_noteactions; - Database_BibleActions database_bibleactions; - database_noteactions.clear (); - database_noteactions.create (); - database_bibleactions.clear (); - database_bibleactions.create (); - webserver_request.session_logic ()->set_username (username); - webserver_request.database_config_user()->setUpdatedSettings ({}); - Database_Config_General::setUnsentBibleDataTime (0); - Database_Config_General::setUnreceivedBibleDataTime (filter::date::seconds_since_epoch ()); - - // Set flag for first run after connecting. - Database_Config_General::setJustConnectedToCloud (true); - - // Set it to repeat sync every so often. - if (Database_Config_General::getRepeatSendReceive () == 0) { - Database_Config_General::setRepeatSendReceive (2); - } - - // Schedule a sync operation straightaway. - sendreceive_queue_sync (-1, 0); -} - - -std::string client_index (Webserver_Request& webserver_request) -{ - Assets_View view {}; - - if (webserver_request.query.count ("disable")) { - client_logic_enable_client (false); - client_index_remove_all_users (webserver_request); - Database_Config_General::setRepeatSendReceive (0); - Database_Config_General::setUnsentBibleDataTime (0); - Database_Config_General::setUnreceivedBibleDataTime (0); - Database_Config_General::setJustConnectedToCloud (false); - } - - bool connect = webserver_request.post.count ("connect"); - bool demo = webserver_request.query.count ("demo"); - if (connect || demo) { - - bool proceed {true}; - - std::string address {}; - if (proceed) address = webserver_request.post ["address"]; - if (demo) address = demo_address (); - // If there's not something like "http" in the server address, then add it. - if (address.find ("http") == std::string::npos) - address = filter_url_set_scheme (address, false); - if (proceed) { - // Get schema, host and port. - std::string scheme {}; - std::string host {}; - int port {0}; - filter_url_get_scheme_host_port (address, scheme, host, port); - // If no address given, then that's an error. - if (proceed) if (host.empty()) { - view.set_variable ("error", translate ("Supply an internet address")); - proceed = false; - } - // If the user entered a port number here too, then that's an error. - if (proceed) if (port > 0) { - view.set_variable ("error", translate ("Remove the port number from the internet address")); - proceed = false; - } - } - // Store the address. - Database_Config_General::setServerAddress (address); - - int port = filter::strings::convert_to_int (config::logic::http_network_port ()); - if (proceed) port = filter::strings::convert_to_int (webserver_request.post ["port"]); - if (demo) port = demo_port (); - if (proceed) if (port == 0) { - view.set_variable ("error", translate ("Supply a port number")); - proceed = false; - } - Database_Config_General::setServerPort (port); - - std::string user {}; - if (proceed) user = webserver_request.post ["user"]; - if (demo) user = session_admin_credentials (); - if (proceed) if (user.empty()) { - view.set_variable ("error", translate ("Supply a username")); - proceed = false; - } - - std::string pass {}; - if (proceed) pass = webserver_request.post ["pass"]; - if (demo) pass = session_admin_credentials (); - if (proceed) if (pass.empty()) { - view.set_variable ("error", translate ("Supply a password")); - proceed = false; - } - - if (proceed) { - const std::string response = client_logic_connection_setup (user, md5 (pass)); - const int iresponse = filter::strings::convert_to_int (response); - if ((iresponse >= Filter_Roles::guest ()) && (iresponse <= Filter_Roles::admin ())) { - // Enable client mode upon a successful connection. - client_index_enable_client (webserver_request, user, pass, iresponse); - // Feedback. - view.set_variable ("success", translate("Connection is okay.")); - } else { - view.set_variable ("error", translate ("Could not create a connection with Bibledit Cloud") + ": " + response); - } - } - } - - if (client_logic_client_enabled ()) view.enable_zone ("clienton"); - else view.enable_zone ("clientoff"); - - const std::string address {Database_Config_General::getServerAddress ()}; - view.set_variable ("address", address); - - const int port {Database_Config_General::getServerPort ()}; - view.set_variable ("port", filter::strings::convert_to_string (port)); - - view.set_variable ("url", client_logic_link_to_cloud ("", "")); - - const std::vector users {webserver_request.database_users ()->get_users ()}; - for (const auto& user : users) { - const int level = webserver_request.database_users()->get_level (user); - view.set_variable ("role", Filter_Roles::text (level)); - } - - view.set_variable ("demo", demo_client_warning ()); - - view.set_variable ("external", assets_external_logic_link_addon ()); - - if (webserver_request.query.count ("info")) { - view.enable_zone ("info"); - } - - const bool basic_mode {config::logic::basic_mode (webserver_request)}; - if (basic_mode) view.enable_zone("basicmode"); - - std::string page {}; - - // Since the role of the user may change after a successful connection to the server, - // the menu generation in the header should be postponed till when the actual role is known. - page = assets_page::header (translate ("Server"), webserver_request); - - page += view.render ("client", "index"); - - page += assets_page::footer (); - - return page; -} diff --git a/client/index.h b/client/index.h deleted file mode 100644 index 9be10d838..000000000 --- a/client/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string client_index_url (); -bool client_index_acl (Webserver_Request& webserver_request); -std::string client_index (Webserver_Request& webserver_request); diff --git a/client/logic.cpp b/client/logic.cpp deleted file mode 100644 index 8180e5d7c..000000000 --- a/client/logic.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Returns whether Client mode is enabled. -bool client_logic_client_enabled () -{ -#ifndef HAVE_CLIENT - return false; -#endif - return Database_Config_General::getClientMode (); -} - - -// Sets the Client mode. -// $enable: boolean: true or false. -void client_logic_enable_client (bool enable) -{ - Database_Config_General::setClientMode (enable); -} - - -// Generates a URL for connecting to Bibledit Cloud. -// $address is the website. -// $port is the port number. -// $path is the path after the website. -string client_logic_url (const string & address, int port, const string & path) -{ - return address + ":" + filter::strings::convert_to_string (port) + "/" + path; -} - - -// This function does the initial connection from the client to the server. -// It receives settings from the server and applies them to the client. -// It returns the level of the user. -// It returns an empty string in case of failure or the response from the server. -string client_logic_connection_setup (string user, string hash) -{ - Database_Users database_users {}; - - if (user.empty ()) { - vector users = database_users.get_users (); - if (users.empty()) return string(); - user = users [0]; - hash = database_users.get_md5 (user); - } - - string encoded_user = filter::strings::bin2hex (user); - - string address = Database_Config_General::getServerAddress (); - int port = Database_Config_General::getServerPort (); - - string url = client_logic_url (address, port, sync_setup_url ()) + "?user=" + encoded_user + "&pass=" + hash; - - string error {}; - string response = filter_url_http_get (url, error, true); - int iresponse = filter::strings::convert_to_int (response); - - if ((iresponse >= Filter_Roles::guest ()) && (iresponse <= Filter_Roles::admin ())) { - // Set user's role on the client to be the same as on the server. - // Do this only when it differs, to prevent excessive database writes on the client. - int level = database_users.get_level (user); - if (iresponse != level) { - database_users.set_level (user, iresponse); - } - } else { - Database_Logs::log (error, Filter_Roles::translator ()); - // In case Bibledit Cloud requires the client to connect through https, - // and the client connects through http, - // it will give a response code 426 plus text. - // So in such a case clarify the meaning of that to the user. - // https://github.com/bibledit/cloud/issues/829. - string upgrade_required = filter_url_http_response_code_text (426); - size_t pos = error.find (upgrade_required); - if (pos != std::string::npos) { - // Since the error code ends without a full stop, add a full stop to it first. - error.append (". "); - // Add a good explanation to the error code so the user knows what to do if this error occurs. - error.append ("Bibledit Cloud requires the client to connect via the secure https protocol. The client now tried to connect through the insecure http protocol. If connected, please disconnect from Bibledit Cloud and connect again via https. Use the secure port number instead of the insecure port number. Usually the secure port number is the insecure port number plus one."); - Database_Logs::log (error, Filter_Roles::translator ()); - } - } - - if (response.empty ()) response = error; - return response; -} - - -string client_logic_create_note_encode (const string & bible, int book, int chapter, int verse, - const string & summary, const string & contents, bool raw) -{ - vector data {}; - data.push_back (bible); - data.push_back (filter::strings::convert_to_string (book)); - data.push_back (filter::strings::convert_to_string (chapter)); - data.push_back (filter::strings::convert_to_string (verse)); - data.push_back (summary); - data.push_back (filter::strings::convert_to_string (raw)); - data.push_back (contents); - return filter::strings::implode (data, "\n"); -} - - -void client_logic_create_note_decode (const string & data, - string& bible, int& book, int& chapter, int& verse, - string& summary, string& contents, bool& raw) -{ - vector lines = filter::strings::explode (data, '\n'); - if (!lines.empty ()) { - bible = lines [0]; - lines.erase (lines.begin()); - } - if (!lines.empty ()) { - book = filter::strings::convert_to_int (lines [0]); - lines.erase (lines.begin()); - } - if (!lines.empty ()) { - chapter = filter::strings::convert_to_int (lines [0]); - lines.erase (lines.begin()); - } - if (!lines.empty ()) { - verse = filter::strings::convert_to_int (lines [0]); - lines.erase (lines.begin()); - } - if (!lines.empty ()) { - summary = lines [0]; - lines.erase (lines.begin()); - } - if (!lines.empty ()) { - raw = filter::strings::convert_to_bool (lines [0]); - lines.erase (lines.begin()); - } - contents = filter::strings::implode (lines, "\n"); -} - - -// This provides a html link to Bibledit Cloud / $path. -// It displays the $linktext. -string client_logic_link_to_cloud (string path, string linktext) -{ - string url {}; - string external {}; - if (client_logic_client_enabled ()) { - string address = Database_Config_General::getServerAddress (); - int port = Database_Config_General::getServerPort (); - url = address + ":" + filter::strings::convert_to_string (port); - if (!path.empty ()) { - url.append ("/"); - url.append (path); - } - external = " " + assets_external_logic_link_addon (); - } else { - // Client disconnected: Provide the link and the text to connect to the Cloud. - url = "/" + client_index_url (); - linktext.append (" "); - linktext.append (translate("You are not yet connected to Bibledit Cloud.")); - linktext.append (" "); - linktext.append (translate("Connect.")); - } - - if (linktext.empty ()) { - // Empty link text: Select the link itself as the text to display. - linktext = url; - } - - stringstream link {}; - link << "" << linktext << ""; - return link.str(); -} - - -// Path to the file in the client files area that contains a list of USFM resources on the server. -string client_logic_usfm_resources_path () -{ - return filter_url_create_root_path ({database_logic_databases (), "client", "usfm_resources.txt"}); -} - - -void client_logic_usfm_resources_update () -{ - // The Cloud stores the list of USFM resources. - // It is stored in the client files area. - // Clients can access it from there. - string path = client_logic_usfm_resources_path (); - Database_UsfmResources database_usfmresources {}; - vector resources = database_usfmresources.getResources (); - filter_url_file_put_contents (path, filter::strings::implode (resources, "\n")); -} - - -vector client_logic_usfm_resources_get () -{ - string contents = filter_url_file_get_contents (client_logic_usfm_resources_path ()); - return filter::strings::explode (contents, '\n'); -} - - -string client_logic_get_username () -{ - // Set the user name to the first one in the database. - // Or if the database has no users, make the user admin. - // That happens when disconnected from the Cloud. - string user = session_admin_credentials (); - Database_Users database_users; - vector users = database_users.get_users (); - if (!users.empty()) user = users [0]; - return user; -} - - -string client_logic_no_cache_resources_path () -{ - return filter_url_create_root_path ({database_logic_databases (), "client", "no_cache_resources.txt"}); -} - - -void client_logic_no_cache_resources_save (vector resources) -{ - string contents = filter::strings::implode(resources, "\n"); - string path = client_logic_no_cache_resources_path (); - filter_url_file_put_contents(path, contents); -} - - -void client_logic_no_cache_resource_add (string name) -{ - vector resources = client_logic_no_cache_resources_get(); - if (in_array(name, resources)) return; - resources.push_back(name); - client_logic_no_cache_resources_save(resources); -} - - -void client_logic_no_cache_resource_remove (string name) -{ - vector resources = client_logic_no_cache_resources_get(); - if (!in_array(name, resources)) return; - resources = filter::strings::array_diff(resources, {name}); - client_logic_no_cache_resources_save(resources); -} - - -vector client_logic_no_cache_resources_get () -{ - string contents = filter_url_file_get_contents (client_logic_no_cache_resources_path()); - vector resources = filter::strings::explode(contents, "\n"); - return resources; -} diff --git a/client/logic.h b/client/logic.h deleted file mode 100644 index 840dc59d5..000000000 --- a/client/logic.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -bool client_logic_client_enabled (); -void client_logic_enable_client (bool enable); -std::string client_logic_url (const std::string & address, int port, const std::string & path); -std::string client_logic_connection_setup (std::string user, std::string hash); -std::string client_logic_create_note_encode (const std::string & bible, int book, int chapter, int verse, - const std::string & summary, const std::string & contents, bool raw); -void client_logic_create_note_decode (const std::string & data, - std::string& bible, int& book, int& chapter, int& verse, - std::string& summary, std::string& contents, bool& raw); -std::string client_logic_link_to_cloud (std::string path, std::string linktext); -std::string client_logic_usfm_resources_path (); -void client_logic_usfm_resources_update (); -std::vector client_logic_usfm_resources_get (); -std::string client_logic_get_username (); -std::string client_logic_no_cache_resources_path (); -void client_logic_no_cache_resource_add (std::string name); -void client_logic_no_cache_resource_remove (std::string name); -std::vector client_logic_no_cache_resources_get (); diff --git a/collaboration/index.cpp b/collaboration/index.cpp deleted file mode 100644 index e41ab5c8d..000000000 --- a/collaboration/index.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string collaboration_index_url () -{ - return "collaboration/index"; -} - - -bool collaboration_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::admin ()); -} - - -std::string collaboration_index (Webserver_Request& webserver_request) -{ - std::string page {}; - Assets_Header header = Assets_Header (translate("Repository"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - page = header.run (); - Assets_View view; - - -#ifdef HAVE_CLOUD - - - std::string object = webserver_request.query ["object"]; - if (webserver_request.query.count ("select")) { - const std::string& select = webserver_request.query["select"]; - if (select.empty()) { - Dialog_List dialog_list = Dialog_List ("index", translate("Which Bible are you going to use?"), "", ""); - dialog_list.add_query ("object", object); - const std::vector & bibles = webserver_request.database_bibles()->get_bibles(); - for (const auto& value : bibles) { - dialog_list.add_row (value, "select", value); - } - page += dialog_list.run (); - return page; - } else { - object = select; - } - } - view.set_variable ("object", object); - if (!object.empty ()) view.enable_zone ("objectactive"); - - - const std::string& repositoryfolder = filter_git_directory (object); - - - if (webserver_request.query.count ("disable")) { - Database_Config_Bible::setRemoteRepositoryUrl (object, ""); - filter_url_rmdir (repositoryfolder); - } - const std::string& url = Database_Config_Bible::getRemoteRepositoryUrl (object); - view.set_variable ("url", url); - if (url.empty ()) { - view.enable_zone ("urlinactive"); - } else { - view.enable_zone ("urlactive"); - } - - - // Get the status of the git repository. - // This could have been done through the following: - // vector statuslines = filter_git_status (repositoryfolder); - // But this function does not capture standard error. - // And the standard error output is needed in case of failures. - // So the following is used instead. - if (!object.empty ()) { - std::string statusoutput, statuserror; - filter_shell_run (repositoryfolder, "git", {"status"}, &statusoutput, &statuserror); - view.set_variable ("status", statusoutput + " " + statuserror); - } - - -#endif - - - page += view.render ("collaboration", "index"); - page += assets_page::footer (); - return page; -} diff --git a/collaboration/index.h b/collaboration/index.h deleted file mode 100644 index 1f6ef2cfa..000000000 --- a/collaboration/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string collaboration_index_url (); -bool collaboration_index_acl (Webserver_Request& webserver_request); -std::string collaboration_index (Webserver_Request& webserver_request); diff --git a/collaboration/link.cpp b/collaboration/link.cpp deleted file mode 100644 index 88f5d68a7..000000000 --- a/collaboration/link.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -void collaboration_link ([[maybe_unused]] const std::string& object, - [[maybe_unused]] const int jobid, - [[maybe_unused]] const std::string& direction) -{ -#ifdef HAVE_CLOUD - // Repository details for local and remote. - const std::string& url = Database_Config_Bible::getRemoteRepositoryUrl (object); - const std::string& path = filter_git_directory (object); - bool result = true; - std::vector success {}; - std::string error {}; - const bool take_me = (direction == "bibledit"); - const bool take_repo = (direction == "repository"); - - Database_Jobs database_jobs {}; - - // Generate the initial page. - std::string page = collaboration_link_header (); - Assets_View view {}; - view.set_variable ("object", object); - view.set_variable ("url", url); - if (take_me) view.enable_zone ("takeme"); - if (take_repo) view.enable_zone ("takerepo"); - page.append (view.render ("collaboration", "link")); - database_jobs.set_start (jobid, page); - - // Some checks on input values. - if (result) { - if (object.empty ()) { - error = translate ("No Bible given"); - result = false; - } - } - if (result) { - if (!take_me && !take_repo) { - error = translate ("It is unclear which data to copy to where"); - result = false; - } - } - - // Try read access. - database_jobs.set_progress (jobid, translate ("Reading")); - result = filter_git_remote_read (url, error); - if (result) { - success.push_back (translate("Read access to the repository is successful.")); - } else { - error.append (" " + translate ("Read access failed.")); - } - database_jobs.set_percentage (jobid, 8); - - // Clone the remote repository, with feedback about progress. - database_jobs.set_progress (jobid, translate ("Cloning")); - if (result) { - success.push_back (translate("Copy repository to Bibledit")); - result = filter_git_remote_clone (url, path, jobid, error); - } - database_jobs.set_percentage (jobid, 16); - - // Set some configuration values. - database_jobs.set_progress (jobid, translate ("Configuring")); - if (result) { - success.push_back (translate ("Configure copied data")); - filter_git_config (path); - } - database_jobs.set_percentage (jobid, 24); - - // Store a temporal file for trying whether Bibledit has write access. - database_jobs.set_progress (jobid, translate ("Writing")); - const std::string& temporal_file_name = filter_url_create_path ({path, "test_repository_writable"}); - if (result) { - filter_url_file_put_contents (temporal_file_name, "contents"); - } - database_jobs.set_percentage (jobid, 32); - - // Add this file. - if (result) { - result = filter_git_add_remove_all (path, error); - if (result) { - success.push_back (translate("A file was added to the data successfully.")); - } else { - error.append (" " + translate("Failure adding a file to the data.")); - } - } - database_jobs.set_percentage (jobid, 40); - - // Commit the file locally. - database_jobs.set_progress (jobid, translate ("Committing")); - if (result) { - std::vector messages {}; - result = filter_git_commit (path, "", "Write test 1", messages, error); - if (result) { - success.push_back (translate("The file was committed successfully.")); - } else { - error.append (" " + translate("Failure committing the file.")); - } - } - database_jobs.set_percentage (jobid, 48); - - // Pull changes from the remote repository. - // We cannot look at the exit code here in case the repository is empty, - // because in such cases the exit code is undefined. - database_jobs.set_progress (jobid, translate ("Pulling")); - if (result) { - std::vector messages {}; - filter_git_pull (path, messages); - success.insert (success.end(), messages.begin(), messages.end()); - success.push_back (translate("Changes were pulled from the repository successfully.")); - } - database_jobs.set_percentage (jobid, 56); - - // Push the changes to see if there is write access. - // The --all switch is needed for when the remote repository is empty. - database_jobs.set_progress (jobid, translate ("Pushing")); - if (result) { - std::vector messages {}; - result = filter_git_push (path, messages, true); - success.insert (success.end(), messages.begin(), messages.end()); - if (result) { - success.push_back (translate("Changes were pushed to the repository successfully.")); - } else { - error.append (" " + translate("Pushing changes to the repository failed.")); - } - } - database_jobs.set_percentage (jobid, 64); - - // Remove the temporal file from the cloned repository. - database_jobs.set_progress (jobid, translate ("Cleaning")); - filter_url_unlink (temporal_file_name); - if (result) { - result = filter_git_add_remove_all (path, error); - if (result) { - success.push_back (translate("The temporal file was removed from the data successfully.")); - } else { - error.append (" " + translate("Failure removing the temporal file from the data.")); - } - } - if (result) { - std::vector messages {}; - result = filter_git_commit (path, "", "Write test 2", messages, error); - if (result) { - success.push_back (translate("The removed temporal file was committed successfully.")); - } else { - error.append (" " + translate("Failure committing the removed temporal file.")); - } - } - database_jobs.set_percentage (jobid, 72); - - // Push changes to the remote repository. - database_jobs.set_progress (jobid, translate ("Pushing")); - if (result) { - std::vector messages {}; - result = filter_git_push (path, messages); - success.insert (success.end(), messages.begin(), messages.end()); - if (result) { - success.push_back (translate("The changes were pushed to the repository successfully.")); - } else { - error.append (" " + translate("Pushing changes to the repository failed.")); - } - } - database_jobs.set_percentage (jobid, 80); - - // If so requested by the user, - // copy the data from the local cloned repository, - // and store it in Bibledit's Bible given in $object, - // overwriting the whole Bible that was there before. - database_jobs.set_progress (jobid, translate ("Copying")); - if (take_repo && result) { - success.push_back (translate ("Copying the data from the repository and storing it in Bibledit.")); - Webserver_Request webserver_request {}; - filter_git_sync_git_to_bible (webserver_request, path, object); - } - database_jobs.set_percentage (jobid, 88); - - // If so requested by the user, - // copy the data from Bibledit to the local cloned repository, - // and then push it to the remote repository, - // so that the data in the repository matches with Bibledit's local data. - if (take_me && result) { - - // Bibledit's data goes into the local repository. - Webserver_Request webserver_request {}; - success.push_back (translate("Storing the local Bible data to the staging area.")); - filter_git_sync_bible_to_git (webserver_request, object, path); - - // Stage the data: add and remove it as needed. - if (result) { - result = filter_git_add_remove_all (path, error); - if (result) { - success.push_back (translate("The local Bible data was staged successfully.")); - } else { - error.append (" " + translate("Failure staging the local Bible data.")); - } - } - if (result) { - std::vector messages {}; - result = filter_git_commit (path, "", "Write test 3", messages, error); - if (result) { - success.push_back (translate("The local Bible data was committed successfully.")); - } else { - error.append (" " + translate("Failure committing the local Bible data.")); - for (const auto& msg : messages) { - error.append (" "); - error.append (msg); - } - } - } - - // Push changes to the remote repository. - database_jobs.set_progress (jobid, translate ("Pushing")); - if (result) { - std::vector messages {}; - result = filter_git_push (path, messages); - success.insert (success.end(), messages.begin(), messages.end()); - if (result) { - success.push_back (translate("The local Bible data was pushed to the repository successfully.")); - } else { - error.append (" " + translate("Pushing the local Bible data to the repository failed.")); - } - } - } - database_jobs.set_percentage (jobid, 96); - - // Just in case it uses a removable flash disk for the repository, flush any pending writes to disk. - database_jobs.set_progress (jobid, translate ("Syncing")); - sync (); - database_jobs.set_percentage (jobid, 100); - - // Ready linking the repository. - page = collaboration_link_header (); - view = Assets_View (); - view.set_variable ("object", object); - view.set_variable ("url", url); - if (take_me) view.enable_zone ("takeme"); - if (take_repo) view.enable_zone ("takerepo"); - if (result) view.enable_zone ("okay"); - else view.enable_zone ("error"); - view.set_variable ("success", filter::strings::implode (success, "
\n")); - view.set_variable ("error", error); - page.append (view.render ("collaboration", "link")); - page.append (assets_page::footer ()); - database_jobs.set_result (jobid, page); -#endif -} - - -std::string collaboration_link_header () -{ - return "

" + translate ("Link repository") + "

\n"; -} - - -/* - -Here is how to create a local git server: - - $ mkdir /tmp/gitdaemon - $ cd /tmp/gitdaemon - $ git --bare init - $ git daemon --enable=receive-pack --base-path=/tmp/gitdaemon --verbose --export-all - -*/ diff --git a/collaboration/link.h b/collaboration/link.h deleted file mode 100644 index 3b9471338..000000000 --- a/collaboration/link.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void collaboration_link (const std::string& object, const int jobid, const std::string& direction); -std::string collaboration_link_header (); diff --git a/collaboration/settings.cpp b/collaboration/settings.cpp deleted file mode 100644 index 620c21a0a..000000000 --- a/collaboration/settings.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string collaboration_settings_url () -{ - return "collaboration/settings"; -} - - -bool collaboration_settings_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::admin ()); -} - - -string collaboration_settings (Webserver_Request& webserver_request) -{ - string page; - Assets_Header header = Assets_Header (translate("Collaboration"), webserver_request); - page = header.run (); - Assets_View view; - - - string object = webserver_request.query ["object"]; - view.set_variable ("object", object); - - - if (webserver_request.post.count ("url")) { - if (!object.empty ()) { - string url = webserver_request.post["url"]; - Database_Config_Bible::setRemoteRepositoryUrl (object, url); - string source = webserver_request.post["source"]; - string readwrite = webserver_request.post["readwrite"]; - Database_Config_Bible::setReadFromGit (object, readwrite == "sendreceive"); - Database_Jobs database_jobs = Database_Jobs (); - int jobId = database_jobs.get_new_id (); - database_jobs.set_level (jobId, Filter_Roles::admin ()); - database_jobs.set_start (jobId, collaboration_link_header ()); - tasks_logic_queue (LINKGITREPOSITORY, {object, filter::strings::convert_to_string (jobId), source}); - redirect_browser (webserver_request, jobs_index_url () + "?id=" + filter::strings::convert_to_string (jobId)); - return ""; - } - } - string url = Database_Config_Bible::getRemoteRepositoryUrl (object); - view.set_variable ("url", url); - - - page += view.render ("collaboration", "settings"); - page += assets_page::footer (); - return page; -} diff --git a/collaboration/settings.h b/collaboration/settings.h deleted file mode 100644 index 025f3961c..000000000 --- a/collaboration/settings.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string collaboration_settings_url (); -bool collaboration_settings_acl (Webserver_Request& webserver_request); -std::string collaboration_settings (Webserver_Request& webserver_request); diff --git a/compare/compare.cpp b/compare/compare.cpp deleted file mode 100644 index 57a5da88b..000000000 --- a/compare/compare.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void compare_compare (string bible, string compare, int jobId) -{ - Database_Logs::log (translate("Comparing Bibles") + " " + bible + " " + translate ("and") + " " + compare, Filter_Roles::consultant ()); - - - Database_Jobs database_jobs = Database_Jobs (); - Database_Bibles database_bibles; - Database_UsfmResources database_usfmresources = Database_UsfmResources (); - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - database_jobs.set_progress (jobId, translate("The Bibles are being compared...")); - - - // The results of the comparison. Will be displayed to the user. - vector result; - result.push_back (translate("Bible") + " '" + bible + "' " + translate ("has been compared with") + " '" + compare + "'."); - result.push_back (translate("Additions are in bold.") + " " + translate ("Removed words are in strikethrough.")); - result.push_back (""); - - - // Get the combined books in both Bibles / Resources. - vector bibleBooks = database_bibles.get_books (bible); - vector compareBooks = database_bibles.get_books (compare); - vector resourceBooks = database_usfmresources.getBooks (compare); - vector books; - { - set bookset; - bookset.insert (bibleBooks.begin(), bibleBooks.end()); - bookset.insert (compareBooks.begin(), compareBooks.end()); - bookset.insert (resourceBooks.begin(), resourceBooks.end()); - books.assign (bookset.begin(), bookset.end ()); - sort (books.begin(), books.end()); - } - - - // Results of comparison of raw USFM. - vector raw; - - - // Absent books / chapters. - vector absent; - - - // The new verses as in the $bible. - vector new_verses; - - - for (auto & book : books) { - - - string bookName = database::books::get_english_from_id (static_cast(book)); - database_jobs.set_progress (jobId, bookName); - - - if (find (bibleBooks.begin(), bibleBooks.end(), book) == bibleBooks.end()) { - absent.push_back (translate("Bible") + " '" + bible + "' " + translate ("does not contain") + " " + bookName + "."); - continue; - } - - if (find (compareBooks.begin(), compareBooks.end(), book) == compareBooks.end()) { - if (find (resourceBooks.begin(), resourceBooks.end(), book) == resourceBooks.end ()) { - absent.push_back (translate("Bible/Resource") + " '" + compare + "' " + translate ("does not contain") + " " + bookName + "."); - continue; - } - } - - - // Get the combined chapters in both Bibles / Resources. - vector bibleChapters = database_bibles.get_chapters (bible, book); - vector compareChapters = database_bibles.get_chapters (compare, book); - vector resourceChapters = database_usfmresources.getChapters (compare, book); - vector chapters; - { - set chapterset; - chapterset.insert (bibleChapters.begin(), bibleChapters.end()); - chapterset.insert (compareChapters.begin(), compareChapters.end()); - chapterset.insert (resourceChapters.begin(), resourceChapters.end()); - chapters.assign (chapterset.begin(), chapterset.end ()); - sort (chapters.begin(), chapters.end()); - } - - - for (auto & chapter : chapters) { - - - // Look for, report, and skip missing chapters in the source Bible. - if (find (bibleChapters.begin(), bibleChapters.end(), chapter) == bibleChapters.end ()) { - absent.push_back (translate("Bible") + " '" + bible + "' " + translate ("does not contain") + " " + bookName + " " + filter::strings::convert_to_string (chapter) + "."); - continue; - } - - - // Look for, report, and skip missing chapters in the comparison USFM data. - if (find (compareChapters.begin(), compareChapters.end(), chapter) == compareChapters.end()) { - if (find (resourceChapters.begin(), resourceChapters.end(), chapter) == resourceChapters.end()) { - absent.push_back (translate("Bible/Resource") + " '" + compare + "' " + translate ("does not contain") + " " + bookName + " " + filter::strings::convert_to_string (chapter) + "."); - continue; - } - } - - - // Get source and compare USFM, and skip them if they are equal. - string bible_chapter_usfm = database_bibles.get_chapter (bible, book, chapter); - string compare_chapter_usfm = database_bibles.get_chapter (compare, book, chapter); - if (compare_chapter_usfm == "") { - compare_chapter_usfm = database_usfmresources.getUsfm (compare, book, chapter); - } - if (bible_chapter_usfm == compare_chapter_usfm) continue; - - - // Get the combined set of verses in the chapter of the Bible and of the USFM to compare with. - vector bible_verse_numbers = filter::usfm::get_verse_numbers (bible_chapter_usfm); - vector compare_verse_numbers = filter::usfm::get_verse_numbers (compare_chapter_usfm); - vector verses; - { - set verseset; - verseset.insert (bible_verse_numbers.begin(), bible_verse_numbers.end()); - verseset.insert (compare_verse_numbers.begin(), compare_verse_numbers.end()); - verses.assign (verseset.begin(), verseset.end ()); - sort (verses.begin(), verses.end()); - } - - - for (int & verse : verses) { - - - // Get the USFM of verse of the Bible and comparison USFM, and skip it if both are the same. - string bible_verse_usfm = filter::usfm::get_verse_text (bible_chapter_usfm, verse); - string compare_verse_usfm = filter::usfm::get_verse_text (compare_chapter_usfm, verse); - if (bible_verse_usfm == compare_verse_usfm) continue; - - Filter_Text filter_text_bible = Filter_Text (bible); - Filter_Text filter_text_compare = Filter_Text (compare); - filter_text_bible.html_text_standard = new HtmlText (""); - filter_text_compare.html_text_standard = new HtmlText (""); - filter_text_bible.text_text = new Text_Text (); - filter_text_compare.text_text = new Text_Text (); - filter_text_bible.add_usfm_code (bible_verse_usfm); - filter_text_compare.add_usfm_code (compare_verse_usfm); - filter_text_bible.run (stylesheet); - filter_text_compare.run (stylesheet); - string bible_html = filter_text_bible.html_text_standard->get_inner_html (); - string compare_html = filter_text_compare.html_text_standard->get_inner_html (); - string bible_text = filter_text_bible.text_text->get (); - string compare_text = filter_text_compare.text_text->get (); - if (bible_text != compare_text) { - string modification = filter_diff_diff (compare_text, bible_text); - result.push_back (filter_passage_display (book, chapter, filter::strings::convert_to_string (verse)) + " " + modification); - new_verses.push_back (filter_passage_display (book, chapter, filter::strings::convert_to_string (verse)) + " " + bible_text); - } - string modification = filter_diff_diff (compare_verse_usfm, bible_verse_usfm); - raw.push_back (filter_passage_display (book, chapter, filter::strings::convert_to_string (verse)) + " " + modification); - } - } - } - - - // Add the absent books / chapters to the comparison. - if (!absent.empty ()) { - result.push_back (""); - result.insert (result.end (), absent.begin(), absent.end()); - } - - - // Add any differences in the raw USFM to the comparison. - if (!raw.empty ()) { - result.push_back (""); - result.insert (result.end (), raw.begin(), raw.end()); - } - - - // Add the text of the new verses, as they are in the $bible. - if (!new_verses.empty ()) { - result.push_back (""); - result.push_back (translate("The texts as they are in the Bible") + " " + bible); - result.push_back (""); - result.insert (result.end(), new_verses.begin(), new_verses.end()); - } - - - // Format and store the result of the comparison. - for (auto & line : result) { - if (line == "") { - line = "
"; - } else { - line.insert (0, "

"); - line.append ("

"); - } - } - database_jobs.set_result (jobId, filter::strings::implode (result, "\n")); - - - Database_Logs::log (translate("Comparison is ready"), Filter_Roles::consultant ()); -} diff --git a/compare/compare.h b/compare/compare.h deleted file mode 100644 index 6b9d1f008..000000000 --- a/compare/compare.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void compare_compare (std::string bible, std::string compare, int jobId); diff --git a/compare/index.cpp b/compare/index.cpp deleted file mode 100644 index 0d3099652..000000000 --- a/compare/index.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop - - -std::string compare_index_url () -{ - return "compare/index"; -} - - -bool compare_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ()); -} - - -std::string compare_index (Webserver_Request& webserver_request) -{ - std::string page{}; - - Assets_Header header = Assets_Header (translate("Compare"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (bible_manage_url (), menu_logic_bible_manage_text ()); - page = header.run (); - - Assets_View view; - - const std::string bible = webserver_request.query ["bible"]; - view.set_variable ("bible", bible); - - if (webserver_request.query.count ("compare")) { - const std::string compare = webserver_request.query ["compare"]; - Database_Jobs database_jobs = Database_Jobs (); - const int job_id = database_jobs.get_new_id (); - database_jobs.set_level (job_id, Filter_Roles::consultant ()); - tasks_logic_queue (COMPAREUSFM, {bible, compare, filter::strings::convert_to_string (job_id)}); - redirect_browser (webserver_request, jobs_index_url () + "?id=" + filter::strings::convert_to_string (job_id)); - return std::string(); - } - - // Names of the Bibles and the USFM Resources. - std::vector names = webserver_request.database_bibles()->get_bibles (); - - Database_UsfmResources database_usfmresources; - std::vector usfm_resources = database_usfmresources.getResources (); - names.insert (names.end (), usfm_resources.begin(), usfm_resources.end ()); - - sort (names.begin (), names.end ()); - - names = filter::strings::array_diff (names, {bible}); - pugi::xml_document document; - for (const auto& name : names) { - pugi::xml_node li_node = document.append_child("li"); - pugi::xml_node a_node = li_node.append_child("a"); - a_node.append_attribute("href") = ("index?bible=" + bible + "&compare=" + name).c_str(); - a_node.text().set(name.c_str()); - } - std::stringstream ss{}; - document.print(ss, "", pugi::format_raw); - view.set_variable ("bibleblock", ss.str()); - - page += view.render ("compare", "index"); - - page += assets_page::footer (); - - return page; -} diff --git a/compare/index.h b/compare/index.h deleted file mode 100644 index 5f6ad0783..000000000 --- a/compare/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string compare_index_url (); -bool compare_index_acl (Webserver_Request& webserver_request); -std::string compare_index (Webserver_Request& webserver_request); diff --git a/config.h b/config.h.bak similarity index 100% rename from config.h rename to config.h.bak diff --git a/config/config.h b/config/config.h.bak similarity index 100% rename from config/config.h rename to config/config.h.bak diff --git a/config/globals.cpp b/config/globals.cpp deleted file mode 100644 index ee02d021e..000000000 --- a/config/globals.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include - - -#undef max - - -std::string config_globals_document_root {DIRECTORY_SEPARATOR}; -bool config_globals_unit_testing {false}; -bool config_globals_open_installation {false}; -bool config_globals_client_prepared {false}; -bool config_globals_webserver_running {true}; -std::thread * config_globals_http_worker {nullptr}; -std::thread * config_globals_https_worker {nullptr}; -std::thread * config_globals_timer {nullptr}; -bool config_globals_mail_receive_running {false}; -bool config_globals_mail_send_running {false}; -int config_globals_touch_enabled {0}; -int config_globals_timezone_offset_utc {100}; -bool config_globals_change_notifications_available {true}; -int config_globals_setup_progress {10}; -std::string config_globals_setup_message {"install"}; -int config_globals_simultaneous_connection_count {0}; -bool config_globals_data_initialized {false}; -bool config_globals_syncing_bibles {false}; -bool config_globals_syncing_notes {false}; -bool config_globals_syncing_settings {false}; -bool config_globals_syncing_changes {false}; -bool config_globals_syncing_files {false}; -bool config_globals_syncing_resources {false}; -std::map config_globals_prioritized_ip_addresses {}; -bool config_globals_enforce_https_browser {false}; -bool config_globals_enforce_https_client {false}; -std::default_random_engine config_globals_random_engine ((std::random_device())()); -std::uniform_int_distribution config_globals_int_distribution (0, std::numeric_limits ::max()); -std::string config_globals_external_url {}; -std::map config_globals_resource_window_positions {}; -std::string config_globals_pages_to_open {}; -bool config_globals_hide_bible_resources {false}; -bool config_globals_running_on_chrome_os {false}; -bool config_globals_log_network {false}; -std::string config_globals_negotiated_port_number {}; -bool config_globals_has_crashed_while_mailing {false}; - diff --git a/config/globals.h b/config/globals.h deleted file mode 100644 index 2c53ac97a..000000000 --- a/config/globals.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include - - -extern std::string config_globals_document_root; -extern bool config_globals_unit_testing; -extern bool config_globals_open_installation; -extern bool config_globals_client_prepared; -extern bool config_globals_webserver_running; -extern std::thread * config_globals_http_worker; -extern std::thread * config_globals_https_worker; -extern std::thread * config_globals_timer; -extern bool config_globals_mail_receive_running; -extern bool config_globals_mail_send_running; -extern int config_globals_touch_enabled; -extern int config_globals_timezone_offset_utc; -extern bool config_globals_change_notifications_available; -extern int config_globals_setup_progress; -extern std::string config_globals_setup_message; -extern bool config_globals_data_initialized; -extern bool config_globals_syncing_bibles; -extern bool config_globals_syncing_notes; -extern bool config_globals_syncing_settings; -extern bool config_globals_syncing_changes; -extern bool config_globals_syncing_files; -extern bool config_globals_syncing_resources; -extern std::map config_globals_prioritized_ip_addresses; -extern bool config_globals_enforce_https_browser; -extern bool config_globals_enforce_https_client; -extern std::default_random_engine config_globals_random_engine; -extern std::uniform_int_distribution config_globals_int_distribution; -extern std::string config_globals_external_url; -extern std::map config_globals_resource_window_positions; -extern std::string config_globals_pages_to_open; -extern bool config_globals_hide_bible_resources; -extern bool config_globals_running_on_chrome_os; -extern bool config_globals_log_network; -extern std::string config_globals_negotiated_port_number; -extern bool config_globals_has_crashed_while_mailing; diff --git a/config/libraries.h b/config/libraries.h deleted file mode 100644 index 836bf2f78..000000000 --- a/config/libraries.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -// System configuration. -#include - - -// Basic C headers. -#include -#ifndef HAVE_WINDOWS -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include - - -// C headers in sub folders. -#include -#ifndef HAVE_WINDOWS -#include -#endif -#ifdef HAVE_WINDOWS -#include -#else -#include -#include -#include -#include -#include -#include -#endif -#include - - -// C++ headers. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include - - -// Headers dependencies. -#include - - -// Bibledit configuration. -#include -#include diff --git a/config/logic.cpp b/config/logic.cpp deleted file mode 100644 index 182551006..000000000 --- a/config/logic.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -namespace config::logic { - - -const char * config_folder () -{ - return "config"; -} - - -// Returns the Bibledit version number. -const char * version () -{ - return VERSION; -} - - -// Loads the values from the config folder into memory for faster access. -void load_settings () -{ - // Read the setting whether to log network connections. - string path = filter_url_create_root_path ({config::logic::config_folder (), "log-network"}); - config_globals_log_network = file_or_dir_exists (path); -} - - -// Return the network port configured for the server. -string http_network_port () -{ - // If a port number is known already, take that. - if (!config_globals_negotiated_port_number.empty()) return config_globals_negotiated_port_number; - // Read the port number from file. - string path = filter_url_create_root_path ({config::logic::config_folder (), "network-port"}); - config_globals_negotiated_port_number = filter_url_file_get_contents (path); - // Remove white-space, e.g. a new line, that easily makes its way into the configuration file. - config_globals_negotiated_port_number = filter::strings::trim (config_globals_negotiated_port_number); - // Default port number. - if (config_globals_negotiated_port_number.empty ()) config_globals_negotiated_port_number = "8080"; - // Done. - return config_globals_negotiated_port_number; -} - - -// Return the secure network port for the secure server. -string https_network_port () -{ - // Read the port number from file. - string path = filter_url_create_root_path ({config::logic::config_folder (), "network-port-secure"}); - string port = filter_url_file_get_contents (path); - // Remove white-space, e.g. a new line, that easily makes its way into the configuration file. - port = filter::strings::trim (port); - // Default value. - if (port.empty ()) { - // The secure port is the plain http port plus one. - int iport = filter::strings::convert_to_int (config::logic::http_network_port ()); - iport++; - port = filter::strings::convert_to_string (iport); - } - return port; -} - - -// Returns whether demo mode is enabled during configure. -bool demo_enabled () -{ - string path = filter_url_create_root_path ({config::logic::config_folder (), "demo"}); - return file_or_dir_exists (path); -} - - -// The configured admin's username. -string admin_username () -{ - string path = filter_url_create_root_path ({config::logic::config_folder (), "admin-username"}); - return filter::strings::trim (filter_url_file_get_contents (path)); -} - - -// The configured admin's password. -string admin_password () -{ - string path = filter_url_create_root_path ({config::logic::config_folder (), "admin-password"}); - return filter::strings::trim (filter_url_file_get_contents (path)); -} - - -// The configured admin's email. -string admin_email () -{ - string path = filter_url_create_root_path ({config::logic::config_folder (), "admin-email"}); - return filter::strings::trim (filter_url_file_get_contents (path)); -} - - -// Returns whether the interface is supposed to be in basic mode. -bool basic_mode (Webserver_Request& webserver_request) -{ - bool basic_mode {webserver_request.database_config_user ()->getBasicInterfaceMode ()}; - return basic_mode; -} - - -// This returns the URL of Bibledit Cloud that faces the user. -string site_url (Webserver_Request& webserver_request) -{ - // When the administrator has entered a fixed value for the user-facing URL, take that. - // It overrides everything. - string url = config::logic::manual_user_facing_url (); - if (!url.empty ()) return url; - - // If a webserver request is passed, take the host from there. - // The result is that in a situation where 192.168.2.6 is the same as localhost, - // user can connect from localhost and also from 192.168.2.6. - // In the past there was a situation that the admin set up a central server for the whole team on his localhost. - // Then team members that connected to 192.168.2.6 were forwarded to localhost (which of course failed). - // This solution deals with that. - if (!webserver_request.host.empty ()) { - url = get_base_url (webserver_request); - return url; - } - - // No URL found yet. - // This occurs during scheduled tasks that require the URL to add it to emails sent out. - // Take the URL stored on login. - url = Database_Config_General::getSiteURL (); - return url; -} - - -// This returns the filtered value of file userfacingurl.conf. -string manual_user_facing_url () -{ -#ifdef HAVE_CLIENT - return string(); -#else - // Read the configuration file. - string path = filter_url_create_root_path ({config::logic::config_folder (), "userfacingurl.conf"}); - string url = filter_url_file_get_contents (path); - // Remove white space. - url = filter::strings::trim (url); - // The previous file contained dummy text by default. Remove that. - if (url.length () <= 6) url.clear (); - // Ensure it ends with a slash. - if (url.find_last_of ("/") != url.length () - 1) url.append ("/"); - // Done. - return url; -#endif -} - - -// Returns the path to the secure server's private key. -string server_key_path (const bool force) -{ - // Try the correct config file first. - string path = filter_url_create_root_path ({config::logic::config_folder (), "privkey.pem"}); - if (force || file_or_dir_exists (path)) return path; - // Nothing found. - return string(); -} - - -// Returns the path to the secure server's public certificate. -string server_certificate_path (const bool force) -{ - // Try the correct config file first. - string path = filter_url_create_root_path ({config::logic::config_folder (), "cert.pem"}); - if (force || file_or_dir_exists (path)) return path; - // Nothing found. - return string(); -} - - -// Returns the path to the secure server's certificates of the signing authorities. -// This file contains the chain of trusted certificate authorities that have issued the server certificate. -// At the top of the file will be the intermediate authority that issued the server certificate. -// Next can be more intermediate authorities. -// At the bottom of the file should be the trusted root certificate. -string authorities_certificates_path (const bool force) -{ - // Try the correct config file first. - string path = filter_url_create_root_path ({config::logic::config_folder (), "chain.pem"}); - if (force || file_or_dir_exists (path)) return path; - // Nothing found. - return string(); -} - - -// Whether to enforce https traffic for browser communications. -bool enforce_https_browser () -{ - return file_or_dir_exists (filter_url_create_root_path ({config::logic::config_folder (), "browser.https"})); -} - - -// Whether to enforce https traffic for client communications. -bool enforce_https_client () -{ - return file_or_dir_exists (filter_url_create_root_path ({config::logic::config_folder (), "client.https"})); -} - - -void swipe_enabled (Webserver_Request& webserver_request, string & script) -{ - string true_false {"false"}; - if (webserver_request.session_logic ()->touchEnabled ()) { - if (webserver_request.database_config_user ()->getSwipeActionsAvailable ()) { - true_false = "true"; - } - } - - script.append ("\n"); - script.append ("var swipe_operations = "); - script.append (true_false); - script.append (";"); -} - - -// Whether the Indonesian Member Cloud is enabled. -bool indonesian_member_cloud () -{ - // This is to speed up things. - static bool read {false}; - static bool status {false}; - if (read) return status; - - // Read the status from disk and cache it. - string path = filter_url_create_root_path ({config::logic::config_folder (), "indonesianmembercloud"}); - status = file_or_dir_exists (path); - read = true; - - // Done. - return status; -} - - -// Whether the default Bibledit configuration is enabled. -bool default_bibledit_configuration () -{ - // If any other configuration is active, then the default Bibledit configuration is not active. - if (indonesian_member_cloud ()) return false; - // No other configuration is active: Default Bibledit config is active. - return true; -} - - -string google_translate_json_key_path () -{ - return filter_url_create_root_path ({config::logic::config_folder (), "googletranslate.json"}); -} - - -} // End of namespace. diff --git a/config/logic.h b/config/logic.h deleted file mode 100644 index 76fe050fc..000000000 --- a/config/logic.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -namespace config::logic { - -const char * config_folder (); -const char * version (); -void load_settings (); -std::string http_network_port (); -std::string https_network_port (); -bool demo_enabled (); -std::string admin_username (); -std::string admin_password (); -std::string admin_email (); -bool basic_mode (Webserver_Request& webserver_request); -std::string site_url (Webserver_Request& webserver_request); -std::string manual_user_facing_url (); -std::string server_key_path (const bool force); -std::string server_certificate_path (const bool force); -std::string authorities_certificates_path (const bool force); -bool enforce_https_browser (); -bool enforce_https_client (); -void swipe_enabled (Webserver_Request& webserver_request, std::string & script); -bool indonesian_member_cloud (); -bool default_bibledit_configuration (); -std::string google_translate_json_key_path (); - -} // End of namespace. diff --git a/configure.ac.bak b/configure.ac.bak new file mode 100644 index 000000000..07325aef4 --- /dev/null +++ b/configure.ac.bak @@ -0,0 +1,244 @@ +AC_INIT([bibledit],[5.1.010],[http://bibledit.org]) +AM_INIT_AUTOMAKE([tar-ustar subdir-objects]) +AC_CANONICAL_BUILD +ac_default_prefix=/usr + +AC_PROG_CC +AC_PROG_CXX +AC_LANG([C++]) +AX_CXX_COMPILE_STDCXX(17,[noext],[mandatory]) +AC_PROG_RANLIB +AC_CONFIG_HEADERS([config.h]) + + +AC_PATH_PROG(GZIP_PATH, gzip, no) +if test x$GZIP_PATH = xno; then + AC_MSG_ERROR(Program "gzip" is needed. Install this first.) +fi + + +AC_PATH_PROG(GUNZIP_PATH, gunzip, no) +if test x$GUNZIP_PATH = xno; then + AC_MSG_ERROR(Program "gunzip" is needed. Install this first.) +fi + + +AC_PATH_PROG(FIND_TAR, tar, no) +if test x$FIND_TAR = xno; then + AC_MSG_ERROR(Program "tar" is needed. Install this first.) +fi + + +AC_PATH_PROG(ZIP_PATH, zip, no) +if test x$ZIP_PATH = xno; then + AC_MSG_ERROR(Program "zip" is needed. Install this first.) +fi + + +AC_PATH_PROG(UNZIP_PATH, unzip, no) +if test x$UNZIP_PATH = xno; then + AC_MSG_ERROR(Program "unzip" is needed. Install this first.) +fi + + +AC_PATH_PROG(INSTALLMGR_PATH, installmgr, no) +AC_PATH_PROG(DIATHEKE_PATH, diatheke, no) + + +PKG_PROG_PKG_CONFIG +# https://lintian.debian.org/tags/autotools-pkg-config-macro-not-cross-compilation-safe.html +if test x$PKG_CONFIG = x; then + AC_MSG_ERROR(Program "pkg-config" is needed. Install this first.) +fi + +PKG_CHECK_MODULES(CURL, libcurl >= 7.20.0,,AC_MSG_ERROR(libcurl development version >= 7.20.0 is needed.)) +AC_SUBST(CURL_CFLAGS) +AC_SUBST(CURL_LIBS) +AC_CHECK_HEADER(curl/curl.h, , AC_MSG_ERROR([Header file curl/curl.h was not found. Usually this is in libcurl4-openssl-dev or libcurl4-gnutls-dev.])) + +PKG_CHECK_MODULES(OPENSSL, openssl >= 0.9.0,,AC_MSG_ERROR(openssl development version >= 0.9.0 is needed.)) +AC_SUBST(OPENSSL_CFLAGS) +AC_SUBST(OPENSSL_LIBS) + +PKG_CHECK_MODULES(XML2, libxml-2.0 >= 2.9.0,,AC_MSG_ERROR(GNOME XML2 library development version >= 2.9.0 is needed.)) +AC_SUBST(XML2_CFLAGS) +AC_SUBST(XML2_LIBS) + +# linux PKG_CHECK_MODULES(GTK, gtk+-3.0,,AC_MSG_ERROR(Gtk3 development version is needed.)) +# linux AC_SUBST(GTK_LIBS) +# linux AC_SUBST(GTK_CFLAGS) + +# linux PKG_CHECK_MODULES([WEBKIT2GTK], [webkit2gtk-4.1],, [ +# linux PKG_CHECK_MODULES([WEBKIT2GTK], [webkit2gtk-4.0],, [ +# linux PKG_CHECK_MODULES([WEBKIT2GTK], [webkit2gtk-3.0],,AC_MSG_ERROR(Webkit2Gtk development version is needed.)) +# linux ]) +# linux ]) +# linux AC_SUBST(WEBKIT2GTK_LIBS) +# linux AC_SUBST(WEBKIT2GTK_CFLAGS) + +AC_CHECK_LIB([mbedtls], [mbedtls_ssl_init]) +AM_CONDITIONAL([HAVE_LIBMBEDTLS], [test "$ac_cv_lib_mbedtls_ssl_init" = yes]) + +# Tag1 (leave in place) +# Tag2 (leave in place) +# Tag3 (leave in place) +# Tag4 (leave in place) +# Tag5 (leave in place) +# Tag6 (leave in place) +# Tag7 (leave in place) +# Tag8 (leave in place) +# Tag9 (leave in place) +# TagA (leave in place) +# TagB (leave in place) +# TagC (leave in place) +# TagD (leave in place) +# TagE (leave in place) +# TagF (leave in place) +# TagG (leave in place) + + +AC_CHECK_HEADER(pthread.h,AC_DEFINE([HAVE_PTHREAD],[1],[Define whether pthread.h is present]),) + +AC_CHECK_HEADER(libproc.h,AC_DEFINE([HAVE_LIBPROC],[1],[Define whether libproc.h is present]),) + +AC_CHECK_HEADER(execinfo.h,AC_DEFINE([HAVE_EXECINFO],[1],[Define whether execinfo.h is present]),) + +AC_CHECK_HEADER(sys/sysctl.h,AC_DEFINE([HAVE_SYS_SYSCTL],[1],[Define whether sys/sysctl.h is present]),) + +AC_CHECK_HEADER(mach/mach.h,AC_DEFINE([HAVE_MACH_MACH],[1],[Define whether mach/mach.h is present]),) + +if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${ac_default_prefix}/share/bibledit", [Package data directory]) +else + AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${prefix}/share/bibledit", [Package data directory]) +fi + +AC_DEFINE_UNQUOTED(PACKAGE_PREFIX_DIR, "${prefix}", [Package prefix directory]) + +# Check whether function 'stoi' is available +AC_MSG_CHECKING([whether stoi is available]) +AC_COMPILE_IFELSE( +[AC_LANG_SOURCE([[ +#include +using namespace std; +int i = stoi ("string"); + ]])], + [AC_DEFINE([HAVE_STOI], [1], [Define whether function 'stoi' is available]) + AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no])] +) + +# Check ICU Unicode library whether available. +PKG_CHECK_MODULES(ICU, icu-i18n >= 60.0, AC_DEFINE(HAVE_ICU, 1, Define whether ICU is available), AC_MSG_NOTICE(libicui18n development version >= 60.0 is needed for the Cloud.)) +AC_SUBST(ICU_CFLAGS) +AC_SUBST(ICU_LIBS) + +# Check UTF8 proc library whether available. +PKG_CHECK_MODULES(UTF8PROC, libutf8proc >= 2.3.0, AC_DEFINE(HAVE_UTF8PROC, 1, Define whether utf8proc is available), AC_MSG_NOTICE(libutf8proc development version >= 2.3.0 is beneficial to have.)) +AC_SUBST(UTF8PROC_CFLAGS) +AC_SUBST(UTF8PROC_LIBS) + +# Check the gumbo library whether available. +PKG_CHECK_MODULES(GUMBO, gumbo >= 0.10.0,,AC_MSG_ERROR(The gumbo library development version >= 0.10.0 is needed.)) +AC_SUBST(GUMBO_CFLAGS) +AC_SUBST(GUMBO_LIBS) + +# Check the tidy library whether available. +# PKG_CHECK_MODULES(TIDY, tidy >= 5.4.0,,AC_MSG_ERROR(The tidy library development version >= 5.4.0 is needed.)) +# AC_SUBST(TIDY_CFLAGS) +# AC_SUBST(TIDY_LIBS) + +# Check the pugixml library whether available. +PKG_CHECK_MODULES(PUGIXML, pugixml >= 1.10, AC_DEFINE(HAVE_PUGIXML, 1, Define whether pugixml is available), AC_MSG_NOTICE(pugixml development version >= 1.10 is beneficial to have.)) +AC_SUBST(PUGIXML_CFLAGS) +AC_SUBST(PUGIXML_LIBS) + +# Check whether the GTest library is available. +PKG_CHECK_MODULES(GTEST, gtest >= 1.10.0, AC_DEFINE(HAVE_GTEST, 1, Define whether GTest is available), AC_MSG_NOTICE(Install gtest to also build the unit tests.)) +AC_SUBST(GTEST_CFLAGS) +AC_SUBST(GTEST_LIBS) + +AC_MSG_CHECKING([C++ compiler]) +GPPVERSION=`${CXX} --version | grep clang` +if test "$GPPVERSION" = ""; then +AC_MSG_RESULT([GCC]) +else +AC_MSG_RESULT([clang]) +fi +AM_CONDITIONAL([COMPILERGCC],[test "$GPPVERSION" = ""]) +AM_CONDITIONAL([COMPILERCLANG],[test "$GPPVERSION" != ""]) + + +# Windows. +ENABLEWINDOWS=no +AC_ARG_ENABLE(windows, +[ --enable-windows Compile for Windows], +[ +AC_DEFINE([WIN32], [1], [Define whether to compile on Windows]) +AC_DEFINE([HAVE_WINDOWS], [1], [Define whether to compile on Windows]) +ENABLEWINDOWS=yes +] +) + +# Android. +ENABLEANDROID=no +AC_ARG_ENABLE(android, +[ --enable-android Compile for Android], +[ +AC_DEFINE([HAVE_ANDROID], [1], [Define whether to compile for Android]) +ENABLEANDROID=yes +] +) + +# macOS. +ENABLEMAC=no +AC_ARG_ENABLE(mac, +[ --enable-mac Compile for Mac], +[ +AC_DEFINE([HAVE_MAC], [1], [Define whether to compile for Mac]) +ENABLEMAC=yes +] +) +AM_CONDITIONAL([MACFLAGS],[test $ENABLEMAC = yes]) + +# Linux. +ENABLELINUX=no +AC_ARG_ENABLE(linux, +[ --enable-linux Compile for Linux], +[ +AC_DEFINE([HAVE_LINUX], [1], [Define whether to compile for Linux]) +ENABLELINUX=yes +] +) + +# iOS. +ENABLEIOS=no +AC_ARG_ENABLE(ios, +[ --enable-ios Compile for iOS], +[ +AC_DEFINE([HAVE_IOS], [1], [Define whether to compile for iOS]) +ENABLEIOS=yes +] +) + +# Whether to enable compiler warnings. +ENABLEWARNINGS=no +AC_ARG_ENABLE(warnings, +[ --enable-warnings Enable compiler warnings],[ENABLEWARNINGS=yes]) +AM_CONDITIONAL([COMPILERWARNINGS],[test $ENABLEWARNINGS = yes]) + + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT + +echo " +Bibledit $VERSION configuration summary: + +Installation prefix : ${prefix} +Windows (--enable-windows) : ${ENABLEWINDOWS} +Android (--enable-android) : ${ENABLEANDROID} +macOS (--enable-mac) : ${ENABLEMAC} +Linux (--enable-linux) : ${ENABLELINUX} +iOS (--enable-ios) : ${ENABLEIOS} +Enable GCC warnings (--enable-warnings) : ${ENABLEWARNINGS} +" diff --git a/confirm/worker.cpp b/confirm/worker.cpp deleted file mode 100644 index 6d6db4a3c..000000000 --- a/confirm/worker.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -using namespace std; -using namespace pugi; - - -#ifdef HAVE_CLOUD - - -Confirm_Worker::Confirm_Worker (Webserver_Request& webserver_request): -m_webserver_request (webserver_request) -{ -} - - -// Sets up a confirmation cycle in order to change something in the database. -// If for example a user requests the email address to be changed, -// an initial email will be sent, which the user should confirm. -// mailto : Email address for the initial email and the response. -// initial_subject : The subject of the initial email message. -// initial_body : The body of the initial email message. -// query : The query to be executed on the database if the user confirms the email successfully. -// subsequent_subject: The subject of the email to send upon user confirmation. -// subsequent_body : The body of the email to send upon user confirmation. -void Confirm_Worker::setup (string mailto, string username, - string initial_subject, string initial_body, - string query, - string subsequent_subject, string subsequent_body) -{ - Database_Confirm database_confirm; - unsigned int confirmation_id = database_confirm.get_new_id (); - xml_document document; - xml_node node = document.append_child ("p"); - string information; - if (config::logic::default_bibledit_configuration ()) { - information = translate ("Please confirm this request by clicking this following link:"); - } - node.text ().set (information.c_str()); - node = document.append_child ("p"); - string siteUrl = config::logic::site_url (m_webserver_request); - string confirmation_url = filter_url_build_http_query (siteUrl + session_confirm_url (), "id", to_string(confirmation_id)); - node.text ().set (confirmation_url.c_str()); - stringstream output; - document.print (output, "", format_raw); - initial_body += output.str (); - email_schedule (mailto, initial_subject, initial_body); - database_confirm.store (confirmation_id, query, mailto, subsequent_subject, subsequent_body, username); -} - - -// Handles a confirmation email received "from" with "subject" and "body". -// Returns true if the mail was handled, else false. -bool Confirm_Worker::handleEmail ([[maybe_unused]]string from, string subject, string body) -{ - // Find out in the confirmation database whether the subject line contains an active ID. - // If not, bail out. - Database_Confirm database_confirm; - unsigned int id = database_confirm.search_id (subject); - if (id == 0) { - return false; - } - // An active ID was found: Execute the associated database query. - string query = database_confirm.get_query (id); - m_webserver_request.database_users()->execute (query); - // Send confirmation mail. - string mailto = database_confirm.get_mail_to (id); - subject = database_confirm.get_subject (id); - body = database_confirm.get_body (id); - email_schedule (mailto, subject, body); - // Delete the confirmation record. - database_confirm.erase (id); - // Notify managers. - informManagers (mailto, body); - // Job done. - return true; -} - - -// Handles a confirmation link clicked with a confirmation ID. -// Returns true if link was valid, else false. -bool Confirm_Worker::handleLink (string & email) -{ - // Get the confirmation identifier from the link that was clicked. - string web_id = m_webserver_request.query["id"]; - - // If the identifier was not given, the link was not handled successfully. - if (web_id.empty()) return false; - - // Find out in the confirmation database whether the subject line contains an active ID. - // If not, bail out. - Database_Confirm database_confirm; - unsigned int id = database_confirm.search_id (web_id); - if (id == 0) { - return false; - } - - // An active ID was found: Execute the associated database query. - string query = database_confirm.get_query (id); - m_webserver_request.database_users()->execute (query); - - // Send confirmation mail. - string mailto = database_confirm.get_mail_to (id); - string subject = database_confirm.get_subject (id); - string body = database_confirm.get_body (id); - email_schedule (mailto, subject, body); - - // Delete the confirmation record. - database_confirm.erase (id); - - // Notify managers. - informManagers (mailto, body); - - // Pass the email address to the caller. - email = mailto; - - // Job done. - return true; -} - - -// Inform the managers about an account change. -void Confirm_Worker::informManagers (string email, string body) -{ - Database_Users database_users; - vector users = database_users.get_users (); - for (auto & user : users) { - int level = database_users.get_level (user); - if (level >= Filter_Roles::manager ()) { - string mailto = database_users.get_email (user); - string subject = translate ("User account change"); - string newbody = translate ("A user account was changed."); - newbody.append (" "); - newbody.append (translate ("Email address:")); - newbody.append (" "); - newbody.append (email); - newbody.append (". "); - newbody.append (translate ("The following email was sent to this user:")); - newbody.append (" "); - newbody.append (body); - email_schedule (mailto, subject, newbody); - } - } -} - - -#endif diff --git a/confirm/worker.h b/confirm/worker.h deleted file mode 100644 index 31be5bae6..000000000 --- a/confirm/worker.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -#ifdef HAVE_CLOUD - -class Confirm_Worker -{ -public: - Confirm_Worker (Webserver_Request& webserver_request); - void setup (std::string mailto, std::string username, - std::string initial_subject, std::string initial_body, - std::string query, - std::string subsequent_subject, std::string subsequent_body); - bool handleEmail (std::string from, std::string subject, std::string body); - bool handleLink (std::string & email); -private: - Webserver_Request& m_webserver_request; - void informManagers (std::string email, std::string body); -}; - -#endif diff --git a/consistency/index.cpp b/consistency/index.cpp deleted file mode 100644 index 2b67dff0a..000000000 --- a/consistency/index.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string consistency_index_url () -{ - return "consistency/index"; -} - - -bool consistency_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -string consistency_index (Webserver_Request& webserver_request) -{ - string page; - Assets_Header header = Assets_Header (translate("Consistency"), webserver_request); - header.add_bread_crumb (menu_logic_tools_menu (), menu_logic_tools_text ()); - page = header.run (); - Assets_View view; - - - string add = webserver_request.post ["add"]; - if (!add.empty ()) { - vector resources = webserver_request.database_config_user()->getConsistencyResources (); - resources.push_back (add); - webserver_request.database_config_user()->setConsistencyResources (resources); - } - - - string remove = webserver_request.query ["remove"]; - if (!remove.empty ()) { - vector resources = webserver_request.database_config_user()->getConsistencyResources (); - resources = filter::strings::array_diff (resources, {remove}); - webserver_request.database_config_user()->setConsistencyResources (resources); - } - - - stringstream resourceblock; - vector resources = webserver_request.database_config_user()->getConsistencyResources (); - for (auto resource : resources) { - resourceblock << resource; - resourceblock << "\n"; - resourceblock << "[" << translate("remove") << "]"; - resourceblock << " | "; - } - view.set_variable ("resourceblock", resourceblock.str()); - - - page += view.render ("consistency", "index"); - page += assets_page::footer (); - return page; -} diff --git a/consistency/index.h b/consistency/index.h deleted file mode 100644 index 4eccc543d..000000000 --- a/consistency/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string consistency_index_url (); -bool consistency_index_acl (Webserver_Request& webserver_request); -std::string consistency_index (Webserver_Request& webserver_request); diff --git a/consistency/input.cpp b/consistency/input.cpp deleted file mode 100644 index 5196b20d3..000000000 --- a/consistency/input.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -string consistency_input_url () -{ - return "consistency/input"; -} - - -bool consistency_input_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -string consistency_input (Webserver_Request& webserver_request) -{ - const int id = filter::strings::convert_to_int (webserver_request.post ["id"]); - const string passages = webserver_request.post ["passages"]; - const string translations = webserver_request.post ["translations"]; - Database_Volatile::setValue (id, "passages", passages); - Database_Volatile::setValue (id, "translations", translations); - Consistency_Logic consistency_logic (webserver_request, id); - const string response = consistency_logic.response (); - Database_Volatile::setValue (id, "response", response); - return response; -} diff --git a/consistency/input.h b/consistency/input.h deleted file mode 100644 index 079348d56..000000000 --- a/consistency/input.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string consistency_input_url (); -bool consistency_input_acl (Webserver_Request& webserver_request); -std::string consistency_input (Webserver_Request& webserver_request); diff --git a/consistency/logic.cpp b/consistency/logic.cpp deleted file mode 100644 index 14bc96cee..000000000 --- a/consistency/logic.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -Consistency_Logic::Consistency_Logic (Webserver_Request& webserver_request, int id) : -m_webserver_request (webserver_request), m_id (id) -{ -} - - -string Consistency_Logic::response () -{ - // The resources to display in the Consistency tool. - vector resources = m_webserver_request.database_config_user()->getConsistencyResources (); - string bible = access_bible::clamp (m_webserver_request, m_webserver_request.database_config_user()->getBible ()); - resources.insert (resources.begin (), bible); - - // The passages entered in the Consistency tool. - string s_passages = Database_Volatile::getValue (m_id, "passages"); - s_passages = filter::strings::trim (s_passages); - vector passages = filter::strings::explode (s_passages, '\n'); - - // The translations entered in the Consistency tool. - string s_translations = Database_Volatile::getValue (m_id, "translations"); - s_translations = filter::strings::trim (s_translations); - vector translations = filter::strings::explode (s_translations, '\n'); - - // Contains the response to display. - vector response; - - // Go through the passages interpreting them. - Passage previousPassage = Passage ("", 1, 1, "1"); - for (auto line : passages) { - - // Clean line. - line = filter::strings::trim (line); - - // Skip empty line. - if (line.empty ()) continue; - - // Remove verse text remaining with the passage(s) only. - line = omit_verse_text (line); - - vector range_sequence = filter_passage_handle_sequences_ranges (line); - for (auto line2 : range_sequence) { - Passage passage = filter_passage_interpret_passage (previousPassage, line2); - if (passage.m_book != 0) { - int book = passage.m_book; - int chapter = passage.m_chapter; - string verse = passage.m_verse; - line2 = filter_passage_link_for_opening_editor_at (book, chapter, verse); - line2 += " "; - - // Check whether the chapter identifier has changed for this reference. - // If so, set a flag so the data can be re-assembled for this verse. - // If there was no change, then the data can be fetched from the volatile database. - bool redoPassage = false; - string passageKey = filter::strings::convert_to_string (book) + "." + filter::strings::convert_to_string (chapter) + "." + verse; - int currentChapterId = m_webserver_request.database_bibles()->get_chapter_id (resources [0], book, chapter); - int storedChapterId = filter::strings::convert_to_int (Database_Volatile::getValue (m_id, passageKey + ".id")); - if (currentChapterId != storedChapterId) { - Database_Volatile::setValue (m_id, passageKey + ".id", filter::strings::convert_to_string (currentChapterId)); - redoPassage = true; - } - - // Go through each resource. - for (auto resource : resources) { - - // Produce new verse text if the passage is to be redone, or else fetch the existing text. - string text; - if (redoPassage) { - text = verseText (resource, book, chapter, filter::strings::convert_to_int (verse)); - size_t length1 = text.size (); - if (!translations.empty ()) { - text = filter::strings::markup_words (translations, text); - } - size_t length2 = text.size (); - if (length2 == length1) { - text.insert (0, R"(
)"); - text.append ("
"); - } - Database_Volatile::setValue (m_id, passageKey + "." + resource, text); - } else { - text = Database_Volatile::getValue (m_id, passageKey + "." + resource); - } - - // Formatting. - if (resources.size () > 1) { - line2 += "
"; - } - line2 += text; - } - response.push_back (line2); - previousPassage = passage; - } else { - response.push_back (R"()" + translate("Unknown passage") + " " + line2 + ""); - } - } - } - - string output; - for (auto line : response) { - output += "
" + line + "
\n"; - } - return output; -} - - -string Consistency_Logic::verseText (string resource, int book, int chapter, int verse) -{ - return resource_logic_get_html (m_webserver_request, resource, book, chapter, verse, false); -} - - -// This function omits the verse text from a line of text from the search results. -string Consistency_Logic::omit_verse_text (string input) -{ - // Imagine the following $input: - // 1 Peter 4:17 For the time has come for judgment to begin with the household of God. If it begins first with us, what will happen to those who don’t obey the Good News of God? - // The purpose of this function is to extract "1 Peter 4:17" from it, and leave the rest out. - // This is done by leaving out everything after the last numeral. - size_t length = filter::strings::unicode_string_length (input); - size_t last_numeral = 0; - for (size_t i = 0; i < length; i++) { - string character = filter::strings::unicode_string_substr (input, i, 1); - if (filter::strings::is_numeric (character)) { - last_numeral = i; - } - } - last_numeral++; - input = filter::strings::unicode_string_substr (input, 0, last_numeral); - return input; -} diff --git a/consistency/logic.h b/consistency/logic.h deleted file mode 100644 index e0b2551f1..000000000 --- a/consistency/logic.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -class Consistency_Logic -{ -public: - Consistency_Logic (Webserver_Request& webserver_request, int id); - std::string response (); -private: - Webserver_Request& m_webserver_request; - int m_id {0}; - std::string verseText (std::string resource, int book, int chapter, int verse); - std::string omit_verse_text (std::string input); -}; diff --git a/consistency/poll.cpp b/consistency/poll.cpp deleted file mode 100644 index 404db0781..000000000 --- a/consistency/poll.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -string consistency_poll_url () -{ - return "consistency/poll"; -} - - -bool consistency_poll_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -string consistency_poll (Webserver_Request& webserver_request) -{ - const int id = filter::strings::convert_to_int (webserver_request.query ["id"]); - Consistency_Logic consistency_logic = Consistency_Logic (webserver_request, id); - const string response = consistency_logic.response (); - if (response != Database_Volatile::getValue (id, "response")) { - Database_Volatile::setValue (id, "response", response); - return response; - } - return ""; -} diff --git a/consistency/poll.h b/consistency/poll.h deleted file mode 100644 index 43a91129f..000000000 --- a/consistency/poll.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string consistency_poll_url (); -bool consistency_poll_acl (Webserver_Request& webserver_request); -std::string consistency_poll (Webserver_Request& webserver_request); diff --git a/database/abbottsmith.cpp b/database/abbottsmith.cpp deleted file mode 100644 index 55e1715e8..000000000 --- a/database/abbottsmith.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// This is the database that contains Abbott-Smith's Manual Greek Lexicon. -// Resilience: It is not written to. -// Chances of corruption are nearly zero. - - -const char * Database_AbbottSmith::filename () -{ - return "abbottsmith"; -} - - -void Database_AbbottSmith::create () -{ - filter_url_unlink (database_sqlite_file (filename ())); - - SqliteDatabase sql = SqliteDatabase (filename ()); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS entry (lemma text, lemmacf text, strong text, contents string);"); - sql.execute (); -} - - -void Database_AbbottSmith::optimize () -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("VACUUM;"); - sql.execute (); -} - - -void Database_AbbottSmith::store (string lemma, string lemma_casefold, string strong, string contents) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("PRAGMA temp_store = MEMORY;"); - sql.execute (); - sql.clear (); - sql.add ("PRAGMA synchronous = OFF;"); - sql.execute (); - sql.clear (); - sql.add ("PRAGMA journal_mode = OFF;"); - sql.execute (); - sql.clear (); - sql.add ("INSERT INTO entry (lemma, lemmacf, strong, contents) VALUES ("); - sql.add (lemma); - sql.add (","); - sql.add (lemma_casefold); - sql.add (","); - sql.add (strong); - sql.add (","); - sql.add (contents); - sql.add (");"); - sql.execute (); -} - - -string Database_AbbottSmith::get (string lemma, string strong) -{ - string contents; - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT contents FROM entry WHERE"); - if (lemma.empty()) { - // No lemma: Select on Strong's number only. - sql.add ("strong ="); - sql.add (strong); - } else if (strong.empty()) { - // No Strong's number: Select on lemma only. - sql.add ("lemma ="); - sql.add (lemma); - } else { - // Both Strong's number and lemma given: Select on any of those. - sql.add ("lemma ="); - sql.add (lemma); - sql.add ("OR"); - sql.add ("strong ="); - sql.add (strong); - } - sql.add (";"); - vector results = sql.query () ["contents"]; - for (auto result : results) contents.append (result); - return contents; -} - diff --git a/database/abbottsmith.h b/database/abbottsmith.h deleted file mode 100644 index e069a69e8..000000000 --- a/database/abbottsmith.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_AbbottSmith -{ -public: - void create (); - void optimize (); - void store (std::string lemma, std::string lemma_casefold, std::string strong, std::string contents); - std::string get (std::string lemma, std::string strong); -private: - const char * filename (); -}; diff --git a/database/bibleactions.cpp b/database/bibleactions.cpp deleted file mode 100644 index f697fda40..000000000 --- a/database/bibleactions.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -const char * Database_BibleActions::filename () -{ - return "bibleactions"; -} - - -void Database_BibleActions::create () -{ - SqliteDatabase sql (filename ()); - sql.add ("CREATE TABLE IF NOT EXISTS bibleactions (" - " bible text," - " book integer," - " chapter integer," - " usfm text" - ");"); - sql.execute (); -} - - -void Database_BibleActions::clear () -{ - SqliteDatabase sql (filename ()); - sql.add ("DROP TABLE IF EXISTS bibleactions;"); - sql.execute (); -} - - -void Database_BibleActions::optimize () -{ - SqliteDatabase sql (filename ()); - sql.add ("VACUUM;"); - sql.execute (); -} - - -void Database_BibleActions::record (string bible, int book, int chapter, string usfm) -{ - if (getUsfm (bible, book, chapter).empty ()) { - SqliteDatabase sql (filename ()); - sql.add ("INSERT INTO bibleactions VALUES ("); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (usfm); - sql.add (");"); - sql.execute (); - } -} - - -vector Database_BibleActions::getBibles () -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT DISTINCT bible FROM bibleactions ORDER BY bible;"); - vector notes = sql.query ()["bible"]; - return notes; -} - - -vector Database_BibleActions::getBooks (string bible) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT DISTINCT book FROM bibleactions WHERE bible ="); - sql.add (bible); - sql.add ("ORDER BY book;"); - vector result = sql.query ()["book"]; - vector books; - for (auto book : result) books.push_back (filter::strings::convert_to_int (book)); - return books; -} - - -vector Database_BibleActions::getChapters (string bible, int book) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT DISTINCT chapter FROM bibleactions WHERE bible ="); - sql.add (bible); - sql.add ("AND book ="); - sql.add (book); - sql.add ("ORDER BY chapter;"); - vector result = sql.query ()["chapter"]; - vector chapters; - for (auto chapter : result) chapters.push_back (filter::strings::convert_to_int (chapter)); - return chapters; -} - - -string Database_BibleActions::getUsfm (string bible, int book, int chapter) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT usfm FROM bibleactions WHERE bible ="); - sql.add (bible); - sql.add ("AND book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add (";"); - vector result = sql.query ()["usfm"]; - if (!result.empty()) { - string usfm = result[0]; - return usfm; - }; - return string(); -} - - -void Database_BibleActions::erase (string bible, int book, int chapter) -{ - SqliteDatabase sql (filename ()); - sql.add ("DELETE FROM bibleactions WHERE bible ="); - sql.add (bible); - sql.add ("AND book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add (";"); - sql.execute (); -} - diff --git a/database/bibleactions.h b/database/bibleactions.h deleted file mode 100644 index 05ac17333..000000000 --- a/database/bibleactions.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_BibleActions -{ -public: - void create (); - void clear (); - void optimize (); - void record (std::string bible, int book, int chapter, std::string usfm); - std::vector getBibles (); - std::vector getBooks (std::string bible); - std::vector getChapters (std::string bible, int book); - std::string getUsfm (std::string bible, int book, int chapter); - void erase (std::string bible, int book, int chapter); -private: - const char * filename (); -}; diff --git a/database/bibleimages.cpp b/database/bibleimages.cpp deleted file mode 100644 index e9d8e6cfc..000000000 --- a/database/bibleimages.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: -// The data is stored as images and files in the filesystem. -// That should be resilient enough. - - -vector Database_BibleImages::get () -{ - vector files = filter_url_scandir (folder ()); - vector images; - for (auto file : files) { - string extension = filter_url_get_extension (file); - if (extension == "o") continue; - if (extension == "h") continue; - if (extension == "cpp") continue; - if (extension == "html") continue; - images.push_back (file); - } - return images; -} - - -void Database_BibleImages::store (string file) -{ - string image = filter_url_basename (file); - filter_url_file_cp (file, path (image)); -} - - -string Database_BibleImages::get (string image) -{ - string contents = filter_url_file_get_contents (path(image)); - return contents; -} - - -void Database_BibleImages::erase (string image) -{ - string filepath = path(image); - filter_url_unlink (filepath); -} - - -string Database_BibleImages::folder () -{ - return filter_url_create_root_path ({"images"}); -} - - -string Database_BibleImages::path (string image) -{ - return filter_url_create_path ({folder (), image}); -} - - diff --git a/database/bibleimages.h b/database/bibleimages.h deleted file mode 100644 index d456865b2..000000000 --- a/database/bibleimages.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_BibleImages -{ -public: - std::vector get (); - void store (std::string file); - std::string get (std::string image); - void erase (std::string image); -private: - std::string folder (); - std::string path (std::string image); -}; diff --git a/database/bibles.cpp b/database/bibles.cpp deleted file mode 100644 index 0b3afb009..000000000 --- a/database/bibles.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// This database stores its data in files in the filesystem. -// This is a robust and reliable way of storing data. -// Because no real database is used, no database can get corrupted. - - -std::string Database_Bibles::main_folder () -{ - return filter_url_create_root_path ({"bibles"}); -} - - -std::string Database_Bibles::bible_folder (const std::string& bible) -{ - return filter_url_create_path ({main_folder (), bible}); -} - - -std::string Database_Bibles::book_folder (const std::string& bible, int book) -{ - return filter_url_create_path ({bible_folder (bible), filter::strings::convert_to_string (book)}); -} - - -std::string Database_Bibles::chapter_folder (const std::string& bible, int book, int chapter) -{ - return filter_url_create_path ({book_folder (bible, book), filter::strings::convert_to_string (chapter)}); -} - - -// Returns an array with the available Bibles. -std::vector Database_Bibles::get_bibles () -{ - const std::vector bibles {filter_url_scandir (main_folder ())}; - return bibles; -} - - -// Creates a new empty Bible. Returns its ID. -void Database_Bibles::create_bible (const std::string& name) -{ - // Create the empty system. - const std::string folder = bible_folder (name); - filter_url_mkdir (folder); - Database_State::setExport (name, 0, export_logic::export_needed); -} - - -// Deletes a Bible. -void Database_Bibles::delete_bible (const std::string& name) -{ - const std::string path = bible_folder (name); - // Delete directory. - filter_url_rmdir (path); - // Just in case it was a regular file: Delete it. - filter_url_unlink (path); - Database_State::setExport (name, 0, export_logic::export_needed); -} - - -// Stores data of one chapter in Bible $name, -void Database_Bibles::store_chapter (const std::string& name, int book, int chapter_number, std::string chapter_text) -{ - const std::string folder = chapter_folder (name, book, chapter_number); - if (!file_or_dir_exists (folder)) filter_url_mkdir (folder); - - // Ensure that the data to be stored ends with a new line. - if (!chapter_text.empty ()) { - const size_t pos = chapter_text.length () - 1; - if (chapter_text.substr (pos, 1) != "\n") { - chapter_text.append ("\n"); - } - } - // Increase the chapter identifier, and store the chapter data. - int id = get_chapter_id (name, book, chapter_number); - id++; - const std::string file = filter_url_create_path ({folder, filter::strings::convert_to_string (id)}); - filter_url_file_put_contents (file, chapter_text); - - // Update search fields. - update_search_fields (name, book, chapter_number); - - Database_State::setExport (name, 0, export_logic::export_needed); -} - - -void Database_Bibles::update_search_fields (const std::string& name, int book, int chapter) -{ - search_logic_index_chapter (name, book, chapter); -} - - -// Returns an array with the available books in a Bible. -std::vector Database_Bibles::get_books (const std::string& bible) -{ - // Read the books from the database. - const std::string folder = bible_folder (bible); - const std::vector files = filter_url_scandir (folder); - std::vector books {}; - for (const auto& book : files) { - if (filter::strings::is_numeric (book)) { - books.push_back (filter::strings::convert_to_int (book)); - } - } - - // Sort the books according to the order defined in the books database. - std::vector order {}; - for (auto book_number : books) { - const book_id book_enum = static_cast(book_number); - order.push_back (database::books::get_order_from_id (book_enum)); - } - filter::strings::quick_sort (order, books, 0, static_cast(order.size())); - - // Result. - return books; -} - - -void Database_Bibles::delete_book (const std::string& bible, int book) -{ - const std::string folder = book_folder (bible, book); - filter_url_rmdir (folder); - Database_State::setExport (bible, 0, export_logic::export_needed); -} - - -// Returns an array with the available chapters in a $book in a Bible. -std::vector Database_Bibles::get_chapters (const std::string& bible, int book) -{ - // Read the chapters from the database. - const std::string folder = book_folder (bible, book); - std::vector chapters; - const std::vector files = filter_url_scandir (folder); - for (const auto& file : files) { - if (filter::strings::is_numeric (file)) chapters.push_back (filter::strings::convert_to_int (file)); - } - std::sort (chapters.begin (), chapters.end ()); - return chapters; -} - - -void Database_Bibles::delete_chapter (const std::string& bible, int book, int chapter) -{ - const std::string folder = chapter_folder (bible, book, chapter); - filter_url_rmdir (folder); - Database_State::setExport (bible, 0, export_logic::export_needed); -} - - -// Gets the chapter data as a string. -std::string Database_Bibles::get_chapter (const std::string& bible, int book, int chapter) -{ - // Read the chapter data from the database. - const std::string folder = chapter_folder (bible, book, chapter); - const std::vector files = filter_url_scandir (folder); - if (!files.empty ()) { - const std::string file = files.at(files.size() - 1); - std::string data = filter_url_file_get_contents (filter_url_create_path ({folder, file})); - // Remove trailing new line. - data = filter::strings::trim (data); - return data; - } - return std::string(); -} - - -// Gets the chapter id. -int Database_Bibles::get_chapter_id (const std::string& bible, int book, int chapter) -{ - const std::string folder = chapter_folder (bible, book, chapter); - const std::vector files = filter_url_scandir (folder); - if (!files.empty ()) { - const std::string file = files.at(files.size() - 1); - return filter::strings::convert_to_int (file); - } - return 100'000'000; -} - - -// Gets the chapter's time stamp in seconds since the Epoch. -int Database_Bibles::get_chapter_age (const std::string& bible, int book, int chapter) -{ - const std::string folder = chapter_folder (bible, book, chapter); - const std::vector files = filter_url_scandir (folder); - if (!files.empty ()) { - const std::string file = files.at(files.size() - 1); - const std::string path = filter_url_create_path ({folder, file}); - const int time = filter_url_file_modification_time (path); - const int now = filter::date::seconds_since_epoch (); - return now - time; - } - return 100'000'000; -} - - -void Database_Bibles::optimize () -{ - // Go through all chapters in all books and all Ḃibles. - const std::vector bibles = get_bibles (); - for (const auto& bible : bibles) { - const std::vector books = get_books (bible); - for (int book : books) { - const std::vector chapters = get_chapters (bible, book); - for (int chapter : chapters) { - const std::string folder = chapter_folder (bible, book, chapter); - // Read the files in the folder. - const std::vector files = filter_url_scandir (folder); - // Remove files with 0 size. so that in case a chapter was emptied by accident, - // it is removed now, effectually reverting the chapter to an earlier version. - std::vector files2 {}; - for (const auto& file : files) { - const std::string path = filter_url_create_path ({folder, file}); - if (filter_url_filesize (path) == 0) { - filter_url_unlink (path); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - else files2.push_back (file); - } - // Remove the three most recent files from the array, so they don't get deleted. - // Because scandir sorts the files, the files to be kept are at the end. - if (!files2.empty()) files2.pop_back (); - if (!files2.empty()) files2.pop_back (); - if (!files2.empty()) files2.pop_back (); - // Remove the remaining files. These are the older versions. - for (const auto& file : files2) { - const std::string path = filter_url_create_path ({folder, file}); - filter_url_unlink (path); - } - } - } - } -} - diff --git a/database/bibles.h b/database/bibles.h deleted file mode 100644 index 25fca83b9..000000000 --- a/database/bibles.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Bibles -{ -public: - std::vector get_bibles (); - void create_bible (const std::string& name); - void delete_bible (const std::string& name); - void store_chapter (const std::string& name, int book, int chapter_number, std::string chapter_text); - void update_search_fields (const std::string& name, int book, int chapter); - std::vector get_books (const std::string& bible); - void delete_book (const std::string& bible, int book); - std::vector get_chapters (const std::string& bible, int book); - void delete_chapter (const std::string& bible, int book, int chapter); - std::string get_chapter (const std::string& bible, int book, int chapter); - int get_chapter_id (const std::string& bible, int book, int chapter); - int get_chapter_age (const std::string& bible, int book, int chapter); - void optimize (); -private: - std::string main_folder (); -public: - std::string bible_folder (const std::string& bible); -private: - std::string book_folder (const std::string& bible, int book); - std::string chapter_folder (const std::string& bible, int book, int chapter); -}; diff --git a/database/books.cpp b/database/books.cpp deleted file mode 100644 index a856aa2a3..000000000 --- a/database/books.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -namespace database::books { - - -// Internal function for the number of data elements. -constexpr size_t data_count = sizeof (books_table) / sizeof (*books_table); - - -std::vector get_ids () -{ - vector ids; - for (unsigned int i = 0; i < data_count; i++) { - book_id id = books_table[i].id; - ids.push_back (id); - } - return ids; -} - - -book_id get_id_from_english (const string & english) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (english == books_table[i].english) { - return books_table[i].id; - } - } - return book_id::_unknown; -} - - -string get_english_from_id (book_id id) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (id == books_table[i].id) { - return books_table[i].english; - } - } - return translate ("Unknown"); -} - - -string get_usfm_from_id (book_id id) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (id == books_table[i].id) { - return books_table[i].usfm; - } - } - return "XXX"; -} - - -string get_bibleworks_from_id (book_id id) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (id == books_table[i].id) { - return books_table[i].bibleworks; - } - } - return "Xxx"; -} - - -string get_osis_from_id (book_id id) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (id == books_table[i].id) { - return books_table[i].osis; - } - } - return translate ("Unknown"); -} - - -book_id get_id_from_usfm (const string & usfm) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (usfm == books_table[i].usfm) { - return books_table[i].id; - } - } - return book_id::_unknown; -} - - -book_id get_id_from_osis (const string & osis) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (osis == books_table[i].osis) { - return books_table[i].id; - } - } - return book_id::_unknown; -} - - -book_id get_id_from_bibleworks (const string & bibleworks) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (bibleworks == books_table[i].bibleworks) { - return books_table[i].id; - } - } - return book_id::_unknown; -} - - -// Tries to interprete $text as the name of a Bible book. -// Returns the book's identifier if it succeeds. -// If it fails, it returns 0. -book_id get_id_like_text (const string & text) -{ - // Go through all known book names and abbreviations. - // Note how much the $text differs from the known names. - // Then return the best match. - vector ids {}; - vector similarities {}; - for (unsigned int i = 0; i < data_count; i++) { - int id {static_cast(books_table[i].id)}; - ids.push_back (id); - similarities.push_back (filter_diff_character_similarity (text, filter::strings::unicode_string_casefold(books_table[i].english))); - ids.push_back (id); - similarities.push_back (filter_diff_character_similarity (text, filter::strings::unicode_string_casefold(books_table[i].osis))); - ids.push_back (id); - similarities.push_back (filter_diff_character_similarity (text, books_table[i].usfm)); - ids.push_back (id); - similarities.push_back (filter_diff_character_similarity (text, filter::strings::unicode_string_casefold(books_table[i].bibleworks))); - ids.push_back (id); - similarities.push_back (filter_diff_character_similarity (text, filter::strings::unicode_string_casefold(books_table[i].onlinebible))); - } - filter::strings::quick_sort (similarities, ids, 0, static_cast(ids.size())); - int id = ids.back (); - return static_cast(id); -} - - -book_id get_id_from_onlinebible (const string & onlinebible) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (onlinebible == books_table[i].onlinebible) { - return books_table[i].id; - } - } - return book_id::_unknown; -} - - -string get_onlinebible_from_id (book_id id) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (id == books_table[i].id) { - return books_table[i].onlinebible; - } - } - return string(); -} - - -short get_order_from_id (book_id id) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (id == books_table[i].id) { - return books_table[i].order; - } - } - return 0; -} - - -book_type get_type (book_id id) -{ - for (unsigned int i = 0; i < data_count; i++) { - if (id == books_table[i].id) { - return books_table[i].type; - } - } - return book_type::unknown; -} - - -std::string book_type_to_string (book_type type) -{ - switch (type) { - case book_type::unknown: return string(); - case book_type::old_testament: return "ot"; - case book_type::new_testament: return "nt"; - case book_type::front_back: return "frontback"; - case book_type::other: return "other"; - case book_type::apocryphal: return "ap"; - default: return string(); - } - return string(); -} - - -} // End of namespace. diff --git a/database/books.h b/database/books.h deleted file mode 100644 index bb4b85180..000000000 --- a/database/books.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -enum class book_type { - unknown, - old_testament, - new_testament, - front_back, - other, - apocryphal, -}; - -enum class book_id { - _unknown = 0, - _genesis = 1, - _exodus = 2, - _leviticus = 3, - _numbers = 4, - _deuteronomy = 5, - _joshua = 6, - _judges = 7, - _ruth = 8, - _1_samuel = 9, - _2_samuel = 10, - _1_kings = 11, - _2_kings = 12, - _1_chronicles = 13, - _2_chronicles = 14, - _ezra = 15, - _nehemiah = 16, - _esther = 17, - _job = 18, - _psalms = 19, - _proverbs = 20, - _ecclesiastes = 21, - _song_of_solomon = 22, - _isaiah = 23, - _jeremiah = 24, - _lamentations = 25, - _ezekiel = 26, - _daniel = 27, - _hosea = 28, - _joel = 29, - _amos = 30, - _obadiah = 31, - _jonah = 32, - _micah = 33, - _nahum = 34, - _habakkuk = 35, - _zephaniah = 36, - _haggai = 37, - _zechariah = 38, - _malachi = 39, - _matthew = 40, - _mark = 41, - _luke = 42, - _john = 43, - _acts = 44, - _romans = 45, - _1_corinthians = 46, - _2_corinthians = 47, - _galatians = 48, - _ephesians = 49, - _philippians = 50, - _colossians = 51, - _1_thessalonians = 52, - _2_thessalonians = 53, - _1_timothy = 54, - _2_timothy = 55, - _titus = 56, - _philemon = 57, - _hebrews = 58, - _james = 59, - _1_peter = 60, - _2_peter = 61, - _1_john = 62, - _2_john = 63, - _3_john = 64, - _jude = 65, - _revelation = 66, - _front_matter = 67, - _back_matter = 68, - _other_material = 69, - _tobit = 70, - _judith = 71, - _esther_greek = 72, - _wisdom_of_solomon = 73, - _sirach = 74, - _baruch = 75, - _letter_of_jeremiah = 76, - _song_of_the_three_children = 77, - _susanna = 78, - _bel_and_the_dragon = 79, - _1_maccabees = 80, - _2_maccabees = 81, - _1_esdras_greek = 82, - _prayer_of_manasses = 83, - _psalm_151 = 84, - _3_maccabees = 85, - _2_esdras_latin = 86, - _4_maccabees = 87, - _daniel_greek = 88, - _odes = 89, - _psalms_of_solomon = 90, - _ezra_apocalypse = 91, - _5_ezra = 92, - _6_ezra = 93, - _psalms_152_155 = 94, - _2_baruch_apocalypse = 95, - _letter_of_baruch = 96, - _jubilees = 97, - _enoch = 98, - _1_meqabyan_mekabis = 99, - _2_meqabyan_mekabis = 100, - _3_meqabyan_mekabis = 101, - _reproof = 102, - _4_baruch = 103, - _letter_to_the_laodiceans = 104, - _introduction_matter = 105, - _concordance = 106, - _glossary_wordlist = 107, - _topical_index = 108, - _names_index = 109, -}; - -namespace database::books { - -std::vector get_ids (); -book_id get_id_from_english (const std::string & english); -std::string get_english_from_id (book_id id); -std::string get_usfm_from_id (book_id id); -std::string get_bibleworks_from_id (book_id id); -std::string get_osis_from_id (book_id id); -book_id get_id_from_usfm (const std::string & usfm); -book_id get_id_from_osis (const std::string & osis); -book_id get_id_from_bibleworks (const std::string & bibleworks); -book_id get_id_like_text (const std::string & text); -book_id get_id_from_onlinebible (const std::string & onlinebible); -std::string get_onlinebible_from_id (book_id id); -short get_order_from_id (book_id id); -book_type get_type (book_id id); -std::string book_type_to_string (book_type type); - -} diff --git a/database/booksdata.h b/database/booksdata.h deleted file mode 100644 index a36af5645..000000000 --- a/database/booksdata.h +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -// All data is stored in the code in memory, not in a database on disk. - - -typedef struct -{ - const char *english; // English name. - const char *osis; // OSIS abbreviation. - const char *usfm; // USFM ID. - const char *bibleworks; // BibleWorks abbreviation. - const char *onlinebible; // Online Bible abbreviation. - book_id id; // Bibledit's internal book identifier as an enum. - short order; // The order of the books. - book_type type; // The type of the book as an enum. - bool onechapter; // Whether the book has one chapter. -} book_record; - - -/* -This table gives the books Bibledit knows about. -The books are put in the standard order. - -A note about this data. - -* The id should always be a number higher than 0, because 0 is taken for "not found". -* The id is connected to a book, and is used throughout the databases. - Therefore, ids are not supposed to be changed; new ones can be added though. -* The order describes the order of the books. Books may be assigned an updated order when needed. -* type: One of the following - frontback - Frontmatter / Backmatter - ot - Old Testament - nt - New Testament - other - Other matter - ap - Apocrypha -*/ -constexpr book_record books_table [] = -{ - {"Genesis", "Gen", "GEN", "Gen", "Ge", book_id::_genesis, 3, book_type::old_testament, false}, // ‘1 Moses’ in some Bibles. - {"Exodus", "Exod", "EXO", "Exo", "Ex", book_id::_exodus, 4, book_type::old_testament, false}, // ‘2 Moses’ in some Bibles. - {"Leviticus", "Lev", "LEV", "Lev", "Le", book_id::_leviticus, 5, book_type::old_testament, false}, // ‘3 Moses’ in some Bibles. - {"Numbers", "Num", "NUM", "Num", "Nu", book_id::_numbers, 6, book_type::old_testament, false}, // ‘4 Moses’ in some Bibles. - {"Deuteronomy", "Deut", "DEU", "Deu", "De", book_id::_deuteronomy, 7, book_type::old_testament, false}, // ‘5 Moses’ in some Bibles. - {"Joshua", "Josh", "JOS", "Jos", "Jos", book_id::_joshua, 8, book_type::old_testament, false}, - {"Judges", "Judg", "JDG", "Jdg", "Jud", book_id::_judges, 9, book_type::old_testament, false}, - {"Ruth", "Ruth", "RUT", "Rut", "Ru", book_id::_ruth, 10, book_type::old_testament, false}, - {"1 Samuel", "1Sam", "1SA", "1Sa", "1Sa", book_id::_1_samuel, 11, book_type::old_testament, false}, // 1 Kings or Kingdoms in Orthodox Bibles. Do not confuse this abbreviation with ISA for Isaiah. - {"2 Samuel", "2Sam", "2SA", "2Sa", "2Sa", book_id::_2_samuel, 12, book_type::old_testament, false}, // 2 Kings or Kingdoms in Orthodox Bibles. - {"1 Kings", "1Kgs", "1KI", "1Ki", "1Ki", book_id::_1_kings, 13, book_type::old_testament, false}, // 3 Kings or Kingdoms in Orthodox Bibles. - {"2 Kings", "2Kgs", "2KI", "2Ki", "2Ki", book_id::_2_kings, 14, book_type::old_testament, false}, // 4 Kings or Kingdoms in Orthodox Bibles. - {"1 Chronicles", "1Chr", "1CH", "1Ch", "1Ch", book_id::_1_chronicles, 15, book_type::old_testament, false}, // 1 Paralipomenon in Orthodox Bibles. - {"2 Chronicles", "2Chr", "2CH", "2Ch", "2Ch", book_id::_2_chronicles, 16, book_type::old_testament, false}, // 2 Paralipomenon in Orthodox Bibles. - {"Ezra", "Ezra", "EZR", "Ezr", "Ezr", book_id::_ezra, 17, book_type::old_testament, false}, // This is for Hebrew Ezra, sometimes called 1 Ezra or 1 Esdras. Also for Ezra-Nehemiah when one book. - {"Nehemiah", "Neh", "NEH", "Neh", "Ne", book_id::_nehemiah, 18, book_type::old_testament, false}, // Sometimes appended to Ezra; called 2 Esdras in the Vulgate. - {"Esther", "Esth", "EST", "Est", "Es", book_id::_esther, 19, book_type::old_testament, false}, // This is for Hebrew Esther. For the longer Greek LXX Esther use ESG. - {"Job", "Job", "JOB", "Job", "Job", book_id::_job, 20, book_type::old_testament, false}, - {"Psalms", "Ps", "PSA", "Psa", "Ps", book_id::_psalms, 21, book_type::old_testament, false}, // 150 Psalms in Hebrew, 151 Psalms in Orthodox Bibles, 155 Psalms in West Syriac Bibles. If you put Psalm 151 separately in an Apocrypha use PS2, for Psalms 152-155 use PS3. - {"Proverbs", "Prov", "PRO", "Pro", "Pr", book_id::_proverbs, 22, book_type::old_testament, false}, // 31 Proverbs, but 24 Proverbs in the Ethiopian Bible. - {"Ecclesiastes", "Eccl", "ECC", "Ecc", "Ec", book_id::_ecclesiastes, 23, book_type::old_testament, false}, // Qoholeth in Catholic Bibles; for Ecclesiasticus use SIR. - {"Song of Solomon", "Song", "SNG", "Sol", "So", book_id::_song_of_solomon, 24, book_type::old_testament, false}, // Song of Solomon, or Canticles of Canticles in Catholic Bibles. - {"Isaiah", "Isa", "ISA", "Isa", "Isa", book_id::_isaiah, 25, book_type::old_testament, false}, // Do not confuse this abbreviation with 1SA for 1 Samuel. - {"Jeremiah", "Jer", "JER", "Jer", "Jer", book_id::_jeremiah, 26, book_type::old_testament, false}, // The Book of Jeremiah; for the Letter of Jeremiah use LJE. - {"Lamentations", "Lam", "LAM", "Lam", "La", book_id::_lamentations, 27, book_type::old_testament, false}, // The Lamentations of Jeremiah. - {"Ezekiel", "Ezek", "EZK", "Eze", "Eze", book_id::_ezekiel, 28, book_type::old_testament, false}, - {"Daniel", "Dan", "DAN", "Dan", "Da", book_id::_daniel, 29, book_type::old_testament, false}, // This is for Hebrew Daniel; for the longer Greek LXX Daniel use DAG. - {"Hosea", "Hos", "HOS", "Hos", "Ho", book_id::_hosea, 30, book_type::old_testament, false}, - {"Joel", "Joel", "JOL", "Joe", "Joe", book_id::_joel, 31, book_type::old_testament, false}, - {"Amos", "Amos", "AMO", "Amo", "Am", book_id::_amos, 32, book_type::old_testament, false}, - {"Obadiah", "Obad", "OBA", "Oba", "Ob", book_id::_obadiah, 33, book_type::old_testament, true}, - {"Jonah", "Jonah", "JON", "Jon", "Jon", book_id::_jonah, 34, book_type::old_testament, false}, // Do not confuse this abbreviation with JHN for John. - {"Micah", "Mic", "MIC", "Mic", "Mic", book_id::_micah, 35, book_type::old_testament, false}, - {"Nahum", "Nah", "NAM", "Nah", "Na", book_id::_nahum, 36, book_type::old_testament, false}, - {"Habakkuk", "Hab", "HAB", "Hab", "Hab", book_id::_habakkuk, 37, book_type::old_testament, false}, - {"Zephaniah", "Zeph", "ZEP", "Zep", "Zep", book_id::_zephaniah, 38, book_type::old_testament, false}, - {"Haggai", "Hag", "HAG", "Hag", "Hag", book_id::_haggai, 39, book_type::old_testament, false}, - {"Zechariah", "Zech", "ZEC", "Zec", "Zec", book_id::_zechariah, 40, book_type::old_testament, false}, - {"Malachi", "Mal", "MAL", "Mal", "Mal", book_id::_malachi, 41, book_type::old_testament, false}, - {"Matthew", "Matt", "MAT", "Mat", "Mt", book_id::_matthew, 42, book_type::new_testament, false}, // The Gospel according to Matthew. - {"Mark", "Mark", "MRK", "Mar", "Mr", book_id::_mark, 43, book_type::new_testament, false}, // The Gospel according to Mark. - {"Luke", "Luke", "LUK", "Luk", "Lu", book_id::_luke, 44, book_type::new_testament, false}, // The Gospel according to Luke. - {"John", "John", "JHN", "Joh", "Joh", book_id::_john, 45, book_type::new_testament, false}, // The Gospel according to John. - {"Acts", "Acts", "ACT", "Act", "Ac", book_id::_acts, 46, book_type::new_testament, false}, // The Acts of the Apostles. - {"Romans", "Rom", "ROM", "Rom", "Ro", book_id::_romans, 47, book_type::new_testament, false}, // The Letter of Paul to the Romans. - {"1 Corinthians", "1Cor", "1CO", "1Co", "1Co", book_id::_1_corinthians, 48, book_type::new_testament, false}, // The First Letter of Paul to the Corinthians. - {"2 Corinthians", "2Cor", "2CO", "2Co", "2Co", book_id::_2_corinthians, 49, book_type::new_testament, false}, // The Second Letter of Paul to the Corinthians. - {"Galatians", "Gal", "GAL", "Gal", "Ga", book_id::_galatians, 50, book_type::new_testament, false}, // The Letter of Paul to the Galatians. - {"Ephesians", "Eph", "EPH", "Eph", "Eph", book_id::_ephesians, 51, book_type::new_testament, false}, // The Letter of Paul to the Ephesians. - {"Philippians", "Phil", "PHP", "Phi", "Php", book_id::_philippians, 52, book_type::new_testament, false}, // The Letter of Paul to the Philippians. - {"Colossians", "Col", "COL", "Col", "Col", book_id::_colossians, 53, book_type::new_testament, false}, // The Letter of Paul to the Colossians. - {"1 Thessalonians", "1Thess", "1TH", "1Th", "1Th", book_id::_1_thessalonians, 54, book_type::new_testament, false}, // The First Letter of Paul to the Thessalonians. - {"2 Thessalonians", "2Thess", "2TH", "2Th", "2Th", book_id::_2_thessalonians, 55, book_type::new_testament, false}, // The Second Letter of Paul to the Thessalonians. - {"1 Timothy", "1Tim", "1TI", "1Ti", "1Ti", book_id::_1_timothy, 56, book_type::new_testament, false}, // The First Letter of Paul to Timothy. - {"2 Timothy", "2Tim", "2TI", "2Ti", "2Ti", book_id::_2_timothy, 57, book_type::new_testament, false}, // The Second Letter of Paul to Timothy. - {"Titus", "Titus", "TIT", "Tit", "Tit", book_id::_titus, 58, book_type::new_testament, false}, // The Letter of Paul to Titus. - {"Philemon", "Phlm", "PHM", "Phm", "Phm", book_id::_philemon, 59, book_type::new_testament, true}, // The Letter of Paul to Philemon. - {"Hebrews", "Heb", "HEB", "Heb", "Heb", book_id::_hebrews, 60, book_type::new_testament, false}, // The Letter to the Hebrews. - {"James", "Jas", "JAS", "Jam", "Jas", book_id::_james, 61, book_type::new_testament, false}, // The Letter of James. - {"1 Peter", "1Pet", "1PE", "1Pe", "1Pe", book_id::_1_peter, 62, book_type::new_testament, false}, // The First Letter of Peter. - {"2 Peter", "2Pet", "2PE", "2Pe", "2Pe", book_id::_2_peter, 63, book_type::new_testament, false}, // The Second Letter of Peter. - {"1 John", "1John", "1JN", "1Jo", "1Jo", book_id::_1_john, 64, book_type::new_testament, false}, // The First Letter of John. - {"2 John", "2John", "2JN", "2Jo", "2Jo", book_id::_2_john, 65, book_type::new_testament, false}, // The Second Letter of John. - {"3 John", "3John", "3JN", "3Jo", "3Jo", book_id::_3_john, 66, book_type::new_testament, true}, // The Third Letter of John. - {"Jude", "Jude", "JUD", "Jud", "Jude", book_id::_jude, 67, book_type::new_testament, true}, // The Letter of Jude; do not confuse this abbreviation with JDG for Judges, or JDT for Judith. - {"Revelation", "Rev", "REV", "Rev", "Re", book_id::_revelation, 68, book_type::new_testament, false}, // The Revelation to John; called Apocalypse in Catholic Bibles. - {"Front Matter", "", "FRT", "", "", book_id::_front_matter, 1, book_type::front_back, false}, - {"Back Matter", "", "BAK", "", "", book_id::_back_matter, 69, book_type::front_back, false}, - {"Other Material", "", "OTH", "", "", book_id::_other_material, 70, book_type::other, false}, - {"Tobit", "Tob", "TOB", "Tob", "", book_id::_tobit, 71, book_type::apocryphal, false}, - {"Judith", "Jdt", "JDT", "Jdt", "", book_id::_judith, 72, book_type::apocryphal, false}, - {"Esther (Greek)", "AddEsth", "ESG", "EsG", "", book_id::_esther_greek, 73, book_type::apocryphal, false}, - {"Wisdom of Solomon", "Wis", "WIS", "Wis", "", book_id::_wisdom_of_solomon, 74, book_type::apocryphal, false}, - {"Sirach", "Sir", "SIR", "Sir", "", book_id::_sirach, 75, book_type::apocryphal, false}, // Ecclesiasticus or Jesus son of Sirach. - {"Baruch", "Bar", "BAR", "Bar", "", book_id::_baruch, 76, book_type::apocryphal, false}, // 5 chapters in Orthodox Bibles (LJE is separate); 6 chapters in Catholic Bibles (includes LJE); called 1 Baruch in Syriac Bibles. - {"Letter of Jeremiah", "EpJer", "LJE", "LJe", "", book_id::_letter_of_jeremiah, 77, book_type::apocryphal, true}, // Sometimes included in Baruch; called ‘Rest of Jeremiah’ in Ethiopia. - {"Song of the Three Children", "PrAzar", "S3Y", "S3Y", "", book_id::_song_of_the_three_children, 78, book_type::apocryphal, true}, // Includes the Prayer of Azariah; sometimes included in Greek Daniel. - {"Susanna", "Sus", "SUS", "Sus", "", book_id::_susanna, 79, book_type::apocryphal, true}, // Sometimes included in Greek Daniel. - {"Bel and the Dragon", "Bel", "BEL", "Bel", "", book_id::_bel_and_the_dragon, 80, book_type::apocryphal, true}, // Sometimes included in Greek Daniel; called ‘Rest of Daniel’ in Ethiopia. - {"1 Maccabees", "1Macc", "1MA", "1Ma", "", book_id::_1_maccabees, 81, book_type::apocryphal, false}, // Called ‘3 Maccabees’ in some traditions, printed in Catholic and Orthodox Bibles. - {"2 Maccabees", "2Macc", "2MA", "2Ma", "", book_id::_2_maccabees, 82, book_type::apocryphal, false}, // Called ‘1 Maccabees’ in some traditions, printed in Catholic and Orthodox Bibles. - {"1 Esdras (Greek)", "1Esd", "1ES", "1Es", "", book_id::_1_esdras_greek, 83, book_type::apocryphal, false}, // The 9-chapter book of Greek Ezra in the LXX, called ‘2 Esdras’ in Russian Bibles, and called ‘3 Esdras’ in the Vulgate; when Ezra-Nehemiah is one book use EZR. - {"Prayer of Manasses", "PrMan", "MAN", "Man", "", book_id::_prayer_of_manasses, 84, book_type::apocryphal, true}, // Sometimes appended to 2 Chronicles. Included in Orthodox Bibles. - {"Psalm 151", "Ps151", "PS2", "Ps2", "", book_id::_psalm_151, 85, book_type::apocryphal, true}, // An additional Psalm in the Septuagint. Appended to Psalms in Orthodox Bibles. - {"3 Maccabees", "3Macc", "3MA", "3Ma", "", book_id::_3_maccabees, 86, book_type::apocryphal, false}, // Called ‘2 Maccabees’ in some traditions, printed in Orthodox Bibles. - {"2 Esdras (Latin)", "2Esd", "2ES", "2Es", "", book_id::_2_esdras_latin, 87, book_type::apocryphal, false}, // The 16 chapter book of Latin Esdras called ‘3 Esdras’ in Russian Bibles and called ‘4 Esdras’ in the Vulgate. For the 12 chapter Apocalypse of Ezra use EZA. - {"4 Maccabees", "4Macc", "4MA", "4Ma", "", book_id::_4_maccabees, 88, book_type::apocryphal, false}, // In an appendix to the Greek Bible and in the Georgian Bible. - {"Daniel (Greek)", "", "DAG", "", "", book_id::_daniel_greek, 89, book_type::apocryphal, false}, // The 14-chapter version of Daniel from the Septuagint including Greek additions. - {"Odes", "", "ODA", "", "", book_id::_odes, 90, book_type::apocryphal, false}, // Or Odae. A book in some editions of the Septuagint. Odes has different contents in Greek, Russian, and Syriac traditions. - {"Psalms of Solomon", "", "PSS", "", "", book_id::_psalms_of_solomon, 91, book_type::apocryphal, false}, // A book in some editions of the Septuagint, but not printed in modern Bibles. - {"Ezra Apocalypse", "", "EZA", "", "", book_id::_ezra_apocalypse, 92, book_type::apocryphal, false}, // 12-Chapter book of Ezra Apocalypse. Called ‘3 Ezra’ in the Armenian Bible. Called ‘Ezra Shealtiel’ in the Ethiopian Bible. Formerly called 4ES; called ‘2 Esdras’ when it includes 5 Ezra and 6 Ezra. - {"5 Ezra", "", "5EZ", "", "", book_id::_5_ezra, 93, book_type::apocryphal, false}, // 2-Chapter Latin preface to Ezra Apocalypse. Formerly called 5ES. - {"6 Ezra", "", "6EZ", "", "", book_id::_6_ezra, 94, book_type::apocryphal, false}, // 2-Chapter Latin conclusion to Ezra Apocalypse. Formerly called 6ES. - {"Psalms 152-155", "", "PS3", "", "", book_id::_psalms_152_155, 95, book_type::apocryphal, false}, // Additional Psalms 152-155 found in West Syriac manuscripts. - {"2 Baruch (Apocalypse)", "", "2BA", "", "", book_id::_2_baruch_apocalypse, 96, book_type::apocryphal, false}, // The Apocalypse of Baruch in Syriac Bibles. - {"Letter of Baruch", "", "LBA", "", "", book_id::_letter_of_baruch, 97, book_type::apocryphal, false}, // Sometimes appended to 2 Baruch. Sometimes separate in Syriac Bibles. - {"Jubilees", "", "JUB", "", "", book_id::_jubilees, 98, book_type::apocryphal, false}, // Ancient Hebrew book used in the Ethiopian Bible. - {"Enoch", "", "ENO", "", "", book_id::_enoch, 99, book_type::apocryphal, false}, // Sometimes called ‘1 Enoch’. Ancient Hebrew book in the Ethiopian Bible. - {"1 Meqabyan/Mekabis", "", "1MQ", "", "", book_id::_1_meqabyan_mekabis, 100, book_type::apocryphal, false}, // Book of Mekabis of Benjamin in the Ethiopian Bible. - {"2 Meqabyan/Mekabis", "", "2MQ", "", "", book_id::_2_meqabyan_mekabis, 101, book_type::apocryphal, false}, // Book of Mekabis of Moab in the Ethiopian Bible. - {"3 Meqabyan/Mekabis", "", "3MQ", "", "", book_id::_3_meqabyan_mekabis, 102, book_type::apocryphal, false}, // Book of Meqabyan in the Ethiopian Bible. - {"Reproof", "", "REP", "", "", book_id::_reproof, 103, book_type::apocryphal, false}, // Proverbs part 2. Used in the Ethiopian Bible. - {"4 Baruch", "", "4BA", "", "", book_id::_4_baruch, 104, book_type::apocryphal, false}, // Paralipomenon of Jeremiah, called ‘Rest of the Words of Baruch’ in Ethiopia. May include or exclude the Letter of Jeremiah as chapter 1. Used in the Ethiopian Bible. - {"Letter to the Laodiceans", "", "LAO", "", "", book_id::_letter_to_the_laodiceans, 105, book_type::apocryphal, false}, // A Latin Vulgate book, found in the Vulgate and some medieval Catholic translations. - {"Introduction Matter", "", "INT", "", "", book_id::_introduction_matter, 2, book_type::front_back, false}, - {"Concordance", "", "CNC", "", "", book_id::_concordance, 106, book_type::front_back, false}, - {"Glossary / Wordlist", "", "GLO", "", "", book_id::_glossary_wordlist, 107, book_type::front_back, false}, - {"Topical Index", "", "TDX", "", "", book_id::_topical_index, 108, book_type::front_back, false}, - {"Names Index", "", "NDX", "", "", book_id::_names_index, 109, book_type::front_back, false} -}; - - -// For OSIS abbreviations see http://www.crosswire.org/wiki/OSIS_Book_Abbreviations. - diff --git a/database/cache.cpp b/database/cache.cpp deleted file mode 100644 index fbb8caf7d..000000000 --- a/database/cache.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Databases resilience: -// They contain cached data. -// Rarely written to. -// Often read from. - - -string Database_Cache::fragment () -{ - return "cache_resource_"; -} - - -string Database_Cache::path (string resource, int book) -{ - return filter_url_create_path ({database_logic_databases (), filename (filter_url_urlencode (resource), book) + database_sqlite_suffix ()}); -} - - -string Database_Cache::filename (string resource, int book) -{ - // Name of the database for this resource. - resource = filter_url_clean_filename (resource); - string book_fragment; - if (book) { - book_fragment = "_" + filter::strings::convert_to_string (book); - } - return fragment () + resource + book_fragment; -} - - -void Database_Cache::create (string resource, int book) -{ - SqliteDatabase sql = SqliteDatabase (filename (resource, book)); - - sql.add ("CREATE TABLE IF NOT EXISTS cache (chapter integer, verse integer, value text);"); - sql.execute (); - - sql.clear (); - - sql.add ("CREATE TABLE IF NOT EXISTS ready (ready boolean);"); - sql.execute (); -} - - -void Database_Cache::remove (string resource) -{ - for (int book = 0; book < 100; book++) { - remove (resource, book); - } -} - - -void Database_Cache::remove (string resource, int book) -{ - string file = database_sqlite_file (filename (resource, book)); - if (file_or_dir_exists (file)) { - filter_url_unlink (file); - } -} - - -// Returns true if the cache for the $resource exists. -bool Database_Cache::exists (string resource) -{ - for (int book = 0; book < 100; book++) { - if (exists (resource, book)) return true; - } - return false; -} - - -// Returns true if the cache for the $resource $book exists. -bool Database_Cache::exists (string resource, int book) -{ - string file = database_sqlite_file (filename (resource, book)); - return file_or_dir_exists (file); -} - - -// Returns true if a cached value for $resource/book/chapter/verse exists. -bool Database_Cache::exists (string resource, int book, int chapter, int verse) -{ - // If the the book-based cache exists, check existence from there. - if (exists (resource, book)) { - SqliteDatabase sql = SqliteDatabase (filename (resource, book)); - sql.add ("SELECT count(*) FROM cache WHERE chapter = "); - sql.add (chapter); - sql.add ("AND verse = "); - sql.add (verse); - sql.add (";"); - vector result = sql.query () ["count(*)"]; - int count = 0; - if (!result.empty ()) count = filter::strings::convert_to_int (result [0]); - return (count > 0); - } - // Else if the previous cache layout exists, check that. - if (exists (resource, 0)) { - SqliteDatabase sql = SqliteDatabase (filename (resource, 0)); - sql.add ("SELECT count(*) FROM cache WHERE book ="); - sql.add (book); - sql.add ("AND chapter = "); - sql.add (chapter); - sql.add ("AND verse = "); - sql.add (verse); - sql.add (";"); - vector result = sql.query () ["count(*)"]; - int count = 0; - if (!result.empty ()) count = filter::strings::convert_to_int (result [0]); - return (count > 0); - } - // Nothing exists. - return false; -} - - -// Caches a value. -void Database_Cache::cache (string resource, int book, int chapter, int verse, string value) -{ - SqliteDatabase sql = SqliteDatabase (filename (resource, book)); - - sql.clear (); - sql.add ("DELETE FROM cache WHERE chapter = "); - sql.add (chapter); - sql.add ("AND verse = "); - sql.add (verse); - sql.add (";"); - sql.execute (); - - sql.clear (); - sql.add ("INSERT INTO cache VALUES ("); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (value); - sql.add (");"); - sql.execute (); -} - - -// Retrieves a cached value. -string Database_Cache::retrieve (string resource, int book, int chapter, int verse) -{ - // If the the book-based cache exists, retrieve it from there. - if (exists (resource, book)) { - SqliteDatabase sql = SqliteDatabase (filename (resource, book)); - sql.add ("SELECT value FROM cache WHERE chapter = "); - sql.add (chapter); - sql.add ("AND verse = "); - sql.add (verse); - sql.add (";"); - vector result = sql.query () ["value"]; - if (result.empty ()) return ""; - return result [0]; - } - // Else if the previous cache layout exists, retrieve it from there. - if (exists (resource, 0)) { - SqliteDatabase sql = SqliteDatabase (filename (resource, 0)); - sql.add ("SELECT value FROM cache WHERE book ="); - sql.add (book); - sql.add ("AND chapter = "); - sql.add (chapter); - sql.add ("AND verse = "); - sql.add (verse); - sql.add (";"); - vector result = sql.query () ["value"]; - if (result.empty ()) return ""; - return result [0]; - } - return ""; -} - - -// Returns how many element are in cache $resource. -int Database_Cache::count (string resource) -{ - int count = 0; - // Book 0 is for the old layout. Book 1++ is for the new layout. - for (int book = 0; book < 100; book++) { - if (exists (resource, book)) { - count ++; - } - } - return count; -} - - -// Return true if the database has loaded all its expected content. -bool Database_Cache::ready (string resource, int book) -{ - SqliteDatabase sql = SqliteDatabase (filename (resource, book)); - sql.add ("SELECT ready FROM ready;"); - vector result = sql.query () ["ready"]; - if (!result.empty()) { - auto ready = result[0]; - return filter::strings::convert_to_bool (ready); - } - return false; -} - - -// Sets the 'ready' flag in the database. -void Database_Cache::ready (string resource, int book, bool ready) -{ - SqliteDatabase sql = SqliteDatabase (filename (resource, book)); - - sql.clear (); - sql.add ("DELETE FROM ready;"); - sql.execute (); - - sql.clear (); - sql.add ("INSERT INTO ready VALUES ("); - sql.add (ready); - sql.add (");"); - sql.execute (); -} - - -int Database_Cache::size (string resource, int book) -{ - string file = database_sqlite_file (filename (resource, book)); - return filter_url_filesize (file); -} - - -string database_cache_full_path (string file) -{ - return filter_url_create_root_path ({database_logic_databases (), "cache", file}); -} - - -// The purpose of splitting the file up into paths is -// to avoid that the cache folder would contain too many files -// and so would become slow. -string database_cache_split_file (string file) -{ - if (file.size () > 9) file.insert (9, "/"); - if (file.size () > 18) file.insert (18, "/"); - if (file.size () > 27) file.insert (27, "/"); - file.append (".txt"); - return file; -} - - -bool database_filebased_cache_exists (string schema) -{ - schema = filter_url_clean_filename (schema); - schema = database_cache_split_file (schema); - schema = database_cache_full_path (schema); - return file_or_dir_exists (schema); -} - - -void database_filebased_cache_put (string schema, string contents) -{ - schema = filter_url_clean_filename (schema); - schema = database_cache_split_file (schema); - schema = database_cache_full_path (schema); - string path = filter_url_dirname (schema); - if (!file_or_dir_exists (path)) filter_url_mkdir (path); - filter_url_file_put_contents (schema, contents); -} - - -string database_filebased_cache_get (string schema) -{ - schema = filter_url_clean_filename (schema); - schema = database_cache_split_file (schema); - schema = database_cache_full_path (schema); - return filter_url_file_get_contents (schema); -} - - -void database_filebased_cache_remove (string schema) -{ - schema = filter_url_clean_filename (schema); - schema = database_cache_split_file (schema); - schema = database_cache_full_path (schema); - filter_url_unlink (schema); -} - - -// Create a file name based on the client's IPv4 and a unique data identifier. -string database_filebased_cache_name_by_ip (string address, string id) -{ - id = "_" + id; - string ipv4_sp = "::ffff:"; - const unsigned long pos = address.find (ipv4_sp); - if (address.find (ipv4_sp) != std::string::npos) address.erase (pos, ipv4_sp.length ()); - if (address.find (id) == std::string::npos) address.append (id); - return address; -} - - -// Create a file name based on the client's session id and a unique -// data identifier. -string database_filebased_cache_name_by_session_id (string sid, string id) -{ - id = "_" + id; - if (sid.find (id) == std::string::npos) sid.append (id); - return sid; -} - - -// File name for focused book file based database cache by session id -// plus abbreviation. -string focused_book_filebased_cache_filename (string sid) -{ - return database_filebased_cache_name_by_session_id (sid, "focbo"); -} - - -// File name for focused chapter file based database cache by session -// id plus abbreviation. -string focused_chapter_filebased_cache_filename (string sid) -{ - return database_filebased_cache_name_by_session_id (sid, "focch"); -} - - -// File name for focused verse file based database cache by session id -// plus abbreviation. -string focused_verse_filebased_cache_filename (string sid) -{ - return database_filebased_cache_name_by_session_id (sid, "focve"); -} - - -// File name for general font size file based database cache by -// session id plus abbreviation. -string general_font_size_filebased_cache_filename (string sid) -{ - return database_filebased_cache_name_by_session_id (sid, "genfs"); -} - - -// File name for menu font size file based database cache by session -// id plus abbreviation. -string menu_font_size_filebased_cache_filename (string sid) -{ - return database_filebased_cache_name_by_session_id (sid, "menfs"); -} - - -// File name for resource font size file based database cache by -// session id plus abbreviation. -string resource_font_size_filebased_cache_filename (string sid) -{ - return database_filebased_cache_name_by_session_id (sid, "resfs"); -} - - -// File name for hebrew font size file based database cache by -// session id plus abbreviation. -string hebrew_font_size_filebased_cache_filename (string sid) -{ - return database_filebased_cache_name_by_session_id (sid, "hebfs"); -} - - -// File name for greek font size file based database cache by session -// id plus abbreviation. -string greek_font_size_filebased_cache_filename (string sid) -{ - return database_filebased_cache_name_by_session_id (sid, "grefs"); -} - - -// File name for current theme file based database cache by session -// id plus abbreviation. -string current_theme_filebased_cache_filename (string sid) -{ - return database_filebased_cache_name_by_session_id (sid, "curth"); -} - - -// Deletes expired cached items. -void database_cache_trim (bool clear) -{ - if (clear) Database_Logs::log ("Clearing cache"); - - string output, error; - - // The directory that contains the file-based cache files. - string path = database_cache_full_path (""); - - // Get the free space on the file system that contains the cache. - output.clear (); - error.clear (); - filter_shell_run (path, "df", {"."}, &output, &error); - if (!error.empty ()) Database_Logs::log (error); - int percentage_disk_in_use = 0; - { - vector bits = filter::strings::explode(output, ' '); - for (auto bit : bits) { - if (bit.find ("%") != std::string::npos) { - percentage_disk_in_use = filter::strings::convert_to_int(bit); - // If a real percentage was found, other than 0, then skip the remainder. - // On macOS the first percentage found is %iused, so will be skipped. - if (percentage_disk_in_use != 0) break; - } - } - } - Database_Logs::log ("Disk space in use is " + filter::strings::convert_to_string(percentage_disk_in_use) + "%"); - - // There have been instances that the cache takes up 4, 5, or 6 Gbytes in the Cloud. - // If the cache is left untrimmed, the size can be even larger. - // This leads to errors when the disk runs out of space. - // Therefore it's good to remove cached files older than a couple of hours - // in cases where disk space is tight. - // Two hours. - string minutes = "+120"; - // One day. - if (percentage_disk_in_use < 70) minutes = "+1440"; - // One week. - if (percentage_disk_in_use < 50) minutes = "+10080"; - - // Handle clearing the cache immediately. - if (clear) minutes = "+0"; - - // Remove files that have not been modified for x minutes. - // It uses a Linux shell command. - // This can be done because it runs on the server only. - // It used to do "cd /path/to/cache; find /path/to/cache ...". - // This could remove the folder "cache" too. - // After this folder was removed, no caching could take place anymore. - // https://github.com/bibledit/cloud/issues/366 - // This was not visible on macOS, but it was visible on Linux. - // The fix is to do "cd /path/to/cache; find . ...". - output.clear (); - error.clear (); - filter_shell_run (path, "find", {".", "-amin", minutes, "-delete"}, &output, &error); - if (!output.empty ()) Database_Logs::log (output); - if (!error.empty ()) Database_Logs::log (error); - - // Remove empty directories. - output.clear (); - error.clear (); - filter_shell_run (path, "find", {".", "-type", "d", "-empty", "-delete"}, &output, &error); - if (!output.empty ()) Database_Logs::log (output); - if (!error.empty ()) Database_Logs::log (error); - - // The directory that contains the database-based cache files. - path = filter_url_create_root_path ({database_logic_databases ()}); - - // The number of days to keep cached data depends on the percentage of the disk in use. - // There have been instances that the cache takes up 4, 5, or 6 Gbytes in the Cloud. - // This can be even more. - // This may lead to errors when the disk runs out of space. - // Therefore it's good to limit caches more if the space is tight. - // By default keep the resources cache for 30 days. - string days = "+30"; - // If keeping the resources cache for an extended period of time, keep it for a full year. - if (Database_Config_General::getKeepResourcesCacheForLong()) days = "+365"; - // If free disk space is tighter, keep the caches for a shorter period. - if (percentage_disk_in_use > 80) days = "+14"; - if (percentage_disk_in_use > 85) days = "+7"; - if (percentage_disk_in_use > 90) days = "+1"; - - // Handle clearing the cache immediately. - if (clear) days = "0"; - - Database_Logs::log ("Will remove resource caches not accessed for " + days + " days"); - - // Remove database-based cached files that have not been modified for x days. - output.clear (); - error.clear (); - filter_shell_run (path, "find", {path, "-name", Database_Cache::fragment () + "*", "-atime", days, "-delete"}, &output, &error); - if (!output.empty ()) Database_Logs::log (output); - if (!error.empty ()) Database_Logs::log (error); - - if (clear) Database_Logs::log ("Ready clearing cache"); -} - - -// This returns true if the $html can be cached. -bool database_cache_can_cache (const string & error, const string & html) -{ - // Normally if everything is fine, then caching is possible. - bool cache = true; - - // Do not cache the data in an error situation. - if (!error.empty()) cache = false; - - // Do not cache the data if Cloudflare does DDoS protection. - // https://github.com/bibledit/cloud/issues/693. - if (html.find ("Cloudflare") != std::string::npos) cache = false; - - return cache; -} diff --git a/database/cache.h b/database/cache.h deleted file mode 100644 index 97556b4a9..000000000 --- a/database/cache.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Cache -{ -public: - static void create (std::string resource, int book); - static void remove (std::string resource); - static void remove (std::string resource, int book); - static bool exists (std::string resource); - static bool exists (std::string resource, int book); - static bool exists (std::string resource, int book, int chapter, int verse); - static void cache (std::string resource, int book, int chapter, int verse, std::string value); - static std::string retrieve (std::string resource, int book, int chapter, int verse); - static int count (std::string resource); - static bool ready (std::string resource, int book); - static void ready (std::string resource, int book, bool ready); - static int size (std::string resource, int book); - static std::string fragment (); - static std::string path (std::string resource, int book); -private: - static std::string filename (std::string resource, int book); -}; - - -bool database_filebased_cache_exists (std::string schema); -void database_filebased_cache_put (std::string schema, std::string contents); -std::string database_filebased_cache_get (std::string schema); -void database_filebased_cache_remove (std::string schema); -std::string database_filebased_cache_name_by_ip (std::string address, std::string id); -std::string database_filebased_cache_name_by_session_id (std::string sid, std::string id); - - -std::string focused_book_filebased_cache_filename (std::string sid); -std::string focused_chapter_filebased_cache_filename (std::string sid); -std::string focused_verse_filebased_cache_filename (std::string sid); -std::string general_font_size_filebased_cache_filename (std::string sid); -std::string menu_font_size_filebased_cache_filename (std::string sid); -std::string resource_font_size_filebased_cache_filename (std::string sid); -std::string hebrew_font_size_filebased_cache_filename (std::string sid); -std::string greek_font_size_filebased_cache_filename (std::string sid); -std::string current_theme_filebased_cache_filename (std::string sid); - - -void database_cache_trim (bool clear); - - -bool database_cache_can_cache (const std::string & error, const std::string & html); diff --git a/database/check.cpp b/database/check.cpp deleted file mode 100644 index 861258375..000000000 --- a/database/check.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience. -// Write operations to table "suppress" are very infrequent. -// Write operations to table "output" happen every night. -// In case of database corruption, running the Bibledit setup re-creates -// this table. The table does not contain important data. -// In cases of extreme corruption, the database file should be manually removed -// before running setup. - - -const char * Database_Check::filename () -{ - return "check"; -} - - -void Database_Check::create () -{ - SqliteDatabase sql (filename ()); - - sql.add ("DROP TABLE IF EXISTS output;"); - sql.execute (); - - sql.clear (); - - sql.add ("CREATE TABLE IF NOT EXISTS output2 (" - " bible text," - " book integer," - " chapter integer," - " verse integer," - " data text" - ");"); - sql.execute (); - - sql.clear (); - - sql.add ("DROP TABLE IF EXISTS suppress;"); - sql.execute (); - - sql.clear (); - - sql.add ("CREATE TABLE IF NOT EXISTS suppress2 (" - " bible text," - " book integer," - " chapter integer," - " verse integer," - " data text" - ");"); - sql.execute (); -} - - -void Database_Check::optimize () -{ - SqliteDatabase sql (filename ()); - sql.add ("VACUUM;"); - sql.execute (); -} - - -void Database_Check::truncateOutput (string bible) -{ - SqliteDatabase sql (filename ()); - if (bible == "") { - sql.add ("DELETE FROM output2;"); - } else { - sql.add ("DELETE FROM output2 WHERE bible ="); - sql.add (bible); - sql.add (";"); - } - sql.execute (); -} - - -void Database_Check::recordOutput (string bible, int book, int chapter, int verse, string data) -{ - SqliteDatabase sql (filename ()); - int count = 0; - // Check whether this is a suppressed item. - // If it was suppressed, do not record it. - sql.clear (); - sql.add ("SELECT count(*) FROM suppress2 WHERE bible ="); - sql.add (bible); - sql.add ("AND book = "); - sql.add (book); - sql.add ("AND chapter = "); - sql.add (chapter); - sql.add ("AND verse = "); - sql.add (verse); - sql.add ("AND data = "); - sql.add (data); - sql.add (";"); - vector result = sql.query () ["count(*)"]; - if (!result.empty ()) { - count = filter::strings::convert_to_int (result [0]); - } - if (count == 0) { - // Check how often $data has been recorded already. - sql.clear (); - sql.add ("SELECT count(*) FROM output2 WHERE bible ="); - sql.add (bible); - sql.add ("AND data = "); - sql.add (data); - sql.add (";"); - vector count_result = sql.query () ["count(*)"]; - if (!count_result.empty ()) { - count = filter::strings::convert_to_int (count_result [0]); - } - // Record the data no more than so often. - if (count < 10) { - sql.clear (); - sql.add ("INSERT INTO output2 VALUES ("); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (data); - sql.add (");"); - sql.execute (); - } - // Store message saying that no more of this messages will be stored. - // This is for situations where the checks produce thousands and thousands of results. - // That would choke the entire server. - // It has been seen on a service provider that its system shut Bibledit's server down - // due to excessive CPU usage during a long time. - if (count == 9) { - data.append (" (" + translate ("displaying no more of these") + ")"); - sql.clear (); - sql.add ("INSERT INTO output2 VALUES ("); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (data); - sql.add (");"); - sql.execute (); - } - } -} - - -vector Database_Check::getHits () -{ - vector hits; - SqliteDatabase sql (filename ()); - sql.add ("SELECT rowid, bible, book, chapter, verse, data FROM output2;"); - map > result = sql.query (); - vector rowids = result ["rowid"]; - vector bibles = result ["bible"]; - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - vector data = result ["data"]; - for (unsigned int i = 0; i < rowids.size(); i++) { - Database_Check_Hit hit = Database_Check_Hit (); - hit.rowid = filter::strings::convert_to_int (rowids [i]); - hit.bible = bibles [i]; - hit.book = filter::strings::convert_to_int (books [i]); - hit.chapter = filter::strings::convert_to_int (chapters [i]); - hit.verse = filter::strings::convert_to_int (verses [i]); - hit.data = data [i]; - hits.push_back (hit); - } - return hits; -} - - -void Database_Check::approve (int id) -{ - // The query moves all values, apart from the auto_increment id. - SqliteDatabase sql (filename ()); - sql.add ("INSERT INTO suppress2 (bible, book, chapter, verse, data) SELECT bible, book, chapter, verse, data FROM output2 WHERE rowid ="); - sql.add (id); - sql.add (";"); - sql.execute (); - sql.clear (); - sql.add ("DELETE FROM output2 WHERE rowid ="); - sql.add (id); - sql.add (";"); - sql.execute (); -} - - -void Database_Check::erase (int id) -{ - SqliteDatabase sql (filename ()); - sql.add ("DELETE FROM output2 WHERE rowid ="); - sql.add (id); - sql.add (";"); - sql.execute (); -} - - -Passage Database_Check::getPassage (int id) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT book, chapter, verse FROM output2 WHERE rowid ="); - sql.add (id); - sql.add (";"); - map > result = sql.query (); - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - if (!books.empty()) { - Passage passage = Passage ("", filter::strings::convert_to_int (books[0]), filter::strings::convert_to_int (chapters[0]), verses[0]); - return passage; - } - return Passage ("", 0, 0, ""); -} - - -vector Database_Check::getSuppressions () -{ - SqliteDatabase sql (filename ()); - vector hits; - sql.add ("SELECT rowid, bible, book, chapter, verse, data FROM suppress2;"); - map > result = sql.query (); - vector rowids = result ["rowid"]; - vector bibles = result ["bible"]; - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - vector data = result ["data"]; - for (unsigned int i = 0; i < rowids.size(); i++) { - Database_Check_Hit hit = Database_Check_Hit (); - hit.rowid = filter::strings::convert_to_int (rowids [i]); - hit.bible = bibles [i]; - hit.book = filter::strings::convert_to_int (books [i]); - hit.chapter = filter::strings::convert_to_int (chapters [i]); - hit.verse = filter::strings::convert_to_int (verses [i]); - hit.data = data [i]; - hits.push_back (hit); - } - return hits; -} - - -void Database_Check::release (int id) -{ - SqliteDatabase sql (filename ()); - sql.add ("INSERT INTO output2 (bible, book, chapter, verse, data) SELECT bible, book, chapter, verse, data FROM suppress2 WHERE rowid ="); - sql.add (id); - sql.add (";"); - sql.execute (); - sql.clear (); - sql.add ("DELETE FROM suppress2 WHERE rowid ="); - sql.add (id); - sql.add (";"); - sql.execute (); -} - diff --git a/database/check.h b/database/check.h deleted file mode 100644 index 458521345..000000000 --- a/database/check.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - - -class Database_Check_Hit -{ -public: - int rowid {0}; - std::string bible {}; - int book {0}; - int chapter {0}; - int verse {0}; - std::string data {}; -}; - - -class Database_Check -{ -public: - void create (); - void optimize (); - void truncateOutput (std::string bible); - void recordOutput (std::string bible, int book, int chapter, int verse, std::string data); - std::vector getHits (); - void approve (int id); - void erase (int id); - Passage getPassage (int id); - std::vector getSuppressions (); - void release (int id); -private: - const char * filename (); -}; - diff --git a/database/config/bible.cpp b/database/config/bible.cpp deleted file mode 100644 index 657c0f3bd..000000000 --- a/database/config/bible.cpp +++ /dev/null @@ -1,894 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Cache values in memory for better speed. -// The speed improvement is supposed to come from reading a value from disk only once, -// and after that to read the value straight from the memory cache. -map database_config_bible_cache; - - -// Functions for getting and setting values or lists of values follow now: - - -// The path to the folder for storing the settings for the $bible. -string Database_Config_Bible::file (string bible) -{ - return filter_url_create_root_path ({database_logic_databases (), "config", "bible", bible}); -} - - -// The path to the file that contains this setting. -string Database_Config_Bible::file (string bible, const char * key) -{ - return filter_url_create_path ({file (bible), key}); -} - - -// The key in the cache for this setting. -string Database_Config_Bible::mapkey (string bible, const char * key) -{ - return bible + key; -} - - -string Database_Config_Bible::getValue (string bible, const char * key, const char * default_value) -{ - // Check the memory cache. - string cachekey = mapkey (bible, key); - if (database_config_bible_cache.count (cachekey)) { - return database_config_bible_cache [cachekey]; - } - // Get the setting from file. - string value; - string filename = file (bible, key); - if (file_or_dir_exists (filename)) value = filter_url_file_get_contents (filename); - else value = default_value; - // Cache it. - database_config_bible_cache [cachekey] = value; - // Done. - return value; -} - - -void Database_Config_Bible::setValue (string bible, const char * key, string value) -{ - if (bible.empty ()) return; - // Store in memory cache. - database_config_bible_cache [mapkey (bible, key)] = value; - // Store on disk. - string filename = file (bible, key); - string dirname = filter_url_dirname (filename); - if (!file_or_dir_exists (dirname)) filter_url_mkdir (dirname); - filter_url_file_put_contents (filename, value); -} - - -bool Database_Config_Bible::getBValue (string bible, const char * key, bool default_value) -{ - return filter::strings::convert_to_bool (getValue (bible, key, filter::strings::convert_to_string (default_value).c_str())); -} - - -void Database_Config_Bible::setBValue (string bible, const char * key, bool value) -{ - setValue (bible, key, filter::strings::convert_to_string (value)); -} - - -int Database_Config_Bible::getIValue (string bible, const char * key, int default_value) -{ - return filter::strings::convert_to_int (getValue (bible, key, filter::strings::convert_to_string (default_value).c_str())); -} - - -void Database_Config_Bible::setIValue (string bible, const char * key, int value) -{ - setValue (bible, key, filter::strings::convert_to_string (value)); -} - - -void Database_Config_Bible::remove (string bible) -{ - // Remove from disk. - string folder = file (bible); - filter_url_rmdir (folder); - // Clear cache. - database_config_bible_cache.clear (); -} - - -// Named configuration functions. - - -string Database_Config_Bible::getRemoteRepositoryUrl (string bible) -{ - return getValue (bible, "remote-repo-url", ""); -} -void Database_Config_Bible::setRemoteRepositoryUrl (string bible, string url) -{ - setValue (bible, "remote-repo-url", url); -} - - -bool Database_Config_Bible::getCheckDoubleSpacesUsfm (string bible) -{ - // Check is on by default in the Cloud, and off on a client. -#ifdef HAVE_CLIENT - bool standard = false; -#else - bool standard = true; -#endif - return getBValue (bible, "double-spaces-usfm", standard); -} -void Database_Config_Bible::setCheckDoubleSpacesUsfm (string bible, bool value) -{ - setBValue (bible, "double-spaces-usfm", value); -} - - -bool Database_Config_Bible::getCheckFullStopInHeadings (string bible) -{ - return getBValue (bible, "full-stop-headings", false); -} -void Database_Config_Bible::setCheckFullStopInHeadings (string bible, bool value) -{ - setBValue (bible, "full-stop-headings", value); -} - - -bool Database_Config_Bible::getCheckSpaceBeforePunctuation (string bible) -{ - return getBValue (bible, "space-before-punctuation", false); -} -void Database_Config_Bible::setCheckSpaceBeforePunctuation (string bible, bool value) -{ - setBValue (bible, "space-before-punctuation", value); -} - - -const char * space_before_final_note_marker_key () -{ - return "space-before-final-note-marker"; -} -bool Database_Config_Bible::getCheckSpaceBeforeFinalNoteMarker (string bible) -{ - return getBValue (bible, space_before_final_note_marker_key (), false); -} -void Database_Config_Bible::setCheckSpaceBeforeFinalNoteMarker (string bible, bool value) -{ - setBValue (bible, space_before_final_note_marker_key (), value); -} - - -bool Database_Config_Bible::getCheckSentenceStructure (string bible) -{ - return getBValue (bible, "sentence-structure", false); -} -void Database_Config_Bible::setCheckSentenceStructure (string bible, bool value) -{ - setBValue (bible, "sentence-structure", value); -} - - -bool Database_Config_Bible::getCheckParagraphStructure (string bible) -{ - return getBValue (bible, "paragraph-structure", false); -} -void Database_Config_Bible::setCheckParagraphStructure (string bible, bool value) -{ - setBValue (bible, "paragraph-structure", value); -} - - -bool Database_Config_Bible::getCheckBooksVersification (string bible) -{ - return getBValue (bible, "check-books-versification", false); -} -void Database_Config_Bible::setCheckBooksVersification (string bible, bool value) -{ - setBValue (bible, "check-books-versification", value); -} - - -bool Database_Config_Bible::getCheckChaptesVersesVersification (string bible) -{ - return getBValue (bible, "check-chapters-verses-versification", false); -} -void Database_Config_Bible::setCheckChaptesVersesVersification (string bible, bool value) -{ - setBValue (bible, "check-chapters-verses-versification", value); -} - - -bool Database_Config_Bible::getCheckWellFormedUsfm (string bible) -{ - // Check is on by default in the Cloud, and off on a client. -#ifdef HAVE_CLIENT - bool standard = false; -#else - bool standard = true; -#endif - return getBValue (bible, "check-well-formed-usfm", standard); -} -void Database_Config_Bible::setCheckWellFormedUsfm (string bible, bool value) -{ - setBValue (bible, "check-well-formed-usfm", value); -} - - -bool Database_Config_Bible::getCheckMissingPunctuationEndVerse (string bible) -{ - return getBValue (bible, "missing-punctuation-end-verse", false); -} -void Database_Config_Bible::setCheckMissingPunctuationEndVerse (string bible, bool value) -{ - setBValue (bible, "missing-punctuation-end-verse", value); -} - - -bool Database_Config_Bible::getCheckPatterns (string bible) -{ - return getBValue (bible, "check_patterns", false); -} -void Database_Config_Bible::setCheckPatterns (string bible, bool value) -{ - setBValue (bible, "check_patterns", value); -} - - -string Database_Config_Bible::getCheckingPatterns (string bible) -{ - return getValue (bible, "checking-patterns", ""); -} -void Database_Config_Bible::setCheckingPatterns (string bible, string value) -{ - setValue (bible, "checking-patterns", value); -} - - -string Database_Config_Bible::getSentenceStructureCapitals (string bible) -{ - return getValue (bible, "sentence-structure-capitals", "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"); -} -void Database_Config_Bible::setSentenceStructureCapitals (string bible, string value) -{ - setValue (bible, "sentence-structure-capitals", value); -} - - -string Database_Config_Bible::getSentenceStructureSmallLetters (string bible) -{ - return getValue (bible, "sentence-structure-small-letters", "a b c d e f g h i j k l m n o p q r s t u v w x y z"); -} -void Database_Config_Bible::setSentenceStructureSmallLetters (string bible, string value) -{ - setValue (bible, "sentence-structure-small-letters", value); -} - - -string Database_Config_Bible::getSentenceStructureEndPunctuation (string bible) -{ - return getValue (bible, "sentence-structure-end-punctuation", ". ! ? :"); -} -void Database_Config_Bible::setSentenceStructureEndPunctuation (string bible, string value) -{ - setValue (bible, "sentence-structure-end-punctuation", value); -} - - -string Database_Config_Bible::getSentenceStructureMiddlePunctuation (string bible) -{ - return getValue (bible, "sentence-structure-middle-punctuation", ", ;"); -} -void Database_Config_Bible::setSentenceStructureMiddlePunctuation (string bible, string value) -{ - setValue (bible, "sentence-structure-middle-punctuation", value); -} - - -string Database_Config_Bible::getSentenceStructureDisregards (string bible) -{ - return getValue (bible, "sentence-structure-disregards", "( ) [ ] { } ' \" * - 0 1 2 3 4 5 6 7 8 9"); -} -void Database_Config_Bible::setSentenceStructureDisregards (string bible, string value) -{ - setValue (bible, "sentence-structure-disregards", value); -} - - -string Database_Config_Bible::getSentenceStructureNames (string bible) -{ - return getValue (bible, "sentence-structure-names", ""); -} -void Database_Config_Bible::setSentenceStructureNames (string bible, string value) -{ - setValue (bible, "sentence-structure-names", value); -} - - -string Database_Config_Bible::getSentenceStructureWithinSentenceMarkers (string bible) -{ - return getValue (bible, "sentence-structure-within_sentence-markers", "q q1 q2 q3"); -} -void Database_Config_Bible::setSentenceStructureWithinSentenceMarkers (string bible, string value) -{ - setValue (bible, "sentence-structure-within_sentence-markers", value); -} - - -bool Database_Config_Bible::getCheckMatchingPairs (string bible) -{ - return getBValue (bible, "check-matching-pairs", false); -} -void Database_Config_Bible::setCheckMatchingPairs (string bible, bool value) -{ - setBValue (bible, "check-matching-pairs", value); -} - - -string Database_Config_Bible::getMatchingPairs (string bible) -{ - return getValue (bible, "matching-pairs", "[] () {} “” ‘’ «» ‹›"); -} -void Database_Config_Bible::setMatchingPairs (string bible, string value) -{ - setValue (bible, "matching-pairs", value); -} - - -bool Database_Config_Bible::getCheckSpaceEndVerse (string bible) -{ - return getBValue (bible, "check-space-end-verse", true); -} -void Database_Config_Bible::setCheckSpaceEndVerse (string bible, bool value) -{ - setBValue (bible, "check-space-end-verse", value); -} - - -bool Database_Config_Bible::getCheckFrenchPunctuation (string bible) -{ - return getBValue (bible, "check-french-punctuation", false); -} -void Database_Config_Bible::setCheckFrenchPunctuation (string bible, bool value) -{ - setBValue (bible, "check-french-punctuation", value); -} - - -const char * check_french_citation_style_key () -{ - return "check-french-citation-style"; -} -bool Database_Config_Bible::getCheckFrenchCitationStyle (string bible) -{ - return getBValue (bible, check_french_citation_style_key (), false); -} -void Database_Config_Bible::setCheckFrenchCitationStyle (string bible, bool value) -{ - setBValue (bible, check_french_citation_style_key (), value); -} - - -const char * transpose_fix_spaces_notes_key () -{ - return "transpose-fix-spaces-notes"; -} -bool Database_Config_Bible::getTransposeFixSpacesNotes (string bible) -{ - return getBValue (bible, transpose_fix_spaces_notes_key (), false); -} -void Database_Config_Bible::setTransposeFixSpacesNotes (string bible, bool value) -{ - setBValue (bible, transpose_fix_spaces_notes_key (), value); -} - - -const char * check_valid_utf8_text_key () -{ - return "check-valid-utf8-text"; -} -bool Database_Config_Bible::getCheckValidUTF8Text (string bible) -{ - return getBValue (bible, check_valid_utf8_text_key (), false); -} -void Database_Config_Bible::setCheckValidUTF8Text (string bible, bool value) -{ - setBValue (bible, check_valid_utf8_text_key (), value); -} - - -string Database_Config_Bible::getSprintTaskCompletionCategories (string bible) -{ - return getValue (bible, "sprint-task-completion-categories", "Translate\nCheck\nHebrew/Greek\nDiscussions"); -} -void Database_Config_Bible::setSprintTaskCompletionCategories (string bible, string value) -{ - setValue (bible, "sprint-task-completion-categories", value); -} - - -int Database_Config_Bible::getRepeatSendReceive (string bible) -{ - return getIValue (bible, "repeat-send-receive", 0); -} -void Database_Config_Bible::setRepeatSendReceive (string bible, int value) -{ - setIValue (bible, "repeat-send-receive", value); -} - - -bool Database_Config_Bible::getExportChapterDropCapsFrames (string bible) -{ - return getBValue (bible, "export-chapter-drop-caps-frames", false); -} -void Database_Config_Bible::setExportChapterDropCapsFrames (string bible, bool value) -{ - setBValue (bible, "export-chapter-drop-caps-frames", value); -} - - -string Database_Config_Bible::getPageWidth (string bible) -{ - return getValue (bible, "page-width", "210"); -} -void Database_Config_Bible::setPageWidth (string bible, string value) -{ - setValue (bible, "page-width", value); -} - - -string Database_Config_Bible::getPageHeight (string bible) -{ - return getValue (bible, "page-height", "297"); -} -void Database_Config_Bible::setPageHeight (string bible, string value) -{ - setValue (bible, "page-height", value); -} - - -string Database_Config_Bible::getInnerMargin (string bible) -{ - return getValue (bible, "inner-margin", "20"); -} -void Database_Config_Bible::setInnerMargin (string bible, string value) -{ - setValue (bible, "inner-margin", value); -} - - -string Database_Config_Bible::getOuterMargin (string bible) -{ - return getValue (bible, "outer-margin", "10"); -} -void Database_Config_Bible::setOuterMargin (string bible, string value) -{ - setValue (bible, "outer-margin", value); -} - - -string Database_Config_Bible::getTopMargin (string bible) -{ - return getValue (bible, "top-margin", "10"); -} -void Database_Config_Bible::setTopMargin (string bible, string value) -{ - setValue (bible, "top-margin", value); -} - - -string Database_Config_Bible::getBottomMargin (string bible) -{ - return getValue (bible, "bottom-margin", "10"); -} -void Database_Config_Bible::setBottomMargin (string bible, string value) -{ - setValue (bible, "bottom-margin", value); -} - - -bool Database_Config_Bible::getDateInHeader (string bible) -{ - return getBValue (bible, "date-in-header", false); -} -void Database_Config_Bible::setDateInHeader (string bible, bool value) -{ - setBValue (bible, "date-in-header", value); -} - - -string Database_Config_Bible::getHyphenationFirstSet (string bible) -{ - return getValue (bible, "hyphenation-first-set", ""); -} -void Database_Config_Bible::setHyphenationFirstSet (string bible, string value) -{ - setValue (bible, "hyphenation-first-set", value); -} - - -string Database_Config_Bible::getHyphenationSecondSet (string bible) -{ - return getValue (bible, "hyphenation-second-set", ""); -} -void Database_Config_Bible::setHyphenationSecondSet (string bible, string value) -{ - setValue (bible, "hyphenation-second-set", value); -} - - -string Database_Config_Bible::getEditorStylesheet (string bible) -{ - return getValue (bible, "editor-stylesheet", styles_logic_standard_sheet ().c_str()); -} -void Database_Config_Bible::setEditorStylesheet (string bible, string value) -{ - setValue (bible, "editor-stylesheet", value); -} - - -string Database_Config_Bible::getExportStylesheet (string bible) -{ - return getValue (bible, "export-stylesheet", styles_logic_standard_sheet ().c_str()); -} -void Database_Config_Bible::setExportStylesheet (string bible, string value) -{ - setValue (bible, "export-stylesheet", value); -} - - -string Database_Config_Bible::getVersificationSystem (string bible) -{ - return getValue (bible, "versification-system", filter::strings::english ()); -} -void Database_Config_Bible::setVersificationSystem (string bible, string value) -{ - setValue (bible, "versification-system", value); -} - - -bool Database_Config_Bible::getExportWebDuringNight (string bible) -{ - return getBValue (bible, "export-web-during-night", false); -} -void Database_Config_Bible::setExportWebDuringNight (string bible, bool value) -{ - setBValue (bible, "export-web-during-night", value); -} - - -bool Database_Config_Bible::getExportHtmlDuringNight (string bible) -{ - return getBValue (bible, "export-html-during-night", false); -} -void Database_Config_Bible::setExportHtmlDuringNight (string bible, bool value) -{ - setBValue (bible, "export-html-during-night", value); -} - - -const char * export_html_notes_on_hover_key () -{ - return "export-html-notes-on-hover"; -} -bool Database_Config_Bible::getExportHtmlNotesOnHover (string bible) -{ - return getBValue (bible, export_html_notes_on_hover_key (), false); -} -void Database_Config_Bible::setExportHtmlNotesOnHover (string bible, bool value) -{ - setBValue (bible, export_html_notes_on_hover_key (), value); -} - - -bool Database_Config_Bible::getExportUsfmDuringNight (string bible) -{ - return getBValue (bible, "export-usfm-during-night", false); -} -void Database_Config_Bible::setExportUsfmDuringNight (string bible, bool value) -{ - setBValue (bible, "export-usfm-during-night", value); -} - - -bool Database_Config_Bible::getExportTextDuringNight (string bible) -{ - return getBValue (bible, "export-text-during-night", false); -} -void Database_Config_Bible::setExportTextDuringNight (string bible, bool value) -{ - setBValue (bible, "export-text-during-night", value); -} - - -bool Database_Config_Bible::getExportOdtDuringNight (string bible) -{ - return getBValue (bible, "export-odt-during-night", false); -} -void Database_Config_Bible::setExportOdtDuringNight (string bible, bool value) -{ - setBValue (bible, "export-odt-during-night", value); -} - - -bool Database_Config_Bible::getGenerateInfoDuringNight (string bible) -{ - return getBValue (bible, "generate-info-during-night", false); -} -void Database_Config_Bible::setGenerateInfoDuringNight (string bible, bool value) -{ - setBValue (bible, "generate-info-during-night", value); -} - - -bool Database_Config_Bible::getExportESwordDuringNight (string bible) -{ - return getBValue (bible, "export-esword-during-night", false); -} -void Database_Config_Bible::setExportESwordDuringNight (string bible, bool value) -{ - setBValue (bible, "export-esword-during-night", value); -} - - -bool Database_Config_Bible::getExportOnlineBibleDuringNight (string bible) -{ - return getBValue (bible, "export-onlinebible-during-night", false); -} -void Database_Config_Bible::setExportOnlineBibleDuringNight (string bible, bool value) -{ - setBValue (bible, "export-onlinebible-during-night", value); -} - - -string Database_Config_Bible::getExportPassword (string bible) -{ - return getValue (bible, "export-password", ""); -} -void Database_Config_Bible::setExportPassword (string bible, string value) -{ - setValue (bible, "export-password", value); -} - - -bool Database_Config_Bible::getSecureUsfmExport (string bible) -{ - return getBValue (bible, "secure-usfm-export", false); -} -void Database_Config_Bible::setSecureUsfmExport (string bible, bool value) -{ - setBValue (bible, "secure-usfm-export", value); -} - - -bool Database_Config_Bible::getSecureOdtExport (string bible) -{ - return getBValue (bible, "secure-odt-export", false); -} -void Database_Config_Bible::setSecureOdtExport (string bible, bool value) -{ - setBValue (bible, "secure-odt-export", value); -} - - -const char * export_font_key () -{ - return "export-font"; -} -string Database_Config_Bible::getExportFont (string bible) -{ - return getValue (bible, export_font_key (), ""); -} -void Database_Config_Bible::setExportFont (string bible, string value) -{ - setValue (bible, export_font_key (), value); -} - - -const char * export_feedback_email_key () -{ - return "export-feedback-email"; -} -string Database_Config_Bible::getExportFeedbackEmail (string bible) -{ - return getValue (bible, export_feedback_email_key (), ""); -} -void Database_Config_Bible::setExportFeedbackEmail (string bible, string value) -{ - setValue (bible, export_feedback_email_key (), value); -} - - -string Database_Config_Bible::getBookOrder (string bible) -{ - return getValue (bible, "book-order", ""); -} -void Database_Config_Bible::setBookOrder (string bible, string value) -{ - setValue (bible, "book-order", value); -} - - -int Database_Config_Bible::getTextDirection (string bible) -{ - return getIValue (bible, "text-direction", 0); -} -void Database_Config_Bible::setTextDirection (string bible, int value) -{ - setIValue (bible, "text-direction", value); -} - - -string Database_Config_Bible::getTextFont (string bible) -{ - return getValue (bible, "text-font", ""); -} -void Database_Config_Bible::setTextFont (string bible, string value) -{ - setValue (bible, "text-font", value); -} - - -string Database_Config_Bible::getTextFontClient (string bible) -{ - return getValue (bible, "text-font-client", ""); -} -void Database_Config_Bible::setTextFontClient (string bible, string value) -{ - setValue (bible, "text-font-client", value); -} - - -string Database_Config_Bible::getParatextProject (string bible) -{ - return getValue (bible, "paratext-project", ""); -} -void Database_Config_Bible::setParatextProject (string bible, string value) -{ - setValue (bible, "paratext-project", value); -} - - -bool Database_Config_Bible::getParatextCollaborationEnabled (string bible) -{ - return getBValue (bible, "paratext-collaboration-enabled", false); -} -void Database_Config_Bible::setParatextCollaborationEnabled (string bible, bool value) -{ - setBValue (bible, "paratext-collaboration-enabled", value); -} - - -int Database_Config_Bible::getLineHeight (string bible) -{ - return getIValue (bible, "line-height", 100); -} -void Database_Config_Bible::setLineHeight (string bible, int value) -{ - setIValue (bible, "line-height", value); -} - - -int Database_Config_Bible::getLetterSpacing (string bible) -{ - return getIValue (bible, "letter-spacing", 0); -} -void Database_Config_Bible::setLetterSpacing (string bible, int value) -{ - setIValue (bible, "letter-spacing", value); -} - - -bool Database_Config_Bible::getPublicFeedbackEnabled (string bible) -{ - return getBValue (bible, "public-feedback-enabled", true); -} -void Database_Config_Bible::setPublicFeedbackEnabled (string bible, bool value) -{ - setBValue (bible, "public-feedback-enabled", value); -} - - -bool Database_Config_Bible::getReadFromGit (string bible) -{ - return getBValue (bible, "read-from-git", false); -} -void Database_Config_Bible::setReadFromGit (string bible, bool value) -{ - setBValue (bible, "read-from-git", value); -} - - -const char * send_changes_to_rss_key () -{ - return "send-changes-to-rss"; -} -bool Database_Config_Bible::getSendChangesToRSS (string bible) -{ - return getBValue (bible, send_changes_to_rss_key (), false); -} -void Database_Config_Bible::setSendChangesToRSS (string bible, bool value) -{ - setBValue (bible, send_changes_to_rss_key (), value); -} - - -const char * odt_space_after_verse_key () -{ - return "odt-space-after-verse"; -} -string Database_Config_Bible::getOdtSpaceAfterVerse (string bible) -{ - return getValue (bible, odt_space_after_verse_key (), " "); -} -void Database_Config_Bible::setOdtSpaceAfterVerse (string bible, string value) -{ - setValue (bible, odt_space_after_verse_key (), value); -} - - -const char * daily_checks_enabled_key () -{ - return "daily-checks-enabled"; -} -bool Database_Config_Bible::getDailyChecksEnabled (string bible) -{ - return getBValue (bible, daily_checks_enabled_key (), true); -} -void Database_Config_Bible::setDailyChecksEnabled (string bible, bool value) -{ - setBValue (bible, daily_checks_enabled_key (), value); -} - - -const char * odt_poetry_verses_left_key () -{ - return "odt-poetry-verses-left"; -} -bool Database_Config_Bible::getOdtPoetryVersesLeft (string bible) -{ - return getBValue (bible, odt_poetry_verses_left_key(), false); -} -void Database_Config_Bible::setOdtPoetryVersesLeft (string bible, bool value) -{ - setBValue (bible, odt_poetry_verses_left_key(), value); -} - - -const char * odt_automatic_note_caller_key () -{ - return "odt-automatic-note-caller"; -} -bool Database_Config_Bible::getOdtAutomaticNoteCaller (string bible) -{ - return getBValue (bible, odt_automatic_note_caller_key(), false); -} -void Database_Config_Bible::setOdtAutomaticNoteCaller (string bible, bool value) -{ - setBValue (bible, odt_automatic_note_caller_key(), value); -} diff --git a/database/config/bible.h b/database/config/bible.h deleted file mode 100644 index 3d0942516..000000000 --- a/database/config/bible.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Config_Bible -{ -public: - static void remove (std::string bible); - static std::string getRemoteRepositoryUrl (std::string bible); - static void setRemoteRepositoryUrl (std::string bible, std::string url); - static bool getCheckDoubleSpacesUsfm (std::string bible); - static void setCheckDoubleSpacesUsfm (std::string bible, bool value); - static bool getCheckFullStopInHeadings (std::string bible); - static void setCheckFullStopInHeadings (std::string bible, bool value); - static bool getCheckSpaceBeforePunctuation (std::string bible); - static void setCheckSpaceBeforePunctuation (std::string bible, bool value); - static bool getCheckSpaceBeforeFinalNoteMarker (std::string bible); - static void setCheckSpaceBeforeFinalNoteMarker (std::string bible, bool value); - static bool getCheckSentenceStructure (std::string bible); - static void setCheckSentenceStructure (std::string bible, bool value); - static bool getCheckParagraphStructure (std::string bible); - static void setCheckParagraphStructure (std::string bible, bool value); - static bool getCheckBooksVersification (std::string bible); - static void setCheckBooksVersification (std::string bible, bool value); - static bool getCheckChaptesVersesVersification (std::string bible); - static void setCheckChaptesVersesVersification (std::string bible, bool value); - static bool getCheckWellFormedUsfm (std::string bible); - static void setCheckWellFormedUsfm (std::string bible, bool value); - static bool getCheckMissingPunctuationEndVerse (std::string bible); - static void setCheckMissingPunctuationEndVerse (std::string bible, bool value); - static bool getCheckPatterns (std::string bible); - static void setCheckPatterns (std::string bible, bool value); - static std::string getCheckingPatterns (std::string bible); - static void setCheckingPatterns (std::string bible, std::string value); - static std::string getSentenceStructureCapitals (std::string bible); - static void setSentenceStructureCapitals (std::string bible, std::string value); - static std::string getSentenceStructureSmallLetters (std::string bible); - static void setSentenceStructureSmallLetters (std::string bible, std::string value); - static std::string getSentenceStructureEndPunctuation (std::string bible); - static void setSentenceStructureEndPunctuation (std::string bible, std::string value); - static std::string getSentenceStructureMiddlePunctuation (std::string bible); - static void setSentenceStructureMiddlePunctuation (std::string bible, std::string value); - static std::string getSentenceStructureDisregards (std::string bible); - static void setSentenceStructureDisregards (std::string bible, std::string value); - static std::string getSentenceStructureNames (std::string bible); - static void setSentenceStructureNames (std::string bible, std::string value); - static std::string getSentenceStructureWithinSentenceMarkers (std::string bible); - static void setSentenceStructureWithinSentenceMarkers (std::string bible, std::string value); - static bool getCheckMatchingPairs (std::string bible); - static void setCheckMatchingPairs (std::string bible, bool value); - static std::string getMatchingPairs (std::string bible); - static void setMatchingPairs (std::string bible, std::string value); - static bool getCheckSpaceEndVerse (std::string bible); - static void setCheckSpaceEndVerse (std::string bible, bool value); - static bool getCheckFrenchPunctuation (std::string bible); - static void setCheckFrenchPunctuation (std::string bible, bool value); - static bool getCheckFrenchCitationStyle (std::string bible); - static void setCheckFrenchCitationStyle (std::string bible, bool value); - static bool getTransposeFixSpacesNotes (std::string bible); - static void setTransposeFixSpacesNotes (std::string bible, bool value); - static bool getCheckValidUTF8Text (std::string bible); - static void setCheckValidUTF8Text (std::string bible, bool value); - static std::string getSprintTaskCompletionCategories (std::string bible); - static void setSprintTaskCompletionCategories (std::string bible, std::string value); - static int getRepeatSendReceive (std::string bible); - static void setRepeatSendReceive (std::string bible, int value); - static bool getExportChapterDropCapsFrames (std::string bible); - static void setExportChapterDropCapsFrames (std::string bible, bool value); - static std::string getPageWidth (std::string bible); - static void setPageWidth (std::string bible, std::string value); - static std::string getPageHeight (std::string bible); - static void setPageHeight (std::string bible, std::string value); - static std::string getInnerMargin (std::string bible); - static void setInnerMargin (std::string bible, std::string value); - static std::string getOuterMargin (std::string bible); - static void setOuterMargin (std::string bible, std::string value); - static std::string getTopMargin (std::string bible); - static void setTopMargin (std::string bible, std::string value); - static std::string getBottomMargin (std::string bible); - static void setBottomMargin (std::string bible, std::string value); - static bool getDateInHeader (std::string bible); - static void setDateInHeader (std::string bible, bool value); - static std::string getHyphenationFirstSet (std::string bible); - static void setHyphenationFirstSet (std::string bible, std::string value); - static std::string getHyphenationSecondSet (std::string bible); - static void setHyphenationSecondSet (std::string bible, std::string value); - static std::string getEditorStylesheet (std::string bible); - static void setEditorStylesheet (std::string bible, std::string value); - static std::string getExportStylesheet (std::string bible); - static void setExportStylesheet (std::string bible, std::string value); - static std::string getVersificationSystem (std::string bible); - static void setVersificationSystem (std::string bible, std::string value); - static bool getExportWebDuringNight (std::string bible); - static void setExportWebDuringNight (std::string bible, bool value); - static bool getExportHtmlDuringNight (std::string bible); - static void setExportHtmlDuringNight (std::string bible, bool value); - static bool getExportHtmlNotesOnHover (std::string bible); - static void setExportHtmlNotesOnHover (std::string bible, bool value); - static bool getExportUsfmDuringNight (std::string bible); - static void setExportUsfmDuringNight (std::string bible, bool value); - static bool getExportTextDuringNight (std::string bible); - static void setExportTextDuringNight (std::string bible, bool value); - static bool getExportOdtDuringNight (std::string bible); - static void setExportOdtDuringNight (std::string bible, bool value); - static bool getGenerateInfoDuringNight (std::string bible); - static void setGenerateInfoDuringNight (std::string bible, bool value); - static bool getExportESwordDuringNight (std::string bible); - static void setExportESwordDuringNight (std::string bible, bool value); - static bool getExportOnlineBibleDuringNight (std::string bible); - static void setExportOnlineBibleDuringNight (std::string bible, bool value); - static std::string getExportPassword (std::string bible); - static void setExportPassword (std::string bible, std::string value); - static bool getSecureUsfmExport (std::string bible); - static void setSecureUsfmExport (std::string bible, bool value); - static bool getSecureOdtExport (std::string bible); - static void setSecureOdtExport (std::string bible, bool value); - static std::string getExportFont (std::string bible); - static void setExportFont (std::string bible, std::string value); - static std::string getExportFeedbackEmail (std::string bible); - static void setExportFeedbackEmail (std::string bible, std::string value); - static std::string getBookOrder (std::string bible); - static void setBookOrder (std::string bible, std::string value); - static int getTextDirection (std::string bible); - static void setTextDirection (std::string bible, int value); - static std::string getTextFont (std::string bible); - static void setTextFont (std::string bible, std::string value); - static std::string getTextFontClient (std::string bible); - static void setTextFontClient (std::string bible, std::string value); - static std::string getParatextProject (std::string bible); - static void setParatextProject (std::string bible, std::string value); - static bool getParatextCollaborationEnabled (std::string bible); - static void setParatextCollaborationEnabled (std::string bible, bool value); - static int getLineHeight (std::string bible); - static void setLineHeight (std::string bible, int value); - static int getLetterSpacing (std::string bible); - static void setLetterSpacing (std::string bible, int value); - static bool getPublicFeedbackEnabled (std::string bible); - static void setPublicFeedbackEnabled (std::string bible, bool value); - static bool getReadFromGit (std::string bible); - static void setReadFromGit (std::string bible, bool value); - static bool getSendChangesToRSS (std::string bible); - static void setSendChangesToRSS (std::string bible, bool value); - static std::string getOdtSpaceAfterVerse (std::string bible); - static void setOdtSpaceAfterVerse (std::string bible, std::string value); - static bool getDailyChecksEnabled (std::string bible); - static void setDailyChecksEnabled (std::string bible, bool value); - static bool getOdtPoetryVersesLeft (std::string bible); - static void setOdtPoetryVersesLeft (std::string bible, bool value); - static bool getOdtAutomaticNoteCaller (std::string bible); - static void setOdtAutomaticNoteCaller (std::string bible, bool value); -private: - static std::string file (std::string bible); - static std::string file (std::string bible, const char * key); - static std::string mapkey (std::string bible, const char * key); - static std::string getValue (std::string bible, const char * key, const char * default_value); - static void setValue (std::string bible, const char * key, std::string value); - static bool getBValue (std::string bible, const char * key, bool default_value); - static void setBValue (std::string bible, const char * key, bool value); - static int getIValue (std::string bible, const char * key, int default_value); - static void setIValue (std::string bible, const char * key, int value); -}; diff --git a/database/config/general.cpp b/database/config/general.cpp deleted file mode 100644 index 2a7bcc476..000000000 --- a/database/config/general.cpp +++ /dev/null @@ -1,597 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Cache values in memory for better speed. -// The speed improvement is supposed to come from reading a value from disk only once, -// and after that to read the value straight from the memory cache. -map database_config_general_cache; - - -// Functions for getting and setting values or lists of values follow here: - - -string Database_Config_General::file (const char * key) -{ - return filter_url_create_root_path ({database_logic_databases (), "config", "general", key}); -} - - -string Database_Config_General::getValue (const char * key, const char * default_value) -{ - // Check the memory cache. - if (database_config_general_cache.count (key)) { - return database_config_general_cache [key]; - } - // Get value from disk. - string value; - string filename = file (key); - if (file_or_dir_exists (filename)) value = filter_url_file_get_contents (filename); - else value = default_value; - // Cache it. - database_config_general_cache [key] = value; - // Done. - return value; -} - - -void Database_Config_General::setValue (const char * key, string value) -{ - // Store in memory cache. - database_config_general_cache [key] = value; - // Store on disk. - string filename = file (key); - filter_url_file_put_contents (filename, value); -} - - -bool Database_Config_General::getBValue (const char * key, bool default_value) -{ - string value = getValue (key, filter::strings::convert_to_string (default_value).c_str()); - return filter::strings::convert_to_bool (value); -} - - -void Database_Config_General::setBValue (const char * key, bool value) -{ - setValue (key, filter::strings::convert_to_string (value).c_str()); -} - - -int Database_Config_General::getIValue (const char * key, int default_value) -{ - string value = getValue (key, filter::strings::convert_to_string (default_value).c_str()); - return filter::strings::convert_to_int (value); -} - - -void Database_Config_General::setIValue (const char * key, int value) -{ - setValue (key, filter::strings::convert_to_string (value).c_str()); -} - - -vector Database_Config_General::getList (const char * key) -{ - string contents = getValue (key, ""); - return filter::strings::explode (contents, '\n'); -} - - -void Database_Config_General::setList (const char * key, vector values) -{ - string value = filter::strings::implode (values, "\n"); - setValue (key, value); -} - - -// Named configuration functions. - - -string Database_Config_General::getSiteMailName () -{ - return getValue ("site-mail-name", "Cloud"); -} -void Database_Config_General::setSiteMailName (string value) -{ - setValue ("site-mail-name", value); -} - - -string Database_Config_General::getSiteMailAddress () -{ - return getValue ("site-mail-address", ""); -} -void Database_Config_General::setSiteMailAddress (string value) -{ - setValue ("site-mail-address", value); -} - - -string Database_Config_General::getMailStorageHost () -{ - return getValue ("mail-storage-host", ""); -} -void Database_Config_General::setMailStorageHost (string value) -{ - setValue ("mail-storage-host", value); -} - - -string Database_Config_General::getMailStorageUsername () -{ - return getValue ("mail-storage-username", ""); -} -void Database_Config_General::setMailStorageUsername (string value) -{ - setValue ("mail-storage-username", value); -} - - -string Database_Config_General::getMailStoragePassword () -{ - return getValue ("mail-storage-password", ""); -} - - -void Database_Config_General::setMailStoragePassword (string value) -{ - setValue ("mail-storage-password", value); -} - - -string Database_Config_General::getMailStorageProtocol () -{ - return getValue ("mail-storage-protocol", ""); -} -void Database_Config_General::setMailStorageProtocol (string value) -{ - setValue ("mail-storage-protocol", value); -} - - -string Database_Config_General::getMailStoragePort () -{ - return getValue ("mail-storage-port", ""); -} -void Database_Config_General::setMailStoragePort (string value) -{ - setValue ("mail-storage-port", value); -} - - -string Database_Config_General::getMailSendHost () -{ - return getValue ("mail-send-host", ""); -} -void Database_Config_General::setMailSendHost (string value) -{ - setValue ("mail-send-host", value); -} - - -string Database_Config_General::getMailSendUsername () -{ - return getValue ("mail-send-username", ""); -} -void Database_Config_General::setMailSendUsername (string value) -{ - setValue ("mail-send-username", value); -} - - -string Database_Config_General::getMailSendPassword () -{ - return getValue ("mail-send-password", ""); -} -void Database_Config_General::setMailSendPassword (string value) -{ - setValue ("mail-send-password", value); -} - - -string Database_Config_General::getMailSendPort () -{ - return getValue ("mail-send-port", ""); -} -void Database_Config_General::setMailSendPort (string value) -{ - setValue ("mail-send-port", value); -} - - -string Database_Config_General::getTimerMinute () -{ - return getValue ("timer-minute", ""); -} -void Database_Config_General::setTimerMinute (string value) -{ - setValue ("timer-minute", value); -} - - -int Database_Config_General::getTimezone () -{ - // If the global offset variable is set, that is, - // within certain limits, then take that. - if ((config_globals_timezone_offset_utc < MINIMUM_TIMEZONE) - || (config_globals_timezone_offset_utc > MAXIMUM_TIMEZONE)) { - return getIValue ("timezone", 0); - } - // Else take variable as set in the configuration. - return config_globals_timezone_offset_utc; -} -void Database_Config_General::setTimezone (int value) -{ - setIValue ("timezone", value); -} - - -string Database_Config_General::getSiteURL () -{ - // The site URL is set upon login, normally. - // In a client setup, there is never a login. - // Consequently the site URL is never set. -#ifdef HAVE_CLIENT - // In case of a client, return a predefined URL. - string url = "http://localhost:"; - url.append (config::logic::http_network_port ()); - url.append ("/"); - return url; -#else - // Get the URL that was set upon login. - return getValue ("site-url", ""); -#endif -} -void Database_Config_General::setSiteURL (string value) -{ - setValue ("site-url", value); -} - - -constexpr const char * general_site_language_key {"site-language"}; -string Database_Config_General::getSiteLanguage () -{ - // The default site language is an empty string. - // It means not to localize the interface. - // Since the default messages are all in English, - // the default language for the interface will be English. - return getValue (general_site_language_key, ""); -} -void Database_Config_General::setSiteLanguage (string value) -{ - setValue (general_site_language_key, value); -} - - -bool Database_Config_General::getClientMode () -{ - return getBValue ("client-mode", false); -} -void Database_Config_General::setClientMode (bool value) -{ - setBValue ("client-mode", value); -} - - -string Database_Config_General::getServerAddress () -{ - return getValue ("server-address", ""); -} -void Database_Config_General::setServerAddress (string value) -{ - setValue ("server-address", value); -} - - -int Database_Config_General::getServerPort () -{ - return getIValue ("server-port", 8080); -} -void Database_Config_General::setServerPort (int value) -{ - setIValue ("server-port", value); -} - - -int Database_Config_General::getRepeatSendReceive () -{ - return getIValue ("repeat-send-receive", 0); -} -void Database_Config_General::setRepeatSendReceive (int value) -{ - setIValue ("repeat-send-receive", value); -} - - -int Database_Config_General::getLastSendReceive () -{ - return getIValue ("last-send-receive", 0); -} -void Database_Config_General::setLastSendReceive (int value) -{ - setIValue ("last-send-receive", value); -} - - -string Database_Config_General::getInstalledInterfaceVersion () -{ - return getValue ("installed-interface-version", ""); -} -void Database_Config_General::setInstalledInterfaceVersion (string value) -{ - setValue ("installed-interface-version", value); -} - - -string Database_Config_General::getInstalledDatabaseVersion () -{ - return getValue ("installed-database-version", ""); -} -void Database_Config_General::setInstalledDatabaseVersion (string value) -{ - setValue ("installed-database-version", value); -} - - -bool Database_Config_General::getJustStarted () -{ - return getBValue ("just-started", false); -} -void Database_Config_General::setJustStarted (bool value) -{ - setBValue ("just-started", value); -} - - -string Database_Config_General::getParatextProjectsFolder () -{ - return getValue ("paratext-projects-folder", ""); -} -void Database_Config_General::setParatextProjectsFolder (string value) -{ - setValue ("paratext-projects-folder", value); -} - - -// Encryption / decryption key storage on client. -string Database_Config_General::getSyncKey () -{ - return getValue ("sync-key", ""); -} -void Database_Config_General::setSyncKey (string key) -{ - setValue ("sync-key", key); -} - - -string Database_Config_General::getLastMenuClick () -{ - return getValue ("last-menu-click", ""); -} -void Database_Config_General::setLastMenuClick (string url) -{ - setValue ("last-menu-click", url); -} - - -// Store the resources to be cached. -// The format is this: -// -vector Database_Config_General::getResourcesToCache () -{ - return getList ("resources-to-cache"); -} - - -void Database_Config_General::setResourcesToCache (vector values) -{ - setList ("resources-to-cache", values); -} - - -bool Database_Config_General::getIndexNotes () -{ - return getBValue ("index-notes", false); -} -void Database_Config_General::setIndexNotes (bool value) -{ - setBValue ("index-notes", value); -} - - -bool Database_Config_General::getIndexBibles () -{ - return getBValue ("index-bibles", false); -} -void Database_Config_General::setIndexBibles (bool value) -{ - setBValue ("index-bibles", value); -} - - -int Database_Config_General::getUnsentBibleDataTime () -{ - return getIValue ("unsent-bible-data-time", 0); -} -void Database_Config_General::setUnsentBibleDataTime (int value) -{ - setIValue ("unsent-bible-data-time", value); -} - - -int Database_Config_General::getUnreceivedBibleDataTime () -{ - return getIValue ("unreceived-bible-data-time", 0); -} -void Database_Config_General::setUnreceivedBibleDataTime (int value) -{ - setIValue ("unreceived-bible-data-time", value); -} - - -bool Database_Config_General::getAuthorInRssFeed () -{ - return getBValue ("author-in-rss-feed", false); -} -void Database_Config_General::setAuthorInRssFeed (bool value) -{ - setBValue ("author-in-rss-feed", value); -} - - -bool Database_Config_General::getJustConnectedToCloud () -{ - return getBValue ("just-connected-to-cloud", false); -} -void Database_Config_General::setJustConnectedToCloud (bool value) -{ - setBValue ("just-connected-to-cloud", value); -} - - -constexpr const char * menu_in_tabbed_view_on_key {"menu-in-tabbed-view-on"}; -bool Database_Config_General::getMenuInTabbedViewOn () -{ - return getBValue (menu_in_tabbed_view_on_key, true); -} -void Database_Config_General::setMenuInTabbedViewOn (bool value) -{ - setBValue (menu_in_tabbed_view_on_key, value); -} - - -constexpr const char * menu_in_tabbed_view_json_key {"menu-in-tabbed-view-json"}; -string Database_Config_General::getMenuInTabbedViewJSON () -{ - return getValue (menu_in_tabbed_view_json_key, ""); -} -void Database_Config_General::setMenuInTabbedViewJSON (string value) -{ - setValue (menu_in_tabbed_view_json_key, value); -} - - -constexpr const char * disable_selection_popup_chrome_os_key {"disable-selection-popup-chrome-os"}; -bool Database_Config_General::getDisableSelectionPopupChromeOS () -{ - return getBValue (disable_selection_popup_chrome_os_key, false); -} -void Database_Config_General::setDisableSelectionPopupChromeOS (bool value) -{ - setBValue (disable_selection_popup_chrome_os_key, value); -} - - -constexpr const char * notes_verse_separator_key {"notes-verse-separator"}; -string Database_Config_General::getNotesVerseSeparator () -{ - // The colon is the default value. See https://github.com/bibledit/cloud/issues/509 - return getValue (notes_verse_separator_key, ":"); -} -void Database_Config_General::setNotesVerseSeparator (string value) -{ - setValue (notes_verse_separator_key, value); -} - - -constexpr const char * comparative_resources_key {"comparative-resources"}; -vector Database_Config_General::getComparativeResources () -{ - return getList (comparative_resources_key); -} -void Database_Config_General::setComparativeResources (vector values) -{ - setList (comparative_resources_key, values); -} - - -constexpr const char * translated_resources_key {"translated-resources"}; -vector Database_Config_General::getTranslatedResources () -{ - return getList (translated_resources_key); -} -void Database_Config_General::setTranslatedResources (vector values) -{ - setList (translated_resources_key, values); -} - - -constexpr const char * default_active_resources_key {"default-active-resources"}; -vector Database_Config_General::getDefaultActiveResources () -{ - return getList (default_active_resources_key); -} -void Database_Config_General::setDefaultActiveResources (vector values) -{ - setList (default_active_resources_key, values); -} - - -constexpr const char * account_creation_times_key {"account-creation-times"}; -vector Database_Config_General::getAccountCreationTimes () -{ - return getList (account_creation_times_key); -} -void Database_Config_General::setAccountCreationTimes (vector values) -{ - setList (account_creation_times_key, values); -} - - -constexpr const char * keep_resources_cache_for_long_key {"keep-resources-cache-for-long"}; -bool Database_Config_General::getKeepResourcesCacheForLong () -{ - return getBValue (keep_resources_cache_for_long_key, false); -} -void Database_Config_General::setKeepResourcesCacheForLong (bool value) -{ - setBValue (keep_resources_cache_for_long_key, value); -} - - -constexpr const char * default_new_user_access_level_key {"default-new-user-access-level"}; -int Database_Config_General::getDefaultNewUserAccessLevel () -{ - return getIValue (default_new_user_access_level_key, Filter_Roles::member ()); -} -void Database_Config_General::setDefaultNewUserAccessLevel (int value) -{ - setIValue (default_new_user_access_level_key, value); -} - - -constexpr const char * keep_osis_content_in_sword_resources_key {"keep-osis-content-in-sword-resources"}; -bool Database_Config_General::getKeepOsisContentInSwordResources () -{ - return getBValue (keep_osis_content_in_sword_resources_key, false); -} -void Database_Config_General::setKeepOsisContentInSwordResources (bool value) -{ - setBValue (keep_osis_content_in_sword_resources_key, value); -} diff --git a/database/config/general.h b/database/config/general.h deleted file mode 100644 index 954018d94..000000000 --- a/database/config/general.h +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Database_Config_General -{ -public: - static std::string getSiteMailName(); - static void setSiteMailName (std::string value); - - static std::string getSiteMailAddress(); - static void setSiteMailAddress (std::string value); - - static std::string getMailStorageHost(); - static void setMailStorageHost (std::string value); - - static std::string getMailStorageUsername(); - static void setMailStorageUsername (std::string value); - - static std::string getMailStoragePassword(); - static void setMailStoragePassword (std::string value); - - static std::string getMailStorageProtocol(); - static void setMailStorageProtocol (std::string value); - - static std::string getMailStoragePort(); - static void setMailStoragePort (std::string value); - - static std::string getMailSendHost(); - static void setMailSendHost (std::string value); - - static std::string getMailSendUsername(); - static void setMailSendUsername (std::string value); - - static std::string getMailSendPassword(); - static void setMailSendPassword (std::string value); - - static std::string getMailSendPort(); - static void setMailSendPort (std::string value); - - static std::string getTimerMinute(); - static void setTimerMinute (std::string value); - - static int getTimezone(); - static void setTimezone (int value); - - static std::string getSiteURL(); - static void setSiteURL (std::string value); - - static std::string getSiteLanguage (); - static void setSiteLanguage (std::string value); - - static bool getClientMode (); - static void setClientMode (bool value); - - static std::string getServerAddress (); - static void setServerAddress (std::string value); - - static int getServerPort (); - static void setServerPort (int value); - - static int getRepeatSendReceive (); - static void setRepeatSendReceive (int value); - - static int getLastSendReceive (); - static void setLastSendReceive (int value); - - static std::string getInstalledInterfaceVersion (); - static void setInstalledInterfaceVersion (std::string value); - - static std::string getInstalledDatabaseVersion (); - static void setInstalledDatabaseVersion (std::string value); - - static bool getJustStarted (); - static void setJustStarted (bool value); - - static std::string getParatextProjectsFolder (); - static void setParatextProjectsFolder (std::string value); - - static std::string getSyncKey (); - static void setSyncKey (std::string key); - - static std::string getLastMenuClick (); - static void setLastMenuClick (std::string url); - - static std::vector getResourcesToCache (); - static void setResourcesToCache (std::vector values); - - static bool getIndexNotes (); - static void setIndexNotes (bool value); - - static bool getIndexBibles (); - static void setIndexBibles (bool value); - - static int getUnsentBibleDataTime (); - static void setUnsentBibleDataTime (int value); - - static int getUnreceivedBibleDataTime (); - static void setUnreceivedBibleDataTime (int value); - - static bool getAuthorInRssFeed (); - static void setAuthorInRssFeed (bool value); - - static bool getJustConnectedToCloud (); - static void setJustConnectedToCloud (bool value); - - static bool getMenuInTabbedViewOn (); - static void setMenuInTabbedViewOn (bool value); - static std::string getMenuInTabbedViewJSON (); - static void setMenuInTabbedViewJSON (std::string value); - - static bool getDisableSelectionPopupChromeOS (); - static void setDisableSelectionPopupChromeOS (bool value); - - static std::string getNotesVerseSeparator (); - static void setNotesVerseSeparator (std::string url); - - static std::vector getComparativeResources (); - static void setComparativeResources (std::vector values); - - static std::vector getTranslatedResources (); - static void setTranslatedResources (std::vector values); - - static std::vector getDefaultActiveResources (); - static void setDefaultActiveResources (std::vector values); - - static std::vector getAccountCreationTimes (); - static void setAccountCreationTimes (std::vector values); - - static bool getKeepResourcesCacheForLong (); - static void setKeepResourcesCacheForLong (bool value); - - static int getDefaultNewUserAccessLevel (); - static void setDefaultNewUserAccessLevel (int value); - - static bool getKeepOsisContentInSwordResources (); - static void setKeepOsisContentInSwordResources (bool value); - -private: - static std::string file (const char * key); - static std::string getValue (const char * key, const char * default_value); - static void setValue (const char * key, std::string value); - static bool getBValue (const char * key, bool default_value); - static void setBValue (const char * key, bool value); - static int getIValue (const char * key, int default_value); - static void setIValue (const char * key, int value); - static std::vector getList (const char * key); - static void setList (const char * key, std::vector values); -}; diff --git a/database/config/user.cpp b/database/config/user.cpp deleted file mode 100644 index 75401860a..000000000 --- a/database/config/user.cpp +++ /dev/null @@ -1,1499 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -Database_Config_User::Database_Config_User (Webserver_Request& webserver_request): -m_webserver_request (webserver_request) -{ -} - - -// Cache values in memory for better speed. -// The speed improvement comes from reading a value from disk only once, -// and after that to read the value straight from the memory cache. -map database_config_user_cache; - - -// Functions for getting and setting values or lists of values follow here: - - -string Database_Config_User::file (string user) -{ - return filter_url_create_root_path ({database_logic_databases (), "config", "user", user}); -} - - -string Database_Config_User::file (string user, const char * key) -{ - return filter_url_create_path ({file (user), key}); -} - - -// The key in the cache for this setting. -string Database_Config_User::mapkey (string user, const char * key) -{ - return user + key; -} - - -string Database_Config_User::getValue (const char * key, const char * default_value) -{ - string user = m_webserver_request.session_logic ()->currentUser (); - return getValueForUser (user, key, default_value); -} - - -bool Database_Config_User::getBValue (const char * key, bool default_value) -{ - string value = getValue (key, filter::strings::convert_to_string (default_value).c_str()); - return filter::strings::convert_to_bool (value); -} - - -int Database_Config_User::getIValue (const char * key, int default_value) -{ - string value = getValue (key, filter::strings::convert_to_string (default_value).c_str()); - return filter::strings::convert_to_int (value); -} - - -string Database_Config_User::getValueForUser (string user, const char * key, const char * default_value) -{ - // Check the memory cache. - string cachekey = mapkey (user, key); - if (database_config_user_cache.count (cachekey)) { - return database_config_user_cache [cachekey]; - } - // Read from file. - string value; - string filename = file (user, key); - if (file_or_dir_exists (filename)) value = filter_url_file_get_contents (filename); - else value = default_value; - // Cache it. - database_config_user_cache [cachekey] = value; - // Done. - return value; -} - - -bool Database_Config_User::getBValueForUser (string user, const char * key, bool default_value) -{ - string value = getValueForUser (user, key, filter::strings::convert_to_string (default_value).c_str()); - return filter::strings::convert_to_bool (value); -} - - -int Database_Config_User::getIValueForUser (string user, const char * key, int default_value) -{ - string value = getValueForUser (user, key, filter::strings::convert_to_string (default_value).c_str()); - return filter::strings::convert_to_int (value); -} - - -void Database_Config_User::setValue (const char * key, string value) -{ - string user = m_webserver_request.session_logic ()->currentUser (); - setValueForUser (user, key, value); -} - - -void Database_Config_User::setBValue (const char * key, bool value) -{ - setValue (key, filter::strings::convert_to_string (value)); -} - - -void Database_Config_User::setIValue (const char * key, int value) -{ - setValue (key, filter::strings::convert_to_string (value)); -} - - -void Database_Config_User::setValueForUser (string user, const char * key, string value) -{ - // Store in memory cache. - database_config_user_cache [mapkey (user, key)] = value; - // Store on disk. - string filename = file (user, key); - string directory = filter_url_dirname (filename); - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - filter_url_file_put_contents (filename, value); -} - - -void Database_Config_User::setBValueForUser (string user, const char * key, bool value) -{ - setValueForUser (user, key, filter::strings::convert_to_string (value)); -} - - -vector Database_Config_User::getList (const char * key) -{ - string user = m_webserver_request.session_logic ()->currentUser (); - return getListForUser (user, key); -} - - -vector Database_Config_User::getListForUser (string user, const char * key) -{ - // Check whether value is in cache. - string cachekey = mapkey (user, key); - if (database_config_user_cache.count (cachekey)) { - string value = database_config_user_cache [cachekey]; - return filter::strings::explode (value, '\n'); - } - // Read setting from disk. - string filename = file (user, key); - if (file_or_dir_exists (filename)) { - string value = filter_url_file_get_contents (filename); - // Cache it in memory. - database_config_user_cache [cachekey] = value; - // Done. - return filter::strings::explode (value, '\n'); - } - // Empty value. - return {}; -} - - -void Database_Config_User::setList (const char * key, vector values) -{ - string user = m_webserver_request.session_logic ()->currentUser (); - setListForUser (user, key, values); -} - - -void Database_Config_User::setListForUser (string user, const char * key, vector values) -{ - // Store it on disk. - string filename = file (user, key); - string directory = filter_url_dirname (filename); - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - string value = filter::strings::implode (values, "\n"); - filter_url_file_put_contents (filename, value); - // Put it in the memory cache. - string cachekey = mapkey (user, key); - database_config_user_cache [cachekey] = value; -} - - -vector Database_Config_User::getIList (const char * key) -{ - vector lines = getList (key); - vector result; - for (auto & line : lines) { - result.push_back (filter::strings::convert_to_int (line)); - } - return result; -} - - -void Database_Config_User::setIList (const char * key, vector values) -{ - vector lines; - for (auto & value : values) { - lines.push_back (filter::strings::convert_to_string (value)); - } - setList (key, lines); -} - - -void Database_Config_User::trim () -{ - // Reset the sprint month and year after some time. - // When a user visits the Sprint page after a few days, it will then display the current Sprint. - // If the Sprint is not reset, the user may enter new tasks in the wrong sprint. - int time = filter::date::seconds_since_epoch () - (2 * 24 * 3600); - Database_Users database_users; - vector users = database_users.get_users (); - for (unsigned int i = 0; i < users.size(); i++) { - string filename = file (users[i], keySprintMonth ()); - if (file_or_dir_exists (filename)) { - if (filter_url_file_modification_time (filename) < time) { - // Remove from disk. - filter_url_unlink (filename); - filename = file (users[i], keySprintYear ()); - filter_url_unlink (filename); - // Clear cache. - database_config_user_cache.clear (); - } - } - } -} - - -// Remove any configuration setting of $username. -void Database_Config_User::remove (string username) -{ - // Remove from disk. - string folder = file (username); - filter_url_rmdir (folder); - // Clear cache. - database_config_user_cache.clear (); -} - - -// Clear the settings cache. -void Database_Config_User::clear_cache () -{ - database_config_user_cache.clear (); -} - - -// Named configuration functions. - - -string Database_Config_User::getBible () -{ - string bible = getValue ("bible", ""); - // If the Bible does not exist, take the first one available. - Database_Bibles * database_bibles = m_webserver_request.database_bibles (); - vector bibles = database_bibles->get_bibles (); - if (find (bibles.begin (), bibles.end (), bible) == bibles.end ()) { - // There may not even be a first Bible: Create sample Bible. - if (bibles.empty ()) { - bible = demo_sample_bible_name (); - demo_create_sample_bible (); - database_bibles->create_bible (bible); - } else { - bible = bibles [0]; - } - setBible (bible); - } - return bible; -} -void Database_Config_User::setBible (string bible) -{ - setValue ("bible", bible); -} - - -bool Database_Config_User::getSubscribeToConsultationNotesEditedByMe () -{ - return getBValue ("subscribe-to-consultation-notes-edited-by-me", false); -} -void Database_Config_User::setSubscribeToConsultationNotesEditedByMe (bool value) -{ - setBValue ("subscribe-to-consultation-notes-edited-by-me", value); -} - - -bool Database_Config_User::getNotifyMeOfAnyConsultationNotesEdits () -{ - return getBValue ("notify-me-of-any-consultation-notes-edits", false); -} -bool Database_Config_User::getNotifyUserOfAnyConsultationNotesEdits (string username) -{ - return getBValueForUser (username, "notify-me-of-any-consultation-notes-edits", false); -} -void Database_Config_User::setNotifyMeOfAnyConsultationNotesEdits (bool value){ - setBValue ("notify-me-of-any-consultation-notes-edits", value); -} - - -bool Database_Config_User::getSubscribedConsultationNoteNotification () -{ - return getBValue ("subscribed-consultation-note-notification", true); -} -bool Database_Config_User::getUserSubscribedConsultationNoteNotification (string username) -{ - return getBValueForUser (username, "subscribed-consultation-note-notification", true); -} -void Database_Config_User::setSubscribedConsultationNoteNotification (bool value) -{ - setBValue ("subscribed-consultation-note-notification", value); -} - - -bool Database_Config_User::getAssignedToConsultationNotesChanges () -{ - return getBValue ("get-assigned-to-consultation-notes-changes", false); -} -bool Database_Config_User::getUserAssignedToConsultationNotesChanges (string username) -{ - return getBValueForUser (username, "get-assigned-to-consultation-notes-changes", false); -} -void Database_Config_User::setAssignedToConsultationNotesChanges (bool value) -{ - setBValue ("get-assigned-to-consultation-notes-changes", value); -} - - -bool Database_Config_User::getGenerateChangeNotifications () -{ - return getBValue ("generate-change-notifications", false); -} -bool Database_Config_User::getUserGenerateChangeNotifications (string username) -{ - return getBValueForUser (username, "generate-change-notifications", false); -} -void Database_Config_User::setGenerateChangeNotifications (bool value) -{ - setBValue ("generate-change-notifications", value); -} - - -bool Database_Config_User::getAssignedConsultationNoteNotification () -{ - return getBValue ("assigned-consultation-note-notification", true); -} -bool Database_Config_User::getUserAssignedConsultationNoteNotification (string username) -{ - return getBValueForUser (username, "assigned-consultation-note-notification", true); -} -void Database_Config_User::setAssignedConsultationNoteNotification (bool value) -{ - setBValue ("assigned-consultation-note-notification", value); -} - - -// 0: current verse; 1: current chapter; 2: current book; 3: any passage. -int Database_Config_User::getConsultationNotesPassageSelector () -{ - // Default value is to select notes of the current chapter. - // It used to be the current verse. - // But that led to a situation where a user created a note, - // navigated to another verse within the same chapter, - // and then was confused because the user could not find the note just created. - // With the updated selection, current chapter, this confusing situation does not occur. - return getIValue ("consultation-notes-passage-selector", 1); -} -void Database_Config_User::setConsultationNotesPassageSelector (int value) -{ - setIValue ("consultation-notes-passage-selector", value); -} - - -// 0: any time; 1: last 30 days; 2: last 7 days; 3: since yesterday; 4: today. -int Database_Config_User::getConsultationNotesEditSelector () -{ - return getIValue ("consultation-notes-edit-selector", 0); -} -void Database_Config_User::setConsultationNotesEditSelector (int value) -{ - setIValue ("consultation-notes-edit-selector", value); -} - - -// 0: don't care; 1: for last 30 days; 2: for last 7 days; 3: since yesterday; 4: today. -int Database_Config_User::getConsultationNotesNonEditSelector () -{ - return getIValue ("consultation-notes-non-edit-selector", 0); -} -void Database_Config_User::setConsultationNotesNonEditSelector (int value) -{ - setIValue ("consultation-notes-non-edit-selector", value); -} - - -// Status is a string; can be empty as well. -string Database_Config_User::getConsultationNotesStatusSelector () -{ - return getValue ("consultation-notes-status-selector", ""); -} -void Database_Config_User::setConsultationNotesStatusSelector (string value) -{ - setValue ("consultation-notes-status-selector", value); -} - - -// "": any Bible; : named Bible. -string Database_Config_User::getConsultationNotesBibleSelector () -{ - return getValue ("consultation-notes-bible-selector", ""); -} -void Database_Config_User::setConsultationNotesBibleSelector (string value) -{ - setValue ("consultation-notes-bible-selector", value); -} - - -// "": don't care; "user": notes assigned to "user". -string Database_Config_User::getConsultationNotesAssignmentSelector () -{ - return getValue ("consultation-notes-assignment-selector", ""); -} -void Database_Config_User::setConsultationNotesAssignmentSelector (string value) -{ - setValue ("consultation-notes-assignment-selector", value); -} - - -// false: don't care; true: subscribed. -bool Database_Config_User::getConsultationNotesSubscriptionSelector () -{ - return getBValue ("consultation-notes-subscription-selector", false); -} -void Database_Config_User::setConsultationNotesSubscriptionSelector (bool value) -{ - setBValue ("consultation-notes-subscription-selector", value); -} - - -int Database_Config_User::getConsultationNotesSeveritySelector () -{ - return getIValue ("consultation-notes-severity-selector", -1); -} -void Database_Config_User::setConsultationNotesSeveritySelector (int value) -{ - setIValue ("consultation-notes-severity-selector", value); -} - - -int Database_Config_User::getConsultationNotesTextSelector () -{ - return getIValue ("consultation-notes-text-selector", 0); -} -void Database_Config_User::setConsultationNotesTextSelector (int value) -{ - setIValue ("consultation-notes-text-selector", value); -} - - -string Database_Config_User::getConsultationNotesSearchText () -{ - return getValue ("consultation-notes-search-text", ""); -} -void Database_Config_User::setConsultationNotesSearchText (string value) -{ - setValue ("consultation-notes-search-text", value); -} - - -int Database_Config_User::getConsultationNotesPassageInclusionSelector () -{ - return getIValue ("consultation-notes-passage-inclusion-selector", 0); -} -void Database_Config_User::setConsultationNotesPassageInclusionSelector (int value) -{ - setIValue ("consultation-notes-passage-inclusion-selector", value); -} - - -int Database_Config_User::getConsultationNotesTextInclusionSelector () -{ - return getIValue ("consultation-notes-text-inclusion-selector", 0); -} -void Database_Config_User::setConsultationNotesTextInclusionSelector (int value) -{ - setIValue ("consultation-notes-text-inclusion-selector", value); -} - - -bool Database_Config_User::getBibleChangesNotification () -{ - return getBValue ("bible-changes-notification", false); -} -bool Database_Config_User::getUserBibleChangesNotification (string username) -{ - return getBValueForUser (username, "bible-changes-notification", false); -} -void Database_Config_User::setBibleChangesNotification (bool value) -{ - setBValue ("bible-changes-notification", value); -} - - -bool Database_Config_User::getDeletedConsultationNoteNotification () -{ - return getBValue ("deleted-consultation-note-notification", false); -} -bool Database_Config_User::getUserDeletedConsultationNoteNotification (string username) -{ - return getBValueForUser (username, "deleted-consultation-note-notification", false); -} -void Database_Config_User::setDeletedConsultationNoteNotification (bool value) -{ - setBValue ("deleted-consultation-note-notification", value); -} - - -bool Database_Config_User::defaultBibleChecksNotification () -{ -#ifdef HAVE_CLIENT - return false; -#else - int level = m_webserver_request.session_logic ()->currentLevel (); - return (level >= Filter_Roles::translator () && level <= Filter_Roles::manager ()); -#endif -} -bool Database_Config_User::getBibleChecksNotification () -{ - return getBValue ("bible-checks-notification", defaultBibleChecksNotification ()); -} -bool Database_Config_User::getUserBibleChecksNotification (string username) -{ - return getBValueForUser (username, "bible-checks-notification", defaultBibleChecksNotification ()); -} -void Database_Config_User::setBibleChecksNotification (bool value) -{ - setBValue ("bible-checks-notification", value); -} - - -bool Database_Config_User::getPendingChangesNotification () -{ - return getBValue ("pending-changes-notification", false); -} -bool Database_Config_User::getUserPendingChangesNotification (string username) -{ - return getBValueForUser (username, "pending-changes-notification", false); -} -void Database_Config_User::setPendingChangesNotification (bool value) -{ - setBValue ("pending-changes-notification", value); -} - - -bool Database_Config_User::getUserChangesNotification () -{ - return getBValue ("user-changes-notification", false); -} -bool Database_Config_User::getUserUserChangesNotification (string username) -{ - return getBValueForUser (username, "user-changes-notification", false); -} -void Database_Config_User::setUserChangesNotification (bool value) -{ - setBValue ("user-changes-notification", value); -} - - -bool Database_Config_User::getAssignedNotesStatisticsNotification () -{ - return getBValue ("assigned-notes-statistics-notification", false); -} -bool Database_Config_User::getUserAssignedNotesStatisticsNotification (string username) -{ - return getBValueForUser (username, "assigned-notes-statistics-notification", false); -} -void Database_Config_User::setAssignedNotesStatisticsNotification (bool value) -{ - setBValue ("assigned-notes-statistics-notification", value); -} - - -bool Database_Config_User::getSubscribedNotesStatisticsNotification () -{ - return getBValue ("subscribed-notes-statistics-notification", false); -} -bool Database_Config_User::getUserSubscribedNotesStatisticsNotification (string username) -{ - return getBValueForUser (username, "subscribed-notes-statistics-notification", false); -} -void Database_Config_User::setSubscribedNotesStatisticsNotification (bool value) -{ - setBValue ("subscribed-notes-statistics-notification", value); -} - - -bool Database_Config_User::getNotifyMeOfMyPosts () -{ - return getBValue ("notify-me-of-my-posts", true); -} -bool Database_Config_User::getUserNotifyMeOfMyPosts (string username) -{ - return getBValueForUser (username, "notify-me-of-my-posts", true); -} -void Database_Config_User::setNotifyMeOfMyPosts (bool value) -{ - setBValue ("notify-me-of-my-posts", value); -} - - -bool Database_Config_User::getSuppressMailFromYourUpdatesNotes () -{ - return getBValue ("suppress-mail-my-updated-notes", false); -} -bool Database_Config_User::getUserSuppressMailFromYourUpdatesNotes (string username) -{ - return getBValueForUser (username, "suppress-mail-my-updated-notes", false); -} -void Database_Config_User::setSuppressMailFromYourUpdatesNotes (bool value) -{ - setBValue ("suppress-mail-my-updated-notes", value); -} - - -vector Database_Config_User::getActiveResources () -{ - // Default values. - return getList ("active-resources"); -} -void Database_Config_User::setActiveResources (vector values) -{ - setList ("active-resources", values); -} - - -vector Database_Config_User::getConsistencyResources () -{ - return getList ("consistency-bibles"); -} -void Database_Config_User::setConsistencyResources (vector values) -{ - setList ("consistency-bibles", values); -} - - -const char * Database_Config_User::keySprintMonth () -{ - return "sprint-month"; -} -int Database_Config_User::getSprintMonth () -{ - return getIValue (keySprintMonth (), filter::date::numerical_month (filter::date::seconds_since_epoch ())); -} -void Database_Config_User::setSprintMonth (int value) -{ - setIValue (keySprintMonth (), value); -} - - -const char * Database_Config_User::keySprintYear () -{ - return "sprint-year"; -} -int Database_Config_User::getSprintYear () -{ - return getIValue (keySprintYear (), filter::date::numerical_year (filter::date::seconds_since_epoch ())); -} -void Database_Config_User::setSprintYear (int value) -{ - setIValue (keySprintYear (), value); -} - - -bool Database_Config_User::getSprintProgressNotification () -{ - return getBValue ("sprint-progress-notification", false); -} -bool Database_Config_User::getUserSprintProgressNotification (string username) -{ - return getBValueForUser (username, "sprint-progress-notification", false); -} -void Database_Config_User::setSprintProgressNotification (bool value) -{ - setBValue ("sprint-progress-notification", value); -} - - -bool Database_Config_User::getUserChangesNotificationsOnline () -{ - return getBValue ("user-changes-notifications-online", false); -} -bool Database_Config_User::getUserUserChangesNotificationsOnline (string username) -{ - return getBValueForUser (username, "user-changes-notifications-online", false); -} -void Database_Config_User::setUserChangesNotificationsOnline (bool value) -{ - setBValue ("user-changes-notifications-online", value); -} - - -bool Database_Config_User::getContributorChangesNotificationsOnline () -{ - return getBValue ("contributor-changes-notifications-online", false); -} -bool Database_Config_User::getContributorChangesNotificationsOnline (string username) -{ - return getBValueForUser (username, "contributor-changes-notifications-online", false); -} -void Database_Config_User::setContributorChangesNotificationsOnline (bool value) -{ - setBValue ("contributor-changes-notifications-online", value); -} - - -string Database_Config_User::getWorkspaceURLs () -{ - return getValue ("workbench-urls", ""); -} -void Database_Config_User::setWorkspaceURLs (string value) -{ - setValue ("workbench-urls", value); -} - - -string Database_Config_User::getWorkspaceWidths () -{ - return getValue ("workbench-widths", ""); -} -void Database_Config_User::setWorkspaceWidths (string value) -{ - setValue ("workbench-widths", value); -} - - -string Database_Config_User::getWorkspaceHeights () -{ - return getValue ("workbench-heights", ""); -} -void Database_Config_User::setWorkspaceHeights (string value) -{ - setValue ("workbench-heights", value); -} - - -string Database_Config_User::getEntireWorkspaceWidths () -{ - return getValue ("entire-workbench-widths", ""); -} -void Database_Config_User::setEntireWorkspaceWidths (string value) -{ - setValue ("entire-workbench-widths", value); -} - - -string Database_Config_User::getActiveWorkspace () -{ - return getValue ("active-workbench", ""); -} -void Database_Config_User::setActiveWorkspace (string value) -{ - setValue ("active-workbench", value); -} - - -bool Database_Config_User::getPostponeNewNotesMails () -{ - return getBValue ("postpone-new-notes-mails", false); -} -void Database_Config_User::setPostponeNewNotesMails (bool value) -{ - setBValue ("postpone-new-notes-mails", value); -} - - -string Database_Config_User::getRecentlyAppliedStyles () -{ - return getValue ("recently-applied-styles", "p s add nd f x v"); -} -void Database_Config_User::setRecentlyAppliedStyles (string values) -{ - setValue ("recently-applied-styles", values); -} - - -vector Database_Config_User::getPrintResources () -{ - return getList ("print-resources"); -} -vector Database_Config_User::getPrintResourcesForUser (string user) -{ - return getListForUser (user, "print-resources"); -} -void Database_Config_User::setPrintResources (vector values) -{ - setList ("print-resources", values); -} - - -Passage database_config_user_fix_passage (string value, const char * fallback) -{ - vector values = filter::strings::explode (value, '.'); - if (values.size () != 3) values = filter::strings::explode (fallback, '.'); - Passage passage = Passage ("", filter::strings::convert_to_int (values[0]), filter::strings::convert_to_int (values[1]), values[2]); - return passage; -} - - -Passage Database_Config_User::getPrintPassageFrom () -{ - return database_config_user_fix_passage (getValue ("print-passage-from", ""), "1.1.1"); -} -Passage Database_Config_User::getPrintPassageFromForUser (string user) -{ - return database_config_user_fix_passage (getValueForUser (user, "print-passage-from", ""), "1.1.1"); -} -void Database_Config_User::setPrintPassageFrom (Passage value) -{ - string s = filter::strings::convert_to_string (value.m_book) + "." + filter::strings::convert_to_string (value.m_chapter) + "." + value.m_verse; - setValue ("print-passage-from", s); -} - - -Passage Database_Config_User::getPrintPassageTo () -{ - return database_config_user_fix_passage (getValue ("print-passage-to", ""), "1.1.31"); -} -Passage Database_Config_User::getPrintPassageToForUser (string user) -{ - return database_config_user_fix_passage (getValueForUser (user, "print-passage-to", ""), "1.1.31"); -} -void Database_Config_User::setPrintPassageTo (Passage value) -{ - string s = filter::strings::convert_to_string (value.m_book) + "." + filter::strings::convert_to_string (value.m_chapter) + "." + value.m_verse; - setValue ("print-passage-to", s); -} - - -int Database_Config_User::getFocusedBook () -{ - return getIValue ("focused-book", 1); -} -void Database_Config_User::setFocusedBook (int book) -{ - setIValue ("focused-book", book); -} - - -int Database_Config_User::getFocusedChapter () -{ - return getIValue ("focused-chapter", 1); -} -void Database_Config_User::setFocusedChapter (int chapter) -{ - setIValue ("focused-chapter", chapter); -} - - -int Database_Config_User::getFocusedVerse () -{ - return getIValue ("focused-verse", 1); -} -void Database_Config_User::setFocusedVerse (int verse) -{ - setIValue ("focused-verse", verse); -} - - -vector Database_Config_User::getUpdatedSettings () -{ - return getIList ("updated-settings"); -} -void Database_Config_User::setUpdatedSettings (vector values) -{ - setIList ("updated-settings", values); -} -void Database_Config_User::addUpdatedSetting (int value) -{ - vector settings = getUpdatedSettings (); - settings.push_back (value); - settings = filter::strings::array_unique (settings); - setUpdatedSettings (settings); -} -void Database_Config_User::removeUpdatedSetting (int value) -{ - vector settings = getUpdatedSettings (); - vector against; - against.push_back (value); - settings = filter::strings::array_diff (settings, against); - setUpdatedSettings (settings); -} - - -vector Database_Config_User::getRemovedChanges () -{ - return getIList ("removed-changes"); -} -void Database_Config_User::setRemovedChanges (vector values) -{ - setIList ("removed-changes", values); -} -void Database_Config_User::addRemovedChange (int value) -{ - vector settings = getRemovedChanges (); - settings.push_back (value); - settings = filter::strings::array_unique (settings); - setRemovedChanges (settings); -} -void Database_Config_User::removeRemovedChange (int value) -{ - vector settings = getRemovedChanges (); - vector against; - against.push_back (value); - settings = filter::strings::array_diff (settings, against); - setRemovedChanges (settings); -} - - -string Database_Config_User::getChangeNotificationsChecksum () -{ - return getValue ("change-notifications-checksum", ""); -} -void Database_Config_User::setChangeNotificationsChecksum (string value) -{ - setValue ("change-notifications-checksum", value); -} -void Database_Config_User::setUserChangeNotificationsChecksum (string user, string value) -{ - setValueForUser (user, "change-notifications-checksum", value); -} - - -int Database_Config_User::getLiveBibleEditor () -{ - return getIValue ("live-bible-editor", 0); -} -void Database_Config_User::setLiveBibleEditor (int time) -{ - setIValue ("live-bible-editor", time); -} - - -int Database_Config_User::getResourceVersesBefore () -{ - return getIValue ("resource-verses-before", 0); -} -void Database_Config_User::setResourceVersesBefore (int verses) -{ - setIValue ("resource-verses-before", verses); -} - - -int Database_Config_User::getResourceVersesAfter () -{ - return getIValue ("resource-verses-after", 0); -} -void Database_Config_User::setResourceVersesAfter (int verses) -{ - setIValue ("resource-verses-after", verses); -} - - -// Encryption key storage on server. -string Database_Config_User::getSyncKey () -{ - return getValue ("sync-key", ""); -} -void Database_Config_User::setSyncKey (string key) -{ - setValue ("sync-key", key); -} - - - -//const char * site_language_key () -//{ -// return "site-language"; -//} -//string Database_Config_User::getSiteLanguage () -//{ -// // The default value is "default". -// // That means: Take the system setting. The user has no language preference. -// return getValue (site_language_key (), ""); -//} -//void Database_Config_User::setSiteLanguage (string value) -//{ -// setValue (site_language_key (), value); -//} - - -const char * general_font_size_key () -{ - return "general-font-size"; -} -int Database_Config_User::getGeneralFontSize () -{ - // Default value, see https://github.com/bibledit/cloud/issues/509 - return getIValue (general_font_size_key (), 112); -} -void Database_Config_User::setGeneralFontSize (int size) -{ - setIValue (general_font_size_key (), size); -} - - -const char * menu_font_size_key () -{ - return "menu-font-size"; -} -int Database_Config_User::getMenuFontSize () -{ - // Default value, see https://github.com/bibledit/cloud/issues/509 - return getIValue (menu_font_size_key (), 112); -} -void Database_Config_User::setMenuFontSize (int size) -{ - setIValue (menu_font_size_key (), size); -} - - -int Database_Config_User::getBibleEditorsFontSize () -{ - return getIValue ("bible-editors-font-size", 100); -} -void Database_Config_User::setBibleEditorsFontSize (int size) -{ - setIValue ("bible-editors-font-size", size); -} - - -int Database_Config_User::getResourcesFontSize () -{ - return getIValue ("resources-font-size", 100); -} -void Database_Config_User::setResourcesFontSize (int size) -{ - setIValue ("resources-font-size", size); -} - - -int Database_Config_User::getHebrewFontSize () -{ - return getIValue ("hebrew-font-size", 100); -} -void Database_Config_User::setHebrewFontSize (int size) -{ - setIValue ("hebrew-font-size", size); -} - - -int Database_Config_User::getGreekFontSize () -{ - return getIValue ("greek-font-size", 100); -} -void Database_Config_User::setGreekFontSize (int size) -{ - setIValue ("greek-font-size", size); -} - - -const char * vertical_caret_position_key () -{ - return "vertical-caret-position"; -} -int Database_Config_User::getVerticalCaretPosition () -{ - // Updated default value, see https://github.com/bibledit/cloud/issues/509 - return getIValue (vertical_caret_position_key (), 30); -} -void Database_Config_User::setVerticalCaretPosition (int position) -{ - setIValue (vertical_caret_position_key (), position); -} - - -const char * current_theme_style_key () -{ - return "current-theme-style"; -} -int Database_Config_User::getCurrentTheme () -{ - return getIValue (current_theme_style_key (), 0); -} -void Database_Config_User::setCurrentTheme (int index) -{ - setIValue (current_theme_style_key (), index); -} - - -bool Database_Config_User::getDisplayBreadcrumbs () -{ - return getBValue ("display-breadcrumbs", false); -} -void Database_Config_User::setDisplayBreadcrumbs (bool value) -{ - setBValue ("display-breadcrumbs", value); -} - - -int Database_Config_User::getWorkspaceMenuFadeoutDelay () -{ - return getIValue ("workspace-menu-fadeout-delay", 4); -} -void Database_Config_User::setWorkspaceMenuFadeoutDelay (int value) -{ - setIValue ("workspace-menu-fadeout-delay", value); -} - - -const char * editing_allowed_difference_chapter_key () -{ - return "editing-allowed-difference-chapter"; -} -int Database_Config_User::getEditingAllowedDifferenceChapter () -{ - return getIValue (editing_allowed_difference_chapter_key (), 20); -} -void Database_Config_User::setEditingAllowedDifferenceChapter (int value) -{ - setIValue (editing_allowed_difference_chapter_key (), value); -} - - -const char * editing_allowed_difference_verse_key () -{ - return "editing-allowed-difference-verse"; -} -int Database_Config_User::getEditingAllowedDifferenceVerse () -{ - return getIValue (editing_allowed_difference_verse_key (), 75); -} -void Database_Config_User::setEditingAllowedDifferenceVerse (int value) -{ - setIValue (editing_allowed_difference_verse_key (), value); -} - - -bool Database_Config_User::getBasicInterfaceModeDefault () -{ - // Touch devices default to basic mode. -#ifdef HAVE_ANDROID - return true; -#endif -#ifdef HAVE_IOS - return true; -#endif - // The app running on a workspace or laptop have default to basic mode for a lower role. - int level = m_webserver_request.session_logic ()->currentLevel (); - if (level <= Filter_Roles::manager ()) return true; - // Higher role: default to advanced mode. - return false; -} -bool Database_Config_User::getBasicInterfaceMode () -{ - return getBValue ("basic-interface-mode", getBasicInterfaceModeDefault ()); -} -void Database_Config_User::setBasicInterfaceMode (bool value) -{ - setBValue ("basic-interface-mode", value); -} - - -bool Database_Config_User::getMainMenuAlwaysVisible () -{ - // Default visible in basic mode. - // Advanced mode: By default it is not visible. - return getBValue ("main-menu-always-visible", getBasicInterfaceModeDefault ()); -} -void Database_Config_User::setMainMenuAlwaysVisible (bool value) -{ - setBValue ("main-menu-always-visible", value); -} - - -bool Database_Config_User::getSwipeActionsAvailable () -{ - return getBValue ("swipe-actions-available", true); -} -void Database_Config_User::setSwipeActionsAvailable (bool value) -{ - setBValue ("swipe-actions-available", value); -} - - -bool Database_Config_User::getFastEditorSwitchingAvailable () -{ - return getBValue ("fast-editor-switching-available", true); -} -void Database_Config_User::setFastEditorSwitchingAvailable (bool value) -{ - setBValue ("fast-editor-switching-available", value); -} - - -bool Database_Config_User::getIncludeRelatedPassages () -{ - return getBValue ("include-related-passages", false); -} -void Database_Config_User::setIncludeRelatedPassages (bool value) -{ - setBValue ("include-related-passages", value); -} - - -const char * enabled_visual_editors_key () -{ - return "enabled-visual-editors"; -} -int Database_Config_User::getFastSwitchVisualEditors () -{ - // Updated default values, see https://github.com/bibledit/cloud/issues/509 - return getIValue (enabled_visual_editors_key (), 0); -} -void Database_Config_User::setFastSwitchVisualEditors (int value) -{ - setIValue (enabled_visual_editors_key (), value); -} - - -int Database_Config_User::getFastSwitchUsfmEditors () -{ - // Initially only the USFM chapter editor is enabled. - return getIValue ("enabled-usfm-editors", 1); -} -void Database_Config_User::setFastSwitchUsfmEditors (int value) -{ - setIValue ("enabled-usfm-editors", value); -} - - -bool Database_Config_User::getEnableStylesButtonVisualEditors () -{ - return getBValue ("enable-styles-button-visual-editors", true); -} -void Database_Config_User::setEnableStylesButtonVisualEditors (bool value) -{ - setBValue ("enable-styles-button-visual-editors", value); -} - - -bool Database_Config_User::getMenuChangesInBasicMode () -{ - return getBValue ("menu-changes-in-basic-mode", false); -} -void Database_Config_User::setMenuChangesInBasicMode (bool value) -{ - setBValue ("menu-changes-in-basic-mode", value); -} - - -const char * privilege_use_advanced_mode_key () -{ - return "privilege-use-advanced-mode"; -} -bool Database_Config_User::getPrivilegeUseAdvancedMode () -{ - return getBValue (privilege_use_advanced_mode_key (), true); -} -bool Database_Config_User::getPrivilegeUseAdvancedModeForUser (string username) -{ - return getBValueForUser (username, privilege_use_advanced_mode_key (), true); -} -void Database_Config_User::setPrivilegeUseAdvancedModeForUser (string username, bool value) -{ - setBValueForUser (username, privilege_use_advanced_mode_key (), value); -} - - -const char * privilege_delete_consultation_notes_key () -{ - return "privilege-delete-consultation-notes"; -} -bool Database_Config_User::getPrivilegeDeleteConsultationNotes () -{ - return getBValue (privilege_delete_consultation_notes_key (), false); -} -void Database_Config_User::setPrivilegeDeleteConsultationNotes (bool value) -{ - setBValue (privilege_delete_consultation_notes_key (), value); -} -bool Database_Config_User::getPrivilegeDeleteConsultationNotesForUser (string username) -{ - return getBValueForUser (username, privilege_delete_consultation_notes_key (), false); -} -void Database_Config_User::setPrivilegeDeleteConsultationNotesForUser (string username, bool value) -{ - setBValueForUser (username, privilege_delete_consultation_notes_key (), value); -} - - -const char * privilege_set_stylesheets_key () -{ - return "privilege-set-stylesheets"; -} -bool Database_Config_User::getPrivilegeSetStylesheets () -{ - return getBValue (privilege_set_stylesheets_key (), false); -} -bool Database_Config_User::getPrivilegeSetStylesheetsForUser (string username) -{ - return getBValueForUser (username, privilege_set_stylesheets_key (), false); -} -void Database_Config_User::setPrivilegeSetStylesheetsForUser (string username, bool value) -{ - setBValueForUser (username, privilege_set_stylesheets_key (), value); -} - - -bool Database_Config_User::getDismissChangesAtTop () -{ - return getBValue ("dismiss-changes-at-top", false); -} -void Database_Config_User::setDismissChangesAtTop (bool value) -{ - setBValue ("dismiss-changes-at-top", value); -} - - -const char * quick_note_edit_link_key () -{ - return "quick-note-edit-link"; -} -bool Database_Config_User::getQuickNoteEditLink () -{ - return getBValue (quick_note_edit_link_key (), false); -} -void Database_Config_User::setQuickNoteEditLink (bool value) -{ - setBValue (quick_note_edit_link_key (), value); -} - - -const char * show_bible_in_notes_list_key () -{ - return "show-bible-in-notes-list"; -} -bool Database_Config_User::getShowBibleInNotesList () -{ - return getBValue (show_bible_in_notes_list_key (), false); -} -void Database_Config_User::setShowBibleInNotesList (bool value) -{ - setBValue (show_bible_in_notes_list_key (), value); -} - - -const char * show_note_status_key () -{ - return "show-note-status"; -} -bool Database_Config_User::getShowNoteStatus () -{ - return getBValue (show_note_status_key (), false); -} -void Database_Config_User::setShowNoteStatus (bool value) -{ - setBValue (show_note_status_key (), value); -} - - -const char * show_verse_text_at_create_note_key () -{ - return "show-verse-text-at-create-note"; -} -bool Database_Config_User::getShowVerseTextAtCreateNote () -{ - return getBValue (show_verse_text_at_create_note_key (), false); -} -void Database_Config_User::setShowVerseTextAtCreateNote (bool value) -{ - setBValue (show_verse_text_at_create_note_key (), value); -} - - -const char * order_changes_by_author_key () -{ - return "order-changes-by-author"; -} -bool Database_Config_User::getOrderChangesByAuthor () -{ - return getBValue (order_changes_by_author_key (), false); -} -void Database_Config_User::setOrderChangesByAuthor (bool value) -{ - setBValue (order_changes_by_author_key (), value); -} - - -const char * automatic_note_assignment_key () -{ - return "automatic-note-assignment"; -} -vector Database_Config_User::getAutomaticNoteAssignment () -{ - return getList (automatic_note_assignment_key ()); -} -void Database_Config_User::setAutomaticNoteAssignment (vector values) -{ - setList (automatic_note_assignment_key (), values); -} - - -const char * receive_focused_reference_from_paratext_key () -{ - return "receive-focused-reference-from-paratext"; -} -bool Database_Config_User::getReceiveFocusedReferenceFromParatext () -{ - return getBValue (receive_focused_reference_from_paratext_key (), true); -} -void Database_Config_User::setReceiveFocusedReferenceFromParatext (bool value) -{ - setBValue (receive_focused_reference_from_paratext_key (), value); -} - - -const char * receive_focused_reference_from_accordance_key () -{ - return "receive-focused-reference-from-accordance"; -} -bool Database_Config_User::getReceiveFocusedReferenceFromAccordance () -{ - return getBValue (receive_focused_reference_from_accordance_key (), true); -} -void Database_Config_User::setReceiveFocusedReferenceFromAccordance (bool value) -{ - setBValue (receive_focused_reference_from_accordance_key (), value); -} - - -const char * use_colored_note_status_labels_key () -{ - return "use-colored-note-status-labels"; -} -bool Database_Config_User::getUseColoredNoteStatusLabels () -{ - return getBValue (use_colored_note_status_labels_key (), false); -} -void Database_Config_User::setUseColoredNoteStatusLabels (bool value) -{ - setBValue (use_colored_note_status_labels_key (), value); -} - - -const char * notes_date_format_key () -{ - return "notes_date-format"; -} -int Database_Config_User::getNotesDateFormat () -{ - return getIValue (notes_date_format_key (), 0); -} -void Database_Config_User::setNotesDateFormat (int value) -{ - setIValue (notes_date_format_key (), value); -} - - -const char * change_notifications_bibles_key () -{ - return "change-notifications-bibles"; -} -vector Database_Config_User::getChangeNotificationsBibles () -{ - return getList (change_notifications_bibles_key ()); -} -vector Database_Config_User::getChangeNotificationsBiblesForUser (const string & user) -{ - return getListForUser (user, change_notifications_bibles_key ()); -} -void Database_Config_User::setChangeNotificationsBibles (const vector & values) -{ - setList (change_notifications_bibles_key (), values); -} diff --git a/database/config/user.h b/database/config/user.h deleted file mode 100644 index 3b6b3f39a..000000000 --- a/database/config/user.h +++ /dev/null @@ -1,274 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Webserver_Request; - -class Database_Config_User -{ -public: - Database_Config_User (Webserver_Request& webserver_request); - void trim (); - void remove (std::string username); - void clear_cache (); - std::string getBible (); - void setBible (std::string bible); - bool getSubscribeToConsultationNotesEditedByMe (); - void setSubscribeToConsultationNotesEditedByMe (bool value); - bool getNotifyMeOfAnyConsultationNotesEdits (); - bool getNotifyUserOfAnyConsultationNotesEdits (std::string username); - void setNotifyMeOfAnyConsultationNotesEdits (bool value); - bool getSubscribedConsultationNoteNotification (); - bool getUserSubscribedConsultationNoteNotification (std::string username); - void setSubscribedConsultationNoteNotification (bool value); - bool getAssignedToConsultationNotesChanges (); - bool getUserAssignedToConsultationNotesChanges (std::string username); - void setAssignedToConsultationNotesChanges (bool value); - bool getGenerateChangeNotifications (); - bool getUserGenerateChangeNotifications (std::string username); - void setGenerateChangeNotifications (bool value); - bool getAssignedConsultationNoteNotification (); - bool getUserAssignedConsultationNoteNotification (std::string username); - void setAssignedConsultationNoteNotification (bool value); - int getConsultationNotesPassageSelector (); - void setConsultationNotesPassageSelector (int value); - int getConsultationNotesEditSelector (); - void setConsultationNotesEditSelector (int value); - int getConsultationNotesNonEditSelector (); - void setConsultationNotesNonEditSelector (int value); - std::string getConsultationNotesStatusSelector (); - void setConsultationNotesStatusSelector (std::string value); - std::string getConsultationNotesBibleSelector (); - void setConsultationNotesBibleSelector (std::string value); - std::string getConsultationNotesAssignmentSelector (); - void setConsultationNotesAssignmentSelector (std::string value); - bool getConsultationNotesSubscriptionSelector (); - void setConsultationNotesSubscriptionSelector (bool value); - int getConsultationNotesSeveritySelector (); - void setConsultationNotesSeveritySelector (int value); - int getConsultationNotesTextSelector (); - void setConsultationNotesTextSelector (int value); - std::string getConsultationNotesSearchText (); - void setConsultationNotesSearchText (std::string value); - int getConsultationNotesPassageInclusionSelector (); - void setConsultationNotesPassageInclusionSelector (int value); - int getConsultationNotesTextInclusionSelector (); - void setConsultationNotesTextInclusionSelector (int value); - bool getBibleChangesNotification (); - bool getUserBibleChangesNotification (std::string username); - void setBibleChangesNotification (bool value); - bool getDeletedConsultationNoteNotification (); - bool getUserDeletedConsultationNoteNotification (std::string username); - void setDeletedConsultationNoteNotification (bool value); - bool getBibleChecksNotification (); - bool getUserBibleChecksNotification (std::string username); - void setBibleChecksNotification (bool value); - bool getPendingChangesNotification (); - bool getUserPendingChangesNotification (std::string username); - void setPendingChangesNotification (bool value); - bool getUserChangesNotification (); - bool getUserUserChangesNotification (std::string username); - void setUserChangesNotification (bool value); - bool getAssignedNotesStatisticsNotification (); - bool getUserAssignedNotesStatisticsNotification (std::string username); - void setAssignedNotesStatisticsNotification (bool value); - bool getSubscribedNotesStatisticsNotification (); - bool getUserSubscribedNotesStatisticsNotification (std::string username); - void setSubscribedNotesStatisticsNotification (bool value); - bool getNotifyMeOfMyPosts (); - bool getUserNotifyMeOfMyPosts (std::string username); - void setNotifyMeOfMyPosts (bool value); - bool getSuppressMailFromYourUpdatesNotes (); - bool getUserSuppressMailFromYourUpdatesNotes (std::string username); - void setSuppressMailFromYourUpdatesNotes (bool value); - std::vector getActiveResources (); - void setActiveResources (std::vector values); - std::vector getConsistencyResources (); - void setConsistencyResources (std::vector values); - int getSprintMonth (); - void setSprintMonth (int value); - int getSprintYear (); - void setSprintYear (int value); - bool getSprintProgressNotification (); - bool getUserSprintProgressNotification (std::string username); - void setSprintProgressNotification (bool value); - bool getUserChangesNotificationsOnline (); - bool getUserUserChangesNotificationsOnline (std::string username); - void setUserChangesNotificationsOnline (bool value); - bool getContributorChangesNotificationsOnline (); - bool getContributorChangesNotificationsOnline (std::string username); - void setContributorChangesNotificationsOnline (bool value); - std::string getWorkspaceURLs (); - void setWorkspaceURLs (std::string value); - std::string getWorkspaceWidths (); - void setWorkspaceWidths (std::string value); - std::string getWorkspaceHeights (); - void setWorkspaceHeights (std::string value); - std::string getEntireWorkspaceWidths (); - void setEntireWorkspaceWidths (std::string value); - std::string getActiveWorkspace (); - void setActiveWorkspace (std::string value); - bool getPostponeNewNotesMails (); - void setPostponeNewNotesMails (bool value); - std::string getRecentlyAppliedStyles (); - void setRecentlyAppliedStyles (std::string values); - std::vector getPrintResources (); - std::vector getPrintResourcesForUser (std::string user); - void setPrintResources (std::vector values); - Passage getPrintPassageFrom (); - Passage getPrintPassageFromForUser (std::string user); - void setPrintPassageFrom (Passage value); - Passage getPrintPassageTo (); - Passage getPrintPassageToForUser (std::string user); - void setPrintPassageTo (Passage value); - int getFocusedBook (); - void setFocusedBook (int book); - int getFocusedChapter (); - void setFocusedChapter (int chapter); - int getFocusedVerse (); - void setFocusedVerse (int verse); - std::vector getUpdatedSettings (); - void setUpdatedSettings (std::vector values); - void addUpdatedSetting (int value); - void removeUpdatedSetting (int value); - std::vector getRemovedChanges (); - void setRemovedChanges (std::vector values); - void addRemovedChange (int value); - void removeRemovedChange (int value); - std::string getChangeNotificationsChecksum (); - void setChangeNotificationsChecksum (std::string value); - void setUserChangeNotificationsChecksum (std::string user, std::string value); - void setLiveBibleEditor (int time); - int getLiveBibleEditor (); - void setResourceVersesBefore (int verses); - int getResourceVersesBefore (); - void setResourceVersesAfter (int verses); - int getResourceVersesAfter (); - std::string getSyncKey (); - void setSyncKey (std::string key); -// std::string getSiteLanguage (); -// void setSiteLanguage (std::string value); - void setGeneralFontSize (int size); - int getGeneralFontSize (); - void setMenuFontSize (int size); - int getMenuFontSize (); - void setResourcesFontSize (int size); - int getBibleEditorsFontSize (); - void setBibleEditorsFontSize (int size); - int getResourcesFontSize (); - void setHebrewFontSize (int size); - int getHebrewFontSize (); - void setGreekFontSize (int size); - int getGreekFontSize (); - void setVerticalCaretPosition (int position); - int getVerticalCaretPosition (); - void setCurrentTheme (int index); - int getCurrentTheme (); - bool getDisplayBreadcrumbs (); - void setDisplayBreadcrumbs (bool value); - void setWorkspaceMenuFadeoutDelay (int value); - int getWorkspaceMenuFadeoutDelay (); - int getEditingAllowedDifferenceChapter (); - void setEditingAllowedDifferenceChapter (int value); - int getEditingAllowedDifferenceVerse (); - void setEditingAllowedDifferenceVerse (int value); - bool getBasicInterfaceModeDefault (); - bool getBasicInterfaceMode (); - void setBasicInterfaceMode (bool value); - bool getMainMenuAlwaysVisible (); - void setMainMenuAlwaysVisible (bool value); - bool getSwipeActionsAvailable (); - void setSwipeActionsAvailable (bool value); - bool getFastEditorSwitchingAvailable (); - void setFastEditorSwitchingAvailable (bool value); - bool getIncludeRelatedPassages (); - void setIncludeRelatedPassages (bool value); - int getFastSwitchVisualEditors (); - void setFastSwitchVisualEditors (int value); - int getFastSwitchUsfmEditors (); - void setFastSwitchUsfmEditors (int value); - bool getEnableStylesButtonVisualEditors (); - void setEnableStylesButtonVisualEditors (bool value); - bool getMenuChangesInBasicMode (); - void setMenuChangesInBasicMode (bool value); - bool getPrivilegeUseAdvancedMode (); - bool getPrivilegeUseAdvancedModeForUser (std::string username); - void setPrivilegeUseAdvancedModeForUser (std::string username, bool value); - bool getPrivilegeDeleteConsultationNotes (); - void setPrivilegeDeleteConsultationNotes (bool value); - bool getPrivilegeDeleteConsultationNotesForUser (std::string username); - void setPrivilegeDeleteConsultationNotesForUser (std::string username, bool value); - bool getPrivilegeSetStylesheets (); - bool getPrivilegeSetStylesheetsForUser (std::string username); - void setPrivilegeSetStylesheetsForUser (std::string username, bool value); - bool getDismissChangesAtTop (); - void setDismissChangesAtTop (bool value); - bool getQuickNoteEditLink (); - void setQuickNoteEditLink (bool value); - bool getShowBibleInNotesList (); - void setShowBibleInNotesList (bool value); - bool getShowNoteStatus (); - void setShowNoteStatus (bool value); - bool getShowVerseTextAtCreateNote (); - void setShowVerseTextAtCreateNote (bool value); - bool getOrderChangesByAuthor (); - void setOrderChangesByAuthor (bool value); - std::vector getAutomaticNoteAssignment (); - void setAutomaticNoteAssignment (std::vector values); - bool getReceiveFocusedReferenceFromParatext (); - void setReceiveFocusedReferenceFromParatext (bool value); - bool getReceiveFocusedReferenceFromAccordance (); - void setReceiveFocusedReferenceFromAccordance (bool value); - bool getUseColoredNoteStatusLabels (); - void setUseColoredNoteStatusLabels (bool value); - int getNotesDateFormat (); - void setNotesDateFormat (int value); - std::vector getChangeNotificationsBibles (); - std::vector getChangeNotificationsBiblesForUser (const std::string & user); - void setChangeNotificationsBibles (const std::vector & values); -private: - Webserver_Request& m_webserver_request; - std::string file (std::string user); - std::string file (std::string user, const char * key); - std::string mapkey (std::string user, const char * key); - std::string getValue (const char * key, const char * default_value); - bool getBValue (const char * key, bool default_value); - int getIValue (const char * key, int default_value); - std::string getValueForUser (std::string user, const char * key, const char * default_value); - bool getBValueForUser (std::string user, const char * key, bool default_value); - int getIValueForUser (std::string user, const char * key, int default_value); - void setValue (const char * key, std::string value); - void setBValue (const char * key, bool value); - void setIValue (const char * key, int value); - void setValueForUser (std::string user, const char * key, std::string value); - void setBValueForUser (std::string user, const char * key, bool value); - std::vector getList (const char * key); - std::vector getListForUser (std::string user, const char * key); - void setList (const char * key, std::vector values); - void setListForUser (std::string user, const char * key, std::vector values); - std::vector getIList (const char * key); - void setIList (const char * key, std::vector values); - const char * keySprintMonth (); - const char * keySprintYear (); - bool defaultBibleChecksNotification (); -}; diff --git a/database/confirm.cpp b/database/confirm.cpp deleted file mode 100644 index 2a9c5b7b4..000000000 --- a/database/confirm.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Handles email and web page confirmations. -// Database resilience: It is used infrequently. -// It does not contain essential information. - - -#ifdef HAVE_CLOUD - - -const char * Database_Confirm::filename () -{ - return "confirm"; -} - - -void Database_Confirm::create () -{ - SqliteDatabase sql (filename ()); - sql.add ("CREATE TABLE IF NOT EXISTS confirm (" - " id integer," - " query text," - " timestamp integer," - " mailto text," - " subject text," - " body text" - ");"); - sql.execute (); -} - - -void Database_Confirm::upgrade () -{ - // Get the existing columns in the database. - SqliteDatabase sql (filename ()); - sql.add ("PRAGMA table_info (confirm);"); - vector columns = sql.query () ["name"]; - - // Add the column for the username if it's not yet there. - if (!in_array (static_cast ("username"), columns)) { - sql.clear (); - sql.add ("ALTER TABLE confirm ADD COLUMN username text;"); - sql.execute (); - } -} - - -void Database_Confirm::optimize () -{ - SqliteDatabase sql (filename ()); - sql.add ("VACUUM;"); - sql.execute (); -} - - -// getNewID - returns a new unique confirmation ID as an integer -unsigned int Database_Confirm::get_new_id () -{ - unsigned int id = 0; - do { - id = static_cast(config_globals_int_distribution (config_globals_random_engine)); - } while (id_exists (id)); - return id; -} - - -// Returns true if the $id exists -bool Database_Confirm::id_exists (unsigned int id) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT id FROM confirm WHERE id ="); - sql.add (static_cast(id)); - sql.add (";"); - vector ids = sql.query () ["id"]; - return !ids.empty (); -} - - -// Store a confirmation cycle -void Database_Confirm::store (unsigned int id, string query, - string to, string subject, string body, - string username) -{ - SqliteDatabase sql (filename ()); - sql.add ("INSERT INTO confirm VALUES ("); - sql.add (static_cast(id)); - sql.add (","); - sql.add (query); - sql.add (","); - sql.add (filter::date::seconds_since_epoch ()); - sql.add (","); - sql.add (to); - sql.add (","); - sql.add (subject); - sql.add (","); - sql.add (body); - sql.add (","); - sql.add (username); - sql.add (");"); - sql.execute (); -} - - -// Search the database for an existing ID in $subject. -// If it exists, it returns the ID number, else it returns 0. -unsigned int Database_Confirm::search_id (string subject) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT id FROM confirm;"); - vector ids = sql.query () ["id"]; - for (string id : ids) { - size_t pos = subject.find (id); - if (pos != std::string::npos) { - return static_cast(filter::strings::convert_to_int (id)); - } - } - return 0; -} - - -vector Database_Confirm::get_ids () -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT id FROM confirm;"); - vector s_ids = sql.query () ["id"]; - vector ids; - for (auto id : s_ids) ids.push_back(filter::strings::convert_to_int(id)); - return ids; -} - - -// Returns the query for $id. -string Database_Confirm::get_query (unsigned int id) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT query FROM confirm WHERE id ="); - sql.add (static_cast(id)); - sql.add (";"); - vector result = sql.query () ["query"]; - if (!result.empty ()) return result [0]; - return ""; -} - - -// Returns the To: address for $id. -string Database_Confirm::get_mail_to (unsigned int id) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT mailto FROM confirm WHERE id ="); - sql.add (static_cast(id)); - sql.add (";"); - vector result = sql.query () ["mailto"]; - if (!result.empty ()) return result [0]; - return ""; -} - - -// Returns the Subject: for $id. -string Database_Confirm::get_subject (unsigned int id) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT subject FROM confirm WHERE id ="); - sql.add (static_cast(id)); - sql.add (";"); - vector result = sql.query () ["subject"]; - if (!result.empty ()) return result [0]; - return ""; -} - - -// Returns the email's body for $id. -string Database_Confirm::get_body (unsigned int id) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT body FROM confirm WHERE id ="); - sql.add (static_cast(id)); - sql.add (";"); - vector result = sql.query () ["body"]; - if (!result.empty ()) return result [0]; - return ""; -} - - -// Returns the username for $id. -string Database_Confirm::get_username (unsigned int id) // Test return valid and invalid username. -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT username FROM confirm WHERE id ="); - sql.add (static_cast(id)); - sql.add (";"); - vector result = sql.query () ["username"]; - if (!result.empty ()) return result [0]; - return string(); -} - - -// Deletes $id from the table. -void Database_Confirm::erase (unsigned int id) -{ - SqliteDatabase sql (filename ()); - sql.add ("DELETE FROM confirm WHERE id ="); - sql.add (static_cast(id)); - sql.add (";"); - sql.execute (); -} - - -void Database_Confirm::trim () -{ - // Leave entries for no more than 30 days. - int time = filter::date::seconds_since_epoch () - 2592000; - SqliteDatabase sql (filename ()); - sql.add ("DELETE FROM confirm WHERE timestamp <"); - sql.add (time); - sql.add (";"); - sql.execute (); -} - - -#endif diff --git a/database/confirm.h b/database/confirm.h deleted file mode 100644 index 070a1f448..000000000 --- a/database/confirm.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - - -#ifdef HAVE_CLOUD - - -class Database_Confirm -{ -public: - void create (); - void upgrade (); - void optimize (); - unsigned int get_new_id (); - bool id_exists (unsigned int id); - void store (unsigned int id, std::string query, std::string to, std::string subject, std::string body, std::string username); - unsigned int search_id (std::string subject); - std::vector get_ids (); - std::string get_query (unsigned int id); - std::string get_mail_to (unsigned int id); - std::string get_subject (unsigned int id); - std::string get_body (unsigned int id); - std::string get_username (unsigned int id); - void erase (unsigned int id); - void trim (); -private: - const char * filename (); -}; - - -#endif - diff --git a/database/etcbc4.cpp b/database/etcbc4.cpp deleted file mode 100644 index 892e31161..000000000 --- a/database/etcbc4.cpp +++ /dev/null @@ -1,552 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: -// The database is normally only read from. - - -sqlite3 * Database_Etcbc4::connect () -{ - return database_sqlite_connect ("etcb4"); -} - - -void Database_Etcbc4::create () -{ - sqlite3 * db = connect (); - string sql; - - sql = - "CREATE TABLE IF NOT EXISTS rawdata (book int, chapter int, verse int, data text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS data;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS data (book int, chapter int, verse int, " - "word int, vocalized_lexeme int, consonantal_lexeme int, " - "gloss int, pos int, subpos int, " - "gender int, number int, person int, " - "state int, tense int, stem int, " - "phrase_function int, phrase_type int, phrase_relation int, " - "phrase_a_relation int, clause_text_type int, clause_type int, clause_relation int" - ");"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS word;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS word (word text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS vocalized_lexeme;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS vocalized_lexeme (vocalized_lexeme text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS consonantal_lexeme;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS consonantal_lexeme (consonantal_lexeme text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS gloss;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS gloss (gloss text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS pos;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS pos (pos text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS subpos;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS subpos (subpos text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS gender;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS gender (gender text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS number;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS number (number text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS person;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS person (person text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS state;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS state (state text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS tense;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS tense (tense text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS stem;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS stem (stem text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS phrase_function;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS phrase_function (phrase_function text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS phrase_type;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS phrase_type (phrase_type text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS phrase_relation;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS phrase_relation (phrase_relation text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS phrase_a_relation;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS phrase_a_relation (phrase_a_relation text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS clause_text_type;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS clause_text_type (clause_text_type text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS clause_type;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS clause_type (clause_type text);"; - database_sqlite_exec (db, sql); - - sql = - "DROP TABLE IF EXISTS clause_relation;"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS clause_relation (clause_relation text);"; - database_sqlite_exec (db, sql); - - database_sqlite_disconnect (db); -} - - -string Database_Etcbc4::raw (int book, int chapter, int verse) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT data FROM rawdata WHERE book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("AND verse ="); - sql.add (verse); - sql.add (";"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["data"]; - database_sqlite_disconnect (db); - if (!result.empty ()) return result [0]; - return ""; -} - - -void Database_Etcbc4::store (int book, int chapter, int verse, string data) -{ - sqlite3 * db = connect (); - { - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM rawdata WHERE book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("AND verse ="); - sql.add (verse); - sql.add (";"); - database_sqlite_exec (db, sql.sql); - } - { - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO rawdata VALUES ("); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (data); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - } - database_sqlite_disconnect (db); -} - - -void Database_Etcbc4::store (int book, int chapter, int verse, - string word, string vocalized_lexeme, string consonantal_lexeme, - string gloss, string pos, string subpos, - string gender, string number, string person, - string state, string tense, string stem, - string phrase_function, string phrase_type, string phrase_relation, - string phrase_a_relation, string clause_text_type, string clause_type, string clause_relation) -{ - sqlite3 * db = connect (); - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO data VALUES ("); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (get_id (db, "word", word)); - sql.add (","); - sql.add (get_id (db, "vocalized_lexeme", vocalized_lexeme)); - sql.add (","); - sql.add (get_id (db, "consonantal_lexeme", consonantal_lexeme)); - sql.add (","); - sql.add (get_id (db, "gloss", gloss)); - sql.add (","); - sql.add (get_id (db, "pos", pos)); - sql.add (","); - sql.add (get_id (db, "subpos", subpos)); - sql.add (","); - sql.add (get_id (db, "gender", gender)); - sql.add (","); - sql.add (get_id (db, "number", number)); - sql.add (","); - sql.add (get_id (db, "person", person)); - sql.add (","); - sql.add (get_id (db, "state", state)); - sql.add (","); - sql.add (get_id (db, "tense", tense)); - sql.add (","); - sql.add (get_id (db, "stem", stem)); - sql.add (","); - sql.add (get_id (db, "phrase_function", phrase_function)); - sql.add (","); - sql.add (get_id (db, "phrase_type", phrase_type)); - sql.add (","); - sql.add (get_id (db, "phrase_relation", phrase_relation)); - sql.add (","); - sql.add (get_id (db, "phrase_a_relation", phrase_a_relation)); - sql.add (","); - sql.add (get_id (db, "clause_text_type", clause_text_type)); - sql.add (","); - sql.add (get_id (db, "clause_type", clause_type)); - sql.add (","); - sql.add (get_id (db, "clause_relation", clause_relation)); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -vector Database_Etcbc4::books () -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT book FROM rawdata ORDER BY book;"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["book"]; - database_sqlite_disconnect (db); - vector books; - for (auto b : result) books.push_back (filter::strings::convert_to_int (b)); - return books; -} - - -vector Database_Etcbc4::chapters (int book) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT chapter FROM rawdata WHERE book ="); - sql.add (book); - sql.add ("ORDER BY chapter;"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["chapter"]; - database_sqlite_disconnect (db); - vector chapters; - for (auto c : result) chapters.push_back (filter::strings::convert_to_int (c)); - return chapters; -} - - -vector Database_Etcbc4::verses (int book, int chapter) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT verse FROM rawdata WHERE book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("ORDER BY verse;"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["verse"]; - database_sqlite_disconnect (db); - vector verses; - for (auto v : result) verses.push_back (filter::strings::convert_to_int (v)); - return verses; -} - - -vector Database_Etcbc4::rowids (int book, int chapter, int verse) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid FROM data WHERE book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("AND verse ="); - sql.add (verse); - sql.add (";"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["rowid"]; - database_sqlite_disconnect (db); - vector rowids; - for (auto rowid : result) rowids.push_back (filter::strings::convert_to_int (rowid)); - return rowids; -} - - -string Database_Etcbc4::word (int rowid) -{ - return get_item ("word", rowid); -} - - -string Database_Etcbc4::vocalized_lexeme (int rowid) -{ - return get_item ("vocalized_lexeme", rowid); -} - - -string Database_Etcbc4::consonantal_lexeme (int rowid) -{ - return get_item ("consonantal_lexeme", rowid); -} - - -string Database_Etcbc4::gloss (int rowid) -{ - return get_item ("gloss", rowid); -} - - -string Database_Etcbc4::pos (int rowid) -{ - return get_item ("pos", rowid); -} - - -string Database_Etcbc4::subpos (int rowid) -{ - return get_item ("subpos", rowid); -} - - -string Database_Etcbc4::gender (int rowid) -{ - return get_item ("gender", rowid); -} - - -string Database_Etcbc4::number (int rowid) -{ - return get_item ("number", rowid); -} - - -string Database_Etcbc4::person (int rowid) -{ - return get_item ("person", rowid); -} - - -string Database_Etcbc4::state (int rowid) -{ - return get_item ("state", rowid); -} - - -string Database_Etcbc4::tense (int rowid) -{ - return get_item ("tense", rowid); -} - - -string Database_Etcbc4::stem (int rowid) -{ - return get_item ("stem", rowid); -} - - -string Database_Etcbc4::phrase_function (int rowid) -{ - return get_item ("phrase_function", rowid); -} - - -string Database_Etcbc4::phrase_type (int rowid) -{ - return get_item ("phrase_type", rowid); -} - - -string Database_Etcbc4::phrase_relation (int rowid) -{ - return get_item ("phrase_relation", rowid); -} - - -string Database_Etcbc4::phrase_a_relation (int rowid) -{ - return get_item ("phrase_a_relation", rowid); -} - - -string Database_Etcbc4::clause_text_type (int rowid) -{ - return get_item ("clause_text_type", rowid); -} - - -string Database_Etcbc4::clause_type (int rowid) -{ - return get_item ("clause_type", rowid); -} - - -string Database_Etcbc4::clause_relation (int rowid) -{ - return get_item ("clause_relation", rowid); -} - - -int Database_Etcbc4::get_id (sqlite3 * db, const char * table_row, string item) -{ - // Two iterations to be sure a rowid can be returned. - for (unsigned int i = 0; i < 2; i++) { - { - // Check on the rowid and return it if it's there. - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid FROM"); - sql.add (table_row); - sql.add ("WHERE"); - sql.add (table_row); - sql.add ("="); - sql.add (item); - sql.add (";"); - vector result = database_sqlite_query (db, sql.sql) ["rowid"]; - if (!result.empty ()) return filter::strings::convert_to_int (result [0]); - } - { - // The rowid was not found: Insert the word into the table. - // The rowid will now be found during the second iteration. - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO"); - sql.add (table_row); - sql.add ("VALUES ("); - sql.add (item); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - } - } - return 0; -} - - -string Database_Etcbc4::get_item (const char * item, int rowid) -{ - // The $rowid refers to the main table. - // Update it so it refers to the sub table. - sqlite3 * db = connect (); - { - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT"); - sql.add (item); - sql.add ("FROM data WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - vector result = database_sqlite_query (db, sql.sql) [item]; - rowid = 0; - if (!result.empty ()) rowid = filter::strings::convert_to_int (result [0]); - } - // Retrieve the requested value from the sub table. - string value; - { - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT"); - sql.add (item); - sql.add ("FROM"); - sql.add (item); - sql.add ("WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - vector result = database_sqlite_query (db, sql.sql) [item]; - if (!result.empty ()) value = result [0]; - } - database_sqlite_disconnect (db); - // Done. - return value; -} diff --git a/database/etcbc4.h b/database/etcbc4.h deleted file mode 100644 index 9618936d5..000000000 --- a/database/etcbc4.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Etcbc4 -{ -public: - void create (); - std::string raw (int book, int chapter, int verse); - void store (int book, int chapter, int verse, std::string data); - void store (int book, int chapter, int verse, - std::string word, std::string vocalized_lexeme, std::string consonantal_lexeme, - std::string gloss, std::string pos, std::string subpos, - std::string gender, std::string number, std::string person, - std::string state, std::string tense, std::string stem, - std::string phrase_function, std::string phrase_type, std::string phrase_relation, - std::string phrase_a_relation, std::string clause_text_type, std::string clause_type, std::string clause_relation); - std::vector books (); - std::vector chapters (int book); - std::vector verses (int book, int chapter); - std::vector rowids (int book, int chapter, int verse); - std::string word (int rowid); - std::string vocalized_lexeme (int rowid); - std::string consonantal_lexeme (int rowid); - std::string gloss (int rowid); - std::string pos (int rowid); - std::string subpos (int rowid); - std::string gender (int rowid); - std::string number (int rowid); - std::string person (int rowid); - std::string state (int rowid); - std::string tense (int rowid); - std::string stem (int rowid); - std::string phrase_function (int rowid); - std::string phrase_type (int rowid); - std::string phrase_relation (int rowid); - std::string phrase_a_relation (int rowid); - std::string clause_text_type (int rowid); - std::string clause_type (int rowid); - std::string clause_relation (int rowid); -private: - sqlite3 * connect (); - int get_id (sqlite3 * db, const char * table_row, std::string item); - std::string get_item (const char * item, int rowid); -}; diff --git a/database/git.cpp b/database/git.cpp deleted file mode 100644 index 01206711b..000000000 --- a/database/git.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: It contains statistical and non-essential data. -// It is checked and optionally recreated at least once a day. - - -#ifdef HAVE_CLOUD - - -void Database_Git::create () -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("CREATE TABLE IF NOT EXISTS changes (" - " timestamp integer," - " user text," - " bible text," - " book integer," - " chapter integer," - " oldusfm text," - " newusfm text" - ");"); - sql.execute (); -} - - -void Database_Git::optimize () -{ - bool healthy_database = database_sqlite_healthy (name ()); - if (!healthy_database) { - filter_url_unlink (database_sqlite_file (name ())); - create (); - } - - SqliteDatabase sql = SqliteDatabase (name ()); - - // On Android, this pragma prevents the following error: VACUUM; Unable to open database file. - sql.add ("PRAGMA temp_store = MEMORY;"); - sql.execute (); - - sql.clear (); - - // Delete entries older than 10 days. - int timestamp = filter::date::seconds_since_epoch () - 432000; - sql.add ("DELETE FROM changes WHERE timestamp <"); - sql.add (timestamp); - sql.add (";"); - sql.execute (); - - sql.clear (); - - sql.add ("VACUUM;"); - sql.execute (); -} - - -void Database_Git::store_chapter (string user, string bible, int book, int chapter, - string oldusfm, string newusfm) -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("INSERT INTO changes VALUES ("); - sql.add (filter::date::seconds_since_epoch ()); - sql.add (","); - sql.add (user); - sql.add (","); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (oldusfm); - sql.add (","); - sql.add (newusfm); - sql.add (");"); - sql.execute (); -} - - -// Fetches the distinct users from the database for $bible. -vector Database_Git::get_users (string bible) -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("SELECT DISTINCT user FROM changes WHERE bible ="); - sql.add (bible); - sql.add (";"); - vector users = sql.query () ["user"]; - return users; -} - - -// Fetches the rowids from the database for $user and $bible. -vector Database_Git::get_rowids (string user, string bible) -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("SELECT rowid FROM changes WHERE user ="); - sql.add (user); - sql.add ("AND bible ="); - sql.add (bible); - sql.add ("ORDER BY rowid;"); - vector values = sql.query () ["rowid"]; - vector rowids; - for (auto value : values) { - rowids.push_back (filter::strings::convert_to_int (value)); - } - return rowids; -} - - -bool Database_Git::get_chapter (int rowid, - string & user, string & bible, int & book, int & chapter, - string & oldusfm, string & newusfm) -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("SELECT * FROM changes WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - map > result = sql.query (); - vector users = result ["user"]; - vector bibles = result ["bible"]; - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector oldusfms = result ["oldusfm"]; - vector newusfms = result ["newusfm"]; - if (bibles.empty ()) return false; - if (!users.empty ()) user = users [0]; - if (!bibles.empty ()) bible = bibles [0]; - if (!books.empty ()) book = filter::strings::convert_to_int (books [0]); - if (!chapters.empty ()) chapter = filter::strings::convert_to_int (chapters [0]); - if (oldusfm.empty ()) oldusfm = oldusfms [0]; - if (newusfm.empty ()) newusfm = newusfms [0]; - return true; -} - - -// Flag export of $bible $book to $format. -void Database_Git::erase_rowid (int rowid) -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("DELETE FROM changes WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - sql.execute (); -} - - -void Database_Git::touch_timestamps (int timestamp) -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("UPDATE changes SET timestamp ="); - sql.add (timestamp); - sql.add (";"); - sql.execute (); -} - - -const char * Database_Git::name () -{ - return "git"; -} - - -#endif diff --git a/database/git.h b/database/git.h deleted file mode 100644 index 35723f469..000000000 --- a/database/git.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - - -#include - - -#ifdef HAVE_CLOUD - - -class Database_Git -{ -public: - static void create (); - static void optimize (); - static void store_chapter (std::string user, std::string bible, int book, int chapter, - std::string oldusfm, std::string newusfm); - static std::vector get_users (std::string bible); - static std::vector get_rowids (std::string user, std::string bible); - static bool get_chapter (int rowid, - std::string & user, std::string & bible, int & book, int & chapter, - std::string & oldusfm, std::string & newusfm); - static void erase_rowid (int rowid); - static void touch_timestamps (int timestamp); -private: - static const char * name (); -}; - - -#endif diff --git a/database/hebrewlexicon.cpp b/database/hebrewlexicon.cpp deleted file mode 100644 index 5b3f65f3a..000000000 --- a/database/hebrewlexicon.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// This is the database that contains Open Scriptures's Hebrew Lexicon. -// Resilience: It is not written to. -// Chances of corruption are nearly zero. - - -const char * Database_HebrewLexicon::filename () -{ - return "hebrewlexicon"; -} - - -void Database_HebrewLexicon::create () -{ - filter_url_unlink (database_sqlite_file (filename ())); - - SqliteDatabase sql = SqliteDatabase (filename ()); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS aug (aug text, target text);"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS bdb (id text, definition text);"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS map (id text, bdb text);"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS pos (code text, name text);"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS strong (strong text, definition text);"); - sql.execute (); -} - - -void Database_HebrewLexicon::optimize () -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("VACUUM;"); - sql.execute (); -} - - -void Database_HebrewLexicon::setaug (string aug, string target) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("INSERT INTO aug VALUES ("); - sql.add (aug); - sql.add (","); - sql.add (target); - sql.add (");"); - sql.execute (); -} - - -void Database_HebrewLexicon::setbdb (string id, string definition) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("INSERT INTO bdb VALUES ("); - sql.add (id); - sql.add (","); - sql.add (definition); - sql.add (");"); - sql.execute (); -} - - -void Database_HebrewLexicon::setmap (string id, string bdb) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("INSERT INTO map VALUES ("); - sql.add (id); - sql.add (","); - sql.add (bdb); - sql.add (");"); - sql.execute (); -} - - -void Database_HebrewLexicon::setpos (string code, string name) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("INSERT INTO pos VALUES ("); - sql.add (code); - sql.add (","); - sql.add (name); - sql.add (");"); - sql.execute (); -} - - -void Database_HebrewLexicon::setstrong (string strong, string definition) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("INSERT INTO strong VALUES ("); - sql.add (strong); - sql.add (","); - sql.add (definition); - sql.add (");"); - sql.execute (); -} - - -string Database_HebrewLexicon::getaug (string aug) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT target FROM aug WHERE aug ="); - sql.add (aug); - sql.add (";"); - vector result = sql.query () ["target"]; - if (!result.empty ()) return result [0]; - return ""; -} - - -string Database_HebrewLexicon::getbdb (string id) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT definition FROM bdb WHERE id ="); - sql.add (id); - sql.add (";"); - vector result = sql.query () ["definition"]; - if (!result.empty ()) return result [0]; - return ""; -} - - -string Database_HebrewLexicon::getmap (string id) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT bdb FROM map WHERE id ="); - sql.add (id); - sql.add (";"); - vector result = sql.query () ["bdb"]; - if (!result.empty ()) return result [0]; - return ""; -} - - -string Database_HebrewLexicon::getpos (string code) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT name FROM pos WHERE code ="); - sql.add (code); - sql.add (";"); - vector result = sql.query () ["name"]; - if (!result.empty ()) return result [0]; - return ""; -} - - -string Database_HebrewLexicon::getstrong (string strong) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT definition FROM strong WHERE strong ="); - sql.add (strong); - sql.add (";"); - vector result = sql.query () ["definition"]; - if (!result.empty ()) return result [0]; - return ""; -} diff --git a/database/hebrewlexicon.h b/database/hebrewlexicon.h deleted file mode 100644 index 4fb3685ba..000000000 --- a/database/hebrewlexicon.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_HebrewLexicon -{ -public: - void create (); - void optimize (); - void setaug (std::string aug, std::string target); - void setbdb (std::string id, std::string definition); - void setmap (std::string id, std::string bdb); - void setpos (std::string code, std::string name); - void setstrong (std::string strong, std::string definition); - std::string getaug (std::string aug); - std::string getbdb (std::string id); - std::string getmap (std::string id); - std::string getpos (std::string code); - std::string getstrong (std::string strong); -private: - const char * filename (); -}; diff --git a/database/imageresources.cpp b/database/imageresources.cpp deleted file mode 100644 index 33b07ef98..000000000 --- a/database/imageresources.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: -// The data is stored as images and files in the filesystem. -// That should be resilient enough. - - -string Database_ImageResources::mainFolder () -{ - return filter_url_create_root_path ({database_logic_databases (), "imageresources"}); -} - - -string Database_ImageResources::resourceFolder (const string& name) -{ - return filter_url_create_path ({mainFolder (), name}); -} - - -string Database_ImageResources::imagePath (string name, string image) -{ - return filter_url_create_path ({resourceFolder (name), image}); -} - - -string Database_ImageResources::databaseFile () -{ - return "passages.sqlite"; -} - - -sqlite3 * Database_ImageResources::connect (string name) -{ - string path = filter_url_create_path ({resourceFolder (name), databaseFile ()}); - return database_sqlite_connect (path); -} - - -vector Database_ImageResources::names () -{ - return filter_url_scandir (mainFolder ()); -} - - -void Database_ImageResources::create (string name) -{ - // Create folder to store the images. - string path = resourceFolder (name); - filter_url_unlink (path); - filter_url_mkdir (path); - - // Create the passages database. - sqlite3 * db = connect (name); - string sql = - "CREATE TABLE IF NOT EXISTS passages (" - " start integer," - " end integer," - " image text" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -void Database_ImageResources::erase (string name) -{ - string path = resourceFolder (name); - // If a folder: Delete it. - filter_url_rmdir (path); - // If a file: Delete it. - filter_url_unlink (path); -} - - -void Database_ImageResources::erase (string name, string image) -{ - filter_url_unlink (imagePath (name, image)); - sqlite3 * db = connect (name); - { - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM passages WHERE image ="); - sql.add (image); - sql.add (";"); - database_sqlite_exec (db, sql.sql); - } - database_sqlite_disconnect (db); -} - - -// Moves $file (path to an image file) into the database. -string Database_ImageResources::store (string name, string file) -{ - string folder = resourceFolder (name); - string image = filter_url_basename (file); - string path; - bool exists = false; - do { - path = filter_url_create_path ({folder, image}); - exists = file_or_dir_exists (path); - if (exists) image = filter::strings::replace (".", "0.", image); - } while (exists); - filter_url_rename (file, path); - return image; -} - - -// Assign a passage range to the $image. -// It means that this image contains text for the passage range. -void Database_ImageResources::assign (string name, string image, - int book1, int chapter1, int verse1, - int book2, int chapter2, int verse2) -{ - sqlite3 * db = connect (name); - { - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM passages WHERE image ="); - sql.add (image); - sql.add (";"); - database_sqlite_exec (db, sql.sql); - } - { - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO passages VALUES ("); - sql.add (filter_passage_to_integer (Passage ("", book1, chapter1, filter::strings::convert_to_string (verse1)))); - sql.add (","); - sql.add (filter_passage_to_integer (Passage ("", book2, chapter2, filter::strings::convert_to_string (verse2)))); - sql.add (","); - sql.add (image); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - } - database_sqlite_disconnect (db); -} - - -vector Database_ImageResources::get (string name, int book, int chapter, int verse) -{ - int passage = filter_passage_to_integer (Passage ("", book, chapter, filter::strings::convert_to_string (verse))); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT image FROM passages WHERE start <="); - sql.add (passage); - sql.add ("AND end >="); - sql.add (passage); - sql.add ("ORDER BY start;"); - sqlite3 * db = connect (name); - vector images = database_sqlite_query (db, sql.sql) ["image"]; - database_sqlite_disconnect (db); - return images; -} - - -vector Database_ImageResources::get (string name) -{ - // Get images from database, sorted on passage. - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT image FROM passages ORDER by start;"); - sqlite3 * db = connect (name); - vector images = database_sqlite_query (db, sql.sql) ["image"]; - database_sqlite_disconnect (db); - - // Get images from the folder. - vector files = filter_url_scandir (resourceFolder (name)); - - // Files on disk, and not in the list from the database, add them. - for (auto & file : files) { - if (!in_array (file, images)) { - if (file != databaseFile ()) { - images.push_back (file); - } - } - } - - // Result. - return images; -} - - -void Database_ImageResources::get (string name, string image, - int & book1, int & chapter1, int & verse1, - int & book2, int & chapter2, int & verse2) -{ - book1 = 0; - chapter1 = 0; - verse1 = 0; - book2 = 0; - chapter2 = 0; - verse2 = 0; - - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT start, end FROM passages WHERE image ="); - sql.add (image); - sql.add ("ORDER by start;"); - sqlite3 * db = connect (name); - map > results = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector start = results["start"]; - vector end = results["end"]; - - if (!start.empty ()) { - Passage passage = filter_integer_to_passage (filter::strings::convert_to_int (start [0])); - book1 = passage.m_book; - chapter1 = passage.m_chapter; - verse1 = filter::strings::convert_to_int (passage.m_verse); - } - - if (!end.empty ()) { - Passage passage = filter_integer_to_passage (filter::strings::convert_to_int (end [0])); - book2 = passage.m_book; - chapter2 = passage.m_chapter; - verse2 = filter::strings::convert_to_int (passage.m_verse); - } -} - - -string Database_ImageResources::get (string name, string image) -{ - string path = imagePath (name, image); - return filter_url_file_get_contents (path); -} diff --git a/database/imageresources.h b/database/imageresources.h deleted file mode 100644 index 252a71e02..000000000 --- a/database/imageresources.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_ImageResources -{ -public: - std::vector names (); - void create (std::string name); - void erase (std::string name); - void erase (std::string name, std::string image); - std::string store (std::string name, std::string file); - void assign (std::string name, std::string image, - int book1, int chapter1, int verse1, - int book2, int chapter2, int verse2); - std::vector get (std::string name, int book, int chapter, int verse); - std::vector get (std::string name); - void get (std::string name, std::string image, - int & book1, int & chapter1, int & verse1, - int & book2, int & chapter2, int & verse2); - std::string get (std::string name, std::string image); -private: - std::string mainFolder (); - std::string resourceFolder (const std::string& name); - std::string imagePath (std::string name, std::string image); - std::string databaseFile (); - sqlite3 * connect (std::string name); -}; diff --git a/database/ipc.cpp b/database/ipc.cpp deleted file mode 100644 index 4b8bdeeb1..000000000 --- a/database/ipc.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: Stored in plain file system. - - -Database_Ipc::Database_Ipc (Webserver_Request& webserver_request): -m_webserver_request (webserver_request) -{ -} - - -void Database_Ipc::trim () -{ - vector data = readData (); - for (auto & record : data) { - if (record.user == "") { - deleteMessage (record.rowid); - } - } - int now = filter::date::seconds_since_epoch (); - vector files = filter_url_scandir (folder ()); - for (string item : files) { - string path = file(item); - int time = filter_url_file_modification_time (path); - int age_seconds = now - time; - if (age_seconds > 3600) { - filter_url_unlink (path); - } - } -} - - -void Database_Ipc::storeMessage (string user, string channel, string command, string message) -{ - // Load entire database into memory. - vector data = readData (); - - // Gather information about records to delete. - vector deletes; - if (channel == "") { - for (auto & record : data) { - if ((record.user == user) && (record.channel == channel) && (record.command == command)) { - deletes.push_back (record.rowid); - } - } - } - - // Write new information. - int rowid = getNextId (data); - writeRecord (rowid, user, channel, command, message); - - // Actually delete the records. - // Do this after writing new data, to be sure there is always some data on disk. - for (auto& erase : deletes) { - deleteMessage (erase); - } -} - - -// Retrieves a message if there is any. -// Returns an object with the data. -// The rowid is 0 if there was nothing, -// Else the object's properties are set properly. -Database_Ipc_Message Database_Ipc::retrieveMessage (int id, string user, string channel, string command) -{ - int highestId = 0; - string hitChannel = ""; - string hitCommand = ""; - string hitMessage = ""; - vector data = readData (); - for (auto & record : data) { - // Selection condition 1: The database record has a message identifier younger than the calling identifier. - int recordid = record.rowid; - if (recordid > id) { - // Selection condition 2: Channel matches calling channel, or empty channel. - string recordchannel = record.channel; - if ((recordchannel == channel) || (recordchannel == "")) { - // Selection condition 3: Record user matches calling user, or empty user. - string recorduser = record.user; - if ((recorduser == user) || (recorduser == "")) { - // Selection condition 4: Matching command. - string recordcommand = record.command; - if (recordcommand == command) { - if (recordid > highestId) { - highestId = recordid; - hitChannel = recordchannel; - hitCommand = recordcommand; - hitMessage = filter_url_file_get_contents (file (record.file)); - } - } - } - } - } - } - Database_Ipc_Message message = Database_Ipc_Message (); - if (highestId) { - message.id = highestId; - message.channel = hitChannel; - message.command = hitCommand; - message.message = hitMessage; - } - return message; -} - - -void Database_Ipc::deleteMessage (int id) -{ - vector data = readData (); - for (auto & record : data) { - if (record.rowid == id) { - filter_url_unlink (file (record.file)); - } - } -} - - -string Database_Ipc::getFocus () -{ - string user = m_webserver_request.session_logic ()->currentUser (); - - int highestId = 0; - string hitMessage = ""; - vector data = readData (); - for (auto & record : data) { - int recordid = record.rowid; - // Conditions: Command is "focus", and matching user. - if (record.command == "focus") { - if (record.user == user) { - if (recordid > highestId) { - highestId = recordid; - hitMessage = filter_url_file_get_contents (file (record.file)); - } - } - } - } - - if (highestId) return hitMessage; - - // No focus found: Return Genesis 1:1. - return "1.1.1"; -} - - -Database_Ipc_Message Database_Ipc::getNote () -{ - string user = m_webserver_request.session_logic ()->currentUser (); - - int highestId = 0; - string hitMessage = ""; - - vector data = readData (); - for (auto & record : data) { - int recordid = record.rowid; - // Conditions: Command is "opennote", and matching user. - if (record.command == "opennote") { - if (record.user == user) { - if (recordid > highestId) { - highestId = recordid; - hitMessage = filter_url_file_get_contents (file (record.file)); - } - } - } - } - - Database_Ipc_Message note = Database_Ipc_Message (); - if (highestId) { - note.id = highestId; - note.message = hitMessage; - } - - return note; -} - - -bool Database_Ipc::getNotesAlive () -{ - string user = m_webserver_request.session_logic ()->currentUser (); - - int highestId = 0; - string hitMessage = ""; - - vector data = readData (); - for (auto & record : data) { - int recordid = record.rowid; - // Conditions: Command is "notesalive", and matching user. - if (record.command == "notesalive") { - if (record.user == user) { - if (recordid > highestId) { - highestId = recordid; - hitMessage = filter_url_file_get_contents (file (record.file)); - } - } - } - } - - if (highestId) return filter::strings::convert_to_bool (hitMessage); - - return false; -} - - -string Database_Ipc::folder () -{ - return filter_url_create_root_path ({database_logic_databases (), "ipc"}); -} - - -string Database_Ipc::file (string file) -{ - return filter_url_create_path ({folder (), file}); -} - - -// Reads most fields of all data in this database. -// Returns an array containing the above. -// The fields are those that can be obtained from the name of the files. -// One file is one entry in the database. -// The filename looks like this: rowid__user__channel__command -vector Database_Ipc::readData () -{ - vector data; - vector files = filter_url_scandir (folder ()); - for (string file : files) { - vector explosion = filter::strings::explode (file, '_'); - if (explosion.size () == 7) { - Database_Ipc_Item item = Database_Ipc_Item (); - item.file = file; - item.rowid = filter::strings::convert_to_int (explosion [0]); - item.user = explosion [2]; - item.channel = explosion [4]; - item.command = explosion [6]; - data.push_back (item); - } - } - return data; -} - - -void Database_Ipc::writeRecord (int rowid, string user, string channel, string command, string message) -{ - string filename = filter::strings::convert_to_string (rowid) + "__" + user + "__" + channel + "__" + command; - filename = file (filename); - filter_url_file_put_contents (filename, message); -} - - -// Returns the next available row identifier. -int Database_Ipc::getNextId (const vector & data) -{ - int id = 0; - for (auto & record : data) { - if (record.rowid > id) id = record.rowid; - } - id++; - return id; -} - - diff --git a/database/ipc.h b/database/ipc.h deleted file mode 100644 index ec6641155..000000000 --- a/database/ipc.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - - -#include - - -class Webserver_Request; - - -struct Database_Ipc_Item -{ - std::string file {}; - int rowid {0}; - std::string user {}; - std::string channel {}; - std::string command {}; -}; - - -struct Database_Ipc_Message -{ - int id {0}; - std::string channel {}; - std::string command {}; - std::string message {}; -}; - - -class Database_Ipc -{ -public: - Database_Ipc (Webserver_Request& webserver_request); - void trim (); - void storeMessage (std::string user, std::string channel, std::string command, std::string message); - Database_Ipc_Message retrieveMessage (int id, std::string user, std::string channel, std::string command); - void deleteMessage (int id); - std::string getFocus (); - Database_Ipc_Message getNote (); - bool getNotesAlive (); -private: - Webserver_Request& m_webserver_request; - std::string folder (); - std::string file (std::string file); - std::vector readData (); - void writeRecord (int rowid, std::string user, std::string channel, std::string command, std::string message); - int getNextId (const std::vector & data); -}; - - diff --git a/database/jobs.cpp b/database/jobs.cpp deleted file mode 100644 index 6b4ba004c..000000000 --- a/database/jobs.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: -// The database does not contain important information. -// Re-create it on corruption. - - -sqlite3 * Database_Jobs::connect () -{ - return database_sqlite_connect ("jobs"); -} - - -void Database_Jobs::create () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "DROP TABLE IF EXISTS jobs"); - string sql = "CREATE TABLE IF NOT EXISTS jobs (" - " id integer," - " timestamp integer," - " level integer," - " start text," - " percentage integer," - " progress text," - " result text" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -void Database_Jobs::optimize () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_disconnect (db); -} - - -void Database_Jobs::trim () -{ - // Delete jobs older than 30 days. - int timestamp = filter::date::seconds_since_epoch () - (30 * 24 * 3600); - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM jobs WHERE timestamp <"); - sql.add (timestamp); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -bool Database_Jobs::id_exists (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT id FROM jobs WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["id"]; - database_sqlite_disconnect (db); - return !result.empty (); -} - - -// Gets a new unique identifier. -int Database_Jobs::get_new_id () -{ - // Iterate till a non-existing identifier is found. - int id; - do { - id = filter::strings::rand (100'000'000, 999'999'999); - } while (id_exists (id)); - // Store the new id so it can't be given out again just now. - // Also store the timestamp. used for entry expiry. - int timestamp = filter::date::seconds_since_epoch (); - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO jobs (id, timestamp) VALUES ("); - sql.add (id); - sql.add (","); - sql.add (timestamp); - sql.add (");"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - return id; -} - - -void Database_Jobs::set_level (int id, int level) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("UPDATE jobs SET level ="); - sql.add (level); - sql.add ("WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -int Database_Jobs::get_level (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT level FROM jobs WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector levels = database_sqlite_query (db, sql.sql) ["level"]; - database_sqlite_disconnect (db); - if (!levels.empty()) { - return filter::strings::convert_to_int (levels[0]); - } - return 0; -} - - -void Database_Jobs::set_start (int id, string start) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("UPDATE jobs SET start ="); - sql.add (start); - sql.add ("WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -string Database_Jobs::get_start (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT start FROM jobs WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["start"]; - database_sqlite_disconnect (db); - if (!result.empty()) { - auto start = result[0]; - return start; - } - return ""; -} - - -void Database_Jobs::set_percentage (int id, int percentage) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("UPDATE jobs SET percentage ="); - sql.add (percentage); - sql.add ("WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -string Database_Jobs::get_percentage (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT percentage FROM jobs WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector percentages = database_sqlite_query (db, sql.sql) ["percentage"]; - database_sqlite_disconnect (db); - if (!percentages.empty()) { - return percentages[0]; - } - return ""; -} - - -void Database_Jobs::set_progress (int id, string progress) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("UPDATE jobs SET progress ="); - sql.add (progress); - sql.add ("WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -string Database_Jobs::get_progress (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT progress FROM jobs WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector progress = database_sqlite_query (db, sql.sql) ["progress"]; - database_sqlite_disconnect (db); - if (!progress.empty()) { - return progress[0]; - } - return ""; -} - - -void Database_Jobs::set_result (int id, string result) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("UPDATE jobs SET result ="); - sql.add (result); - sql.add ("WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -string Database_Jobs::get_result (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT result FROM jobs WHERE id ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["result"]; - database_sqlite_disconnect (db); - if (!result.empty()) { - return result[0]; - } - return string(); -} - - diff --git a/database/jobs.h b/database/jobs.h deleted file mode 100644 index dfba8fad6..000000000 --- a/database/jobs.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Jobs -{ -public: - void create (); - void optimize (); - void trim (); - bool id_exists (int id); - int get_new_id (); - void set_level (int id, int level); - int get_level (int id); - void set_start (int id, std::string start); - std::string get_start (int id); - void set_percentage (int id, int percentage); - std::string get_percentage (int id); - void set_progress (int id, std::string progress); - std::string get_progress (int id); - void set_result (int id, std::string result); - std::string get_result (int id); -private: - sqlite3 * connect (); -}; diff --git a/database/kjv.cpp b/database/kjv.cpp deleted file mode 100644 index c1965a85d..000000000 --- a/database/kjv.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// This is the database for the Strong's numbers and English glosses. -// Resilience: It is not written to. -// Chances of corruption are nearly zero. - - -void Database_Kjv::create () -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("DROP TABLE IF EXISTS kjv2;"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE kjv2 (book int, chapter int, verse int, strong int, english int);"); - sql.execute (); - - sql.clear (); - sql.add ("DROP TABLE IF EXISTS strong;"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS strong (strong text);"); - sql.execute (); - - sql.clear (); - sql.add ("DROP TABLE IF EXISTS english;"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS english (english text);"); - sql.execute (); - - sql.clear (); - sql.add ("VACUUM;"); - sql.execute (); -} - - -void Database_Kjv::optimize () -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("VACUUM;"); - sql.execute (); -} - - -const char * Database_Kjv::filename () -{ - return "kjv"; -} - - -// Get Strong's numbers and English snippets for book / chapter / verse. -vector Database_Kjv::getVerse (int book, int chapter, int verse) -{ - vector hits; - vector rows = rowids (book, chapter, verse); - for (auto row : rows) { - Database_Kjv_Item item; - item.strong = strong (row); - item.english = english (row); - hits.push_back (item); - } - return hits; -} - - -// Get all passages that contain a strong's number. -vector Database_Kjv::searchStrong (string strong) -{ - int strongid = get_id ("strong", strong); - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT DISTINCT book, chapter, verse FROM kjv2 WHERE strong ="); - sql.add (strongid); - sql.add ("ORDER BY rowid;"); - vector hits; - map > result = sql.query (); - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - for (unsigned int i = 0; i < books.size (); i++) { - Passage passage; - passage.m_book = filter::strings::convert_to_int (books [i]); - passage.m_chapter = filter::strings::convert_to_int (chapters [i]); - passage.m_verse = verses [i]; - hits.push_back (passage); - } - return hits; -} - - -void Database_Kjv::store (int book, int chapter, int verse, string strong, string english) -{ - int strongid = get_id ("strong", strong); - int englishid = get_id ("english", english); - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("PRAGMA temp_store = MEMORY;"); - sql.execute (); - sql.clear (); - sql.add ("PRAGMA synchronous = OFF;"); - sql.execute (); - sql.clear (); - sql.add ("PRAGMA journal_mode = OFF;"); - sql.execute (); - sql.clear (); - sql.add ("INSERT INTO kjv2 VALUES ("); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (strongid); - sql.add (","); - sql.add (englishid); - sql.add (");"); - sql.execute (); -} - - -vector Database_Kjv::rowids (int book, int chapter, int verse) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT rowid FROM kjv2 WHERE book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("AND verse ="); - sql.add (verse); - sql.add ("ORDER BY rowid;"); - vector result = sql.query () ["rowid"]; - vector rowids; - for (auto rowid : result) rowids.push_back (filter::strings::convert_to_int (rowid)); - return rowids; -} - - -string Database_Kjv::strong (int rowid) -{ - return get_item ("strong", rowid); -} - - -string Database_Kjv::english (int rowid) -{ - return get_item ("english", rowid); -} - - -int Database_Kjv::get_id (const char * table_row, string item) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - // Two iterations to be sure a rowid can be returned. - for (unsigned int i = 0; i < 2; i++) { - // Check on the rowid and return it if it's there. - sql.clear (); - sql.add ("SELECT rowid FROM"); - sql.add (table_row); - sql.add ("WHERE"); - sql.add (table_row); - sql.add ("="); - sql.add (item); - sql.add (";"); - vector result = sql.query () ["rowid"]; - if (!result.empty ()) return filter::strings::convert_to_int (result [0]); - // The rowid was not found: Insert the word into the table. - // The rowid will now be found during the second iteration. - sql.clear (); - sql.add ("INSERT INTO"); - sql.add (table_row); - sql.add ("VALUES ("); - sql.add (item); - sql.add (");"); - sql.execute (); - } - return 0; -} - - -string Database_Kjv::get_item (const char * item, int rowid) -{ - // The $rowid refers to the main table. - // Update it so it refers to the sub table. - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT"); - sql.add (item); - sql.add ("FROM kjv2 WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - vector result = sql.query () [item]; - rowid = 0; - if (!result.empty ()) rowid = filter::strings::convert_to_int (result [0]); - // Retrieve the requested value from the sub table. - sql.clear (); - sql.add ("SELECT"); - sql.add (item); - sql.add ("FROM"); - sql.add (item); - sql.add ("WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - result = sql.query () [item]; - if (!result.empty ()) return result [0]; - // Not found. - return ""; -} diff --git a/database/kjv.h b/database/kjv.h deleted file mode 100644 index 7b9dd29e8..000000000 --- a/database/kjv.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - - -#include -#include - - -struct Database_Kjv_Item -{ - std::string strong {}; - std::string english {}; -}; - - -class Database_Kjv -{ -public: - void create (); - void optimize (); - std::vector getVerse (int book, int chapter, int verse); - std::vector searchStrong (std::string strong); - void store (int book, int chapter, int verse, std::string strong, std::string english); - std::vector rowids (int book, int chapter, int verse); - std::string strong (int rowid); - std::string english (int rowid); -private: - const char * filename (); - int get_id (const char * table_row, std::string item); - std::string get_item (const char * item, int rowid); -}; - - diff --git a/database/localization.cpp b/database/localization.cpp deleted file mode 100644 index 5a47d3691..000000000 --- a/database/localization.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience. -// It is written to once upon Bibledit setup. -// After that it is only read. -// In case of corruption, upgrade Bibledit and it will recreate the database. - - -Database_Localization::Database_Localization (const string& language_in) -{ - language = language_in; -} - - -sqlite3 * Database_Localization::connect () -{ - return database_sqlite_connect ("localization_" + language); -} - - -void Database_Localization::create (string po) -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "PRAGMA temp_store = MEMORY;"); - database_sqlite_exec (db, "PRAGMA synchronous = OFF;"); - database_sqlite_exec (db, "PRAGMA journal_mode = OFF;"); - database_sqlite_exec (db, "DROP TABLE IF EXISTS localization;"); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_exec (db, "CREATE TABLE IF NOT EXISTS localization (msgid text, msgstr text);"); - unordered_map translations = locale_logic_read_msgid_msgstr (po); - for (auto & element : translations) { - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO localization VALUES ("); - sql.add (element.first); - sql.add (","); - sql.add (element.second); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - } - database_sqlite_disconnect (db); -} - - -string Database_Localization::translate (const string& english) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT msgstr FROM localization WHERE msgid ="); - sql.add (english); - sql.add (";"); - sqlite3 * db = connect (); - vector msgstrs = database_sqlite_query (db, sql.sql) ["msgstr"]; - database_sqlite_disconnect (db); - if (!msgstrs.empty ()) if (!msgstrs[0].empty ()) return msgstrs [0]; - return english; -} - - -string Database_Localization::backtranslate (const string& localization) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT msgid FROM localization WHERE msgstr ="); - sql.add (localization); - sql.add (";"); - sqlite3 * db = connect (); - vector msgids = database_sqlite_query (db, sql.sql) ["msgid"]; - database_sqlite_disconnect (db); - if (!msgids.empty ()) if (!msgids[0].empty ()) return msgids [0]; - return localization; -} diff --git a/database/localization.h b/database/localization.h deleted file mode 100644 index c664adac7..000000000 --- a/database/localization.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Localization -{ -public: - Database_Localization (const std::string& language_in); - void create (std::string po); - std::string translate (const std::string& english); - std::string backtranslate (const std::string& localization); -private: - std::string language {}; - sqlite3 * connect (); -}; - diff --git a/database/logic.cpp b/database/logic.cpp deleted file mode 100644 index ac103b2e9..000000000 --- a/database/logic.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include - - -const char * database_logic_databases () -{ - return "databases"; -} diff --git a/database/logic.h b/database/logic.h deleted file mode 100644 index a4bf5d04b..000000000 --- a/database/logic.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -const char * database_logic_databases (); diff --git a/database/login.cpp b/database/login.cpp deleted file mode 100644 index d28673841..000000000 --- a/database/login.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// This database is resilient. -// The data is stored in a SQLite database. -// This part is read often, and infrequently written to. -// Due to the infrequent write operations, there is a low and acceptable change of corruption. - - -// The name of the database. -const char * Database_Login::database () -{ - return "login"; -} - - -void Database_Login::create () -{ - SqliteDatabase sql (database ()); - sql.add ("CREATE TABLE IF NOT EXISTS logins (" - " username text," - " address text," - " agent text," - " fingerprint text," - " cookie text," - " touch boolean," - " timestamp integer" - ");"); - sql.execute (); -} - - -void Database_Login::trim () -{ - // Remove persistent logins after 365 days of inactivity. - SqliteDatabase sql (database ()); - sql.add ("DELETE FROM logins WHERE timestamp < "); - sql.add (timestamp () - 365); - sql.add (";"); - sql.execute (); -} - - -void Database_Login::optimize () -{ - if (!healthy ()) { - // (Re)create damaged or non-existing database. - filter_url_unlink (database_sqlite_file (database ())); - create (); - } - // Vacuum it. - SqliteDatabase sql (database ()); - // On Android, this pragma prevents the following error: VACUUM; Unable to open database file. - sql.add ("PRAGMA temp_store = MEMORY;"); - sql.execute (); - sql.clear (); - sql.add ("VACUUM;"); - sql.execute (); -} - - -bool Database_Login::healthy () -{ - return database_sqlite_healthy (database ()); -} - - -// Sets the login security tokens for a user. -// Also store whether the device is touch-enabled. -// It only writes to the table if the combination of username and tokens differs from what the table already contains. -void Database_Login::setTokens (string username, string address, string agent, string fingerprint, string cookie, bool touch) -{ - bool daily; - if (username == getUsername (cookie, daily)) return; - address = md5 (address); - agent = md5 (agent); - fingerprint = md5 (fingerprint); - SqliteDatabase sql (database ()); - sql.add ("INSERT INTO logins VALUES ("); - sql.add (username); - sql.add (","); - sql.add (address); - sql.add (","); - sql.add (agent); - sql.add (","); - sql.add (fingerprint); - sql.add (","); - sql.add (cookie); - sql.add (","); - sql.add (touch); - sql.add (","); - sql.add (timestamp ()); - sql.add (");"); - sql.execute (); -} - - -// Remove the login security tokens for a user. -void Database_Login::removeTokens (string username) -{ - SqliteDatabase sql (database ()); - sql.add ("DELETE FROM logins WHERE username ="); - sql.add (username); - sql.add (";"); - sql.execute (); -} - - -// Remove the login security tokens for a user based on the cookie. -void Database_Login::removeTokens (string username, string cookie) -{ - //address = md5 (address); - //agent = md5 (agent); - //fingerprint = md5 (fingerprint); - SqliteDatabase sql (database ()); - sql.add ("DELETE FROM logins WHERE username ="); - sql.add (username); - sql.add ("AND cookie ="); - sql.add (cookie); - sql.add (";"); - sql.execute (); -} - - -void Database_Login::renameTokens (string username_existing, string username_new, string cookie) -{ - SqliteDatabase sql (database ()); - sql.add ("UPDATE logins SET username ="); - sql.add (username_new); - sql.add ("WHERE username ="); - sql.add (username_existing); - sql.add ("AND cookie ="); - sql.add (cookie); - sql.add (";"); - sql.execute (); -} - - -// Returns the username that matches the cookie sent by the browser. -// Once a day, $daily will be set true. -string Database_Login::getUsername (string cookie, bool & daily) -{ - SqliteDatabase sql (database ()); - sql.add ("SELECT rowid, timestamp, username FROM logins WHERE cookie ="); - sql.add (cookie); - sql.add (";"); - map > result = sql.query (); - if (result.empty()) return ""; - string username = result ["username"][0]; - int stamp = filter::strings::convert_to_int (result ["timestamp"] [0]); - if (stamp != timestamp ()) { - // Touch the timestamp. This occurs once a day. - int rowid = filter::strings::convert_to_int (result ["rowid"] [0]); - sql.clear (); - sql.add ("UPDATE logins SET timestamp ="); - sql.add (timestamp ()); - sql.add ("WHERE rowid ="); - sql.add (rowid); - sql.execute (); - daily = true; - } else { - daily = false; - } - return username; -} - - -// Returns whether the device, that matches the cookie it sent, is touch-enabled. -bool Database_Login::getTouchEnabled (string cookie) -{ - SqliteDatabase sql (database ()); - sql.add ("SELECT touch FROM logins WHERE cookie ="); - sql.add (cookie); - sql.add (";"); - vector result = sql.query () ["touch"]; - if (!result.empty()) return filter::strings::convert_to_bool (result [0]); - return false; -} - - -void Database_Login::testTimestamp () -{ - SqliteDatabase sql (database ()); - sql.add ("UPDATE logins SET timestamp = timestamp - 370;"); - sql.execute (); -} - - -// Gets the current number of days since the Unix epoch. -int Database_Login::timestamp () -{ - return filter::date::seconds_since_epoch () / 86400; -} diff --git a/database/login.h b/database/login.h deleted file mode 100644 index 872bbbba1..000000000 --- a/database/login.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Login -{ -public: - static const char * database (); - static void create (); - static void trim (); - static void optimize (); - static bool healthy (); - static void setTokens (std::string username, std::string address, std::string agent, std::string fingerprint, std::string cookie, bool touch); - static void removeTokens (std::string username); - static void removeTokens (std::string username, std::string cookie); - static void renameTokens (std::string username_existing, std::string username_new, std::string cookie); - static std::string getUsername (std::string cookie, bool & daily); - static bool getTouchEnabled (std::string cookie); - static void testTimestamp (); -private: - static int timestamp (); -}; diff --git a/database/logs.cpp b/database/logs.cpp deleted file mode 100644 index 7cc833334..000000000 --- a/database/logs.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Bibledit no longer uses a database for storing the journal. -// Reasons that a database is no longer used: -// 1. Simpler system. -// 2. Android has VACUUM errors due to a locked database. - - -// Records a journal entry. -void Database_Logs::log (string description, int level) -{ - // Trim spaces. - description = filter::strings::trim (description); - // Discard empty line. - if (description.empty()) return; - // Truncate very long entry. - size_t length = description.length (); - if (length > 50000) { - description.erase (50000); - description.append ("... This entry was too large and has been truncated: " + filter::strings::convert_to_string (length) + " bytes"); - } - // Save this logbook entry to a filename with seconds and microseconds. - string seconds = filter::strings::convert_to_string (filter::date::seconds_since_epoch ()); - string time = seconds + filter::strings::fill (filter::strings::convert_to_string (filter::date::numerical_microseconds ()), 8, '0'); - string file = filter_url_create_path ({folder (), time}); - // The microseconds granularity depends on the platform. - // On Windows it is lower than on Linux. - // There may be the rare case of more than one entry per file. - // Append the data so it won't overwrite an earlier entry. - if (file_or_dir_exists (file)) { - description.insert (0, " | "); - } else { - description.insert (0, filter::strings::convert_to_string (level) + " "); - } - filter_url_file_put_contents_append (file, description); -#ifdef HAVE_WINDOWS - // Delay to cover for lower usec granularity on Windows. - this_thread::sleep_for (chrono::milliseconds (1)); -#endif -} - - -// Records an extended journal entry. -void Database_Logs::log (string subject, string body, int level) -{ - string description (subject); - description.append ("\n"); - description.append (body); - log (description, level); -} - - -void Database_Logs::rotate () -{ - // Under PHP it used a mechanism that handled huge amounts of entries. - // The PHP function scandir choked on this or took a very long time. - // The PHP functions opendir / readdir / closedir handled it better. - // But now, in C++, with the new journal mechanism, this is no longer relevant. - string directory = folder (); - vector files = filter_url_scandir (directory); - - - // Timestamp for removing older records, depending on whether it's a tiny journal. -#ifdef HAVE_TINY_JOURNAL - int oldtimestamp = filter::date::seconds_since_epoch () - (14400); -#else - int oldtimestamp = filter::date::seconds_since_epoch () - (6 * 86400); -#endif - - - // Limit the journal entry count in the filesystem. - // This speeds up subsequent reading of the journal by the users. - // In previous versions of Bibledit, there were certain conditions - // that led to an infinite loop, as had been noticed at times, - // and this quickly exhausted the available inodes on the filesystem. -#ifdef HAVE_TINY_JOURNAL - const int limitfilecount = static_cast(files.size () - 200); -#else - const int limitfilecount = static_cast(files.size () - 2000); -#endif - - - bool filtered_entries = false; - for (unsigned int i = 0; i < files.size(); i++) { - string path = filter_url_create_path ({directory, files [i]}); - - // Limit the number of journal entries. - if (static_cast (i) < limitfilecount) { - filter_url_unlink (path); - continue; - } - - // Remove expired entries. - int timestamp = filter::strings::convert_to_int (files [i].substr (0, 10)); - if (timestamp < oldtimestamp) { - filter_url_unlink (path); - continue; - } - - // Filtering of certain entries. - string entry = filter_url_file_get_contents (path); - if (journal_logic_filter_entry (entry)) { - filtered_entries = true; - filter_url_unlink (path); - continue; - } - - } - - if (filtered_entries) { - log (journal_logic_filtered_message ()); - } -} - - -// Get the logbook entries. -vector Database_Logs::get (string & lastfilename) -{ - lastfilename = "0"; - - // Read the journal records from the filesystem. - vector files = filter_url_scandir (folder ()); - for (unsigned int i = 0; i < files.size(); i++) { - // Last second gets updated based on the filename. - lastfilename = files [i]; - } - - // Done. - return files; -} - - -// Gets journal entry more recent than "filename". -// Updates "filename" to the item it got. -string Database_Logs::next (string &filename) -{ - vector files = filter_url_scandir (folder ()); - for (unsigned int i = 0; i < files.size (); i++) { - string file = files [i]; - if (file > filename) { - filename = file; - return file; - } - } - return ""; -} - - -// Clears all journal entries. -void Database_Logs::clear () -{ - string directory = folder (); - vector files = filter_url_scandir (directory); - for (auto file : files) { - filter_url_unlink (filter_url_create_path ({directory, file})); - } - log ("The journal was cleared"); -} - - -// The folder where to store the records. -string Database_Logs::folder () -{ - return filter_url_create_root_path ({"logbook"}); -} diff --git a/database/logs.h b/database/logs.h deleted file mode 100644 index 65b1d67f7..000000000 --- a/database/logs.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Logs -{ -public: - static void log (std::string description, int level = 5); - static void log (std::string subject, std::string body, int level = 5); - static void rotate (); - static std::vector get (std::string & lastfilename); - static std::string next (std::string &filename); - static void clear (); - static std::string folder (); -}; diff --git a/database/mail.cpp b/database/mail.cpp deleted file mode 100644 index 4cd8cb927..000000000 --- a/database/mail.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Handles mail sent from Bibledit to the users. -// Database resilience: It stores the emails to be sent shortly after. -// The database is not very often written to. -// The risk of corruption is low and acceptable. - - -Database_Mail::Database_Mail (Webserver_Request& webserver_request): -m_webserver_request (webserver_request) -{ -} - - -Database_Mail::~Database_Mail () -{ -} - - -sqlite3 * Database_Mail::connect () -{ - return database_sqlite_connect ("mail"); -} - - -void Database_Mail::create () -{ - sqlite3 * db = connect (); - string sql = - "CREATE TABLE IF NOT EXISTS mail (" - " username text," - " timestamp integer," - " subject text," - " body text," - " retry integer" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -void Database_Mail::optimize () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_disconnect (db); -} - - -void Database_Mail::trim () -{ - int time = filter::date::seconds_since_epoch () - 2592000; // Remove entries after 30 days. - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM mail WHERE timestamp <"); - sql.add (time); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_exec (db, "DELETE FROM mail WHERE retry > 10;"); - database_sqlite_disconnect (db); -} - - -// Send email. -// to: The email address. -// subject: The subject. -// body: The body. -// time: Normally not given, but if given, it indicates the time stamp for sending this email. -void Database_Mail::send (string to, string subject, string body, int time) -{ - if (time == 0) time = filter::date::seconds_since_epoch (); - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO mail VALUES ("); - sql.add (to); - sql.add (","); - sql.add (time); - sql.add (","); - sql.add (subject); - sql.add (","); - sql.add (body); - sql.add (", 0);"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Get number of mails for the current user. -int Database_Mail::getMailCount () -{ - string user = m_webserver_request.session_logic ()->currentUser(); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT count(*) FROM mail WHERE username ="); - sql.add (user); - sql.add (";"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["count(*)"]; - database_sqlite_disconnect (db); - if (!result.empty ()) { - return filter::strings::convert_to_int (result [0]); - } - return 0; -} - - -// Get the mails of the current user. -vector Database_Mail::getMails () -{ - vector mails; - string user = m_webserver_request.session_logic ()->currentUser(); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid, timestamp, subject FROM mail WHERE username ="); - sql.add (user); - sql.add ("ORDER BY timestamp DESC;"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector rowids = result ["rowid"]; - vector timestamps = result ["timestamp"]; - vector subjects = result ["subject"]; - for (unsigned int i = 0; i < rowids.size(); i++) { - Database_Mail_User mail = Database_Mail_User (); - mail.rowid = filter::strings::convert_to_int (rowids [i]); - mail.timestamp = filter::strings::convert_to_int (timestamps [i]); - mail.subject = subjects [i]; - mails.push_back (mail); - } - return mails; -} - - -// Delete a mail. -void Database_Mail::erase (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM mail WHERE rowid ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Get a mail. -Database_Mail_Item Database_Mail::get (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT username, subject, body FROM mail WHERE rowid ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - Database_Mail_Item item = Database_Mail_Item (); - if (!result.empty ()) { - item.username = result ["username"] [0]; - item.subject = result ["subject"] [0]; - item.body = result ["body"] [0]; - } - return item; -} - - -// Get ids of all mails ready for sending. -vector Database_Mail::getMailsToSend () -{ - vector ids; - int timestamp = filter::date::seconds_since_epoch (); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid FROM mail WHERE timestamp <="); - sql.add (timestamp); - sql.add (";"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["rowid"]; - database_sqlite_disconnect (db); - for (auto & id : result) { - ids.push_back (filter::strings::convert_to_int (id)); - } - return ids; -} - - -// Postpones a mail till later. -// Used for retrying after failure to send the mail. -void Database_Mail::postpone (int id) -{ - SqliteSQL sql1 = SqliteSQL (); - sql1.add ("UPDATE mail SET retry = retry + 1 WHERE rowid ="); - sql1.add (id); - sql1.add (";"); - SqliteSQL sql2 = SqliteSQL (); - sql2.add ("UPDATE mail SET timestamp = timestamp + retry * 900 WHERE rowid ="); - sql2.add (id); - sql2.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql1.sql); - database_sqlite_exec (db, sql2.sql); - database_sqlite_disconnect (db); - -} - - -// Get the row IDs of all mails in the database. -vector Database_Mail::getAllMails () -{ - vector rowids; - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid FROM mail;"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["rowid"]; - database_sqlite_disconnect (db); - for (auto rowid : result) { - int id = filter::strings::convert_to_int (rowid); - rowids.push_back (id); - } - return rowids; -} diff --git a/database/mail.h b/database/mail.h deleted file mode 100644 index e2ec4ad63..000000000 --- a/database/mail.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -struct Database_Mail_User -{ - int rowid {0}; - int timestamp {0}; - std::string subject {}; -}; - -struct Database_Mail_Item -{ - std::string username {}; - std::string subject {}; - std::string body {}; -}; - -class Database_Mail -{ -public: - Database_Mail (Webserver_Request& webserver_request); - ~Database_Mail (); - Database_Mail(const Database_Mail&) = delete; - Database_Mail operator=(const Database_Mail&) = delete; - void create (); - void optimize (); - void trim (); - void send (std::string to, std::string subject, std::string body, int time = 0); - int getMailCount (); - std::vector getMails (); - void erase (int id); - Database_Mail_Item get (int id); - std::vector getMailsToSend (); - void postpone (int id); - std::vector getAllMails (); -private: - sqlite3 * connect (); - Webserver_Request& m_webserver_request; -}; diff --git a/database/maintenance.cpp b/database/maintenance.cpp deleted file mode 100644 index 63a19064a..000000000 --- a/database/maintenance.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -void database_maintenance () -{ - Database_Logs::log ("Maintaining databases", Filter_Roles::manager ()); - - - // Whether running in client mode. - bool client_mode = client_logic_client_enabled (); - - - Webserver_Request webserver_request; - - - // While VACUUM or REINDEX on a SQLite database are running, - // querying the database then introduces errors like "database schema has changed". - // Therefore this type of maintenance should not be done automatically. - - - Database_Users database_users; - database_users.trim (); - database_users.optimize (); - - - Database_Mail database_mail (webserver_request); - database_mail.trim (); - database_mail.optimize (); - - -#ifdef HAVE_CLOUD - Database_Confirm database_confirm; - database_confirm.trim (); - database_confirm.optimize (); -#endif - - - // No need to optimize the following because it is hardly ever written to. - // Database_Books database_book = Database_Books (); - // Database_Styles database_styles; - - - Database_Bibles database_bibles; - database_bibles.optimize (); - - - Database_Ipc database_ipc (webserver_request); - database_ipc.trim (); - - - Database_Notes database_notes (webserver_request); - database_notes.trim (); - if (!client_mode) database_notes.trim_server (); - database_notes.optimize (); - - - Database_Check database_check = Database_Check (); - database_check.optimize (); - - -#ifdef HAVE_CLOUD - Database_Sprint database_sprint = Database_Sprint (); - database_sprint.optimize (); -#endif - - - Database_Navigation database_navigation = Database_Navigation (); - database_navigation.create (); - database_navigation.trim(); - - - Database_Jobs database_jobs = Database_Jobs (); - database_jobs.trim (); - database_jobs.optimize (); - - - Database_Config_User database_config_user (webserver_request); - database_config_user.trim (); - - - Database_Login::trim (); - Database_Login::optimize (); - - - DatabasePrivileges::optimize (); - - -#ifdef HAVE_CLOUD - Database_Git::optimize (); -#endif - - -#ifdef HAVE_CLOUD - Database_Statistics::optimize (); -#endif - - - // Only maintain it when it does not yet exist, to avoid unnecessary downloads by the clients. - notes_logic_maintain_note_assignees (false); - - - access_logic::create_client_files (); - - -#ifdef HAVE_CLOUD - sword_logic_trim_modules (); -#endif -} diff --git a/database/maintenance.h b/database/maintenance.h deleted file mode 100644 index 831bf6be7..000000000 --- a/database/maintenance.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -void database_maintenance (); diff --git a/database/mappings.cpp b/database/mappings.cpp deleted file mode 100644 index 0c850fc26..000000000 --- a/database/mappings.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// This is a database for the verse mapping systems. -// Resilience: It is normally not written to, so corruption is unlikely. - - -Database_Mappings::Database_Mappings () -{ -} - - -Database_Mappings::~Database_Mappings () -{ -} - - -sqlite3 * Database_Mappings::connect () -{ - return database_sqlite_connect ("mappings"); -} - - -void Database_Mappings::create1 () -{ - sqlite3 * db = connect (); - string sql = - "CREATE TABLE IF NOT EXISTS maps (" - "name text," - "book integer," - "chapter integer," - "verse integer," - "origbook integer," - "origchapter integer," - "origverse integer" - ");"; - database_sqlite_exec (db, sql); - sql = "DROP INDEX IF EXISTS bible;"; - database_sqlite_exec (db, sql); - sql = "DROP INDEX IF EXISTS original;"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -void Database_Mappings::create2 () -{ - string sql; - sqlite3 * db = connect (); - sql = "CREATE INDEX IF NOT EXISTS bible ON maps (name, book, chapter, verse);"; - database_sqlite_exec (db, sql); - sql = "CREATE INDEX IF NOT EXISTS original ON maps (name, book, chapter, verse);"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -// Import the default mappings that come with Bibledit. -void Database_Mappings::defaults () -{ - string folder = filter_url_create_root_path ({"mapping"}); - vector files = filter_url_scandir (folder); - for (auto & file : files) { - string name (file); - string extension = filter_url_get_extension (name); - if (extension != "txt") continue; - name = name.substr (0, strlen (name.c_str()) - 4); - name = filter::strings::replace ("_", " ", name); - string path = filter_url_create_path ({folder, file}); - string data = filter_url_file_get_contents (path); - import (name, data); - } -} - - -void Database_Mappings::optimize () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_disconnect (db); -} - - -void Database_Mappings::import (const string& name, const string& data) -{ - // Delete existing mapping with this name. - erase (name); - - sqlite3 * db = connect (); - - // Begin a transaction for better speed. - database_sqlite_exec (db, "BEGIN;"); - - vector lines = filter::strings::explode (data, '\n'); - for (string line : lines) { - - // Each line looks like this: - // Haggai 2:15 = Haggai 2:14 - // At the left is the passage in this versification. - // At the right is the passage in the original Hebrew and Greek versification. - line = filter::strings::trim (line); - if (line.empty ()) continue; - - // Cut the line into two: The two passages. - vector entry = filter::strings::explode (line, '='); - if (entry.size() != 2) continue; - - string passage_string = filter::strings::trim (entry [0]); - string original_string = filter::strings::trim (entry [1]); - - // Storage for further interpretation. - vector bits; - - // Split the passage entry on the colon (:) to get the verse. - bits = filter::strings::explode(passage_string, ':'); - if (bits.size() != 2) continue; - int passage_verse = filter::strings::convert_to_int(bits[1]); - // Split the first bit on the spaces and get the last item as the chapter. - bits = filter::strings::explode(bits[0], ' '); - if (bits.size() < 2) continue; - int passage_chapter = filter::strings::convert_to_int(bits[bits.size()-1]); - // Remove the last bit so it remains with the book, and get that book. - bits.pop_back(); - string passage_book_string = filter::strings::implode(bits, " "); - int passage_book = static_cast(database::books::get_id_from_english(passage_book_string)); - - // Split the original entry on the colon (:) to get the verse. - bits = filter::strings::explode(original_string, ':'); - if (bits.size() != 2) continue; - int original_verse = filter::strings::convert_to_int(bits[1]); - // Split the first bit on the spaces and get the last item as the chapter. - bits = filter::strings::explode(bits[0], ' '); - if (bits.size() < 2) continue; - int original_chapter = filter::strings::convert_to_int(bits[bits.size()-1]); - // Remove the last bit so it remains with the book, and get that book. - bits.pop_back(); - string original_book_string = filter::strings::implode(bits, " "); - int original_book = static_cast(database::books::get_id_from_english(original_book_string)); - - // Store it in the database. - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO maps VALUES ("); - sql.add (name); - sql.add (","); - sql.add (passage_book); - sql.add (","); - sql.add (passage_chapter); - sql.add (","); - sql.add (passage_verse); - sql.add (","); - sql.add (original_book); - sql.add (","); - sql.add (original_chapter); - sql.add (","); - sql.add (original_verse); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - } - - // Commit the transaction. - database_sqlite_exec (db, "COMMIT;"); - - database_sqlite_disconnect (db); -} - - -// Exports a mapping. -string Database_Mappings::output (const string& name) -{ - vector data; - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT * FROM maps WHERE name ="); - sql.add (name); - sql.add ("ORDER BY book ASC, chapter ASC, verse ASC;"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - vector origbooks = result ["origbook"]; - vector origchapters = result ["origchapter"]; - vector origverses = result ["origverse"]; - - for (unsigned int i = 0; i < books.size (); i++) { - int book = filter::strings::convert_to_int (books [i]); - string bookname = database::books::get_english_from_id (static_cast(book)); - string chapter = chapters [i]; - string verse = verses [i]; - int origbook = filter::strings::convert_to_int (origbooks[i]); - string origbookname = database::books::get_english_from_id (static_cast(origbook)); - string origchapter = origchapters[i]; - string origverse = origverses [i]; - string item = bookname + " " + chapter + ":" + verse + " = " + origbookname + " " + origchapter + ":" + origverse; - data.push_back (item); - } - return filter::strings::implode (data, "\n"); -} - - -void Database_Mappings::create (const string & name) -{ - // Insert one entry, so the $name makes it into the database. - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO maps VALUES ("); - sql.add (name); - sql.add (", 1, 1, 1, 1, 1, 1);"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -void Database_Mappings::erase (const string & name) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM maps WHERE name ="); - sql.add (name); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Returns the mapping names in the database. -vector Database_Mappings::names () -{ - // Get the names from the database. - sqlite3 * db = connect (); - vector names = database_sqlite_query (db, "SELECT DISTINCT name FROM maps;")["name"]; - database_sqlite_disconnect (db); - // Ensure the original mapping is there too. - if (find (names.begin (), names.end (), original ()) == names.end()) { - names.push_back (original ()); - } - - sort (names.begin (), names.end()); - - return names; -} - - -string Database_Mappings::original () -{ - return "Hebrew Greek"; -} - - -// This function translates a $book, $chapter, and $verse -// in the $input versification to a $book, $chapter and $verse -// in the $output versification. -// It returns an array with one passage in most cases. -// When the verses in the $input and $output versifications overlap, -// it may return an array with two passages. -vector Database_Mappings::translate (const string& input, const string& output, int book, int chapter, int verse) -{ - // Care for situation that the input and output are the same. - if (input == output) { - Passage passage = Passage ("", book, chapter, filter::strings::convert_to_string (verse)); - return {passage}; - } - - // Get the $input mapping for the passage from the database. - // This maps the $input to the Hebrew/Greek versification system. - // Skip this phase if the $input mapping is Hebrew / Greek. - vector origpassage; - if (input != original ()) { - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT origbook, origchapter, origverse FROM maps WHERE name ="); - sql.add (input); - sql.add ("AND book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("AND verse ="); - sql.add (verse); - sql.add (";"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector origbooks = result ["origbook"]; - vector origchapters = result ["origchapter"]; - vector origverses = result ["origverse"]; - for (unsigned int i = 0; i < origbooks.size (); i++) { - Passage passage = Passage ("", filter::strings::convert_to_int (origbooks [i]), filter::strings::convert_to_int (origchapters [i]), origverses [i]); - origpassage.push_back (passage); - } - } - - // Check that the search yields a passage. - // If there is none, it means that the $input passage is the same as in Hebrew/Greek. - if (origpassage.empty ()) { - Passage passage = Passage ("", book, chapter, filter::strings::convert_to_string (verse)); - origpassage.push_back (passage); - } - - // If the $output mapping is Hebrew/Greek, then we're done. - if (output == original ()) { - return origpassage; - } - - // Get the $output mapping for the passage or two passages from the database. - // This is a translation from Hebrew/Greek to the $output system. - vector targetpassage; - for (Passage & passage : origpassage) { - int origbook = passage.m_book; - int origchapter = passage.m_chapter; - int origverse = filter::strings::convert_to_int (passage.m_verse); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT book, chapter, verse FROM maps WHERE name ="); - sql.add (output); - sql.add ("AND origbook ="); - sql.add (origbook); - sql.add ("AND origchapter ="); - sql.add (origchapter); - sql.add ("AND origverse ="); - sql.add (origverse); - sql.add (";"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - for (unsigned int i = 0; i < books.size (); i++) { - Passage passage2 = Passage (string(), filter::strings::convert_to_int (books [i]), filter::strings::convert_to_int (chapters [i]), verses [i]); - bool passageExists = false; - for (auto & existingpassage : targetpassage) { - if (existingpassage.equal (passage2)) passageExists = true; - } - if (!passageExists) targetpassage.push_back (passage2); - } - } - - // Check that the search yields a passage. - // If none, it means that the $output passage is the same as in Hebrew/Greek. - if (targetpassage.empty()) { - targetpassage = origpassage; - } - - // Result. - return targetpassage; -} - - -/* - - To not overwrite updated verse mappings, - there could be one database with the defaults, - and another one on the system with the modifications. - The updated mappings will be stored in the second database. - That means that if the name of a mapping occurs in a second database, - that it won't read it from the first database. - This enables the first database to be always updated, - while the system keeps reading from the second database. - - Another way of doing is to keep it as it is, and make the clients download updated mappings from the Cloud. - And then to preserver existing mappings in the Cloud on update. - -*/ diff --git a/database/mappings.h b/database/mappings.h deleted file mode 100644 index 7372dd004..000000000 --- a/database/mappings.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Database_Mappings -{ -public: - Database_Mappings (); - ~Database_Mappings (); - void create1 (); - void create2 (); - void defaults (); - void optimize (); - void import (const std::string& name, const std::string& data); - std::string output (const std::string& name); - void create (const std::string & name); - void erase (const std::string & name); - std::vector names (); - std::string original (); - std::vector translate (const std::string& input, const std::string& output, int book, int chapter, int verse); -private: - sqlite3 * connect (); -}; diff --git a/database/modifications.cpp b/database/modifications.cpp deleted file mode 100644 index eaad7e3d9..000000000 --- a/database/modifications.cpp +++ /dev/null @@ -1,1117 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: -// All information is stored in the filesystem as files or as very small databases. -// The large database is only used as an index. -// It is re-indexed every night. - - -const char * Database_Modifications::filename () -{ - return "modifications"; -} - - -sqlite3 * Database_Modifications::connect () -{ - return database_sqlite_connect (filename ()); -} - - -// Delete the entire database -void Database_Modifications::erase () -{ - string file = database_sqlite_file ("modifications"); - filter_url_unlink (file); -} - - -void Database_Modifications::create () -{ - sqlite3 * db = connect (); - string sql = - "CREATE TABLE IF NOT EXISTS notifications (" - " identifier integer," - " timestamp integer," - " username text," - " category text," - " bible text," - " book integer," - " chapter integer," - " verse integer," - " modification text" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -bool Database_Modifications::healthy () -{ - return database_sqlite_healthy ("modifications"); -} - - -void Database_Modifications::vacuum () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_disconnect (db); -} - - -// Code dealing with the "teams" data. - - -string Database_Modifications::teamFolder () -{ - return filter_url_create_root_path ({database_logic_databases (), "modifications", "team"}); -} - - -string Database_Modifications::teamFile (const string& bible, int book, int chapter) -{ - return filter_url_create_path ({teamFolder (), bible + "." + filter::strings::convert_to_string (book) + "." + filter::strings::convert_to_string (chapter)}); -} - - -// Returns true if diff data exists for the chapter. -// Else it returns false. -bool Database_Modifications::teamDiffExists (const string& bible, int book, int chapter) -{ - string file = teamFile (bible, book, chapter); - return file_or_dir_exists (file); -} - - -// Stores diff data for a "bible" (string) and book (int) and chapter (int). -void Database_Modifications::storeTeamDiff (const string& bible, int book, int chapter) -{ - // Return when the diff exists. - if (teamDiffExists (bible, book, chapter)) return; - - // Retrieve current chapter USFM data. - Database_Bibles database_bibles; - string data = database_bibles.get_chapter (bible, book, chapter); - - // Store. - string file = teamFile (bible, book, chapter); - filter_url_file_put_contents (file, data); -} - - -// Gets the diff data as a string. -string Database_Modifications::getTeamDiff (const string& bible, int book, int chapter) -{ - string file = teamFile (bible, book, chapter); - return filter_url_file_get_contents (file); -} - - -// Stores diff data for all chapters in a "bible" (string) and book (int). -void Database_Modifications::storeTeamDiffBook (const string& bible, int book) -{ - Database_Bibles database_bibles; - vector chapters = database_bibles.get_chapters (bible, book); - for (auto & chapter : chapters) { - storeTeamDiff (bible, book, chapter); - } -} - - -// Stores diff data for all books in a "bible" (string). -void Database_Modifications::storeTeamDiffBible (const string& bible) -{ - Database_Bibles database_bibles; - vector books = database_bibles.get_books (bible); - for (auto & book : books) { - storeTeamDiffBook (bible, book); - } -} - - -// Deletes the diffs for a whole Bible. -void Database_Modifications::deleteTeamDiffBible (const string& bible) -{ - string pattern = bible + "."; - size_t length = pattern.length (); - vector files = filter_url_scandir (teamFolder ()); - for (auto & file : files) { - if (file.substr (0, length) != pattern) continue; - filter_url_unlink (filter_url_create_path ({teamFolder (), file})); - } -} - - -// Deletes the diffs for one chapter of a Bible. -void Database_Modifications::deleteTeamDiffChapter (const string& bible, int book, int chapter) -{ - string file = teamFile (bible, book, chapter); - filter_url_unlink (file); -} - - -// Returns an array with the available chapters that have diff data in a book in a Bible. -vector Database_Modifications::getTeamDiffChapters (const string& bible, int book) -{ - string pattern = bible + "." + filter::strings::convert_to_string (book) + "."; - size_t length = pattern.length (); - vector chapters; - vector files = filter_url_scandir (teamFolder ()); - for (auto & file : files) { - if (file.substr (0, length) != pattern) continue; - vector bits = filter::strings::explode (file, '.'); - if (bits.size() != 3) continue; - string path = filter_url_create_path ({teamFolder (), file}); - int time = filter_url_file_modification_time (path); - int days = (filter::date::seconds_since_epoch () - time) / 86400; - if (days > 5) { - // Unprocessed team changes older than so many days usually indicate a problem. - // Perhaps the server crashed so it never could process them. - // Cases like this have been seen on servers with limited memory. - // Therefore just remove this change, without processing it. - filter_url_unlink (path); - } else { - chapters.push_back (filter::strings::convert_to_int (bits [2])); - } - } - sort (chapters.begin(), chapters.end()); - return chapters; -} - - -// Returns the number of items in bible that have diff data. -// The bible can be a name or an identifier. This is because the bible identifier may no longer exist. -int Database_Modifications::getTeamDiffCount (const string& bible) -{ - string pattern = bible + "."; - size_t length = pattern.length (); - int count = 0; - vector files = filter_url_scandir (teamFolder ()); - for (auto & file : files) { - if (file.substr (0, length) != pattern) continue; - count++; - } - return count; -} - - -// Returns an array with the available books that have diff data in a Bible. -// The bible can be a name, or an identifier. This is because the bible identifier may no longer exist. -vector Database_Modifications::getTeamDiffBooks (const string& bible) -{ - vector books; - string pattern = bible + "."; - size_t length = pattern.length (); - vector files = filter_url_scandir (teamFolder ()); - for (auto & file : files) { - if (file.substr (0, length) != pattern) continue; - vector bits = filter::strings::explode (file, '.'); - if (bits.size() != 3) continue; - books.push_back (filter::strings::convert_to_int (bits [1])); - } - set bookset (books.begin (), books.end()); - books.assign (bookset.begin(), bookset.end()); - sort (books.begin(), books.end()); - return books; -} - - -// Returns an array with the available Bibles that have diff data. -vector Database_Modifications::getTeamDiffBibles () -{ - vector bibles; - vector files = filter_url_scandir (teamFolder ()); - for (auto & file : files) { - vector bits = filter::strings::explode (file, '.'); - if (bits.size() != 3) continue; - bibles.push_back (bits [0]); - } - set bibleset (bibles.begin (), bibles.end()); - bibles.assign (bibleset.begin(), bibleset.end()); - sort (bibles.begin(), bibles.end()); - return bibles; -} - - -// Truncates all team modifications. -void Database_Modifications::truncateTeams () -{ - vector files = filter_url_scandir (teamFolder ()); - for (auto file : files) { - filter_url_unlink (filter_url_create_path ({teamFolder (), file})); - } -} - - -// Code dealing with the "users" data. - - -string Database_Modifications::userMainFolder () -{ - return filter_url_create_root_path ({database_logic_databases (), "modifications", "users"}); -} - - -string Database_Modifications::userUserFolder (const string& username) -{ - return filter_url_create_path ({userMainFolder (), username}); -} - - -string Database_Modifications::userBibleFolder (const string& username, const string& bible) -{ - return filter_url_create_path ({userUserFolder (username), bible}); -} - - -string Database_Modifications::userBookFolder (const string& username, const string& bible, int book) -{ - return filter_url_create_path ({userBibleFolder (username, bible), filter::strings::convert_to_string (book)}); -} - - -string Database_Modifications::userChapterFolder (const string& username, const string& bible, int book, int chapter) -{ - return filter_url_create_path ({userBookFolder (username, bible, book), filter::strings::convert_to_string (chapter)}); -} - - -string Database_Modifications::userNewIDFolder (const string& username, const string& bible, int book, int chapter, int newID) -{ - return filter_url_create_path ({userChapterFolder (username, bible, book, chapter), filter::strings::convert_to_string (newID)}); -} - - -string Database_Modifications::userTimeFile (const string& username, const string& bible, int book, int chapter, int newID) -{ - return filter_url_create_path ({userNewIDFolder (username, bible, book, chapter, newID), "time"}); -} - - -string Database_Modifications::userOldIDFile (const string& username, const string& bible, int book, int chapter, int newID) -{ - return filter_url_create_path ({userNewIDFolder (username, bible, book, chapter, newID), "oldid"}); -} - - -string Database_Modifications::userOldTextFile (const string& username, const string& bible, int book, int chapter, int newID) -{ - return filter_url_create_path ({userNewIDFolder (username, bible, book, chapter, newID), "oldtext"}); -} - - -string Database_Modifications::userNewTextFile (const string& username, const string& bible, int book, int chapter, int newID) -{ - return filter_url_create_path ({userNewIDFolder (username, bible, book, chapter, newID), "newtext"}); -} - - -void Database_Modifications::recordUserSave (const string& username, const string& bible, int book, int chapter, int oldID, const string& oldText, int newID, const string& newText) -{ - // This entry is saved in a deep folder structure with the new ID in it. - string folder = userNewIDFolder (username, bible, book, chapter, newID); - if (!file_or_dir_exists (folder)) filter_url_mkdir (folder); - // The other data is stored in separate files in the newID folder. - string timeFile = userTimeFile (username, bible, book, chapter, newID); - filter_url_file_put_contents (timeFile, filter::strings::convert_to_string (filter::date::seconds_since_epoch ())); - string oldIDFile = userOldIDFile (username, bible, book, chapter, newID); - filter_url_file_put_contents (oldIDFile, filter::strings::convert_to_string (oldID)); - string oldTextFile = userOldTextFile (username, bible, book, chapter, newID); - filter_url_file_put_contents (oldTextFile, oldText); - string newTextFile = userNewTextFile (username, bible, book, chapter, newID); - filter_url_file_put_contents (newTextFile, newText); -} - - -void Database_Modifications::clearUserUser (const string& username) -{ - string folder = userUserFolder (username); - filter_url_rmdir (folder); -} - - -vector Database_Modifications::getUserUsernames () -{ - string folder = userMainFolder (); - vector usernames = filter_url_scandir (folder); - return usernames; -} - - -vector Database_Modifications::getUserBibles (const string& username) -{ - string folder = userUserFolder (username); - return filter_url_scandir (folder); -} - - -vector Database_Modifications::getUserBooks (const string& username, const string& bible) -{ - string folder = userBibleFolder (username, bible); - vector files = filter_url_scandir (folder); - vector books; - for (auto & file : files) { - books.push_back (filter::strings::convert_to_int (file)); - } - sort (books.begin(), books.end()); - return books; -} - - -vector Database_Modifications::getUserChapters (const string& username, const string& bible, int book) -{ - string folder = userBookFolder (username, bible, book); - vector files = filter_url_scandir (folder); - vector chapters; - for (auto & file : files) { - string path = filter_url_create_path ({folder, file}); - int time = filter_url_file_modification_time (path); - int days = (filter::date::seconds_since_epoch () - time) / 86400; - if (days > 5) { - // Unprocessed user changes older than so many days usually indicate a problem. - // Perhaps the server crashed so it never could process them. - // Cases like this have been seen on servers with limited memory. - // Therefore just remove this change, without processing it. - filter_url_rmdir (path); - } else { - chapters.push_back (filter::strings::convert_to_int (file)); - } - } - sort (chapters.begin(), chapters.end()); - return chapters; -} - - -vector Database_Modifications::getUserIdentifiers (const string& username, const string& bible, int book, int chapter) -{ - string folder = userChapterFolder (username, bible, book, chapter); - vector ids; - vector newids = filter_url_scandir (folder); - for (auto & newid : newids) { - string file = userOldIDFile (username, bible, book, chapter, filter::strings::convert_to_int (newid)); - string oldid = filter_url_file_get_contents (file); - Database_Modifications_Id id; - id.oldid = filter::strings::convert_to_int (oldid); - id.newid = filter::strings::convert_to_int (newid); - ids.push_back (id); - } - return ids; -} - - -Database_Modifications_Text Database_Modifications::getUserChapter (const string& username, const string& bible, int book, int chapter, int newID) -{ - string oldfile = userOldTextFile (username, bible, book, chapter, newID); - string newfile = userNewTextFile (username, bible, book, chapter, newID); - string oldtext = filter_url_file_get_contents (oldfile); - string newtext = filter_url_file_get_contents (newfile); - Database_Modifications_Text data; - data.oldtext = oldtext; - data.newtext = newtext; - return data; -} - - -int Database_Modifications::getUserTimestamp (const string& username, const string& bible, int book, int chapter, int newID) -{ - string file = userTimeFile (username, bible, book, chapter, newID); - string contents = filter_url_file_get_contents (file); - int time = filter::strings::convert_to_int (contents); - if (time > 0) return time; - return filter::date::seconds_since_epoch (); -} - - -// Code dealing with the notifications. - - -string Database_Modifications::notificationsMainFolder () -{ - return filter_url_create_root_path ({database_logic_databases (), "modifications", "notifications"}); -} - - -string Database_Modifications::notificationIdentifierDatabase (int identifier) -{ - return filter_url_create_path ({notificationsMainFolder (), filter::strings::convert_to_string (identifier)}); -} - - -// This function is for the unit tests. -void Database_Modifications::notificationUpdateTime (int identifier, int timestamp) -{ - SqliteDatabase sql (notificationIdentifierDatabase (identifier)); - sql.add ("UPDATE notification SET timestamp ="); - sql.add (timestamp); - sql.add (";"); - sql.execute (); -} - - -int Database_Modifications::getNextAvailableNotificationIdentifier () -{ - // Read the existing identifiers in the folder. - vector files = filter_url_scandir (notificationsMainFolder ()); - // Sort from low to high. - vector identifiers; - for (auto file : files) { - identifiers.push_back (filter::strings::convert_to_int (file)); - } - sort (identifiers.begin(), identifiers.end()); - // Fetch the last and highest identifier. - int identifier = 0; - size_t length = identifiers.size(); - if (length) identifier = identifiers [length - 1]; - // Take next one. - identifier++; - // Done. - return identifier; -} - - -void Database_Modifications::recordNotification (const vector & users, const string& category, const string& bible, int book, int chapter, int verse, const string& oldtext, const string& modification, const string& newtext) -{ - // Normally this function is called just after midnight. - // It would then put the current time on changes made the day before. - // Make a correction for that by subtracting 6 hours. - int timestamp = filter::date::seconds_since_epoch () - 21600; - for (auto & user : users) { - int identifier = getNextAvailableNotificationIdentifier (); - SqliteDatabase sql (notificationIdentifierDatabase (identifier)); - sql.add (createNotificationsDbSql ()); - sql.execute (); - sql.clear (); - sql.add ("INSERT INTO notification VALUES ("); - sql.add (timestamp); - sql.add (","); - sql.add (user); - sql.add (","); - sql.add (category); - sql.add (","); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (oldtext); - sql.add (","); - sql.add (modification); - sql.add (","); - sql.add (newtext); - sql.add (");"); - sql.execute (); - } -} - - -void Database_Modifications::indexTrimAllNotifications () -{ - // When the index is not healthy, delete it. - if (!healthy ()) erase (); - // Create a new index if it does not exist. - create (); - - // Get the notification identifiers on disk. - vector sidentifiers = filter_url_scandir (notificationsMainFolder ()); - - // Change notifications expire after 30 days. - // But the more there are, the sooner they expire. - int expiry_time = filter::date::seconds_since_epoch () - (30 * 3600 * 24); - if (sidentifiers.size () > 10000) expiry_time = filter::date::seconds_since_epoch () - (14 * 3600 * 24); - if (sidentifiers.size () > 20000) expiry_time = filter::date::seconds_since_epoch () - (7 * 3600 * 14); - if (sidentifiers.size () > 30000) expiry_time = filter::date::seconds_since_epoch () - (4 * 3600 * 14); - - // Database: Connect and speed it up. - sqlite3 * db = connect (); - database_sqlite_exec (db, "PRAGMA synchronous = OFF;"); - - // Go through the notifications on disk. - vector identifiers; - for (auto s : sidentifiers) { - identifiers.push_back (filter::strings::convert_to_int (s)); - } - sort (identifiers.begin(), identifiers.end()); - for (auto & identifier : identifiers) { - - // Fetch the data from the database and validate it. - - string path = notificationIdentifierDatabase (identifier); - bool valid = !filter_url_is_dir (path); - - map > result; - if (valid) { - SqliteDatabase sql (path); - sql.add ("SELECT * FROM notification;"); - result = sql.query (); - } - if (result.empty ()) valid = false; - - int timestamp = 0; - if (valid) { - vector timestamps = result ["timestamp"]; - if (timestamps.empty ()) valid = false; - else timestamp = filter::strings::convert_to_int (timestamps [0]); - } - if (timestamp < expiry_time) valid = false; - - bool exists = false; - if (valid) { - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT count(*) FROM notifications WHERE identifier = "); - sql.add (identifier); - sql.add (";"); - vector count_result = database_sqlite_query (db, sql.sql) ["count(*)"]; - if (!count_result.empty ()) { - int count = filter::strings::convert_to_int (count_result [0]); - exists = (count > 0); - } - } - - string user; - if (!exists && valid) { - vector usernames = result ["username"]; - if (usernames.empty ()) valid = false; - else user = usernames [0]; - if (user.empty ()) valid = false; - } - - string category; - if (!exists && valid) { - vector categories = result ["category"]; - if (categories.empty ()) valid = false; - else category = categories [0]; - } - - string bible; - if (!exists && valid) { - vector bibles = result ["bible"]; - if (bibles.empty ()) valid = false; - else bible = bibles [0]; - if (bible.empty ()) valid = false; - } - - int book = 0; - if (!exists && valid) { - vector books = result ["book"]; - if (books.empty ()) valid = false; - else book = filter::strings::convert_to_int (books [0]); - if (book == 0) valid = false; - } - - int chapter = 0; - if (!exists && valid) { - vector chapters = result ["chapter"]; - if (chapters.empty ()) valid = false; - else chapter = filter::strings::convert_to_int (chapters [0]); - if (chapters [0].empty ()) valid = false; - } - - int verse = 0; - if (!exists && valid) { - vector verses = result ["verse"]; - if (verses.empty ()) valid = false; - else verse = filter::strings::convert_to_int (verses [0]); - if (verses [0].empty ()) valid = false; - } - - string modification; - if (!exists && valid) { - vector modifications = result ["modification"]; - if (modifications.empty ()) valid = false; - else modification = modifications [0]; - if (modification.empty()) valid = false; - } - - if (valid) { - // Store valid data in the database if it does not yet exist. - if (!exists) { - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO notifications VALUES ("); - sql.add (identifier); - sql.add (","); - sql.add (timestamp); - sql.add (","); - sql.add (user); - sql.add (","); - sql.add (category); - sql.add (","); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (modification); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - } - } else { - // Delete invalid or expired data. - deleteNotification (identifier, db); - } - } - - database_sqlite_disconnect (db); -} - - -vector Database_Modifications::getNotificationIdentifiers (string username, string bible, bool sort_on_category) -{ - vector ids; - - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT identifier FROM notifications WHERE 1"); - if (username != "") { - sql.add ("AND username ="); - sql.add (username); - } - if (bible != "") { - sql.add ("AND bible ="); - sql.add (bible); - } - // Sort on reference, so that related change notifications are in context. - // Or sort on user, so it's easy to view a user's changes together. - // https://github.com/bibledit/cloud/issues/267 - sql.add ("ORDER BY"); - if (sort_on_category) sql.add ("category ASC,"); - sql.add ("book ASC, chapter ASC, verse ASC, identifier ASC;"); - - sqlite3 * db = connect (); - vector sidentifiers = database_sqlite_query (db, sql.sql) ["identifier"]; - database_sqlite_disconnect (db); - for (auto & identifier : sidentifiers) { - ids.push_back (filter::strings::convert_to_int (identifier)); - } - - return ids; -} - - -// This gets the identifiers of the team's changes. -vector Database_Modifications::getNotificationTeamIdentifiers (const string& username, const string& category, string bible) -{ - vector ids; - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT identifier FROM notifications WHERE username ="); - sql.add (username); - sql.add ("AND category ="); - sql.add (category); - if (bible != "") { - sql.add ("AND bible ="); - sql.add (bible); - } - sql.add ("ORDER BY book ASC, chapter ASC, verse ASC, identifier ASC;"); - sqlite3 * db = connect (); - vector sidentifiers = database_sqlite_query (db, sql.sql) ["identifier"]; - database_sqlite_disconnect (db); - for (auto & sid : sidentifiers) { - ids.push_back (filter::strings::convert_to_int (sid)); - } - return ids; -} - - -// This gets the distinct Bibles in the user's notifications. -vector Database_Modifications::getNotificationDistinctBibles (string username) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT bible FROM notifications WHERE 1"); - if (username != "") { - sql.add ("AND username ="); - sql.add (username); - } - sql.add (";"); - - sqlite3 * db = connect (); - vector bibles = database_sqlite_query (db, sql.sql) ["bible"]; - database_sqlite_disconnect (db); - - return bibles; -} - - -void Database_Modifications::deleteNotification (int identifier, sqlite3 * db) -{ - // Delete from file. - deleteNotificationFile (identifier); - // Delete from the database. - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM notifications WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - // Make a very short connection to the database, - // to prevent corruption when a user deletes lots of changes notifications - // by keeping the delete key pressed. - bool local_connection = (db == nullptr); - if (local_connection) db = connect (); - database_sqlite_exec (db, sql.sql); - if (local_connection) database_sqlite_disconnect (db); -} - - -int Database_Modifications::getNotificationTimeStamp (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT timestamp FROM notifications WHERE identifier ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector timestamps = database_sqlite_query (db, sql.sql) ["timestamp"]; - database_sqlite_disconnect (db); - int time = filter::date::seconds_since_epoch (); - for (auto & stamp : timestamps) { - time = filter::strings::convert_to_int (stamp); - } - return time; -} - - -string Database_Modifications::getNotificationCategory (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT category FROM notifications WHERE identifier ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector categories = database_sqlite_query (db, sql.sql) ["category"]; - database_sqlite_disconnect (db); - string category = ""; - for (auto & row : categories) { - category = row; - } - return category; -} - - -string Database_Modifications::getNotificationBible (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT bible FROM notifications WHERE identifier ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector bibles = database_sqlite_query (db, sql.sql) ["bible"]; - database_sqlite_disconnect (db); - string bible = ""; - for (auto & item : bibles) { - bible = item; - } - return bible; -} - - -Passage Database_Modifications::getNotificationPassage (int id) -{ - Passage passage; - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT book, chapter, verse FROM notifications WHERE identifier ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - for (unsigned int i = 0; i < books.size (); i++) { - passage.m_book = filter::strings::convert_to_int (books [i]); - passage.m_chapter = filter::strings::convert_to_int (chapters [i]); - passage.m_verse = verses [i]; - } - return passage; -} - - -string Database_Modifications::getNotificationOldText (int id) -{ - string path = notificationIdentifierDatabase (id); - if (!file_or_dir_exists (path)) return ""; - SqliteDatabase sql (path); - sql.add ("SELECT oldtext FROM notification;"); - vector result = sql.query () ["oldtext"]; - if (result.empty ()) return ""; - return result [0]; -} - - -string Database_Modifications::getNotificationModification (int id) -{ - string path = notificationIdentifierDatabase (id); - if (!file_or_dir_exists (path)) return ""; - SqliteDatabase sql (path); - sql.add ("SELECT modification FROM notification;"); - vector result = sql.query () ["modification"]; - if (result.empty ()) return ""; - return result [0]; -} - - -string Database_Modifications::getNotificationNewText (int id) -{ - string path = notificationIdentifierDatabase (id); - if (!file_or_dir_exists (path)) return ""; - SqliteDatabase sql (path); - sql.add ("SELECT newtext FROM notification;"); - vector result = sql.query () ["newtext"]; - if (result.empty ()) return ""; - return result [0]; -} - - -// Clears change notifications for $username. -// It does not clear all of the change notifications in all cases. -// It clears a limited number of them. -// It returns how many change notifications it cleared. -int Database_Modifications::clearNotificationsUser (const string& username) -{ - int cleared_counter = 0; - string any_bible = ""; - vector identifiers = getNotificationIdentifiers (username, any_bible); - sqlite3 * db = connect (); - // A transaction speeds up the operation. - database_sqlite_exec (db, "BEGIN;"); - for (auto& identifier : identifiers) { - if (cleared_counter >= 100) continue; - deleteNotification (identifier, db); - cleared_counter++; - } - database_sqlite_exec (db, "COMMIT;"); - database_sqlite_disconnect (db); - // How many change notifications it cleared. - return cleared_counter; -} - - -// This function deletes personal changes and their matching change notifications. -// It returns the deleted identifiers. -vector Database_Modifications::clearNotificationMatches (string username, string personal, string team, string bible) -{ - sqlite3 * db = connect (); - - // Select all identifiers of the personal changes. - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT identifier FROM notifications WHERE username ="); - sql.add (username); - sql.add ("AND category ="); - sql.add (personal); - if (!bible.empty ()) { - sql.add ("AND bible ="); - sql.add (bible); - } - sql.add (";"); - - vector personals; - vector result = database_sqlite_query (db, sql.sql) ["identifier"]; - for (auto & item : result) { - personals.push_back (filter::strings::convert_to_int (item)); - } - - // Matches to be deleted. - vector deletes; - - // Go through each of the personal changes. - for (auto & personalID : personals) { - string bible2 = getNotificationBible (personalID); - Passage passage = getNotificationPassage (personalID); - int book = passage.m_book; - int chapter = passage.m_chapter; - int verse = filter::strings::convert_to_int (passage.m_verse); - string modification = getNotificationModification (personalID); - // Get all matching identifiers from the team's change notifications. - SqliteSQL sql2 = SqliteSQL (); - sql2.add ("SELECT identifier FROM notifications WHERE username ="); - sql2.add (username); - sql2.add ("AND category ="); - sql2.add (team); - sql2.add ("AND bible ="); - sql2.add (bible2); - sql2.add ("AND book ="); - sql2.add (book); - sql2.add ("AND chapter ="); - sql2.add (chapter); - sql2.add ("AND verse ="); - sql2.add (verse); - sql2.add ("AND modification ="); - sql2.add (modification); - sql2.add (";"); - vector teamMatches; - vector result2 = database_sqlite_query (db, sql2.sql) ["identifier"]; - for (auto & item : result2) { - teamMatches.push_back (filter::strings::convert_to_int (item)); - } - // There should be exactly one candidate for the matches to be removed. - // If there are none, it means that the personal change didn't make it to the team's text. - // If there are two or more matching changes, then one could have undone the other, so should not be automatically removed. - if (teamMatches.size () == 1) { - // Check there are only two change notifications for this user / Bible / book / chapter / verse. - // If there are more, we can't be sure that the personal change was not overwritten somehow. - vector passageMatches; - SqliteSQL sql3 = SqliteSQL (); - sql3.add ("SELECT identifier FROM notifications WHERE username ="); - sql3.add (username); - sql3.add ("AND bible ="); - sql3.add (bible2); - sql3.add ("AND book ="); - sql3.add (book); - sql3.add ("AND chapter ="); - sql3.add (chapter); - sql3.add ("AND verse ="); - sql3.add (verse); - sql3.add (";"); - vector result3 = database_sqlite_query (db, sql3.sql) ["identifier"]; - for (auto & item : result3) { - passageMatches.push_back (filter::strings::convert_to_int (item)); - } - if (passageMatches.size () == 2) { - // Store the personal change to be deleted. - // Store the matching change notification to be deleted also. - for (auto & passageMatch : passageMatches) { - deletes.push_back (passageMatch); - } - } - } - } - - // Delete all stored identifiers to be deleted. - for (auto & id : deletes) { - deleteNotification (id, db); - } - - database_sqlite_disconnect (db); - - // Return deleted identifiers. - return deletes; -} - - -// Store a change notification on the client, as received from the server. -void Database_Modifications::storeClientNotification (int id, string username, string category, string bible, int book, int chapter, int verse, string oldtext, string modification, string newtext) -{ - // Erase any existing database. - deleteNotificationFile (id); - // Timestamp is not used: Just put the current time. - int timestamp = filter::date::seconds_since_epoch (); - { - SqliteDatabase sql (notificationIdentifierDatabase (id)); - sql.add (createNotificationsDbSql ()); - sql.execute (); - sql.clear (); - sql.add ("INSERT INTO notification VALUES ("); - sql.add (timestamp); - sql.add (","); - sql.add (username); - sql.add (","); - sql.add (category); - sql.add (","); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (oldtext); - sql.add (","); - sql.add (modification); - sql.add (","); - sql.add (newtext); - sql.add (");"); - sql.execute (); - } - { - sqlite3 * db = connect (); - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO notifications VALUES ("); - sql.add (id); - sql.add (","); - sql.add (timestamp); - sql.add (","); - sql.add (username); - sql.add (","); - sql.add (category); - sql.add (","); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (modification); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - } -} - - -const char * Database_Modifications::createNotificationsDbSql () -{ - return - "CREATE TABLE notification (" - " timestamp integer," - " username text," - " category text," - " bible text," - " book integer," - " chapter integer," - " verse integer," - " oldtext text," - " modification text," - " newtext text" - ");"; -} - - -void Database_Modifications::deleteNotificationFile (int identifier) -{ - string path = notificationIdentifierDatabase (identifier); - // Delete the old folder from the file system (used till Februari 2016). - if (filter_url_is_dir (path)) filter_url_rmdir (path); - // Delete the new database file from the file system. - if (file_or_dir_exists (path)) filter_url_unlink (path); -} - - -vector Database_Modifications::getCategories () -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT DISTINCT category FROM notifications ORDER BY category;"); - vector categories = sql.query ()["category"]; - return categories; -} diff --git a/database/modifications.h b/database/modifications.h deleted file mode 100644 index d7426da9e..000000000 --- a/database/modifications.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -struct Database_Modifications_Id -{ - int oldid {0}; - int newid {0}; -}; - -struct Database_Modifications_Text -{ - std::string oldtext {}; - std::string newtext {}; -}; - -class Database_Modifications -{ -public: - void erase (); - void create (); - bool healthy (); - void vacuum (); - bool teamDiffExists (const std::string& bible, int book, int chapter); - void storeTeamDiff (const std::string& bible, int book, int chapter); - std::string getTeamDiff (const std::string& bible, int book, int chapter); - void storeTeamDiffBook (const std::string& bible, int book); - void storeTeamDiffBible (const std::string& bible); - void deleteTeamDiffBible (const std::string& bible); - void deleteTeamDiffChapter (const std::string& bible, int book, int chapter); - std::vector getTeamDiffChapters (const std::string& bible, int book); - int getTeamDiffCount (const std::string& bible); - std::vector getTeamDiffBooks (const std::string& bible); - std::vector getTeamDiffBibles (); - void truncateTeams (); - void recordUserSave (const std::string& username, const std::string& bible, int book, int chapter, int oldID, const std::string& oldText, int newID, const std::string& newText); - void clearUserUser (const std::string& username); - std::vector getUserUsernames (); - std::vector getUserBibles (const std::string& username); - std::vector getUserBooks (const std::string& username, const std::string& bible); - std::vector getUserChapters (const std::string& username, const std::string& bible, int book); - std::vector getUserIdentifiers (const std::string& username, const std::string& bible, int book, int chapter); - Database_Modifications_Text getUserChapter (const std::string& username, const std::string& bible, int book, int chapter, int newID); - int getUserTimestamp (const std::string& username, const std::string& bible, int book, int chapter, int newID); - int getNextAvailableNotificationIdentifier (); - void recordNotification (const std::vector & users, const std::string& category, const std::string& bible, int book, int chapter, int verse, const std::string& oldtext, const std::string& modification, const std::string& newtext); - void indexTrimAllNotifications (); - std::vector getNotificationIdentifiers (std::string username, std::string bible, bool sort_on_category = false); - std::vector getNotificationTeamIdentifiers (const std::string& username, const std::string& category, std::string bible = ""); - std::vector getNotificationDistinctBibles (std::string username = std::string()); - void deleteNotification (int identifier, sqlite3 * db = nullptr); - int getNotificationTimeStamp (int id); - std::string getNotificationCategory (int id); - std::string getNotificationBible (int id); - Passage getNotificationPassage (int id); - std::string getNotificationOldText (int id); - std::string getNotificationModification (int id); - std::string getNotificationNewText (int id); - int clearNotificationsUser (const std::string& username); - std::vector clearNotificationMatches (std::string username, std::string personal, std::string team, std::string bible = ""); - void storeClientNotification (int id, std::string username, std::string category, std::string bible, int book, int chapter, int verse, std::string oldtext, std::string modification, std::string newtext); - void notificationUpdateTime (int identifier, int timestamp); - std::vector getCategories (); -private: - const char * filename (); - sqlite3 * connect (); - std::string teamFolder (); - std::string teamFile (const std::string& bible, int book, int chapter); - std::string userMainFolder (); - std::string userUserFolder (const std::string& username); - std::string userBibleFolder (const std::string& username, const std::string& bible); - std::string userBookFolder (const std::string& username, const std::string& bible, int book); - std::string userChapterFolder (const std::string& username, const std::string& bible, int book, int chapter); - std::string userNewIDFolder (const std::string& username, const std::string& bible, int book, int chapter, int newID); - std::string userTimeFile (const std::string& username, const std::string& bible, int book, int chapter, int newID); - std::string userOldIDFile (const std::string& username, const std::string& bible, int book, int chapter, int newID); - std::string userOldTextFile (const std::string& username, const std::string& bible, int book, int chapter, int newID); - std::string userNewTextFile (const std::string& username, const std::string& bible, int book, int chapter, int newID); - std::string notificationsMainFolder (); - std::string notificationIdentifierDatabase (int identifier); - const char * createNotificationsDbSql (); - void deleteNotificationFile (int identifier); -}; diff --git a/database/morphgnt.cpp b/database/morphgnt.cpp deleted file mode 100644 index c49061fe1..000000000 --- a/database/morphgnt.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// This is the database for the Greek Bible text morphology. -// Resilience: It is not written to. -// Chances of corruption are nearly zero. - - -const char * Database_MorphGnt::filename () -{ - return "morphgnt"; -} - - -void Database_MorphGnt::create () -{ - filter_url_unlink (database_sqlite_file (filename ())); - - SqliteDatabase sql = SqliteDatabase (filename ()); - - sql.clear (); - sql.add ("CREATE TABLE morphgnt (book int, chapter int, verse int, pos int, parsing int, word int, lemma int);"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS pos (pos text);"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS parsing (parsing text);"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS word (word text);"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS lemma (lemma text);"); - sql.execute (); -} - - -void Database_MorphGnt::optimize () -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("VACUUM;"); - sql.execute (); -} - - -void Database_MorphGnt::store (int book, int chapter, int verse, - string pos, string parsing, string word, string lemma) -{ - int pos_id = get_id ("pos", pos); - int parsing_id = get_id ("parsing", parsing); - int word_id = get_id ("word", word); - int lemma_id = get_id ("lemma", lemma); - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("PRAGMA temp_store = MEMORY;"); - sql.execute (); - sql.clear (); - sql.add ("PRAGMA synchronous = OFF;"); - sql.execute (); - sql.clear (); - sql.add ("PRAGMA journal_mode = OFF;"); - sql.execute (); - sql.clear (); - sql.add ("INSERT INTO morphgnt VALUES ("); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (pos_id); - sql.add (","); - sql.add (parsing_id); - sql.add (","); - sql.add (word_id); - sql.add (","); - sql.add (lemma_id); - sql.add (");"); - sql.execute (); -} - - -vector Database_MorphGnt::rowids (int book, int chapter, int verse) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT rowid FROM morphgnt WHERE book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("AND verse ="); - sql.add (verse); - sql.add ("ORDER BY rowid;"); - vector result = sql.query () ["rowid"]; - vector rowids; - for (auto rowid : result) rowids.push_back (filter::strings::convert_to_int (rowid)); - return rowids; -} - - -string Database_MorphGnt::pos (int rowid) -{ - return get_item ("pos", rowid); -} - - -string Database_MorphGnt::parsing (int rowid) -{ - return get_item ("parsing", rowid); -} - - -string Database_MorphGnt::word (int rowid) -{ - return get_item ("word", rowid); -} - - -string Database_MorphGnt::lemma (int rowid) -{ - return get_item ("lemma", rowid); -} - - -int Database_MorphGnt::get_id (const char * table_row, string item) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - // Two iterations to be sure a rowid can be returned. - for (unsigned int i = 0; i < 2; i++) { - // Check on the rowid and return it if it's there. - sql.clear (); - sql.add ("SELECT rowid FROM"); - sql.add (table_row); - sql.add ("WHERE"); - sql.add (table_row); - sql.add ("="); - sql.add (item); - sql.add (";"); - vector result = sql.query () ["rowid"]; - if (!result.empty ()) return filter::strings::convert_to_int (result [0]); - // The rowid was not found: Insert the word into the table. - // The rowid will now be found during the second iteration. - sql.clear (); - sql.add ("INSERT INTO"); - sql.add (table_row); - sql.add ("VALUES ("); - sql.add (item); - sql.add (");"); - sql.execute (); - } - return 0; -} - - -string Database_MorphGnt::get_item (const char * item, int rowid) -{ - // The $rowid refers to the main table. - // Update it so it refers to the sub table. - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT"); - sql.add (item); - sql.add ("FROM morphgnt WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - vector result = sql.query () [item]; - rowid = 0; - if (!result.empty ()) rowid = filter::strings::convert_to_int (result [0]); - // Retrieve the requested value from the sub table. - sql.clear (); - sql.add ("SELECT"); - sql.add (item); - sql.add ("FROM"); - sql.add (item); - sql.add ("WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - result = sql.query () [item]; - if (!result.empty ()) return result [0]; - // Not found. - return ""; -} diff --git a/database/morphgnt.h b/database/morphgnt.h deleted file mode 100644 index dbc772f2c..000000000 --- a/database/morphgnt.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_MorphGnt -{ -public: - void create (); - void optimize (); - void store (int book, int chapter, int verse, - std::string pos, std::string parsing, std::string word, std::string lemma); - std::vector rowids (int book, int chapter, int verse); - std::string pos (int rowid); - std::string parsing (int rowid); - std::string word (int rowid); - std::string lemma (int rowid); -private: - const char * filename (); - int get_id (const char * table_row, std::string item); - std::string get_item (const char * item, int rowid); -}; - diff --git a/database/navigation.cpp b/database/navigation.cpp deleted file mode 100644 index a28d345b5..000000000 --- a/database/navigation.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: It is re-created every night - - -sqlite3 * Database_Navigation::connect () -{ - return database_sqlite_connect ("navigation"); -} - - -void Database_Navigation::create () -{ - sqlite3 * db = connect (); - string sql = - "CREATE TABLE IF NOT EXISTS navigation (" - " timestamp integer," - " username text," - " book integer," - " chapter integer," - " verse integer," - " active boolean" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -void Database_Navigation::trim () -{ - // Delete items older than, say, several weeks. - int time = filter::date::seconds_since_epoch (); - time -= (3600 * 24 * 14); - SqliteSQL sql; - sql.add ("DELETE FROM navigation WHERE timestamp <="); - sql.add (time); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -void Database_Navigation::record (int time, string user, int book, int chapter, int verse) -{ - // Clear any 'active' flags. - SqliteSQL sql1 = SqliteSQL (); - sql1.add ("UPDATE navigation SET active = 0 WHERE username ="); - sql1.add (user); - sql1.add (";"); - - // Remove entries recorded less than several seconds ago. - SqliteSQL sql2 = SqliteSQL (); - int recent = time - 5; - sql2.add ("DELETE FROM navigation WHERE timestamp >="); - sql2.add (recent); - sql2.add ("AND username ="); - sql2.add (user); - sql2.add (";"); - - // Record entry. - SqliteSQL sql3 = SqliteSQL (); - sql3.add ("INSERT INTO navigation VALUES ("); - sql3.add (time); - sql3.add (","); - sql3.add (user); - sql3.add (","); - sql3.add (book); - sql3.add (","); - sql3.add (chapter); - sql3.add (","); - sql3.add (verse); - sql3.add (", 1);"); - - sqlite3 * db = connect (); - database_sqlite_exec (db, sql1.sql); - database_sqlite_exec (db, sql2.sql); - database_sqlite_exec (db, sql3.sql); - database_sqlite_disconnect (db); -} - - -bool Database_Navigation::previous_exists (const string& user) -{ - return (get_previous_id (user) != 0); -} - - -bool Database_Navigation::next_exists (const string& user) -{ - return (get_next_id (user) != 0); -} - - -Passage Database_Navigation::get_previous (const string& user) -{ - int id = get_previous_id (user); - if (id == 0) return Passage (); - - // Update the 'active' flag. - SqliteSQL sql1 = SqliteSQL (); - sql1.add ("UPDATE navigation SET active = 0 WHERE username ="); - sql1.add (user); - sql1.add (";"); - SqliteSQL sql2 = SqliteSQL (); - sql2.add ("UPDATE navigation SET active = 1 WHERE rowid ="); - sql2.add (id); - sql2.add (";"); - - // Read the passage. - map > result; - SqliteSQL sql3 = SqliteSQL (); - sql3.add ("SELECT book, chapter, verse FROM navigation WHERE rowid ="); - sql3.add (id); - sql3.add (";"); - - // Run all of the SQL at once, to minimize the database connection time. - sqlite3 * db = connect (); - database_sqlite_exec (db, sql1.sql); - database_sqlite_exec (db, sql2.sql); - result = database_sqlite_query (db, sql3.sql); - database_sqlite_disconnect (db); - - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - if (!books.empty()) { - Passage passage; - passage.m_book = filter::strings::convert_to_int (books [0]); - passage.m_chapter = filter::strings::convert_to_int (chapters [0]); - passage.m_verse = verses [0]; - return passage; - } - return Passage (); -} - - -Passage Database_Navigation::get_next (const string& user) -{ - int id = get_next_id (user); - if (id == 0) return Passage (); - - // Update the 'active' flag. - SqliteSQL sql1 = SqliteSQL (); - sql1.add ("UPDATE navigation SET active = 0 WHERE username ="); - sql1.add (user); - sql1.add (";"); - SqliteSQL sql2 = SqliteSQL (); - sql2.add ("UPDATE navigation SET active = 1 WHERE rowid ="); - sql2.add (id); - sql2.add (";"); - - // Read the passage. - map > result; - SqliteSQL sql3 = SqliteSQL (); - sql3.add ("SELECT book, chapter, verse FROM navigation WHERE rowid ="); - sql3.add (id); - sql3.add (";"); - - // Run all of the SQL at once. - sqlite3 * db = connect (); - database_sqlite_exec (db, sql1.sql); - database_sqlite_exec (db, sql2.sql); - result = database_sqlite_query (db, sql3.sql); - database_sqlite_disconnect (db); - - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - if (!books.empty()) { - Passage passage; - passage.m_book = filter::strings::convert_to_int (books [0]); - passage.m_chapter = filter::strings::convert_to_int (chapters [0]); - passage.m_verse = verses [0]; - return passage; - } - return Passage (); -} - - -int Database_Navigation::get_previous_id (const string& user) -{ - // Get the database row identifier of the active entry for the user. - int id = 0; - { - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid FROM navigation WHERE username ="); - sql.add (user); - sql.add ("AND active = 1;"); - sqlite3 * db = connect (); - vector ids = database_sqlite_query (db, sql.sql) ["rowid"]; - for (auto & s : ids) { - id = filter::strings::convert_to_int (s); - } - database_sqlite_disconnect (db); - } - // If no active row identifier was found, return zero. - if (id == 0) return 0; - - // Get the database row identifier of the entry just before the active entry. - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid FROM navigation WHERE rowid <"); - sql.add (id); - sql.add ("AND username ="); - sql.add (user); - sql.add ("ORDER BY rowid DESC LIMIT 1;"); - sqlite3 * db = connect (); - vector ids = database_sqlite_query (db, sql.sql) ["rowid"]; - database_sqlite_disconnect (db); - if (!ids.empty()) { - return filter::strings::convert_to_int (ids[0]); - } - - // Nothing found. - return 0; -} - - -int Database_Navigation::get_next_id (const string& user) -{ - // Get the database row identifier of the active entry for the user. - int id = 0; - { - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid FROM navigation WHERE username ="); - sql.add (user); - sql.add ("AND active = 1;"); - sqlite3 * db = connect (); - vector ids = database_sqlite_query (db, sql.sql) ["rowid"]; - for (auto & s : ids) { - id = filter::strings::convert_to_int (s); - } - database_sqlite_disconnect (db); - } - // If no active row identifier was found, return zero. - if (id == 0) return 0; - - // Get the database row identifier of the entry just after the active entry. - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid FROM navigation WHERE rowid >"); - sql.add (id); - sql.add ("AND username ="); - sql.add (user); - sql.add ("ORDER BY rowid ASC LIMIT 1;"); - sqlite3 * db = connect (); - vector ids = database_sqlite_query (db, sql.sql) ["rowid"]; - database_sqlite_disconnect (db); - if (!ids.empty()) { - return filter::strings::convert_to_int (ids[0]); - } - - // Nothing found. - return 0; -} - - -// The $user for whom to get the history. -// The $direction into which to get the history: -// * negative: Get the past history as if going back. -// * positive: Get the future history as if going forward. -vector Database_Navigation::get_history (const string& user, int direction) -{ - vector passages; - - int id = 0; - if (direction > 0) id = get_next_id(user); - if (direction < 0) id = get_previous_id (user); - if (id) { - - // Read the passages history for this user. - map > result; - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT book, chapter, verse FROM navigation WHERE rowid"); - if (direction > 0) sql.add (">="); - if (direction < 0) sql.add ("<="); - sql.add (id); - sql.add ("AND username ="); - sql.add (user); - - // Order the results depending on getting the history forward or backward. - sql.add ("ORDER BY rowid"); - if (direction > 0) sql.add ("ASC"); - if (direction < 0) sql.add ("DESC"); - sql.add (";"); - - // Run the query on the database. - sqlite3 * db = connect (); - result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - - // Assemble the results. - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - for (unsigned int i = 0; i < books.size(); i++) { - Passage passage; - passage.m_book = filter::strings::convert_to_int (books [i]); - passage.m_chapter = filter::strings::convert_to_int (chapters [i]); - passage.m_verse = verses [i]; - passages.push_back(passage); - } - } - - // Done. - return passages; -} diff --git a/database/navigation.h b/database/navigation.h deleted file mode 100644 index d084155b8..000000000 --- a/database/navigation.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Database_Navigation -{ -public: - void create (); - void trim (); - void record (int time, std::string user, int book, int chapter, int verse); - bool previous_exists (const std::string& user); - bool next_exists (const std::string& user); - Passage get_previous (const std::string& user); - Passage get_next (const std::string& user); - std::vector get_history (const std::string& user, int direction); -private: - sqlite3 * connect (); - int get_previous_id (const std::string& user); - int get_next_id (const std::string& user); -}; diff --git a/database/noteactions.cpp b/database/noteactions.cpp deleted file mode 100644 index 01ed8a722..000000000 --- a/database/noteactions.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// Database resilience. -// It is written to by a single user. -// No simultaneous writes are are rare. -// In case of corruption, the work done on the consultation notes is lost. -// Remove the database file, and re-run setup to correct the problem. - - -sqlite3 * Database_NoteActions::connect () -{ - return database_sqlite_connect ("noteactions"); -} - - -void Database_NoteActions::create () -{ - sqlite3 * db = connect (); - string sql = - "CREATE TABLE IF NOT EXISTS noteactions (" - " username text," - " note integer," - " timestamp integer," - " action integer," - " content text" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -void Database_NoteActions::clear () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "DROP TABLE IF EXISTS noteactions;"); - database_sqlite_disconnect (db); - create (); -} - - -void Database_NoteActions::optimize () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_disconnect (db); -} - - -void Database_NoteActions::record (const string& username, int note, int action, const string& content) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO noteactions VALUES ("); - sql.add (username); - sql.add (","); - sql.add (note); - sql.add (","); - sql.add (filter::date::seconds_since_epoch ()); - sql.add (","); - sql.add (action); - sql.add (","); - sql.add (content); - sql.add (");"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -vector Database_NoteActions::getNotes () -{ - vector notes; - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, "SELECT DISTINCT note FROM noteactions ORDER BY rowid;") ["note"]; - database_sqlite_disconnect (db); - for (auto & note : result) { - notes.push_back (filter::strings::convert_to_int (note)); - } - return notes; -} - - -vector Database_NoteActions::getNoteData (int note) -{ - vector data; - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid, username, timestamp, action, content FROM noteactions WHERE note ="); - sql.add (note); - sql.add ("ORDER BY rowid;"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector rowids = result ["rowid"]; - vector usernames = result ["username"]; - vector timestamps = result ["timestamp"]; - vector actions = result ["action"]; - vector contents = result ["content"]; - for (unsigned int i = 0; i < rowids.size (); i++) { - Database_Note_Action action = Database_Note_Action (); - action.rowid = filter::strings::convert_to_int (rowids [i]); - action.username = usernames [i]; - action.timestamp = filter::strings::convert_to_int (timestamps [i]); - action.action = filter::strings::convert_to_int (actions [i]); - action.content = contents [i]; - data.push_back (action); - } - return data; -} - - -// Update all actions for a note with identifier $old to $new. -void Database_NoteActions::updateNotes (int oldId, int newId) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("UPDATE noteactions SET note ="); - sql.add (newId); - sql.add ("WHERE note ="); - sql.add (oldId); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -void Database_NoteActions::erase (int rowid) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM noteactions where rowid ="); - sql.add (rowid); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -bool Database_NoteActions::exists (int note) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT note FROM noteactions where note ="); - sql.add (note); - sql.add (";"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - return !result.empty (); -} - diff --git a/database/noteactions.h b/database/noteactions.h deleted file mode 100644 index cd4b90d38..000000000 --- a/database/noteactions.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -struct Database_Note_Action -{ - int rowid {0}; - std::string username {}; - int timestamp {0}; - int action {0}; - std::string content {}; -}; - -class Database_NoteActions -{ -public: - void create (); - void clear (); - void optimize (); - void record (const std::string& username, int note, int action, const std::string& content); - std::vector getNotes (); - std::vector getNoteData (int note); - void updateNotes (int oldId, int newId); - void erase (int rowid); - bool exists (int note); -private: - sqlite3 * connect (); -}; diff --git a/database/noteassignment.cpp b/database/noteassignment.cpp deleted file mode 100644 index 0649396fe..000000000 --- a/database/noteassignment.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: -// Data is stored in multiple text files. - - -string Database_NoteAssignment::path (string user) -{ - return filter_url_create_root_path ({database_logic_databases (), "client", "noteassignment_" + user + ".txt"}); -} - - -bool Database_NoteAssignment::exists (string user) -{ - return file_or_dir_exists (path (user)); -} - - -void Database_NoteAssignment::assignees (string user, vector assignees) -{ - filter_url_file_put_contents (path (user), filter::strings::implode (assignees, "\n")); -} - - -vector Database_NoteAssignment::assignees (string user) -{ - string contents = filter_url_file_get_contents (path (user)); - return filter::strings::explode (contents, '\n'); -} - - -bool Database_NoteAssignment::exists (string user, string assignee) -{ - vector users = assignees (user); - return in_array (assignee, users); -} - - -void Database_NoteAssignment::remove (string user) -{ - filter_url_unlink (path (user)); -} diff --git a/database/noteassignment.h b/database/noteassignment.h deleted file mode 100644 index 402d625a9..000000000 --- a/database/noteassignment.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_NoteAssignment -{ -public: - bool exists (std::string user); - void assignees (std::string user, std::vector assignees); - std::vector assignees (std::string user); - bool exists (std::string user, std::string assignee); - void remove (std::string user); -private: - std::string path (std::string user); -}; diff --git a/database/notes.cpp b/database/notes.cpp deleted file mode 100644 index 2d295a0c6..000000000 --- a/database/notes.cpp +++ /dev/null @@ -1,2017 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma GCC diagnostic ignored "-Wuseless-cast" -#include -#pragma GCC diagnostic pop -#include -#include -using namespace std; -using namespace jsonxx; - - -// Database resilience. -// The notes are stored in the plain filesystem for robustness. -// A database can easily be corrupted. The filesystem is more robust. -// The notes database works like this: -// * All read operations are done from the filesystem. -// * All write operations first go to the file system, then to the database. -// * All search and locate operations work through the database. -// * Connections to the database are alive as short as possible. - - -/* - In older versions the notes were stored as a bundle of separate files. - In newer versions each note is stored as one JSON file. - This uses less space on disk. - In older versions, on a Linux server, one notes took 32 kbytes. - A lot of that space is wasted. - In newer versions one notes takes only 4 kbytes. - That is a difference of 8 times. -*/ - - -Database_Notes::Database_Notes (Webserver_Request& webserver_request): -m_webserver_request (webserver_request) -{ -} - - -sqlite3 * Database_Notes::connect () -{ - return database_sqlite_connect ("notes"); -} - - -sqlite3 * Database_Notes::connect_checksums () -{ - return database_sqlite_connect ("notes_checksums"); -} - - -void Database_Notes::create () -{ - // Create the main database and table. - sqlite3 * db = connect (); - string sql; - sql = - "CREATE TABLE IF NOT EXISTS notes (" - " id integer primary key autoincrement," - " identifier integer NOT NULL," - " modified integer NOT NULL," - " assigned text," - " subscriptions text," - " bible text," - " passage text," - " status text," - " severity integer," - " summary text," - " contents text," - " cleantext text" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); - - // Create the database and table for the checksums. - // A general reason for having this separate is robustness. - // A specific reason for this is that when the main notes database is being repaired, - // and several clients keep reading it, it may disrupt the repair. - db = connect_checksums (); - sql = - "CREATE TABLE IF NOT EXISTS checksums (" - " identifier integer," - " checksum checksum" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); - - // Enter the standard statuses in the list of translatable strings. -#ifdef NONE - translate("New"); - translate("Pending"); - translate("In progress"); - translate("Done"); - translate("Reopened"); -#endif - - // Enter the standard severities in the list of translatable strings. -#ifdef NONE - translate("Wish"); - translate("Minor"); - translate("Normal"); - translate("Important"); - translate("Major"); - translate("Critical"); -#endif -} - - -string Database_Notes::database_path () -{ - return filter_url_create_root_path ({database_logic_databases (), "notes.sqlite"}); -} - - -string Database_Notes::checksums_database_path () -{ - return filter_url_create_root_path ({database_logic_databases (), "notes_checksums.sqlite"}); -} - - -// Returns whether the notes database is healthy, as a boolean. -bool Database_Notes::healthy () -{ - return database_sqlite_healthy (database_path ()); -} - - -// Returns whether the notes checksums database is healthy, as a boolean. -bool Database_Notes::checksums_healthy () -{ - return database_sqlite_healthy (checksums_database_path ()); -} - - -// Does a checkup on the health of the main database. -// Optionally recreates it. -// Returns true if to be synced, else false. -bool Database_Notes::checkup () -{ - if (healthy ()) return false; - filter_url_unlink (database_path ()); - create (); - return true; -} - - -// Does a checkup on the health of the checksums database. -// Optionally recreates it. -// Returns true if to synced, else false. -bool Database_Notes::checkup_checksums () -{ - if (checksums_healthy ()) return false; - filter_url_unlink (checksums_database_path ()); - create (); - return true; -} - - -void Database_Notes::trim () -{ - // Clean empty directories. - string message = "Deleting empty notes folder "; - string main_folder = main_folder_path (); - vector bits1 = filter_url_scandir (main_folder); - for (auto bit1 : bits1) { - if (bit1.length () == 3) { - string folder1 = filter_url_create_path ({main_folder, bit1}); - vector bits2 = filter_url_scandir (folder1); - if (bits2.empty ()) { - Database_Logs::log (message + folder1); - remove (folder1.c_str ()); - } - for (auto bit2 : bits2) { - if (bit2.length () == 3) { - string folder2 = filter_url_create_path ({main_folder, bit1, bit2}); - vector bits3 = filter_url_scandir (folder2); - if (bits3.empty ()) { - Database_Logs::log (message + folder2); - remove (folder2.c_str()); - } - } - } - } - } -} - - -void Database_Notes::trim_server () -{ - // Notes expiry. - touch_marked_for_deletion (); - /// Storage for notes to be deleted. - vector identifiers; - // Deal with new notes storage in JSON. - identifiers = get_due_for_deletion (); - for (auto & identifier : identifiers) { - trash_consultation_note (m_webserver_request, identifier); - erase (identifier); - } -} - - -void Database_Notes::optimize () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_disconnect (db); -} - - -void Database_Notes::sync () -{ - string main_folder = main_folder_path (); - - // List of notes in the filesystem. - vector identifiers; - - vector bits1 = filter_url_scandir (main_folder); - for (auto & bit1 : bits1) { - // Bit 1 / 2 / 3 may start with a 0, so conversion to int cannot be used, rather use a length of 3. - // It used conversion to int before to determine it was a real note, - // with the result that it missed 10% of the notes, which subsequently got deleted, oops! - if (bit1.length () == 3) { - vector bits2 = filter_url_scandir (filter_url_create_path ({main_folder, bit1})); - for (auto & bit2 : bits2) { - // Old storage mechanism, e.g. folder "425". - if (bit2.length () == 3) { - vector bits3 = filter_url_scandir (filter_url_create_path ({main_folder, bit1, bit2})); - for (auto & bit3 : bits3) { - if (bit3.length () == 3) { - int identifier = filter::strings::convert_to_int (bit1 + bit2 + bit3); - identifiers.push_back (identifier); - update_search_fields (identifier); - } - } - } - // New JSON storage mechanism, e.g. file "894093.json". - if ((bit2.length () == 11) && bit2.find (".json") != std::string::npos) { - int identifier = filter::strings::convert_to_int (bit1 + bit2.substr (0,6)); - identifiers.push_back (identifier); - update_database (identifier); - update_search_fields (identifier); - update_checksum (identifier); - } - } - } - } - - // Get all identifiers in the main notes index. - sqlite3 * db = connect (); - vector database_identifiers; - vector result = database_sqlite_query (db, "SELECT identifier FROM notes;") ["identifier"]; - for (auto & id : result) { - database_identifiers.push_back (filter::strings::convert_to_int (id)); - } - database_sqlite_disconnect (db); - - // Any note identifiers in the main index, and not in the filesystem, remove them. - for (auto id : database_identifiers) { - if (find (identifiers.begin(), identifiers.end(), id) == identifiers.end()) { - trash_consultation_note (m_webserver_request, id); - erase (id); - } - } - - // Get all identifiers in the checksums database. - db = connect_checksums (); - database_identifiers.clear (); - result = database_sqlite_query (db, "SELECT identifier FROM checksums;") ["identifier"]; - for (auto & id : result) { - database_identifiers.push_back (filter::strings::convert_to_int (id)); - } - database_sqlite_disconnect (db); - - // Any note identifiers in the checksums database, and not in the filesystem, remove them. - for (auto id : database_identifiers) { - if (find (identifiers.begin(), identifiers.end(), id) == identifiers.end()) { - delete_checksum (id); - } - } - -} - - -void Database_Notes::update_database (int identifier) -{ - // Read the relevant values from the filesystem. - int modified = get_modified (identifier); - string assigned = get_field (identifier, assigned_key ()); - string subscriptions = get_field (identifier, subscriptions_key ()); - string bible = get_bible (identifier); - string passage = get_raw_passage (identifier); - string status = get_raw_status (identifier); - int severity = get_raw_severity (identifier); - string summary = get_summary (identifier); - string contents = get_contents (identifier); - - // Sync the values to the database. - update_database_internal (identifier, modified, assigned, subscriptions, bible, passage, status, severity, summary, contents); -} - - -void Database_Notes::update_database_internal (int identifier, int modified, string assigned, string subscriptions, string bible, string passage, string status, int severity, string summary, string contents) -{ - // Read the relevant values from the database. - // If all the values in the database are the same as the values in the filesystem, - // it means that the database is already in sync with the filesystem. - // Bail out in that case. - sqlite3 * db = connect (); - bool database_in_sync = true; - bool record_in_database = false; - SqliteSQL sql; - sql.add ("SELECT modified, assigned, subscriptions, bible, passage, status, severity, summary, contents FROM notes WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector vmodified = result ["modified"]; - vector vassigned = result ["assigned"]; - vector vsubscriptions = result ["subscriptions"]; - vector vbible = result ["bible"]; - vector vpassage = result ["passage"]; - vector vstatus = result ["status"]; - vector vseverity = result ["severity"]; - vector vsummary = result ["summary"]; - vector vcontents = result ["contents"]; - for (unsigned int i = 0; i < vmodified.size(); i++) { - record_in_database = true; - if (modified != filter::strings::convert_to_int (vmodified[i])) database_in_sync = false; - if (assigned != vassigned[i]) database_in_sync = false; - if (subscriptions != vsubscriptions[i]) database_in_sync = false; - if (bible != vbible [i]) database_in_sync = false; - if (passage != vpassage [i]) database_in_sync = false; - if (status != vstatus [i]) database_in_sync = false; - if (severity != filter::strings::convert_to_int (vseverity [i])) database_in_sync = false; - if (summary != vsummary [i]) database_in_sync = false; - if (contents != vcontents [i]) database_in_sync = false; - } - if (database_in_sync && record_in_database) return; - - // At this stage, the index needs to be brought in sync with the filesystem. - db = connect (); - - sql.clear (); - sql.add ("DELETE FROM notes WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - database_sqlite_exec (db, sql.sql); - - sql.clear (); - sql.add ("INSERT INTO notes (identifier, modified, assigned, subscriptions, bible, passage, status, severity, summary, contents) VALUES ("); - sql.add (identifier); - sql.add (","); - sql.add (modified); - sql.add (","); - sql.add (assigned); - sql.add (","); - sql.add (subscriptions); - sql.add (","); - sql.add (bible); - sql.add (","); - sql.add (passage); - sql.add (","); - sql.add (status); - sql.add (","); - sql.add (severity); - sql.add (","); - sql.add (summary); - sql.add (","); - sql.add (contents); - sql.add (")"); - database_sqlite_exec (db, sql.sql); - - database_sqlite_disconnect (db); -} - - -string Database_Notes::main_folder_path () -{ - return filter_url_create_root_path ({"consultations"}); -} - - -string Database_Notes::note_file (int identifier) -{ - // The maximum number of folders a folder may contain is constrained by the filesystem. - // To overcome this, the notes will be stored in a folder structure. - string sidentifier = filter::strings::convert_to_string (identifier); - string folder = sidentifier.substr (0, 3); - string file = sidentifier.substr (3, 6) + ".json"; - return filter_url_create_path ({main_folder_path (), folder, file}); -} - - -// This checks whether the note identifier exists. -// It works for the old way of storing notes in many files, -// and for the new way of storing notes in JSON. -bool Database_Notes::identifier_exists (int identifier) -{ - if (file_or_dir_exists (note_file (identifier))) return true; - return false; -} - - -// Update a note's identifier. -// new_identifier is the value given to the note identified by $identifier. -void Database_Notes::set_identifier (int identifier, int new_identifier) -{ - // Move data on the filesystem. - erase (new_identifier); - string path = note_file (identifier); - string json = filter_url_file_get_contents (path); - path = note_file (new_identifier); - string folder = filter_url_dirname (path); - filter_url_mkdir (folder); - filter_url_file_put_contents (path, json); - - // Update main notes database. - sqlite3 * db = connect (); - SqliteSQL sql; - sql.add ("UPDATE notes SET identifier ="); - sql.add (new_identifier); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - - // Update checksums database. - db = connect_checksums (); - sql.clear (); - sql.add ("UPDATE checksums SET identifier ="); - sql.add (new_identifier); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - - // Update the range-based checksum also. - Database_State::eraseNoteChecksum (identifier); - - // Remove old identifier that was copied to the new. - erase (identifier); -} - - -// Gets new unique note identifier. -// Works for the old and new storage system. -int Database_Notes::get_new_unique_identifier () -{ - int identifier = 0; - do { - identifier = filter::strings::rand (Notes_Logic::lowNoteIdentifier, Notes_Logic::highNoteIdentifier); - } while (identifier_exists (identifier)); - return identifier; -} - - -vector Database_Notes::get_identifiers () -{ - sqlite3 * db = connect (); - vector identifiers; - vector result = database_sqlite_query (db, "SELECT identifier FROM notes;") ["identifier"]; - for (auto & id : result) { - identifiers.push_back (filter::strings::convert_to_int (id)); - } - database_sqlite_disconnect (db); - return identifiers; -} - - -string Database_Notes::assemble_contents (int identifier, string contents) -{ - string new_contents = get_contents (identifier); - string datetime = filter::date::localized_date_format (m_webserver_request); - string user = m_webserver_request.session_logic ()->currentUser (); - // To make the notes more readable, add whitespace between the comments. - bool is_initial_comment = new_contents.empty (); - if (!is_initial_comment) { - new_contents.append ("\n"); - new_contents.append ("
\n"); - } - // Put the user and date in bold, for extra clarity. - new_contents.append ("

"); - new_contents.append (user); - new_contents.append (" ("); - new_contents.append (datetime); - new_contents.append ("):

\n"); - // Add the note body. - if (contents == "
") contents.clear(); - vector lines = filter::strings::explode (contents, '\n'); - for (auto line : lines) { - line = filter::strings::trim (line); - new_contents.append ("

"); - new_contents.append (line); - new_contents.append ("

\n"); - } - return new_contents; -} - - -// Store a new consultation note into the database and in JSON. -// bible: The notes's Bible. -// book, chapter, verse: The note's passage. -// summary: The note's summary. -// contents: The note's contents. -// raw: Import contents as it is. -// It returns the identifier of this new note. -int Database_Notes::store_new_note (const string& bible, int book, int chapter, int verse, string summary, string contents, bool raw) -{ - // Create a new identifier. - int identifier = get_new_unique_identifier (); - - // Passage. - string passage = encode_passage (book, chapter, verse); - - string status = "New"; - int severity = 2; - - // If the summary is not given, take the first line of the contents as the summary. - if (summary == "") { - // The notes editor does not put new lines at each line, but instead
s. Handle these also. - summary = filter::strings::replace ("<", "\n", contents); - vector bits = filter::strings::explode (summary, '\n'); - if (!bits.empty ()) summary = bits [0]; - } - - // Assemble contents. - if (!raw) contents = assemble_contents (identifier, contents); - if ((contents.empty()) && (summary.empty())) return 0; - - // Store the JSON representation of the note in the file system. - string path = note_file (identifier); - string folder = filter_url_dirname (path); - filter_url_mkdir (folder); - Object note; - note << bible_key () << bible; - note << passage_key () << passage; - note << status_key () << status; - note << severity_key () << filter::strings::convert_to_string (severity); - note << summary_key () << summary; - note << contents_key () << contents; - string json = note.json (); - filter_url_file_put_contents (path, json); - - // Store new default note into the database. - sqlite3 * db = connect (); - SqliteSQL sql; - sql.add ("INSERT INTO notes (identifier, modified, assigned, subscriptions, bible, passage, status, severity, summary, contents) VALUES ("); - sql.add (identifier); - sql.add (", 0, '', '',"); - sql.add (bible); - sql.add (","); - sql.add (passage); - sql.add (","); - sql.add (status); - sql.add (","); - sql.add (severity); - sql.add (","); - sql.add (summary); - sql.add (","); - sql.add (contents); - sql.add (")"); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - - // Updates. - update_search_fields (identifier); - note_modified_actions (identifier); - - // Return this new note´s identifier. - return identifier; -} - - -// Returns an array of note identifiers selected. -// bibles: Array of Bible names the user has read access to. -// book, chapter, verse, passage_selector: These are related and can limit the selection. -// edit_selector: Optionally constrains selection based on modification time. -// non_edit_selector: Optionally constrains selection based on modification time. -// status_selector: Optionally constrains selection based on note status. -// bible_selector: Optionally constrains the selection, based on the note's Bible. -// assignment_selector: Optionally constrains the selection based on a note being assigned to somebody. -// subscription_selector: Optionally limits the selection based on a note's subscription. -// severity_selector: Optionally limits the selection, based on a note's severity. -// text_selector: Optionally limits the selection to notes that contains certain text. Used for searching notes. -// search_text: Works with text_selector, contains the text to search for. -// limit: If >= 0, it indicates the starting limit for the selection. -vector Database_Notes::select_notes (vector bibles, int book, int chapter, int verse, int passage_selector, int edit_selector, int non_edit_selector, const string& status_selector, string bible_selector, string assignment_selector, bool subscription_selector, int severity_selector, int text_selector, const string& search_text, int limit) -{ - string username = m_webserver_request.session_logic ()->currentUser (); - vector identifiers; - // SQL SELECT statement. - string query = notes_select_identifier (); - // SQL optional fulltext search statement sorted on relevance. - if (text_selector == 1) { - query.append (notes_optional_fulltext_search_relevance_statement (search_text)); - } - // SQL FROM ... WHERE statement. - query.append (notes_from_where_statement ()); - // Consider passage selector. - string passage; - switch (passage_selector) { - case 0: - // Select notes that refer to the current verse. - // It means that the book, the chapter, and the verse, should match. - passage = encode_passage (book, chapter, verse); - query.append (" AND passage LIKE '%" + passage + "%' "); - break; - case 1: - // Select notes that refer to the current chapter. - // It means that the book and the chapter should match. - passage = encode_passage (book, chapter, -1); - query.append (" AND passage LIKE '%" + passage + "%' "); - break; - case 2: - // Select notes that refer to the current book. - // It means that the book should match. - passage = encode_passage (book, -1, -1); - query.append (" AND passage LIKE '%" + passage + "%' "); - break; - case 3: - // Select notes that refer to any passage: No constraint to apply here. - break; - default: break; - } - // Consider edit selector. - int time { 0 }; - switch (edit_selector) { - case 0: - // Select notes that have been edited at any time. Apply no constraint. - time = 0; - break; - case 1: - // Select notes that have been edited during the last 30 days. - time = filter::date::seconds_since_epoch () - 30 * 24 * 3600; - break; - case 2: - // Select notes that have been edited during the last 7 days. - time = filter::date::seconds_since_epoch () - 7 * 24 * 3600; - break; - case 3: - // Select notes that have been edited since yesterday. - time = filter::date::seconds_since_epoch () - 1 * 24 * 3600 - filter::date::numerical_hour (filter::date::seconds_since_epoch ()) * 3600; - break; - case 4: - // Select notes that have been edited today. - time = filter::date::seconds_since_epoch () - filter::date::numerical_hour (filter::date::seconds_since_epoch ()) * 3600; - break; - default: break; - } - if (time != 0) { - query.append (" AND modified >= "); - query.append (filter::strings::convert_to_string (time)); - query.append (" "); - } - // Consider non-edit selector. - int nonedit { 0 }; - switch (non_edit_selector) { - case 0: - // Select notes that have not been edited at any time. Apply no constraint. - nonedit = 0; - break; - case 1: - // Select notes that have not been edited for a day. - nonedit = filter::date::seconds_since_epoch () - 1 * 24 * 3600; - break; - case 2: - // Select notes that have not been edited for two days. - nonedit = filter::date::seconds_since_epoch () - 2 * 24 * 3600; - break; - case 3: - // Select notes that have not been edited for a week. - nonedit = filter::date::seconds_since_epoch () - 7 * 24 * 3600; - break; - case 4: - // Select notes that have not been edited for a month. - nonedit = filter::date::seconds_since_epoch () - 30 * 24 * 3600; - break; - case 5: - // Select notes that have not been edited for a year. - nonedit = filter::date::seconds_since_epoch () - 365 * 24 * 3600; - break; - default: break; - } - if (nonedit != 0) { - query.append (" AND modified <= "); - query.append (filter::strings::convert_to_string (nonedit)); - query.append (" "); - } - // Consider status constraint. - if (status_selector != "") { - query.append (" AND status = '"); - query.append (database_sqlite_no_sql_injection (status_selector)); - query.append ("' "); - } - // Consider two different Bible constraints: - // 1. The vector of bibles: "bibles". - // This contains all the Bibles a user has access to, so only notes that refer to any Bible in this lot are going to be selected. - // 2. The string "bible_selector". - // If this is left empty, then it selects notes that refer to Bibles in the vector above. - // If this contains a Bible, then it selects notes that refer to this Bible. - // In addition to the above two selectors, it always selects note that refer to any Bible. - if (!bible_selector.empty()) { - bibles.clear (); - bibles.push_back (bible_selector); - } - if (!bibles.empty ()) { - query.append (" AND (bible = '' "); - for (auto bible : bibles) { - bible = database_sqlite_no_sql_injection (bible); - query.append (" OR bible = '"); - query.append (bible); - query.append ("' "); - } - query.append (" ) "); - } - // Consider note assignment constraints. - if (assignment_selector != "") { - assignment_selector = database_sqlite_no_sql_injection (assignment_selector); - query.append (" AND assigned LIKE '% "); - query.append (assignment_selector); - query.append (" %' "); - } - // Consider note subscription constraints. - if (subscription_selector) { - query.append (" AND subscriptions LIKE '% "); - query.append (username); - query.append (" %' "); - } - // Consider the note severity. - if (severity_selector != -1) { - query.append (" AND severity = "); - query.append (filter::strings::convert_to_string (severity_selector)); - query.append (" "); - } - // Consider text contained in notes. - if (text_selector == 1) { - query.append (notes_optional_fulltext_search_statement (search_text)); - } - if (text_selector == 1) { - // If searching in fulltext mode, notes get ordered on relevance of search hits. - query.append (notes_order_by_relevance_statement ()); - } else { - // Notes get ordered by the passage they refer to. It is a rough method and better ordering is needed. - query.append (" ORDER BY ABS (passage) "); - } - // Limit the selection if a limit is given. - if (limit >= 0) { - query.append (" LIMIT "); - query.append (filter::strings::convert_to_string (limit)); - query.append (", 50 "); - } - query.append (";"); - - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, query) ["identifier"]; - database_sqlite_disconnect (db); - for (auto & id : result) { - identifiers.push_back (filter::strings::convert_to_int (id)); - } - return identifiers; -} - - -string Database_Notes::get_summary (int identifier) -{ - return get_field (identifier, summary_key ()); -} - - -void Database_Notes::set_summary (int identifier, const string& summary) -{ - // Store authoritative copy in the filesystem. - set_field (identifier, summary_key (), summary); - // Update the shadow database. - SqliteSQL sql; - sql.add ("UPDATE notes SET summary ="); - sql.add (summary); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - // Update the search data in the database. - update_search_fields (identifier); - // Update checksum. - update_checksum (identifier); -} - - -string Database_Notes::get_contents (int identifier) -{ - return get_field (identifier, contents_key ()); -} - - -void Database_Notes::set_raw_contents (int identifier, const string& contents) -{ - set_field (identifier, contents_key (), contents); -} - - -void Database_Notes::set_contents (int identifier, const string& contents) -{ - // Store in file system. - set_raw_contents (identifier, contents); - // Update database. - SqliteSQL sql; - sql.add ("UPDATE notes SET contents ="); - sql.add (contents); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - // Update search system. - update_search_fields (identifier); - // Update checksum. - update_checksum (identifier); -} - - -// Erases a note stored in the old and in the new format. -void Database_Notes::erase (int identifier) -{ - // Delete new storage from filesystem. - string path = note_file (identifier); - filter_url_unlink (path); - // Update databases as well. - delete_checksum (identifier); - SqliteSQL sql; - sql.add ("DELETE FROM notes WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Add a comment to an exiting note identified by $identifier. -void Database_Notes::add_comment (int identifier, const string& comment) -{ - // Assemble the new content and store it. - // This updates the search database also. - string contents = assemble_contents (identifier, comment); - set_contents (identifier, contents); - - // Some triggers. - note_modified_actions (identifier); - unmark_for_deletion (identifier); - - // Update shadow database. - SqliteSQL sql; - sql.add ("UPDATE notes SET contents ="); - sql.add (contents); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Subscribe the current user to the note identified by identifier. -void Database_Notes::subscribe (int identifier) -{ - string user = m_webserver_request.session_logic ()->currentUser (); - subscribe_user (identifier, user); -} - - -// Subscribe the user to the note identified by identifier. -void Database_Notes::subscribe_user (int identifier, const string& user) -{ - // If the user already is subscribed to the note, bail out. - vector subscribers = get_subscribers (identifier); - if (find (subscribers.begin(), subscribers.end(), user) != subscribers.end()) return; - // Subscribe user. - subscribers.push_back (user); - set_subscribers (identifier, subscribers); -} - - -// Returns an array with the subscribers to the note identified by identifier. -vector Database_Notes::get_subscribers (int identifier) -{ - string contents = get_raw_subscriptions (identifier); - if (contents.empty()) return {}; - vector subscribers = filter::strings::explode (contents, '\n'); - for (auto & subscriber : subscribers) { - subscriber = filter::strings::trim (subscriber); - } - return subscribers; -} - - -string Database_Notes::get_raw_subscriptions (int identifier) -{ - return get_field (identifier, subscriptions_key ()); -} - - -void Database_Notes::set_raw_subscriptions (int identifier, const string& subscriptions) -{ - // Store them in the filesystem. - set_field (identifier, subscriptions_key (), subscriptions); - - // Store them in the database as well. - SqliteSQL sql; - sql.add ("UPDATE notes SET subscriptions ="); - sql.add (subscriptions); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -void Database_Notes::set_subscribers (int identifier, vector subscribers) -{ - // Add a space at both sides of the subscriber to allow for easier note selection based on note assignment. - for (auto & subscriber : subscribers) { - subscriber.insert (0, " "); - subscriber.append (" "); - } - string subscriberstring = filter::strings::implode (subscribers, "\n"); - - // Store them to file and in the database. - set_raw_subscriptions (identifier, subscriberstring); - - // Checksum. - update_checksum (identifier); -} - - -// Returns true if user is subscribed to the note identified by identifier. -bool Database_Notes::is_subscribed (int identifier, const string& user) -{ - vector subscribers = get_subscribers (identifier); - return find (subscribers.begin(), subscribers.end(), user) != subscribers.end(); -} - - -// Unsubscribes the currently logged in user from the note identified by identifier. -void Database_Notes::unsubscribe (int identifier) -{ - string user = m_webserver_request.session_logic ()->currentUser (); - unsubscribe_user (identifier, user); -} - - -// Unsubscribes user from the note identified by identifier. -void Database_Notes::unsubscribe_user (int identifier, const string& user) -{ - // If the user is not subscribed to the note, bail out. - vector subscribers = get_subscribers (identifier); - if (find (subscribers.begin(), subscribers.end(), user) == subscribers.end()) return; - // Unsubscribe user. - subscribers.erase (remove (subscribers.begin(), subscribers.end(), user), subscribers.end()); - set_subscribers (identifier, subscribers); -} - - -string Database_Notes::get_raw_assigned (int identifier) -{ - // Get the asssignees from the filesystem. - return get_field (identifier, assigned_key ()); -} - - -void Database_Notes::set_raw_assigned (int identifier, const string& assigned) -{ - // Store the assignees in the filesystem. - set_field (identifier, assigned_key (), assigned); - - // Store the assignees in the database also. - SqliteSQL sql; - sql.add ("UPDATE notes SET assigned ="); - sql.add (assigned); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Returns an array with all assignees to the notes selection. -// These are the usernames to which one or more notes have been assigned. -// This means that if no notes have been assigned to anybody, it will return an empty array. -// Normally the authoritative copy of the notes is stored in the file system. -// But as retrieving the assignees from the file system would be slow, -// this function retrieves them from the database. -// Normally the database is in sync with the filesystem. -vector Database_Notes::get_all_assignees (const vector & bibles) -{ - set unique_assignees; - SqliteSQL sql; - sql.add ("SELECT DISTINCT assigned FROM notes WHERE bible = ''"); - for (auto & bible : bibles) { - sql.add ("OR bible ="); - sql.add (bible); - } - sql.add (";"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["assigned"]; - for (auto & item : result) { - if (item.empty ()) continue; - vector names = filter::strings::explode (item, '\n'); - for (auto & name : names) unique_assignees.insert (name); - } - database_sqlite_disconnect (db); - - vector assignees (unique_assignees.begin(), unique_assignees.end()); - for (auto & assignee : assignees) { - assignee = filter::strings::trim (assignee); - } - return assignees; -} - - -// Returns an array with the assignees to the note identified by identifier. -vector Database_Notes::get_assignees (int identifier) -{ - // Get the asssignees from the filesystem. - string assignees = get_raw_assigned (identifier); - return get_assignees_internal (assignees); -} - - -vector Database_Notes::get_assignees_internal (string assignees) -{ - if (assignees.empty ()) return {}; - vector assignees_vector = filter::strings::explode (assignees, '\n'); - // Remove the padding space at both sides of the assignee. - for (auto & assignee : assignees_vector) { - assignee = filter::strings::trim (assignee); - } - return assignees_vector; -} - - -// Sets the note's assignees. -// identifier : note identifier. -// assignees : array of user names. -void Database_Notes::set_assignees (int identifier, vector assignees) -{ - // Add a space at both sides of the assignee to allow for easier note selection based on note assignment. - for (auto & assignee : assignees) { - assignee.insert (0, " "); - assignee.append (" "); - } - string assignees_string = filter::strings::implode (assignees, "\n"); - set_raw_assigned (identifier, assignees_string); - note_modified_actions (identifier); -} - - -// Assign the note identified by identifier to user. -void Database_Notes::assign_user (int identifier, const string& user) -{ - // If the note already is assigned to the user, bail out. - vector assignees = get_assignees (identifier); - if (find (assignees.begin (), assignees.end(), user) != assignees.end()) return; - // Assign the note to the user. - assignees.push_back (user); - // Store the whole lot. - set_assignees (identifier, assignees); -} - - -// Returns true if the note identified by identifier has been assigned to user. -bool Database_Notes::is_assigned (int identifier, const string& user) -{ - vector assignees = get_assignees (identifier); - return find (assignees.begin(), assignees.end(), user) != assignees.end(); -} - - -// Unassigns user from the note identified by identifier. -void Database_Notes::unassign_user (int identifier, const string& user) -{ - // If the note is not assigned to the user, bail out. - vector assignees = get_assignees (identifier); - if (find (assignees.begin(), assignees.end(), user) == assignees.end()) return; - // Remove assigned user. - assignees.erase (remove (assignees.begin(), assignees.end(), user), assignees.end()); - set_assignees (identifier, assignees); -} - - -string Database_Notes::get_bible (int identifier) -{ - return get_field (identifier, bible_key ()); -} - - -void Database_Notes::set_bible (int identifier, const string& bible) -{ - // Write the bible to the filesystem. - set_field (identifier, bible_key (), bible); - - // Update the database also. - SqliteSQL sql; - sql.add ("UPDATE notes SET bible ="); - sql.add (bible); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - - note_modified_actions (identifier); -} - - -vector Database_Notes::get_all_bibles () -{ - vector bibles; - sqlite3 * db = connect (); - vector identifiers; - vector result = database_sqlite_query (db, "SELECT DISTINCT bible FROM notes;") ["bible"]; - for (auto & bible : result) { - if (bible.empty ()) continue; - bibles.push_back (bible); - } - database_sqlite_disconnect (db); - return bibles; -} - - -// Encodes the book, chapter and verse, like to, e.g.: "40.5.13", -// and returns this as a string. -// The chapter and the verse can be negative, in which case they won't be included. -string Database_Notes::encode_passage (int book, int chapter, int verse) -{ - // Space before and after the passage enables notes selection on passage. - // Special way of encoding, as done below, is to enable note selection on book / chapter / verse. - string passage; - passage.append (" "); - passage.append (filter::strings::convert_to_string (book)); - passage.append ("."); - // Whether to include the chapter number. - if (chapter >= 0) { - passage.append (filter::strings::convert_to_string (chapter)); - passage.append ("."); - // Inclusion of verse, also depends on chapter inclusion. - if (verse >= 0) { - passage.append (filter::strings::convert_to_string (verse)); - passage.append (" "); - } - } - return passage; -} - - -// Takes the passage as a string, and returns an object with book, chapter, and verse. -Passage Database_Notes::decode_passage (string passage) -{ - passage = filter::strings::trim (passage); - Passage decodedpassage = Passage (); - vector lines = filter::strings::explode (passage, '.'); - if (lines.size() > 0) decodedpassage.m_book = filter::strings::convert_to_int (lines[0]); - if (lines.size() > 1) decodedpassage.m_chapter = filter::strings::convert_to_int (lines[1]); - if (lines.size() > 2) decodedpassage.m_verse = lines[2]; - return decodedpassage; -} - - -// Returns the raw passage text of the note identified by identifier. -string Database_Notes::decode_passage (int identifier) -{ - return get_raw_passage (identifier); -} - - -// Returns the raw passage text of the note identified by identifier. -string Database_Notes::get_raw_passage (int identifier) -{ - return get_field (identifier, passage_key ()); -} - - -// Returns an array with the passages that the note identified by identifier refers to. -// Each passages is an array (book, chapter, verse). -vector Database_Notes::get_passages (int identifier) -{ - string contents = get_raw_passage (identifier); - if (contents.empty()) return {}; - vector lines = filter::strings::explode (contents, '\n'); - vector passages; - for (auto & line : lines) { - if (line.empty()) continue; - Passage passage = decode_passage (line); - passages.push_back (passage); - } - return passages; -} - - -// Set the passages for note identifier. -// passages is an array of an array (book, chapter, verse) passages. -// import: If true, just write passages, no further actions. -void Database_Notes::set_passages (int identifier, const vector & passages, bool import) -{ - // Format the passages. - string line; - for (auto & passage : passages) { - if (!line.empty ()) line.append ("\n"); - line.append (encode_passage (passage.m_book, passage.m_chapter, filter::strings::convert_to_int (passage.m_verse))); - } - // Store it. - set_raw_passage (identifier, line); - - // Update index. - index_raw_passage (identifier, line); - - if (!import) note_modified_actions (identifier); -} - - -// Sets the raw $passage(s) for a note $identifier. -// The reason for having this function is this: -// There is a slight difference in adding a new line or not to the passage -// between Bibledit as it was written in PHP, -// and Bibledit as it is now written in C++. -// Due to this difference, when a client downloads a note from the server, -// it should download the exact passage file contents as it is on the server, -// so as to prevent keeping to download the same notes over and over, -// due to the above mentioned difference in adding a new line or not. -void Database_Notes::set_raw_passage (int identifier, const string& passage) -{ - // Store the authoritative copy in the filesystem. - set_field (identifier, passage_key (), passage); -} - - -void Database_Notes::index_raw_passage (int identifier, const string& passage) -{ - // Update the search index database. - SqliteSQL sql; - sql.add ("UPDATE notes SET passage ="); - sql.add (passage); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - -} - - -// Gets the raw status of a note. -// Returns it as a string. -string Database_Notes::get_raw_status (int identifier) -{ - return get_field (identifier, status_key ()); -} - - -// Gets the localized status of a note. -// Returns it as a string. -string Database_Notes::get_status (int identifier) -{ - string status = get_raw_status (identifier); - // Localize status if possible. - status = translate (status.c_str()); - // Return status. - return status; -} - - -// Sets the status of the note identified by identifier. -// status is a string. -// import: Just write the status, and skip any logic. -void Database_Notes::set_status (int identifier, const string& status, bool import) -{ - // Store the authoritative copy in the filesystem. - set_field (identifier, status_key (), status); - - if (!import) note_modified_actions (identifier); - - // Store a copy in the database also. - SqliteSQL sql; - sql.add ("UPDATE notes SET status ="); - sql.add (status); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Gets an array of array with the possible statuses of consultation notes, -// both raw and localized versions. -vector Database_Notes::get_possible_statuses () -{ - // Get an array with the statuses used in the database, ordered by occurrence, most often used ones first. - string query = "SELECT status, COUNT(status) AS occurrences FROM notes GROUP BY status ORDER BY occurrences DESC;"; - sqlite3 * db = connect (); - vector statuses = database_sqlite_query (db, query) ["status"]; - database_sqlite_disconnect (db); - // Ensure the standard statuses are there too. - vector standard_statuses = {"New", "Pending", "In progress", "Done", "Reopened"}; - for (auto & standard_status : standard_statuses) { - if (find (statuses.begin(), statuses.end(), standard_status) == statuses.end()) { - statuses.push_back (standard_status); - } - } - // Localize the results. - vector localized_statuses; - for (auto & status : statuses) { - string localization = translate (status.c_str()); - Database_Notes_Text localized_status; - localized_status.raw = status; - localized_status.localized = localization; - localized_statuses.push_back (localized_status); - } - // Return result. - return localized_statuses; -} - - -vector Database_Notes::standard_severities () -{ - return {"Wish", "Minor", "Normal", "Important", "Major", "Critical"}; -} - - -// Returns the severity of a note as a number. -int Database_Notes::get_raw_severity (int identifier) -{ - string severity = get_field (identifier, severity_key ()); - if (severity.empty ()) return 2; - return filter::strings::convert_to_int (severity); -} - - -// Returns the severity of a note as a localized string. -string Database_Notes::get_severity (int identifier) -{ - int severity = get_raw_severity (identifier); - vector standard = standard_severities (); - string severitystring; - if ((severity >= 0) && (severity < static_cast(standard.size()))) severitystring = standard [static_cast (severity)]; - if (severitystring.empty()) severitystring = "Normal"; - severitystring = translate (severitystring.c_str()); - return severitystring; -} - - -// Sets the severity of the note identified by identifier. -// severity is a number. -void Database_Notes::set_raw_severity (int identifier, int severity) -{ - // Update the file system. - set_field (identifier, severity_key (), filter::strings::convert_to_string (severity)); - - note_modified_actions (identifier); - - // Update the database also. - SqliteSQL sql; - sql.add ("UPDATE notes SET severity ="); - sql.add (severity); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Gets an array with the possible severities. -vector Database_Notes::get_possible_severities () -{ - vector standard = standard_severities (); - vector severities; - for (size_t i = 0; i < standard.size(); i++) { - Database_Notes_Text severity; - severity.raw = filter::strings::convert_to_string (i); - severity.localized = translate (standard[i].c_str()); - severities.push_back (severity); - } - return severities; -} - - -int Database_Notes::get_modified (int identifier) -{ - string modified = get_field (identifier, modified_key ()); - if (modified.empty ()) return 0; - return filter::strings::convert_to_int (modified); -} - - -void Database_Notes::set_modified (int identifier, int time) -{ - // Update the filesystem. - set_field (identifier, modified_key (), filter::strings::convert_to_string (time)); - // Update the database. - SqliteSQL sql; - sql.add ("UPDATE notes SET modified ="); - sql.add (time); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - // Update checksum. - update_checksum (identifier); -} - - -bool Database_Notes::get_public (int identifier) -{ - string value = get_field (identifier, public_key ()); - return filter::strings::convert_to_bool (value); -} - - -void Database_Notes::set_public (int identifier, bool value) -{ - set_field (identifier, public_key (), filter::strings::convert_to_string (value)); -} - - -// Takes actions when a note has been edited. -void Database_Notes::note_modified_actions (int identifier) -{ - // Update 'modified' field. - set_modified (identifier, filter::date::seconds_since_epoch()); -} - - -void Database_Notes::update_search_fields (int identifier) -{ - // The search field is a combination of the summary and content converted to clean text. - // It enables us to search with wildcards before and after the search query. - string noteSummary = get_summary (identifier); - string noteContents = get_contents (identifier); - string cleanText = noteSummary + "\n" + filter::strings::html2text (noteContents); - // Bail out if the search field is already up to date. - if (cleanText == get_search_field (identifier)) return; - // Update the field. - SqliteSQL sql; - sql.add ("UPDATE notes SET cleantext ="); - sql.add (cleanText); - sql.add ("WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -string Database_Notes::get_search_field (int identifier) -{ - SqliteSQL sql; - sql.add ("SELECT cleantext FROM notes WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, sql.sql) ["cleantext"]; - database_sqlite_disconnect (db); - string value; - for (auto & cleantext : result) { - value = cleantext; - } - return value; -} - - -// Searches the notes. -// Returns an array of note identifiers. -// search: Contains the text to search for. -// bibles: Array of Bibles the notes should refer to. -vector Database_Notes::search_notes (string search, const vector & bibles) -{ - vector identifiers; - - search = filter::strings::trim (search); - if (search == "") return identifiers; - - // SQL SELECT statement. - string query = notes_select_identifier (); - - // SQL fulltext search statement sorted on relevance. - query.append (notes_optional_fulltext_search_relevance_statement (search)); - - // SQL FROM ... WHERE statement. - query.append (notes_from_where_statement ()); - - // Consider text contained in notes. - query.append (notes_optional_fulltext_search_statement (search)); - - // Consider Bible constraints: - // * A user has access to notes that refer to Bibles the user has access to. - // * A note can be a general one, not referring to any specific Bible. - // Select such notes also. - query.append (" AND (bible = '' "); - for (string bible : bibles) { - bible = database_sqlite_no_sql_injection (bible); - query.append (" OR bible = '"); - query.append (bible); - query.append ("' "); - } - query.append (" ) "); - - // Notes get ordered on relevance of search hits. - query.append (notes_order_by_relevance_statement ()); - - // Complete query. - query.append (";"); - - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, query) ["identifier"]; - database_sqlite_disconnect (db); - for (auto & id : result) { - identifiers.push_back (filter::strings::convert_to_int (id)); - } - - return identifiers; -} - - -void Database_Notes::mark_for_deletion (int identifier) -{ - // Delete after 7 days. - set_field (identifier, expiry_key (), "7"); -} - - -void Database_Notes::unmark_for_deletion (int identifier) -{ - set_field (identifier, expiry_key (), ""); -} - - -bool Database_Notes::is_marked_for_deletion (int identifier) -{ - string expiry = get_field (identifier, expiry_key ()); - return !expiry.empty (); -} - - -void Database_Notes::touch_marked_for_deletion () -{ - vector identifiers = get_identifiers (); - for (auto & identifier : identifiers) { - if (is_marked_for_deletion (identifier)) { - string expiry = get_field (identifier, expiry_key ()); - int days = filter::strings::convert_to_int (expiry); - days--; - set_field (identifier, expiry_key (), filter::strings::convert_to_string (days)); - } - } -} - - -vector Database_Notes::get_due_for_deletion () -{ - vector deletes; - vector identifiers = get_identifiers (); - for (auto & identifier : identifiers) { - if (is_marked_for_deletion (identifier)) { - string sdays = get_field (identifier, expiry_key ()); - int idays = filter::strings::convert_to_int (sdays); - if ((sdays == "0") || (idays < 0)) { - deletes.push_back (identifier); - } - } - } - return deletes; -} - - -// Writes the checksum for note identifier in the database. -void Database_Notes::set_checksum (int identifier, const string & checksum) -{ - // Do not write the checksum if it is already up to date. - if (checksum == get_checksum (identifier)) return; - // Write the checksum to the database. - delete_checksum (identifier); - SqliteSQL sql; - sql.add ("INSERT INTO checksums VALUES ("); - sql.add (identifier); - sql.add (","); - sql.add (checksum); - sql.add (");"); - sqlite3 * db = connect_checksums (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Reads the checksum for note identifier from the database. -string Database_Notes::get_checksum (int identifier) -{ - SqliteSQL sql; - sql.add ("SELECT checksum FROM checksums WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect_checksums (); - vector result = database_sqlite_query (db, sql.sql) ["checksum"]; - database_sqlite_disconnect (db); - string value; - for (auto & row : result) { - value = row; - } - return value; -} - - -// Deletes the checksum for note identifier from the database. -void Database_Notes::delete_checksum (int identifier) -{ - SqliteSQL sql; - sql.add ("DELETE FROM checksums WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - sqlite3 * db = connect_checksums (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - // Delete from range-based checksums. - Database_State::eraseNoteChecksum (identifier); -} - - -// The function calculates the checksum of the note signature, -// and writes it to the filesystem. -void Database_Notes::update_checksum (int identifier) -{ - // Read the raw data from disk to speed up checksumming. - string checksum; - checksum.append ("modified"); - checksum.append (get_field (identifier, modified_key ())); - checksum.append ("assignees"); - checksum.append (get_field (identifier, assigned_key ())); - checksum.append ("subscribers"); - checksum.append (get_field (identifier, subscriptions_key ())); - checksum.append ("bible"); - checksum.append (get_field (identifier, bible_key ())); - checksum.append ("passages"); - checksum.append (get_field (identifier, passage_key ())); - checksum.append ("status"); - checksum.append (get_field (identifier, status_key ())); - checksum.append ("severity"); - checksum.append (get_field (identifier, severity_key ())); - checksum.append ("summary"); - checksum.append (get_field (identifier, summary_key ())); - checksum.append ("contents"); - checksum.append (get_field (identifier, contents_key ())); - checksum = md5 (checksum); - set_checksum (identifier, checksum); -} - - -// Queries the database for the checksum for the notes given in the list of $identifiers. -string Database_Notes::get_multiple_checksum (const vector & identifiers) -{ - sqlite3 * db = connect_checksums (); - string checksum; - for (auto & identifier : identifiers) { - SqliteSQL sql; - sql.add ("SELECT checksum FROM checksums WHERE identifier ="); - sql.add (identifier); - sql.add (";"); - vector result = database_sqlite_query (db, sql.sql) ["checksum"]; - string value = ""; - for (auto & row : result) { - value = row; - } - checksum.append (value); - } - database_sqlite_disconnect (db); - checksum = md5 (checksum); - return checksum; -} - - -// This function gets the identifiers for notes -// within the note identifier range of lowId to highId -// which refer to any Bible in the array of bibles -// or refer to no Bible. -vector Database_Notes::get_notes_in_range_for_bibles (int lowId, int highId, vector bibles, bool anybible) -{ - vector identifiers; - - string query = "SELECT identifier FROM notes WHERE identifier >= "; - query.append (filter::strings::convert_to_string (lowId)); - query.append (" AND identifier <= "); - query.append (filter::strings::convert_to_string (highId)); - query.append (" "); - if (!anybible) { - bibles.push_back (""); // Select general note also - string bibleSelector = " AND ("; - for (unsigned int i = 0; i < bibles.size(); i++) { - bibles[i] = database_sqlite_no_sql_injection (bibles[i]); - if (i > 0) bibleSelector.append (" OR "); - bibleSelector.append (" bible = '"); - bibleSelector.append (bibles[i]); - bibleSelector.append ("' "); - } - bibleSelector.append (")"); - query.append (bibleSelector); - } - query.append (" ORDER BY identifier;"); - - sqlite3 * db = connect (); - vector result = database_sqlite_query (db, query) ["identifier"]; - database_sqlite_disconnect (db); - for (auto & row : result) { - identifiers.push_back (filter::strings::convert_to_int (row)); - } - - return identifiers; -} - - -string Database_Notes::availability_flag () -{ - return filter_url_create_root_path ({database_logic_databases (), "notes.busy"}); -} - - -// Sets whether the notes databases are available, as a boolean. -void Database_Notes::set_availability (bool available) -{ - if (available) { - filter_url_unlink (availability_flag ()); - } else { - filter_url_file_put_contents (availability_flag (), ""); - } -} - - -// Returns whether the notes databases are available, as a boolean. -bool Database_Notes::available () -{ - return !file_or_dir_exists (availability_flag ()); -} - - -string Database_Notes::notes_select_identifier () -{ - return " SELECT identifier "; -} - - -string Database_Notes::notes_optional_fulltext_search_relevance_statement (string search) -{ - if (search == "") return ""; - search = filter::strings::replace (",", "", search); - search = database_sqlite_no_sql_injection (search); - string query = ""; - return query; -} - - -string Database_Notes::notes_from_where_statement () -{ - return " FROM notes WHERE 1 "; -} - - -string Database_Notes::notes_optional_fulltext_search_statement (string search) -{ - if (search == "") return ""; - search = filter::strings::replace (",", "", search); - search = database_sqlite_no_sql_injection (search); - string query = " AND cleantext LIKE '%" + search + "%' "; - return query; -} - - -string Database_Notes::notes_order_by_relevance_statement () -{ - return ""; -} - - -// This returns JSON that contains the notes indicated by $identifiers. -string Database_Notes::get_bulk (vector identifiers) -{ - // JSON container for the bulk notes. - Array bulk; - // Go through all the notes. - for (auto identifier : identifiers) { - // JSON object for the note. - Object note; - // Add all the fields of the note. - string assigned = get_field (identifier, assigned_key ()); - note << "a" << assigned; - string bible = get_bible (identifier);; - note << "b" << bible; - string contents = get_contents (identifier); - note << "c" << contents; - note << "i" << identifier; - int modified = get_modified (identifier); - note << "m" << modified; - string passage = get_raw_passage (identifier); - note << "p" << passage; - string subscriptions = get_field (identifier, subscriptions_key ()); - note << "sb" << subscriptions; - string summary; - summary = get_summary (identifier); - note << "sm" << summary; - string status; - status = get_raw_status (identifier); - note << "st" << status; - int severity = get_raw_severity (identifier); - note << "sv" << severity; - // Add the note to the bulk container. - bulk << note; - } - // Resulting JSON string. - return bulk.json (); -} - - -// This takes $json and stores all the notes it contains in the filesystem. -vector Database_Notes::set_bulk (string json) -{ - // Container for the summaries that were stored. - vector summaries; - - // Parse the incoming JSON. - Array bulk; - bulk.parse (json); - - // Go through the notes the JSON contains. - for (size_t i = 0; i < bulk.size (); i++) { - - // Get all the different fields for this note. - Object note = bulk.get(static_cast(i)); - string assigned = note.get ("a"); - string bible = note.get ("b"); - string contents = note.get ("c"); - int identifier = static_cast(note.get ("i")); - int modified = static_cast(note.get ("m")); - string passage = note.get ("p"); - string subscriptions = note.get ("sb"); - string summary = note.get ("sm"); - string status = note.get ("st"); - int severity = static_cast(note.get ("sv")); - - // Feedback about which note it received in bulk. - summaries.push_back (summary); - - // Store the note in the filesystem. - string path = note_file (identifier); - string folder = filter_url_dirname (path); - filter_url_mkdir (folder); - Object note2; - note2 << assigned_key () << assigned; - note2 << bible_key () << bible; - note2 << contents_key () << contents; - note2 << modified_key () << filter::strings::convert_to_string (modified); - note2 << passage_key () << passage; - note2 << subscriptions_key () << subscriptions; - note2 << summary_key () << summary; - note2 << status_key () << status; - note2 << severity_key () << filter::strings::convert_to_string (severity); - string json2 = note2.json (); - filter_url_file_put_contents (path, json2); - - // Update the indexes. - update_database (identifier); - update_search_fields (identifier); - update_checksum (identifier); - } - - // Container with all the summaries of the notes that were stored. - return summaries; -} - - -// Gets a field from a note in JSON format. -string Database_Notes::get_field (int identifier, string key) -{ - string file = note_file (identifier); - string json = filter_url_file_get_contents (file); - Object note; - note.parse (json); - string value; - if (note.has (key)) value = note.get (key); - return value; -} - - -// Sets a field in a note in JSON format. -void Database_Notes::set_field (int identifier, string key, string value) -{ - string file = note_file (identifier); - string json = filter_url_file_get_contents (file); - Object note; - note.parse (json); - note << key << value; - json = note.json (); - filter_url_file_put_contents (file, json); -} - - -string Database_Notes::bible_key () -{ - return "bible"; -} - - -string Database_Notes::passage_key () -{ - return "passage"; -} - - -string Database_Notes::status_key () -{ - return "status"; -} - - -string Database_Notes::severity_key () -{ - return "severity"; -} - - -string Database_Notes::modified_key () -{ - return "modified"; -} - - -string Database_Notes::summary_key () -{ - return "summary"; -} - - -string Database_Notes::contents_key () -{ - return "contents"; -} - - -string Database_Notes::subscriptions_key () -{ - return "subscriptions"; -} - - -string Database_Notes::assigned_key () -{ - return "assigned"; -} - - -string Database_Notes::expiry_key () -{ - return "expiry"; -} - - -string Database_Notes::public_key () -{ - return "public"; -} diff --git a/database/notes.h b/database/notes.h deleted file mode 100644 index b4dc31612..000000000 --- a/database/notes.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - - -#include -#include - -class Webserver_Request; - -struct Database_Notes_Text -{ - std::string raw {}; - std::string localized {}; -}; - - -class Database_Notes -{ - -public: - Database_Notes (Webserver_Request& webserver_request); -private: - Webserver_Request& m_webserver_request; - -public: - void create (); - -private: - std::string database_path (); - std::string checksums_database_path (); - std::string main_folder_path (); - std::string note_file (int identifier); - -public: - bool healthy (); - bool checksums_healthy (); - bool checkup (); - bool checkup_checksums (); - void trim (); - void trim_server (); - void optimize (); - void sync (); - -public: - bool identifier_exists (int identifier); - void set_identifier (int identifier, int new_identifier); - -public: - std::vector get_identifiers (); - int store_new_note (const std::string& bible, int book, int chapter, int verse, std::string summary, std::string contents, bool raw); -private: - int get_new_unique_identifier (); - -public: - std::vector select_notes (std::vector bibles, int book, int chapter, int verse, int passage_selector, int edit_selector, int non_edit_selector, const std::string& status_selector, std::string bible_selector, std::string assignment_selector, bool subscription_selector, int severity_selector, int text_selector, const std::string& search_text, int limit); -private: - std::string notes_select_identifier (); - std::string notes_optional_fulltext_search_relevance_statement (std::string search); - std::string notes_from_where_statement (); - std::string notes_optional_fulltext_search_statement (std::string search); - std::string notes_order_by_relevance_statement (); - -public: - std::string get_summary (int identifier); - void set_summary (int identifier, const std::string& summary); -private: - std::string summary_key (); - -public: - std::string get_contents (int identifier); - void set_contents (int identifier, const std::string& contents); -private: - std::string contents_key (); - std::string assemble_contents (int identifier, std::string contents); - void set_raw_contents (int identifier, const std::string& contents); - -public: - void erase (int identifier); - -public: - void add_comment (int identifier, const std::string& comment); - -public: - void subscribe (int identifier); - void unsubscribe (int identifier); - void subscribe_user (int identifier, const std::string& user); - void unsubscribe_user (int identifier, const std::string& user); - bool is_subscribed (int identifier, const std::string& user); - std::vector get_subscribers (int identifier); - void set_subscribers (int identifier, std::vector subscribers); -private: - std::string subscriptions_key (); - std::string get_raw_subscriptions (int identifier); - void set_raw_subscriptions (int identifier, const std::string& subscriptions); - -public: - void assign_user (int identifier, const std::string& user); - bool is_assigned (int identifier, const std::string& user); - void unassign_user (int identifier, const std::string& user); - std::vector get_all_assignees (const std::vector & bibles); - std::vector get_assignees (int identifier); - void set_assignees (int identifier, std::vector assignees); -private: - std::string assigned_key (); - std::vector get_assignees_internal (std::string assignees); - void set_raw_assigned (int identifier, const std::string& assigned); - std::string get_raw_assigned (int identifier); - -public: - std::string get_bible (int identifier); - void set_bible (int identifier, const std::string& bible); - std::vector get_all_bibles (); -private: - std::string bible_key (); - -public: - std::string encode_passage (int book, int chapter, int verse); - Passage decode_passage (std::string passage); - std::string decode_passage (int identifier); - std::vector get_passages (int identifier); - void set_passages (int identifier, const std::vector & passages, bool import = false); - void set_raw_passage (int identifier, const std::string& passage); - void index_raw_passage (int identifier, const std::string& passage); -private: - std::string passage_key (); - std::string get_raw_passage (int identifier); - -public: - std::string get_raw_status (int identifier); - std::string get_status (int identifier); - void set_status (int identifier, const std::string& status, bool import = false); - std::vector get_possible_statuses (); -private: - std::string status_key (); - -public: - std::string get_severity (int identifier); - int get_raw_severity (int identifier); - void set_raw_severity (int identifier, int severity); - std::vector get_possible_severities (); -private: - std::string severity_key (); - std::vector standard_severities (); - -public: - int get_modified (int identifier); - void set_modified (int identifier, int time); -private: - std::string modified_key (); - void note_modified_actions (int identifier); - -public: - bool get_public (int identifier); - void set_public (int identifier, bool value); -private: - std::string public_key (); - -public: - std::string get_search_field (int identifier); - void update_search_fields (int identifier); - std::vector search_notes (std::string search, const std::vector & bibles); - -public: - void mark_for_deletion (int identifier); - void unmark_for_deletion (int identifier); - bool is_marked_for_deletion (int identifier); -private: - std::string expiry_key (); - void touch_marked_for_deletion (); - std::vector get_due_for_deletion (); - -public: - void set_checksum (int identifier, const std::string & checksum); - std::string get_checksum (int identifier); - void delete_checksum (int identifier); - void update_checksum (int identifier); - std::string get_multiple_checksum (const std::vector & identifiers); - std::vector get_notes_in_range_for_bibles (int lowId, int highId, std::vector bibles, bool anybible); - -public: - void set_availability (bool available); - bool available (); -private: - std::string availability_flag (); - -public: - std::string get_bulk (std::vector identifiers); - std::vector set_bulk (std::string json); - -private: - void update_database (int identifier); - void update_database_internal (int identifier, int modified, std::string assigned, std::string subscriptions, std::string bible, std::string passage, std::string status, int severity, std::string summary, std::string contents); - -private: - friend void test_database_notes (); - -private: - sqlite3 * connect (); - sqlite3 * connect_checksums (); - -private: - std::string get_field (int identifier, std::string key); - void set_field (int identifier, std::string key, std::string value); - -}; - diff --git a/database/oshb.cpp b/database/oshb.cpp deleted file mode 100644 index f0e01c2c0..000000000 --- a/database/oshb.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// This is the database for the Hebrew Bible text plus lemmas and morphology. -// Resilience: It is never written to. -// Chances of corruption are nearly zero. - - -const char * Database_OsHb::filename () -{ - return "oshb"; -} - - -void Database_OsHb::create () -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("DROP TABLE IF EXISTS oshb;"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE oshb (book int, chapter int, verse int, lemma int, word int, morph int);"); - sql.execute (); - - sql.clear (); - sql.add ("DROP TABLE IF EXISTS lemma;"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS lemma (lemma text);"); - sql.execute (); - - sql.clear (); - sql.add ("DROP TABLE IF EXISTS word;"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS word (word text);"); - sql.execute (); - - sql.clear (); - sql.add ("DROP TABLE IF EXISTS morph;"); - sql.execute (); - - sql.clear (); - sql.add ("CREATE TABLE IF NOT EXISTS morph (morph text);"); - sql.execute (); -} - - -void Database_OsHb::optimize () -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("VACUUM;"); - sql.execute (); -} - - -// Get Hebrew words for $book $chapter $verse. -vector Database_OsHb::getVerse (int book, int chapter, int verse) -{ - vector words; - vector rows = rowids (book, chapter, verse); - for (auto row : rows) { - words.push_back (word (row)); - } - return words; -} - - -// Get array of book / chapter / verse of all passages that contain a $hebrew word. -vector Database_OsHb::searchHebrew (string hebrew) -{ - int word_id = get_id ("word", hebrew); - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT DISTINCT book, chapter, verse FROM oshb WHERE word ="); - sql.add (word_id); - sql.add ("ORDER BY book, chapter, verse ASC;"); - vector hits; - map > result = sql.query (); - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - for (unsigned int i = 0; i < books.size (); i++) { - Passage passage; - passage.m_book = filter::strings::convert_to_int (books [i]); - passage.m_chapter = filter::strings::convert_to_int (chapters [i]); - passage.m_verse = verses [i]; - hits.push_back (passage); - } - return hits; -} - - -void Database_OsHb::store (int book, int chapter, int verse, string lemma, string word, string morph) -{ - int lemma_id = get_id ("lemma", lemma); - int word_id = get_id ("word", word); - int morph_id = get_id ("morph", morph); - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("PRAGMA temp_store = MEMORY;"); - sql.execute (); - sql.clear (); - sql.add ("PRAGMA synchronous = OFF;"); - sql.execute (); - sql.clear (); - sql.add ("PRAGMA journal_mode = OFF;"); - sql.execute (); - sql.clear (); - sql.add ("INSERT INTO oshb VALUES ("); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (","); - sql.add (lemma_id); - sql.add (","); - sql.add (word_id); - sql.add (","); - sql.add (morph_id); - sql.add (");"); - sql.execute (); -} - - -vector Database_OsHb::rowids (int book, int chapter, int verse) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT rowid FROM oshb WHERE book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("AND verse ="); - sql.add (verse); - sql.add ("ORDER BY rowid;"); - vector result = sql.query () ["rowid"]; - vector rowids; - for (auto rowid : result) rowids.push_back (filter::strings::convert_to_int (rowid)); - return rowids; -} - - -string Database_OsHb::lemma (int rowid) -{ - return get_item ("lemma", rowid); -} - - -string Database_OsHb::word (int rowid) -{ - return get_item ("word", rowid); -} - - -string Database_OsHb::morph (int rowid) -{ - return get_item ("morph", rowid); -} - - -int Database_OsHb::get_id (const char * table_row, string item) -{ - SqliteDatabase sql = SqliteDatabase (filename ()); - // Two iterations to be sure a rowid can be returned. - for (unsigned int i = 0; i < 2; i++) { - // Check on the rowid and return it if it's there. - sql.clear (); - sql.add ("SELECT rowid FROM"); - sql.add (table_row); - sql.add ("WHERE"); - sql.add (table_row); - sql.add ("="); - sql.add (item); - sql.add (";"); - vector result = sql.query () ["rowid"]; - if (!result.empty ()) return filter::strings::convert_to_int (result [0]); - // The rowid was not found: Insert the word into the table. - // The rowid will now be found during the second iteration. - sql.clear (); - sql.add ("INSERT INTO"); - sql.add (table_row); - sql.add ("VALUES ("); - sql.add (item); - sql.add (");"); - sql.execute (); - } - return 0; -} - - -string Database_OsHb::get_item (const char * item, int rowid) -{ - // The $rowid refers to the main table. - // Update it so it refers to the sub table. - SqliteDatabase sql = SqliteDatabase (filename ()); - sql.add ("SELECT"); - sql.add (item); - sql.add ("FROM oshb WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - vector result = sql.query () [item]; - rowid = 0; - if (!result.empty ()) rowid = filter::strings::convert_to_int (result [0]); - // Retrieve the requested value from the sub table. - sql.clear (); - sql.add ("SELECT"); - sql.add (item); - sql.add ("FROM"); - sql.add (item); - sql.add ("WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - result = sql.query () [item]; - if (!result.empty ()) return result [0]; - // Not found. - return ""; -} diff --git a/database/oshb.h b/database/oshb.h deleted file mode 100644 index 992231370..000000000 --- a/database/oshb.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Database_OsHb -{ -public: - void create (); - void optimize (); - std::vector getVerse (int book, int chapter, int verse); - std::vector searchHebrew (std::string hebrew); - void store (int book, int chapter, int verse, std::string lemma, std::string word, std::string morph); - std::vector rowids (int book, int chapter, int verse); - std::string lemma (int rowid); - std::string word (int rowid); - std::string morph (int rowid); -private: - const char * filename (); - int get_id (const char * table_row, std::string item); - std::string get_item (const char * item, int rowid); -}; diff --git a/database/privileges.cpp b/database/privileges.cpp deleted file mode 100644 index 7a975cee7..000000000 --- a/database/privileges.cpp +++ /dev/null @@ -1,476 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// This database is resilient. -// The data is stored in a SQLite database. -// This part is read often, and infrequently written to. -// Due to the infrequent write operations, there is a low and acceptable change of corruption. - - -// The name of the database. -const char * DatabasePrivileges::database () -{ - return "privileges"; -} - - -void DatabasePrivileges::create () -{ - SqliteDatabase sql (database ()); - - sql.add ("CREATE TABLE IF NOT EXISTS bibles (" - " username text," - " bible text," - " book integer," - " write boolean" - ");"); - sql.execute (); - - sql.add ("CREATE TABLE IF NOT EXISTS features (" - " username text," - " feature integer" - ");"); - sql.execute (); -} - - -void DatabasePrivileges::upgrade () -{ -} - - -void DatabasePrivileges::optimize () -{ - // Recreate damaged database. - if (!healthy ()) { - filter_url_unlink (database_sqlite_file (database ())); - create (); - } - // Vacuum it. - SqliteDatabase sql (database ()); - // On Android, this pragma prevents the following error: VACUUM; Unable to open database file. - sql.add ("PRAGMA temp_store = MEMORY;"); - sql.execute (); - sql.clear (); - sql.add ("VACUUM;"); - sql.execute (); -} - - -bool DatabasePrivileges::healthy () -{ - return database_sqlite_healthy (database ()); -} - - -string DatabasePrivileges::save (const string& username) -{ - SqliteDatabase sql (database ()); - - vector lines {}; - - lines.emplace_back (bibles_start ()); - sql.add ("SELECT bible, book, write FROM bibles WHERE username ="); - sql.add (username); - sql.add (";"); - map > result = sql.query (); - vector bible = result ["bible"]; - vector book = result ["book"]; - vector write = result ["write"]; - for (size_t i = 0; i < bible.size (); i++) { - lines.emplace_back (bible [i]); - lines.emplace_back (book [i]); - // It could have just stored 0 or 1 for the boolean values. - // But if that were done, then there would be no change in the length of the file - // when changing only boolean values. - // And then the client would not re-download that file. - // To use "on" and "off", that solves the issue. - const bool b = filter::strings::convert_to_bool (write[i]); - if (b) lines.emplace_back (on ()); - else lines.emplace_back (off ()); - } - lines.emplace_back (bibles_end ()); - - lines.emplace_back (features_start ()); - sql.clear (); - sql.add ("SELECT feature FROM features WHERE username ="); - sql.add (username); - sql.add (";"); - result = sql.query (); - const vector feature = result ["feature"]; - for (size_t i = 0; i < feature.size (); i++) { - lines.emplace_back (feature [i]); - } - lines.emplace_back (features_end ()); - - return filter::strings::implode (lines, "\n"); -} - - -void DatabasePrivileges::load (const string& username, const string & data) -{ - // Clear all data for the user. - { - SqliteDatabase sql (database ()); - sql.add ("DELETE FROM bibles WHERE username ="); - sql.add (username); - sql.add (";"); - sql.execute (); - sql.clear (); - sql.add ("DELETE FROM features WHERE username ="); - sql.add (username); - sql.add (";"); - sql.execute (); - } - - const vector lines = filter::strings::explode (data, '\n'); - bool loading_bibles {false}; - string bible_value {}; - int book_value {0}; - bool write_value {false}; - bool loading_features {false}; - int counter {0}; - - for (const auto & line : lines) { - - if (line == bibles_end ()) { - loading_bibles = false; - } - if (line == features_end ()) { - loading_features = false; - } - - counter++; - - if (loading_bibles) { - if (counter == 1) bible_value = line; - if (counter == 2) book_value = filter::strings::convert_to_int (line); - if (counter == 3) { - write_value = (line == on ()); - set_bible_book (username, bible_value, book_value, write_value); - counter = 0; - } - } - - if (loading_features) { - set_feature (username, filter::strings::convert_to_int (line), true); - } - - if (line == bibles_start ()) { - loading_bibles = true; - counter = 0; - } - if (line == features_start ()) { - loading_features = true; - counter = 0; - } - - } -} - - -// Give a privilege to a $username to access $bible $book to read it, or also to $write it. -void DatabasePrivileges::set_bible_book (const string& username, const string& bible, const int book, const bool write) -{ - // First remove any entry. - remove_bible_book (username, bible, book); - // Store the new entry. - SqliteDatabase sql (database ()); - sql.add ("INSERT INTO bibles VALUES ("); - sql.add (username); - sql.add (","); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (write); - sql.add (");"); - sql.execute (); -} - - -// Give a privilege to a $username to access $bible to read it, or also to $write it. -void DatabasePrivileges::set_bible (const string& username, const string& bible, const bool write) -{ - // First remove any entry. - remove_bible_book (username, bible, 0); - // Store the new entry. - SqliteDatabase sql (database ()); - sql.add ("INSERT INTO bibles VALUES ("); - sql.add (username); - sql.add (","); - sql.add (bible); - sql.add (","); - sql.add (0); - sql.add (","); - sql.add (write); - sql.add (");"); - sql.execute (); -} - - -// Read the privilege from the database whether $username has access to $bible $book. -// The privileges are stored in $read for read-only access, -// and in $write for write access. -void DatabasePrivileges::get_bible_book (const string& username, const string& bible, const int book, bool & read, bool & write) -{ - SqliteDatabase sql (database ()); - sql.add ("SELECT write FROM bibles WHERE username ="); - sql.add (username); - sql.add ("AND bible ="); - sql.add (bible); - sql.add ("AND book ="); - sql.add (book); - sql.add (";"); - const vector result = sql.query () ["write"]; - if (result.empty()) { - // Not in database: No access. - read = false; - write = false; - } else { - // Occurs in database: Read access. - read = true; - // Take write access from the database field. - write = filter::strings::convert_to_bool (result [0]); - } -} - - -// Returns a tuple with whether the $username has access to the given $bible. -tuple DatabasePrivileges::get_bible (const string& username, const string& bible) -{ - SqliteDatabase sql (database ()); - sql.add ("SELECT write FROM bibles WHERE username ="); - sql.add (username); - sql.add ("AND bible ="); - sql.add (bible); - sql.add (";"); - vector result = sql.query () ["write"]; - const bool read = (!result.empty()); - sql.clear (); - sql.add ("SELECT write FROM bibles WHERE username ="); - sql.add (username); - sql.add ("AND bible ="); - sql.add (bible); - sql.add ("AND write;"); - result = sql.query () ["write"]; - const bool write = (!result.empty()); - return make_tuple(read, write); -} - - -int DatabasePrivileges::get_bible_book_count () -{ - SqliteDatabase sql (database ()); - sql.add ("SELECT count(*) FROM bibles;"); - const vector result = sql.query () ["count(*)"]; - if (result.empty ()) return 0; - return filter::strings::convert_to_int (result [0]); -} - - -// Returns true if a record for $username / $bible / $book exists in the database. -// When the $book = 0, it takes any book. -bool DatabasePrivileges::get_bible_book_exists (const string& username, const string& bible, const int book) -{ - SqliteDatabase sql (database ()); - sql.add ("SELECT rowid FROM bibles WHERE username ="); - sql.add (username); - sql.add ("AND bible ="); - sql.add (bible); - if (book) { - sql.add ("AND book ="); - sql.add (book); - } - sql.add (";"); - const vector result = sql.query () ["rowid"]; - return !result.empty(); -} - - -// Remove the privilege of a $username to have access to $bible $book. -// Removing the privilege for $book 0 removes them for all possible books. -void DatabasePrivileges::remove_bible_book (const string& username, const string& bible, const int book) -{ - SqliteDatabase sql (database ()); - sql.add ("DELETE FROM bibles WHERE username ="); - sql.add (username); - sql.add ("AND bible ="); - sql.add (bible); - if (book) { - sql.add ("AND book ="); - sql.add (book); - } - sql.add (";"); - sql.execute (); -} - - -// Remove data for $bible from the database. -void DatabasePrivileges::remove_bible (const string& bible) -{ - SqliteDatabase sql (database ()); - sql.add ("DELETE FROM bibles WHERE bible ="); - sql.add (bible); - sql.add (";"); - sql.execute (); -} - - -void DatabasePrivileges::set_feature (const string& username, const int feature, const bool enabled) -{ - SqliteDatabase sql (database ()); - sql.add ("DELETE FROM features WHERE username ="); - sql.add (username); - sql.add ("AND feature ="); - sql.add (feature); - sql.add (";"); - sql.execute (); - if (enabled) { - sql.clear (); - sql.add ("INSERT INTO features VALUES ("); - sql.add (username); - sql.add (","); - sql.add (feature); - sql.add (");"); - sql.execute (); - } -} - - -bool DatabasePrivileges::get_feature (const string& username, const int feature) -{ - SqliteDatabase sql (database ()); - sql.add ("SELECT rowid FROM features WHERE username ="); - sql.add (username); - sql.add ("AND feature ="); - sql.add (feature); - sql.add (";"); - const vector result = sql.query () ["rowid"]; - if (result.empty()) return false; - return true; -} - - -// Remove privileges for $username from the entire database. -void DatabasePrivileges::remove_user (const string& username) -{ - SqliteDatabase sql (database ()); - sql.add ("DELETE FROM bibles WHERE username ="); - sql.add (username); - sql.add (";"); - sql.execute (); - sql.clear (); - sql.add ("DELETE FROM features WHERE username ="); - sql.add (username); - sql.add (";"); - sql.execute (); -} - - -const char * DatabasePrivileges::bibles_start () -{ - return "bibles_start"; -} - - -const char * DatabasePrivileges::bibles_end () -{ - return "bibles_end"; -} - - -const char * DatabasePrivileges::features_start () -{ - return "features_start"; -} - - -const char * DatabasePrivileges::features_end () -{ - return "features_start"; -} - - -const char * DatabasePrivileges::on () -{ - return "on"; -} - - -const char * DatabasePrivileges::off () -{ - return "off"; -} - - -string database_privileges_directory (const string & user) -{ - return filter_url_create_path ({database_logic_databases (), "clients", user}); -} - - -string database_privileges_file () -{ - return "privileges.txt"; -} - - -string database_privileges_client_path (const string & user) -{ - return filter_url_create_root_path ({database_privileges_directory (user), database_privileges_file ()}); -} - - -void database_privileges_client_create (const string & user, bool force) -{ - // The path to the file with privileges for the $user. - string path = database_privileges_client_path (user); - - // Without $force, if the file exists, we're done. - if (!force) { - if (file_or_dir_exists (path)) return; - } - - // If needed, create the folder. - string folder = filter_url_dirname (path); - if (!file_or_dir_exists (folder)) filter_url_mkdir (folder); - - // The bits of privileges in human-readable form. - string privileges = DatabasePrivileges::save (user); - - // Write the privileges to disk. - filter_url_file_put_contents (path, privileges); -} - - -void database_privileges_client_remove (const string & user) -{ - string path = database_privileges_client_path (user); - path = filter_url_dirname (path); - filter_url_rmdir (path); -} diff --git a/database/privileges.h b/database/privileges.h deleted file mode 100644 index aaf041ae6..000000000 --- a/database/privileges.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class DatabasePrivileges -{ -public: - static const char * database (); - static void create (); - static void upgrade (); - static void optimize (); - static bool healthy (); - static std::string save (const std::string& username); - static void load (const std::string& username, const std::string & data); - static void set_bible_book (const std::string& username, const std::string& bible, const int book, const bool write); - static void set_bible (const std::string& username, const std::string& bible, const bool write); - static void get_bible_book (const std::string& username, const std::string& bible, const int book, bool & read, bool & write); - static std::tuple get_bible (const std::string& username, const std::string& bible); - static int get_bible_book_count (); - static bool get_bible_book_exists (const std::string& username, const std::string& bible, const int book); - static void remove_bible_book (const std::string& username, const std::string& bible, const int book); - static void remove_bible (const std::string& bible); - static void set_feature (const std::string& username, const int feature, const bool enabled); - static bool get_feature (const std::string& username, const int feature); - static void remove_user (const std::string& username); -private: - static const char * bibles_start (); - static const char * bibles_end (); - static const char * features_start (); - static const char * features_end (); - static const char * on (); - static const char * off (); -}; - -std::string database_privileges_directory (const std::string & user); -std::string database_privileges_file (); -std::string database_privileges_client_path (const std::string & user); -void database_privileges_client_create (const std::string & user, bool force); -void database_privileges_client_remove (const std::string & user); diff --git a/database/sample.cpp b/database/sample.cpp deleted file mode 100644 index 3ea2c3a7a..000000000 --- a/database/sample.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// Database resilience: It is only read from. - - -void Database_Sample::create () -{ - string path = database_sqlite_file (name ()); - filter_url_unlink (path); - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("CREATE TABLE IF NOT EXISTS sample (file text, data text);"); - sql.execute (); -} - - -// Store a file and its data the sample. -void Database_Sample::store (string file, string data) -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("INSERT INTO sample VALUES ("); - sql.add (file); - sql.add (","); - sql.add (data); - sql.add (");"); - sql.execute (); -} - - -// Get the row identifiers in the database. -vector Database_Sample::get () -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("SELECT rowid FROM sample;"); - vector rowids = sql.query () ["rowid"]; - vector ids; - for (auto rowid : rowids) ids.push_back (filter::strings::convert_to_int (rowid)); - return ids; -} - - -// Get a a file and its contents. -void Database_Sample::get (int rowid, string & file, string & data) -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("SELECT file, data FROM sample WHERE rowid ="); - sql.add (rowid); - sql.add (";"); - map > sample = sql.query (); - vector files = sample ["file"]; - if (files.empty ()) file.clear (); - else file = files [0]; - vector datas = sample ["data"]; - if (datas.empty ()) data.clear (); - else data = datas [0]; -} - - -const char * Database_Sample::name () -{ - return "sample"; -} diff --git a/database/sample.h b/database/sample.h deleted file mode 100644 index 35fb066cd..000000000 --- a/database/sample.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Sample -{ -public: - static void create (); - static void store (std::string file, std::string data); - static std::vector get (); - static void get (int rowid, std::string & file, std::string & data); -private: - static const char * name (); -}; diff --git a/database/sblgnt.cpp b/database/sblgnt.cpp deleted file mode 100644 index 5411bd6eb..000000000 --- a/database/sblgnt.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -using namespace std; - - -// This is the database for the Greek New Testament. -// Resilience: It is never written to. -// Chances of corruption are nearly zero. - - -Database_Sblgnt::Database_Sblgnt () -{ -} - - -Database_Sblgnt::~Database_Sblgnt () -{ -} - - -sqlite3 * Database_Sblgnt::connect () -{ - return database_sqlite_connect ("sblgnt"); -} - - -// Get Greek words for $book $chapter $verse. -vector Database_Sblgnt::getVerse (int book, int chapter, int verse) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT greek FROM sblgnt WHERE book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("AND verse ="); - sql.add (verse); - sql.add (";"); - sqlite3 * db = connect (); - vector words = database_sqlite_query (db, sql.sql) ["greek"]; - database_sqlite_disconnect (db); - return words; -} - - -// Get the passages that contain a $greek word. -vector Database_Sblgnt::searchGreek (string greek) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT book, chapter, verse FROM sblgnt WHERE greek ="); - sql.add (greek); - sql.add (";"); - vector hits; - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - for (unsigned int i = 0; i < books.size (); i++) { - Passage passage; - passage.m_book = filter::strings::convert_to_int (books [i]); - passage.m_chapter = filter::strings::convert_to_int (chapters [i]); - passage.m_verse = verses [i]; - hits.push_back (passage); - } - return hits; -} - - diff --git a/database/sblgnt.h b/database/sblgnt.h deleted file mode 100644 index 9c94a2639..000000000 --- a/database/sblgnt.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Database_Sblgnt -{ -public: - Database_Sblgnt (); - ~Database_Sblgnt (); - std::vector getVerse (int book, int chapter, int verse); - std::vector searchGreek (std::string greek); -private: - sqlite3 * connect (); -}; diff --git a/database/sprint.cpp b/database/sprint.cpp deleted file mode 100644 index fa90c2df4..000000000 --- a/database/sprint.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// Database robustness: -// 1. It is infrequently written to. -// 2. Chances of corruption are low. -// 3. In case of corruption, data for the sprints is lost. -// This is acceptable, because translation work can still continue. - - -#ifdef HAVE_CLOUD - - -sqlite3 * Database_Sprint::connect () -{ - return database_sqlite_connect ("sprint"); -} - - -void Database_Sprint::create () -{ - sqlite3 * db = connect (); - - string sql = - "CREATE TABLE IF NOT EXISTS sprint (" - " year integer," - " month integer," - " title text," - " body text," - " complete integer" - ");"; - database_sqlite_exec (db, sql); - - sql = "CREATE INDEX IF NOT EXISTS yearmonth ON sprint (year, month)"; - database_sqlite_exec (db, sql); - - sql = "CREATE INDEX IF NOT EXISTS complete ON sprint (complete)"; - database_sqlite_exec (db, sql); - - sql = - "CREATE TABLE IF NOT EXISTS sprinthistory (" - " year integer," - " month integer," - " day integer," - " tasks integer," - " complete integer" - ");"; - database_sqlite_exec (db, sql); - - // Upgrade the two tables: Add a column for the Bible. - sql = "PRAGMA table_info (sprint);"; - vector columns = database_sqlite_query (db, sql) ["name"]; - if (find (columns.begin(), columns.end(), "bible") == columns.end()) { - sql = "ALTER TABLE sprint ADD COLUMN bible text;"; - database_sqlite_exec (db, sql); - } - sql = "PRAGMA table_info (sprinthistory);"; - columns = database_sqlite_query (db, sql) ["name"]; - if (find (columns.begin(), columns.end(), "bible") == columns.end()) { - sql = "ALTER TABLE sprinthistory ADD COLUMN bible text;"; - database_sqlite_exec (db, sql); - } - - database_sqlite_disconnect (db); -} - - -void Database_Sprint::optimize () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "REINDEX sprint;"); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_disconnect (db); -} - - -void Database_Sprint::storeTask (const string& bible, int year, int month, const string& title) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO sprint VALUES ("); - sql.add (year); - sql.add (","); - sql.add (month); - sql.add (","); - sql.add (title); - sql.add (", '', 0,"); - sql.add (bible); - sql.add (");"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -void Database_Sprint::deleteTask (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM sprint WHERE rowid ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -vector Database_Sprint::getTasks (const string& bible, int year, int month) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT rowid FROM sprint WHERE bible ="); - sql.add (bible); - sql.add ("AND year ="); - sql.add (year); - sql.add ("AND month ="); - sql.add (month); - sql.add ("ORDER BY rowid ASC;"); - sqlite3 * db = connect (); - vector rowids = database_sqlite_query (db, sql.sql) ["rowid"]; - database_sqlite_disconnect (db); - vector ids; - for (auto & id : rowids) { - ids.push_back (filter::strings::convert_to_int (id)); - } - return ids; -} - - -string Database_Sprint::getTitle (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT title FROM sprint WHERE rowid ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector title = database_sqlite_query (db, sql.sql) ["title"]; - database_sqlite_disconnect (db); - if (!title.empty ()) return title [0]; - return ""; -} - - -void Database_Sprint::updateComplete (int id, int percentage) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("UPDATE sprint SET complete ="); - sql.add (percentage); - sql.add ("WHERE rowid ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -int Database_Sprint::getComplete (int id) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT complete FROM sprint WHERE rowid ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - vector complete = database_sqlite_query (db, sql.sql) ["complete"]; - database_sqlite_disconnect (db); - if (!complete.empty ()) return filter::strings::convert_to_int (complete [0]); - return 0; -} - - -void Database_Sprint::updateMonthYear (int id, int month, int year) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("UPDATE sprint SET month ="); - sql.add (month); - sql.add (", year ="); - sql.add (year); - sql.add ("WHERE rowid ="); - sql.add (id); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -void Database_Sprint::logHistory (const string& bible, int year, int month, int day, int tasks, int complete) -{ - SqliteSQL sql1 = SqliteSQL (); - sql1.add ("DELETE FROM sprinthistory WHERE bible ="); - sql1.add (bible); - sql1.add ("AND year ="); - sql1.add (year); - sql1.add ("AND month ="); - sql1.add (month); - sql1.add ("AND day ="); - sql1.add (day); - sql1.add (";"); - - SqliteSQL sql2 = SqliteSQL (); - sql2.add ("INSERT INTO sprinthistory VALUES ("); - sql2.add (year); - sql2.add (","); - sql2.add (month); - sql2.add (","); - sql2.add (day); - sql2.add (","); - sql2.add (tasks); - sql2.add (","); - sql2.add (complete); - sql2.add (","); - sql2.add (bible); - sql2.add (");"); - - sqlite3 * db = connect (); - database_sqlite_exec (db, sql1.sql); - database_sqlite_exec (db, sql2.sql); - database_sqlite_disconnect (db); -} - - -vector Database_Sprint::getHistory (const string& bible, int year, int month) -{ - vector history; - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT day, tasks, complete FROM sprinthistory WHERE bible ="); - sql.add (bible); - sql.add ("AND year ="); - sql.add (year); - sql.add ("AND month ="); - sql.add (month); - sql.add ("ORDER BY day ASC;"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector days = result ["day"]; - vector tasks = result ["tasks"]; - vector completes = result ["complete"]; - for (unsigned int i = 0; i < days.size(); i++) { - Database_Sprint_Item item = Database_Sprint_Item (); - item.day = filter::strings::convert_to_int (days [i]); - item.tasks = filter::strings::convert_to_int (tasks [i]); - item.complete = filter::strings::convert_to_int (completes [i]); - history.push_back (item); - } - return history; -} - - -void Database_Sprint::clearHistory (const string& bible, int year, int month) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM sprinthistory WHERE bible ="); - sql.add (bible); - sql.add ("AND year ="); - sql.add (year); - sql.add ("AND month ="); - sql.add (month); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -#endif diff --git a/database/sprint.h b/database/sprint.h deleted file mode 100644 index 7ffadde31..000000000 --- a/database/sprint.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -#ifdef HAVE_CLOUD - -class Database_Sprint_Item -{ -public: - int day; - int tasks; - int complete; -}; - -class Database_Sprint -{ -public: - void create (); - void optimize (); - void storeTask (const std::string& bible, int year, int month, const std::string& title); - void deleteTask (int id); - std::vector getTasks (const std::string& bible, int year, int month); - std::string getTitle (int id); - void updateComplete (int id, int percentage); - int getComplete (int id); - void updateMonthYear (int id, int month, int year); - void logHistory (const std::string& bible, int year, int month, int day, int tasks, int complete); - std::vector getHistory (const std::string& bible, int year, int month); - void clearHistory (const std::string& bible, int year, int month); -private: - sqlite3 * connect (); -}; - -#endif diff --git a/database/sqlite.cpp b/database/sqlite.cpp deleted file mode 100644 index c1e80a937..000000000 --- a/database/sqlite.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -/* -It has been seen on a shared hosting platform that the MySQL server did not have -sufficient available concurrent connections at times. -Other processes were using many connections, so that none remained for Bibledit. -That is a reason against using MySQL on shared hosting. - -A reason for using SQLite is that it is easier to set up. -No users, no privileges, no server. - -Another reason is that a backup of the web space also back ups the SQLite databases, -provided they are stored in the web space. -With MySQL this is hard to do. - -Usually with shared hosting, the web space is big, but the MySQL database space is small. -With a few Bibles, and several notes, plus resources, the MySQL database is full. -SQLite uses the huge web space that usually come with shared hosting. -Therefore it can store much more data with the same shared hosting package. - -While MySQL is a faster database than SQLite in isolated experiments, -on shared hosts it may be different. -The reasons is that on a shared host, SQLite gets the data in the same process -straight from disk. This works differently for MySQL. In most cases, the shared -host uses a separate database server. Thus the web server fetches its data -from another host through the network. This introduces some delays. -For smaller data sets SQLite is much faster in this scenario. - -Some often-used databases at times display database errors: - disk I/O error - unable to open database file -It was tried wiether the errors go away when "PRAGMA busy_timeout = 100;" -is executed after opening the database connection. The errors did not go away. - -It was tried whether the above errors go away on shared hosting with this command: -PRAGMA journal_mode = TRUNCATE; -The errors did not go away. - -It was tried whether the above errors go away on shared hosting with this command: -PRAGMA temp_store = MEMORY; -The errors did not go away. - -It was tried whether the above errors go away on shared hosting with this command: -PRAGMA journal_mode = MEMORY; -The errors went away, but the database behaved in an inconsistent way. -It did not keeps its data properly, and did not update it properly. -The same behaviour was found with: -PRAGMA journal_mode = OFF; - -It was tried whether setting the environment variable TMPDIR to a directory -in our own web space would improve SQLite, but this did not improve SQLite. -However, in other areas it looked as if this did give improvement. - -What made a big difference is this: -1. Changing the database for the logbook from SQLite to the filesystem. -2. Setting the TMPDIR to a folder inside Bibledit's own webspace. -3. Letting the tasks runner not use a SQLite database, but the file system and memory. -The database errors went away. - -*/ - - -// Despite compiling the SQLite library in thread-safe mode, -// there's still 'database locked' and "SQL error' errors. -// Sample errors: -// INSERT INTO cache VALUES ( 136 , 0 , '' ); - database is locked - database is locked -// INSERT INTO cache VALUES ( 25 , 21 , '' ); - unrecognized token: "'" - SQL logic error or missing database -// Therefore here's an extra mutex for our own logic, and that should fix those errors. -mutex sqlite_execute_mutex; - - -sqlite3 * database_sqlite_connect_file (string filename) -{ - sqlite3 *db {nullptr}; - int rc = sqlite3_open (filename.c_str(), &db); - if (rc) { - const char * error = sqlite3_errmsg (db); - database_sqlite_error (db, "Database " + filename, const_cast(error)); - return nullptr; - } - sqlite3_busy_timeout (db, 1000); - return db; -} - - -// The function provides the path to the "database" in the default database folder. -// It does this in case "database" contains no path. -// If it has a path, then it returns the path as given. -string database_sqlite_file (string database) -{ - if (filter_url_dirname (database) == ".") { - return filter_url_create_root_path ({database_logic_databases (), database + database_sqlite_suffix ()}); - } - return database; -} - - -string database_sqlite_suffix () -{ - return ".sqlite"; -} - - -sqlite3 * database_sqlite_connect (string database) -{ - return database_sqlite_connect_file (database_sqlite_file (database)); -} - - -string database_sqlite_no_sql_injection (string sql) -{ - return filter::strings::replace ("'", "''", sql); -} - - -void database_sqlite_exec (sqlite3 * db, string sql) -{ - char *error = nullptr; - if (db) { - sqlite_execute_mutex.lock (); - int rc = sqlite3_exec (db, sql.c_str(), nullptr, nullptr, &error); - sqlite_execute_mutex.unlock (); - if (rc != SQLITE_OK) database_sqlite_error (db, sql, error); - } else { - database_sqlite_error (db, sql, error); - } - if (error) sqlite3_free (error); -} - - -map > database_sqlite_query (sqlite3 * db, string sql) -{ - char * error = nullptr; - SqliteReader reader (0); - if (db) { - sqlite_execute_mutex.lock (); - int rc = sqlite3_exec (db, sql.c_str(), reader.callback, &reader, &error); - sqlite_execute_mutex.unlock (); - if (rc != SQLITE_OK) database_sqlite_error (db, sql, error); - } else { - database_sqlite_error (db, sql, error); - } - if (error) sqlite3_free (error); - return reader.result; -} - - -void database_sqlite_disconnect (sqlite3 * database) -{ - if (database) sqlite3_close (database); -} - - -// Does an integrity check on the database. -// Returns true if healthy, false otherwise. -bool database_sqlite_healthy (string database) -{ - string file = database_sqlite_file (database); - bool ok = false; - // Do an integrity check on the database. - // An empty file appears healthy too, so deal with that. - if (filter_url_filesize (file) > 0) { - sqlite3 * db = database_sqlite_connect (database); - string query = "PRAGMA integrity_check;"; - map > result = database_sqlite_query (db, query); - vector health = result ["integrity_check"]; - if (health.size () == 1) { - if (health [0] == "ok") ok = true; - } - database_sqlite_disconnect (db); - } - return ok; -} - - -// Logs any error on the database connection, -// The error will be prefixed by $prefix. -void database_sqlite_error (sqlite3 * database, const string & prefix, char * error) -{ - string message = prefix; - if (error) { - message.append (" - "); - message.append (error); - } - if (database) { - int errcode = sqlite3_errcode (database); - const char * errstr = sqlite3_errstr (errcode); - string error_string; - if (errstr) error_string.assign (errstr); - int x_errcode = sqlite3_extended_errcode (database); - const char * x_errstr = sqlite3_errstr (x_errcode); - string extended_error_string; - if (x_errstr) extended_error_string.assign (x_errstr); - if (!error_string.empty ()) { - message.append (" - "); - message.append (error_string); - } - if (extended_error_string != error_string) { - message.append (" - "); - message.append (extended_error_string); - } - const char * filename = sqlite3_db_filename (database, "main"); - if (filename) { - message.append (" - "); - message.append (filename); - } - } else { - if (!message.empty ()) message.append (" - "); - message.append ("No database connection"); - } - Database_Logs::log (message); -} - - -void SqliteSQL::clear () -{ - sql.clear (); -} - - -void SqliteSQL::add (const char * fragment) -{ - sql.append (" "); - sql.append (fragment); - sql.append (" "); -} - -void SqliteSQL::add (int value) -{ - sql.append (" "); - sql.append (filter::strings::convert_to_string (value)); - sql.append (" "); -} - -void SqliteSQL::add (string value) -{ - sql.append (" '"); - value = database_sqlite_no_sql_injection (value); - sql.append (value); - sql.append ("' "); -} - - -SqliteReader::SqliteReader (int dummy) -{ - if (dummy) {}; -} - - -SqliteReader::~SqliteReader () -{ -} - - -int SqliteReader::callback (void *userdata, int argc, char **argv, char **column_names) -{ - SqliteReader * sqlite_reader = static_cast (userdata); - for (int i = 0; i < argc; i++) { - // Handle nullptr field. - if (argv [i] == nullptr) sqlite_reader->result [column_names [i]].push_back (""); - else sqlite_reader->result [column_names [i]].push_back (argv[i]); - } - return 0; -} - - -SqliteDatabase::SqliteDatabase (string filename) -{ - db = database_sqlite_connect (filename); -} - - -SqliteDatabase::~SqliteDatabase () -{ - database_sqlite_disconnect (db); -} - - -void SqliteDatabase::clear () -{ - sql.clear (); -} - - -void SqliteDatabase::add (const char * fragment) -{ - sql.append (" "); - sql.append (fragment); - sql.append (" "); -} - - -void SqliteDatabase::add (int value) -{ - sql.append (" "); - sql.append (filter::strings::convert_to_string (value)); - sql.append (" "); -} - - -void SqliteDatabase::add (string value) -{ - sql.append (" '"); - value = database_sqlite_no_sql_injection (value); - sql.append (value); - sql.append ("' "); -} - - -void SqliteDatabase::execute () -{ - database_sqlite_exec (db, sql); -} - - -map > SqliteDatabase::query () -{ - return database_sqlite_query (db, sql); -} diff --git a/database/sqlite.h b/database/sqlite.h deleted file mode 100644 index 1df8f53d2..000000000 --- a/database/sqlite.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -sqlite3 * database_sqlite_connect_file (std::string filename); -std::string database_sqlite_file (std::string database); -std::string database_sqlite_suffix (); -sqlite3 * database_sqlite_connect (std::string database); -std::string database_sqlite_no_sql_injection (std::string sql); -void database_sqlite_exec (sqlite3 * db, std::string sql); -std::map > database_sqlite_query (sqlite3 * db, std::string sql); -void database_sqlite_disconnect (sqlite3 * database); -bool database_sqlite_healthy (std::string database); -void database_sqlite_error (sqlite3 * database, const std::string & prefix, char * error); - -// Creates a database SQL query. -class SqliteSQL -{ -public: - void clear (); - void add (const char * fragment); - void add (int value); - void add (std::string value); - std::string sql {}; -private: -}; - -// Stores values collected during a reading session of sqlite3. -class SqliteReader -{ -public: - SqliteReader (int dummy); - ~SqliteReader (); - std::map > result {}; - static int callback (void *userdata, int argc, char **argv, char **column_names); -private: -}; - -class SqliteDatabase -{ -public: - SqliteDatabase (std::string filename); - ~SqliteDatabase (); - SqliteDatabase(const SqliteDatabase&) = delete; - SqliteDatabase operator=(const SqliteDatabase&) = delete; - void clear (); - void add (const char * fragment); - void add (int value); - void add (std::string value); - std::string sql {}; - void execute (); - std::map > query (); -private: - sqlite3 * db {nullptr}; -}; diff --git a/database/state.cpp b/database/state.cpp deleted file mode 100644 index fc258c143..000000000 --- a/database/state.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: It only contains state information. -// It is checked and optionally recreated every night. - - -void Database_State::create () -{ - bool healthy_database = database_sqlite_healthy (name ()); - if (!healthy_database) { - filter_url_unlink (database_sqlite_file (name ())); - } - - sqlite3 * db = connect (); - string sql; - - // On Android, this pragma prevents the following error: VACUUM; Unable to open database file. - sql = "PRAGMA temp_store = MEMORY;"; - database_sqlite_exec (db, sql); - - sql = - "CREATE TABLE IF NOT EXISTS notes (" - " first integer," - " last integer," - " value text" - ");"; - database_sqlite_exec (db, sql); - - sql = "DELETE FROM notes;"; - database_sqlite_exec (db, sql); - - // Here something weird was going on when doing a VACUUM at this stage. - // On Android, it always would say this: VACUUM; Unable to open database file. - // Testing on the existence of the database file, right before the VACUUM operation, showed that the database file did exist. The question is then: If the file exists, why does it fail to open it? - // It also was tried to delay with 100 milliseconds before doing the VACUUM. But this made no difference. It would still give the error. - // It also was tried to close the connection to the database, then open it again. This made no difference either. - // It now does not VACUUM a newly created database, but only when it was created. - // Later on, the PRAGMA as above was used to solve the issue. - sql = "VACUUM;"; - database_sqlite_exec (db, sql); - - sql = - "CREATE TABLE IF NOT EXISTS export (" - " bible text," - " book integer," - " format integer" - ");"; - database_sqlite_exec (db, sql); - - sql = - "CREATE TABLE IF NOT EXISTS exported (" - " bible text," - " book integer," - " state boolean" - ");"; - database_sqlite_exec (db, sql); - - database_sqlite_disconnect (db); -} - - -// Stores a notes checksum for a range of notes. -void Database_State::putNotesChecksum (int first, int last, const string& checksum) -{ - sqlite3 * db = connect (); - { - // Remove possible existing range. - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM notes WHERE first ="); - sql.add (first); - sql.add ("AND last ="); - sql.add (last); - sql.add (";"); - database_sqlite_exec (db, sql.sql); - } - { - // Store the new checksum for the range. - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO notes VALUES ("); - sql.add (first); - sql.add (","); - sql.add (last); - sql.add (","); - sql.add (checksum); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - } - database_sqlite_disconnect (db); -} - - -// Retrieves the checksum for a range of notes. -string Database_State::getNotesChecksum (int first, int last) -{ - // Receive the checksum for the exact range. - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT value FROM notes WHERE first ="); - sql.add (first); - sql.add ("AND last ="); - sql.add (last); - sql.add (";"); - sqlite3 * db = connect (); - vector values = database_sqlite_query (db, sql.sql)["value"]; - database_sqlite_disconnect (db); - if (!values.empty()) { - return values[0]; - } - return string(); -} - - -// Erase the checksum for a note contained in any range. -void Database_State::eraseNoteChecksum (int identifier) -{ - // Remove ranges that contain the note identifier. - sqlite3 * db = connect (); - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM notes WHERE first <="); - sql.add (identifier); - sql.add ("AND last >="); - sql.add (identifier); - sql.add (";"); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Flag export of $bible $book to $format. -void Database_State::setExport (const string & bible, int book, int format) -{ - if (getExport (bible, book, format)) return; - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO export VALUES ("); - sql.add (bible); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (format); - sql.add (");"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Get whether the $bible $book has been flagged for export in format $format. -bool Database_State::getExport (const string & bible, int book, int format) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT format FROM export WHERE bible ="); - sql.add (bible); - sql.add ("AND book ="); - sql.add (book); - sql.add ("AND format ="); - sql.add (format); - sql.add (";"); - sqlite3 * db = connect (); - vector values = database_sqlite_query (db, sql.sql)["format"]; - database_sqlite_disconnect (db); - if (!values.empty()) { - return true; - } - return false; -} - - -// Clear the export flag for $bible $book to $format -void Database_State::clearExport (const string & bible, int book, int format) -{ - sqlite3 * db = connect (); - SqliteSQL sql = SqliteSQL (); - sql.add ("DELETE FROM export WHERE bible ="); - sql.add (bible); - sql.add ("AND book ="); - sql.add (book); - sql.add ("AND format ="); - sql.add (format); - sql.add (";"); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -const char * Database_State::name () -{ - return "state"; -} - - -sqlite3 * Database_State::connect () -{ - return database_sqlite_connect (name ()); -} diff --git a/database/state.h b/database/state.h deleted file mode 100644 index 9a152eebf..000000000 --- a/database/state.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_State -{ -public: - static void create (); - static void putNotesChecksum (int first, int last, const std::string& checksum); - static std::string getNotesChecksum (int first, int last); - static void eraseNoteChecksum (int identifier); - static void setExport (const std::string & bible, int book, int format); - static bool getExport (const std::string & bible, int book, int format); - static void clearExport (const std::string & bible, int book, int format); -private: - static sqlite3 * connect (); - static const char * name (); -}; diff --git a/database/statistics.cpp b/database/statistics.cpp deleted file mode 100644 index a9c8d025b..000000000 --- a/database/statistics.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: It contains statistical and non-essential data. -// It is checked and optionally recreated at least once a day. - - -#ifdef HAVE_CLOUD - - -void Database_Statistics::create () -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("CREATE TABLE IF NOT EXISTS changes (timestamp integer, user text, count integer);"); - sql.execute (); -} - - -void Database_Statistics::optimize () -{ - bool healthy_database = database_sqlite_healthy (name ()); - if (!healthy_database) { - filter_url_unlink (database_sqlite_file (name ())); - create (); - } -} - - -void Database_Statistics::store_changes (int timestamp, string user, int count) -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("INSERT INTO changes VALUES ("); - sql.add (timestamp); - sql.add (","); - sql.add (user); - sql.add (","); - sql.add (count); - sql.add (");"); - sql.execute (); -} - - -// Fetches the distinct users who have been active within the last 365 days. -vector Database_Statistics::get_users () -{ - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("SELECT DISTINCT user FROM changes WHERE timestamp >="); - sql.add (year_ago ()); - sql.add ("ORDER BY user;"); - vector users = sql.query () ["user"]; - return users; -} - - -// Fetches the change statistics from the database for $user for no more than a year ago. -vector > Database_Statistics::get_changes (string user) -{ - vector > changes; - SqliteDatabase sql = SqliteDatabase (name ()); - sql.add ("SELECT timestamp, count FROM changes WHERE timestamp >="); - sql.add (year_ago ()); - if (!user.empty ()) { - // Empty user: Get all changes for all users. - sql.add ("AND user ="); - sql.add (user); - } - sql.add ("ORDER BY timestamp DESC;"); - vector timestamps = sql.query () ["timestamp"]; - vector counts = sql.query () ["count"]; - for (size_t i = 0; i < timestamps.size (); i++) { - int timestamp = filter::strings::convert_to_int (timestamps[i]); - int count = filter::strings::convert_to_int (counts[i]); - changes.push_back (pair (timestamp, count)); - } - return changes; -} - - -const char * Database_Statistics::name () -{ - return "statistics"; -} - - -int Database_Statistics::year_ago () -{ - int timestamp = filter::date::seconds_since_epoch (); - timestamp -= (3600 * 24 * 365); - return timestamp; -} - - -#endif diff --git a/database/statistics.h b/database/statistics.h deleted file mode 100644 index 14db509fb..000000000 --- a/database/statistics.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -#ifdef HAVE_CLOUD - -class Database_Statistics -{ -public: - static void create (); - static void optimize (); - static void store_changes (int timestamp, std::string user, int count); - static std::vector get_users (); - static std::vector > get_changes (std::string user); -private: - static const char * name (); - static int year_ago (); -}; - -#endif diff --git a/database/strong.cpp b/database/strong.cpp deleted file mode 100644 index 0974f3d0e..000000000 --- a/database/strong.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// This is the database for the Strong's definitions. -// Resilience: It is never written to. -// Chances of corruption are nearly zero. - - -// Get Strong's definition for the $strong's number. -string Database_Strong::definition (string strong) -{ - sqlite3 * db; - { - // Search Greek lexicon. - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT definition FROM greekstrong WHERE id ="); - sql.add (strong); - sql.add (";"); - db = connect (); - vector definitions = database_sqlite_query (db, sql.sql) ["definition"]; - database_sqlite_disconnect (db); - if (!definitions.empty ()) return definitions[0]; - } - // Nothing found. - return ""; -} - - -// Get Strong's number(s) for the $lemma. -// Most lemma's refer to one Strong's number, but some lemma's refer to more than one. -vector Database_Strong::strong (string lemma) -{ - sqlite3 * db; - { - // Search Greek lexicon. - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT id FROM greekstrong WHERE lemma ="); - sql.add (lemma); - sql.add (";"); - db = connect (); - vector ids = database_sqlite_query (db, sql.sql) ["id"]; - database_sqlite_disconnect (db); - if (!ids.empty ()) return ids; - } - // Nothing found. - return {}; -} - - -sqlite3 * Database_Strong::connect () -{ - return database_sqlite_connect ("greekstrong"); -} diff --git a/database/strong.h b/database/strong.h deleted file mode 100644 index a5b4d0468..000000000 --- a/database/strong.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Strong -{ -public: - std::string definition (std::string strong); - std::vector strong (std::string lemma); -private: - sqlite3 * connect (); -}; diff --git a/database/styles.cpp b/database/styles.cpp deleted file mode 100644 index d5b263866..000000000 --- a/database/styles.cpp +++ /dev/null @@ -1,673 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// This is the database for the styles. -// Resilience: It is hardly written to. -// Chances of corruption are low. -// All default data is stored in the code in memory, not in a database on disk. - - -// Cache for the default styles. -// It used to store the default cache in code. -// That architecture caused 400+ calls to the localization routines during app startup. -// This cache does not make those calls during app startup. -map default_styles_cache; -// The memory cache to speed up reading style values. -// Access a style item like this: cache [stylesheet] [marker]. -// Timing a Bibledit setup phase gave this information: -// * Before the cache was implemented, fetching styles took 30 seconds (38%) of the total setup time. -// * After the cache was there, it took 17 seconds (25%) of the total setup time. -map > database_styles_cache; -// Cache read and write lock. -mutex database_styles_cache_mutex; - - -sqlite3 * Database_Styles::connect () -{ - return database_sqlite_connect ("styles"); -} - - -void Database_Styles::create () -{ - // Create database. - sqlite3 * db = connect (); - string sql; - sql = "CREATE TABLE IF NOT EXISTS users (" - "user text," - "sheet text" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -// Creates a stylesheet. -void Database_Styles::createSheet (string sheet) -{ - // Folder for storing the stylesheet. - filter_url_mkdir (sheetfolder (sheet)); - // Check and/or load defaults. - if (default_styles_cache.empty ()) cache_defaults (); - // Write all style items to file. - for (auto & mapping : default_styles_cache) { - auto & item = mapping.second; - write_item (sheet, item); - } -} - - -// Returns an array with the available stylesheets. -vector Database_Styles::getSheets () -{ - vector sheets = filter_url_scandir (databasefolder ()); - if (find (sheets.begin (), sheets.end (), styles_logic_standard_sheet ()) == sheets.end ()) { - sheets.push_back (styles_logic_standard_sheet ()); - } - sort (sheets.begin(), sheets.end()); - return sheets; -} - - -// Deletes a stylesheet. -void Database_Styles::deleteSheet (string sheet) -{ - if (!sheet.empty ()) filter_url_rmdir (sheetfolder (sheet)); - database_styles_cache_mutex.lock (); - database_styles_cache.clear (); - database_styles_cache_mutex.unlock (); -} - - -// Adds a marker to the stylesheet. -void Database_Styles::addMarker (string sheet, string marker) -{ - Database_Styles_Item item = read_item (sheet, marker); - write_item (sheet, item); -} - - -// Deletes a marker from a stylesheet. -void Database_Styles::deleteMarker (string sheet, string marker) -{ - filter_url_unlink (stylefile (sheet, marker)); - database_styles_cache_mutex.lock (); - database_styles_cache.clear (); - database_styles_cache_mutex.unlock (); -} - - -// Returns a map with all the markers and the names of the styles in the stylesheet. -map Database_Styles::getMarkersAndNames (string sheet) -{ - map markers_names; - vector markers = getMarkers (sheet); - for (auto marker : markers) { - Database_Styles_Item item = read_item (sheet, marker); - markers_names [marker] = item.name; - } - return markers_names; -} - - -// Returns an array with all the markers of the styles in the stylesheet. -vector Database_Styles::getMarkers (string sheet) -{ - // The markers for this stylesheet. - vector markers = filter_url_scandir (sheetfolder (sheet)); - if (markers.empty ()) { - // Check and/or load defaults. - if (default_styles_cache.empty ()) cache_defaults (); - // Load all default markers. - for (auto & mapping : default_styles_cache) { - // The markers are the keys in the std::map. - markers.push_back (mapping.first); - } - } - // Done. - return markers; -} - - -// Returns an object with all data belonging to a marker. -Database_Styles_Item Database_Styles::getMarkerData (string sheet, string marker) -{ - return read_item (sheet, marker); -} - - -// Updates a style's name. -void Database_Styles::updateName (string sheet, string marker, string name) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.name = name; - write_item (sheet, item); -} - - -// Updates a style's info. -void Database_Styles::updateInfo (string sheet, string marker, string info) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.info = info; - write_item (sheet, item); -} - - -// Updates a style's category. -void Database_Styles::updateCategory (string sheet, string marker, string category) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.category = category; - write_item (sheet, item); -} - - -// Updates a style's type. -void Database_Styles::updateType (string sheet, string marker, int type) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.type = type; - write_item (sheet, item); -} - - -// Updates a style's subtype. -void Database_Styles::updateSubType (string sheet, string marker, int subtype) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.subtype = subtype; - write_item (sheet, item); -} - - -// Updates a style's font size. -void Database_Styles::updateFontsize (string sheet, string marker, float fontsize) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.fontsize = fontsize; - write_item (sheet, item); -} - - -// Updates a style's italic setting. -void Database_Styles::updateItalic (string sheet, string marker, int italic) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.italic = italic; - write_item (sheet, item); -} - - -// Updates a style's bold setting. -void Database_Styles::updateBold (string sheet, string marker, int bold) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.bold = bold; - write_item (sheet, item); -} - - -// Updates a style's underline setting. -void Database_Styles::updateUnderline (string sheet, string marker, int underline) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.underline = underline; - write_item (sheet, item); -} - - -// Updates a style's small caps setting. -void Database_Styles::updateSmallcaps (string sheet, string marker, int smallcaps) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.smallcaps = smallcaps; - write_item (sheet, item); -} - - -void Database_Styles::updateSuperscript (string sheet, string marker, int superscript) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.superscript = superscript; - write_item (sheet, item); -} - - -void Database_Styles::updateJustification (string sheet, string marker, int justification) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.justification = justification; - write_item (sheet, item); -} - - -void Database_Styles::updateSpaceBefore (string sheet, string marker, float spacebefore) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.spacebefore = spacebefore; - write_item (sheet, item); -} - - -void Database_Styles::updateSpaceAfter (string sheet, string marker, float spaceafter) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.spaceafter = spaceafter; - write_item (sheet, item); -} - - -void Database_Styles::updateLeftMargin (string sheet, string marker, float leftmargin) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.leftmargin = leftmargin; - write_item (sheet, item); -} - - -void Database_Styles::updateRightMargin (string sheet, string marker, float rightmargin) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.rightmargin = rightmargin; - write_item (sheet, item); -} - - -void Database_Styles::updateFirstLineIndent (string sheet, string marker, float firstlineindent) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.firstlineindent = firstlineindent; - write_item (sheet, item); -} - - -void Database_Styles::updateSpanColumns (string sheet, string marker, bool spancolumns) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.spancolumns = spancolumns; - write_item (sheet, item); -} - - -void Database_Styles::updateColor (string sheet, string marker, string color) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.color = color; - write_item (sheet, item); -} - - -void Database_Styles::updatePrint (string sheet, string marker, bool print) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.print = print; - write_item (sheet, item); -} - - -void Database_Styles::updateUserbool1 (string sheet, string marker, bool userbool1) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.userbool1 = userbool1; - write_item (sheet, item); -} - - -void Database_Styles::updateUserbool2 (string sheet, string marker, bool userbool2) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.userbool2 = userbool2; - write_item (sheet, item); -} - - -void Database_Styles::updateUserbool3 (string sheet, string marker, bool userbool3) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.userbool3 = userbool3; - write_item (sheet, item); -} - - -void Database_Styles::updateUserint1 (string sheet, string marker, int userint1) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.userint1 = userint1; - write_item (sheet, item); -} - - -void Database_Styles::updateUserint2 (string sheet, string marker, int userint2) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.userint2 = userint2; - write_item (sheet, item); -} - - -void Database_Styles::updateUserstring1 (string sheet, string marker, string userstring1) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.userstring1 = userstring1; - write_item (sheet, item); -} - - -void Database_Styles::updateUserstring2 (string sheet, string marker, string userstring2) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.userstring2 = userstring2; - write_item (sheet, item); -} - - -void Database_Styles::updateUserstring3 (string sheet, string marker, string userstring3) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.userstring3 = userstring3; - write_item (sheet, item); -} - - -void Database_Styles::updateBackgroundColor (string sheet, string marker, string color) -{ - Database_Styles_Item item = read_item (sheet, marker); - item.backgroundcolor = color; - write_item (sheet, item); -} - - -// Grant $user write access to stylesheet $sheet. -void Database_Styles::grantWriteAccess (string user, string sheet) -{ - SqliteSQL sql; - sql.add ("INSERT INTO users VALUES ("); - sql.add (user); - sql.add (","); - sql.add (sheet); - sql.add (");"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Revoke a $user's write access to stylesheet $sheet. -// If the $user is empty, then revoke write access of anybody to that $sheet. -void Database_Styles::revokeWriteAccess (string user, string sheet) -{ - SqliteSQL sql; - sql.add ("DELETE FROM users WHERE"); - if (!user.empty ()) { - sql.add ("user ="); - sql.add (user); - sql.add ("AND"); - } - sql.add ("sheet ="); - sql.add (sheet); - sql.add (";"); - sqlite3 * db = connect (); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); -} - - -// Returns true or false depending on whether $user has write access to $sheet. -bool Database_Styles::hasWriteAccess (string user, string sheet) -{ - SqliteSQL sql; - sql.add ("SELECT rowid FROM users WHERE user ="); - sql.add (user); - sql.add ("AND sheet ="); - sql.add (sheet); - sql.add (";"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - return !result["rowid"].empty (); -} - - -string Database_Styles::databasefolder () -{ - return filter_url_create_root_path ({database_logic_databases (), "styles"}); -} - - -string Database_Styles::sheetfolder (string sheet) -{ - return filter_url_create_path ({databasefolder (), sheet}); -} - - -string Database_Styles::stylefile (string sheet, string marker) -{ - return filter_url_create_path ({sheetfolder (sheet), marker}); -} - - -// Reads a style from file. -// If the file is not there, it takes the default value. -Database_Styles_Item Database_Styles::read_item (string sheet, string marker) -{ - Database_Styles_Item item; - - // Check whether sheet is in cache. - bool cache_hit = false; - database_styles_cache_mutex.lock (); - if (database_styles_cache.count (sheet)) { - // Check whether marker is in cache. - if (database_styles_cache [sheet].count (marker)) { - // Cache hit: Return the item. - item = database_styles_cache [sheet] [marker]; - cache_hit = true; - } - } - database_styles_cache_mutex.unlock (); - if (cache_hit) return item; - - // Read the item. - bool take_default = sheet.empty (); - string filename; - if (!take_default) { - filename = stylefile (sheet, marker); - if (!file_or_dir_exists (filename)) take_default = true; - } - if (take_default) { - // Check and/or load defaults. - if (default_styles_cache.empty ()) cache_defaults (); - // Take the default style for the marker. - if (default_styles_cache.count (marker)) { - // Get it. - item = default_styles_cache [marker]; - // Cache it. - database_styles_cache_mutex.lock (); - database_styles_cache [sheet] [marker] = item; - database_styles_cache_mutex.unlock (); - // Return it. - return item; - } - // Non-standard marker. - item.marker = marker; - item.name = translate ("Name"); - item.info = translate ("Information"); - } else { - // Read the style from file. - string contents = filter_url_file_get_contents (filename); - vector lines = filter::strings::explode (contents, '\n'); - for (unsigned int i = 0; i < lines.size(); i++) { - if (i == 0) item.marker = lines [i]; - if (i == 1) item.name = lines [i]; - if (i == 2) item.info = lines [i]; - if (i == 3) item.category = lines [i]; - if (i == 4) item.type = filter::strings::convert_to_int (lines [i]); - if (i == 5) item.subtype = filter::strings::convert_to_int (lines [i]); - if (i == 6) item.fontsize = filter::strings::convert_to_float (lines [i]); - if (i == 7) item.italic = filter::strings::convert_to_int (lines [i]); - if (i == 8) item.bold = filter::strings::convert_to_int (lines [i]); - if (i == 9) item.underline = filter::strings::convert_to_int (lines [i]); - if (i == 10) item.smallcaps = filter::strings::convert_to_int (lines [i]); - if (i == 11) item.superscript = filter::strings::convert_to_int (lines [i]); - if (i == 12) item.justification = filter::strings::convert_to_int (lines [i]); - if (i == 13) item.spacebefore = filter::strings::convert_to_float (lines [i]); - if (i == 14) item.spaceafter = filter::strings::convert_to_float (lines [i]); - if (i == 15) item.leftmargin = filter::strings::convert_to_float (lines [i]); - if (i == 16) item.rightmargin = filter::strings::convert_to_float (lines [i]); - if (i == 17) item.firstlineindent = filter::strings::convert_to_float (lines [i]); - if (i == 18) item.spancolumns = filter::strings::convert_to_bool (lines [i]); - if (i == 19) item.color = lines [i]; - if (i == 20) item.print = filter::strings::convert_to_bool (lines [i]); - if (i == 21) item.userbool1 = filter::strings::convert_to_bool (lines [i]); - if (i == 22) item.userbool2 = filter::strings::convert_to_bool (lines [i]); - if (i == 23) item.userbool3 = filter::strings::convert_to_bool (lines [i]); - if (i == 24) item.userint1 = filter::strings::convert_to_int (lines [i]); - if (i == 25) item.userint2 = filter::strings::convert_to_int (lines [i]); - if (i == 26) item.userint3 = filter::strings::convert_to_int (lines [i]); - if (i == 27) item.userstring1 = lines [i]; - if (i == 28) item.userstring2 = lines [i]; - if (i == 29) item.userstring3 = lines [i]; - if (i == 30) item.backgroundcolor = lines [i]; - } - } - - // Cache the item. - database_styles_cache_mutex.lock (); - database_styles_cache [sheet] [marker] = item; - database_styles_cache_mutex.unlock (); - - // Return the item. - return item; -} - - -void Database_Styles::write_item (string sheet, Database_Styles_Item & item) -{ - // The style is saved to file here. - // When the style is loaded again from file, the various parts of the style are loaded by line number. - // Therefore it cannot handle strings with new lines in them. - // Remove the new lines where appropriate. - item.name = filter::strings::replace ("\n", " ", item.name); - item.name = filter::strings::replace ("\r", " ", item.name); - item.info = filter::strings::replace ("\n", " ", item.info); - item.info = filter::strings::replace ("\r", " ", item.info); - // Load the lines. - vector lines; - lines.push_back (item.marker); - lines.push_back (item.name); - lines.push_back (item.info); - lines.push_back (item.category); - lines.push_back (filter::strings::convert_to_string (item.type)); - lines.push_back (filter::strings::convert_to_string (item.subtype)); - lines.push_back (filter::strings::convert_to_string (item.fontsize)); - lines.push_back (filter::strings::convert_to_string (item.italic)); - lines.push_back (filter::strings::convert_to_string (item.bold)); - lines.push_back (filter::strings::convert_to_string (item.underline)); - lines.push_back (filter::strings::convert_to_string (item.smallcaps)); - lines.push_back (filter::strings::convert_to_string (item.superscript)); - lines.push_back (filter::strings::convert_to_string (item.justification)); - lines.push_back (filter::strings::convert_to_string (item.spacebefore)); - lines.push_back (filter::strings::convert_to_string (item.spaceafter)); - lines.push_back (filter::strings::convert_to_string (item.leftmargin)); - lines.push_back (filter::strings::convert_to_string (item.rightmargin)); - lines.push_back (filter::strings::convert_to_string (item.firstlineindent)); - lines.push_back (filter::strings::convert_to_string (item.spancolumns)); - lines.push_back (item.color); - lines.push_back (filter::strings::convert_to_string (item.print)); - lines.push_back (filter::strings::convert_to_string (item.userbool1)); - lines.push_back (filter::strings::convert_to_string (item.userbool2)); - lines.push_back (filter::strings::convert_to_string (item.userbool3)); - lines.push_back (filter::strings::convert_to_string (item.userint1)); - lines.push_back (filter::strings::convert_to_string (item.userint2)); - lines.push_back (filter::strings::convert_to_string (item.userint3)); - lines.push_back (item.userstring1); - lines.push_back (item.userstring2); - lines.push_back (item.userstring3); - lines.push_back (item.backgroundcolor); - // Save. - string data = filter::strings::implode (lines, "\n"); - filter_url_file_put_contents (stylefile (sheet, item.marker), data); - // Clear cache. - database_styles_cache_mutex.lock (); - database_styles_cache.clear (); - database_styles_cache_mutex.unlock (); -} - - -void Database_Styles::cache_defaults () -{ - // The amount of style values in the table. - unsigned int data_count = sizeof (styles_table) / sizeof (*styles_table); - - // Iterate over the entire table. - for (unsigned int i = 0; i < data_count; i++) { - - // Get the default values for one USFM marker. - Database_Styles_Item item; - item.marker = styles_table[i].marker; - item.name = styles_table[i].name; - item.info = styles_table[i].info; - item.category = styles_table[i].category; - item.type = styles_table[i].type; - item.subtype = styles_table[i].subtype; - item.fontsize = styles_table[i].fontsize; - item.italic = styles_table[i].italic; - item.bold = styles_table[i].bold; - item.underline = styles_table[i].underline; - item.smallcaps = styles_table[i].smallcaps; - item.superscript = styles_table[i].superscript; - item.justification = styles_table[i].justification; - item.spacebefore = styles_table[i].spacebefore; - item.spaceafter = styles_table[i].spaceafter; - item.leftmargin = styles_table[i].leftmargin; - item.rightmargin = styles_table[i].rightmargin; - item.firstlineindent = styles_table[i].firstlineindent; - item.spancolumns = styles_table[i].spancolumns; - item.color = styles_table[i].color; - item.print = styles_table[i].print; - item.userbool1 = styles_table[i].userbool1; - item.userbool2 = styles_table[i].userbool2; - item.userbool3 = styles_table[i].userbool3; - item.userint1 = styles_table[i].userint1; - item.userint2 = styles_table[i].userint2; - item.userint3 = styles_table[i].userint3; - item.userstring1 = styles_table[i].userstring1; - item.userstring2 = styles_table[i].userstring2; - item.userstring3 = styles_table[i].userstring3; - item.backgroundcolor = styles_table[i].backgroundcolor; - - // Store the default item in the global default cache. - database_styles_cache_mutex.lock (); - default_styles_cache [item.marker] = item; - database_styles_cache_mutex.unlock (); - } -} - - diff --git a/database/styles.h b/database/styles.h deleted file mode 100644 index 1869b18b3..000000000 --- a/database/styles.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -struct Database_Styles_Item -{ - std::string marker {}; - std::string name {}; - std::string info {}; - std::string category {}; - int type {0}; - int subtype {0}; - float fontsize {12.0f}; - int italic {0}; - int bold {0}; - int underline {0}; - int smallcaps {0}; - int superscript {0}; - int justification {0}; - float spacebefore {0.0f}; - float spaceafter {0.0f}; - float leftmargin {0.0f}; - float rightmargin {0.0f}; - float firstlineindent {0.0f}; - bool spancolumns {false}; - std::string color {"#000000"}; - bool print {false}; - bool userbool1 {false}; - bool userbool2 {false}; - bool userbool3 {false}; - int userint1 {0}; - int userint2 {0}; - int userint3 {0}; - std::string userstring1 {}; - std::string userstring2 {}; - std::string userstring3 {}; - std::string backgroundcolor {"#FFFFFF"}; -}; - - -class Database_Styles -{ -public: - void create (); - void createSheet (std::string sheet); - std::vector getSheets (); - void deleteSheet (std::string sheet); - void addMarker (std::string sheet, std::string marker); - void deleteMarker (std::string sheet, std::string marker); - std::map getMarkersAndNames (std::string sheet); - std::vector getMarkers (std::string sheet); - Database_Styles_Item getMarkerData (std::string sheet, std::string marker); - void updateName (std::string sheet, std::string marker, std::string name); - void updateInfo (std::string sheet, std::string marker, std::string info); - void updateCategory (std::string sheet, std::string marker, std::string category); - void updateType (std::string sheet, std::string marker, int type); - void updateSubType (std::string sheet, std::string marker, int subtype); - void updateFontsize (std::string sheet, std::string marker, float fontsize); - void updateItalic (std::string sheet, std::string marker, int italic); - void updateBold (std::string sheet, std::string marker, int bold); - void updateUnderline (std::string sheet, std::string marker, int underline); - void updateSmallcaps (std::string sheet, std::string marker, int smallcaps); - void updateSuperscript (std::string sheet, std::string marker, int superscript); - void updateJustification (std::string sheet, std::string marker, int justification); - void updateSpaceBefore (std::string sheet, std::string marker, float spacebefore); - void updateSpaceAfter (std::string sheet, std::string marker, float spaceafter); - void updateLeftMargin (std::string sheet, std::string marker, float leftmargin); - void updateRightMargin (std::string sheet, std::string marker, float rightmargin); - void updateFirstLineIndent (std::string sheet, std::string marker, float firstlineindent); - void updateSpanColumns (std::string sheet, std::string marker, bool spancolumns); - void updateColor (std::string sheet, std::string marker, std::string color); - void updatePrint (std::string sheet, std::string marker, bool print); - void updateUserbool1 (std::string sheet, std::string marker, bool userbool1); - void updateUserbool2 (std::string sheet, std::string marker, bool userbool2); - void updateUserbool3 (std::string sheet, std::string marker, bool userbool3); - void updateUserint1 (std::string sheet, std::string marker, int userint1); - void updateUserint2 (std::string sheet, std::string marker, int userint2); - void updateUserstring1 (std::string sheet, std::string marker, std::string userstring1); - void updateUserstring2 (std::string sheet, std::string marker, std::string userstring2); - void updateUserstring3 (std::string sheet, std::string marker, std::string userstring3); - void updateBackgroundColor (std::string sheet, std::string marker, std::string color); - void grantWriteAccess (std::string user, std::string sheet); - void revokeWriteAccess (std::string user, std::string sheet); - bool hasWriteAccess (std::string user, std::string sheet); -private: - sqlite3 * connect (); - std::string databasefolder (); - std::string sheetfolder (std::string sheet); - std::string stylefile (std::string sheet, std::string marker); - Database_Styles_Item read_item (std::string sheet, std::string marker); - void write_item (std::string sheet, Database_Styles_Item & item); - void cache_defaults (); -}; diff --git a/database/stylesdata.h b/database/stylesdata.h deleted file mode 100644 index 6e25df456..000000000 --- a/database/stylesdata.h +++ /dev/null @@ -1,6829 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -typedef struct -{ - const char * marker; - std::string name; - std::string info; - const char * category; - int type; - int subtype; - float fontsize; - int italic; - int bold; - int underline; - int smallcaps; - int superscript; - int justification; - float spacebefore; - float spaceafter; - float leftmargin; - float rightmargin; - float firstlineindent; - int spancolumns; - const char * color; - bool print; - bool userbool1; - bool userbool2; - bool userbool3; - int userint1; - int userint2; - int userint3; - const char * userstring1; - const char * userstring2; - const char * userstring3; - const char * backgroundcolor; -} -style_record; - - -// Default stylesheet values. -// In English. -style_record styles_table [] = -{ - { - /* marker */ "add", - /* name */ "Translator’s addition", - /* info */ "A translator’s explanation - words added by the translator for clarity – text which is not literally a part of the original language, but which was supplied to make the meaning of the original clear.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "addpn", - /* name */ "Combined add and pn style", - /* info */ "Support for overlapping pn ...pn* and add ...add* occurrences. Deprecated.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "b", - /* name */ "Blank line", - /* info */ "May be used to explicitly indicate additional white space between paragraphs. Poetry text stanza break.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 10, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "bd", - /* name */ "Bold text", - /* info */ "Bold text", - /* category */ "cs", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "bdit", - /* name */ "Bold-italic text", - /* info */ "A character style, use bold + italic text", - /* category */ "cs", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "bk", - /* name */ "Quoted book title", - /* info */ "For the quoted name of a book", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "c", - /* name */ "Chapter number", - /* info */ "Chapter number", - /* category */ "cv", - /* type */ 5, - /* subtype */ 0, - /* fontsize */ 18, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 1, - /* userbool2 */ 1, - /* userbool3 */ 1, - /* userint1 */ 90, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ca", - /* name */ "Alternate chapter number", - /* info */ "Second or alternate chapter number. For coding dual versification. Useful for places where different traditions of chapter breaks need to be supported in the same translation. Bibledit does nothing with this marker yet.", - /* category */ "cv", - /* type */ 0, - /* subtype */ 4, - /* fontsize */ 16, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 20, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "cat", - /* name */ "Category tag", - /* info */ "Extended note or sidebar category tag.", - /* category */ "id", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "cd", - /* name */ "Chapter description", - /* info */ "Chapter description", - /* category */ "cv", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 11, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "cl", - /* name */ "Chapter label", - /* info */ "Chapter label used for translations that add a word such as 'Chapter' before chapter numbers, e.g. Psalms.", - /* category */ "cv", - /* type */ 0, - /* subtype */ 7, - /* fontsize */ 18, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "cls", - /* name */ "Closure of an epistle", - /* info */ "Closure of an epistle", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "cp", - /* name */ "Published chapter character", - /* info */ "Published chapter number. This is a chapter marking that would be used in the published text.", - /* category */ "cv", - /* type */ 0, - /* subtype */ 8, - /* fontsize */ 18, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "d", - /* name */ "Descriptive title or Hebrew subtitle", - /* info */ "A Hebrew text heading, to provide description, e.g. Psalms", - /* category */ "t", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 4, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "dc", - /* name */ "Deuterocanonical", - /* info */ "Deuterocanonical / LXX additions or insertions in the Protocanonical text", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ef", - /* name */ "Extended footnote", - /* info */ "Extended footnote element.", - /* category */ "f", - /* type */ 7, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 2, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "em", - /* name */ "Emphasized text", - /* info */ "A character style, use emphasized text style.", - /* category */ "cs", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "esb", - /* name */ "Sidebar start", - /* info */ "Beginning or opening of the sidebar content section", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "esbe", - /* name */ "Sidebar end", - /* info */ "End or closing of the sidebar content section", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ex", - /* name */ "Extended cross reference", - /* info */ "Extended cross reference element.", - /* category */ "x", - /* type */ 8, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 2, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "f", - /* name */ "Footnote", - /* info */ "A footnote text item.", - /* category */ "f", - /* type */ 7, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 2, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fdc", - /* name */ "Footnote Deuterocanonical content", - /* info */ "Text between these markers is material to be included only in published editions that contain the Deuterocanonical books. Deprecated.", - /* category */ "f", - /* type */ 7, - /* subtype */ 4, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 1, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fe", - /* name */ "Endnote", - /* info */ "An endnote text item.", - /* category */ "f", - /* type */ 7, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "zendnotes", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fig", - /* name */ "Figure / illustration / map", - /* info */ "Illustration [columns to span, height, filename, caption text]", - /* category */ "sf", - /* type */ 10, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fk", - /* name */ "Footnote keyword", - /* info */ "The specific keyword or term from the text for which the footnote is being provided.", - /* category */ "f", - /* type */ 7, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fl", - /* name */ "Footnote label text", - /* info */ "Can be used for marking or “labeling” a word or words which are used consistently across certain types of translation notes, such as the words 'Or' in an alternative translation note, 'Others', 'Heb.', 'LXX' etc.", - /* category */ "f", - /* type */ 7, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fm", - /* name */ "Footnote reference mark", - /* info */ "An additional footnote marker location for a previous footnote.", - /* category */ "f", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 1, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fp", - /* name */ "Footnote additional paragraph", - /* info */ "Use this marker to if you need to indicate the start of a new paragraph within a footnote.", - /* category */ "f", - /* type */ 7, - /* subtype */ 5, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 3, - /* rightmargin */ 0, - /* firstlineindent */ 3, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fq", - /* name */ "Footnote translation quotation", - /* info */ "A quotation from the current scripture text translation for which the note is being provided.", - /* category */ "f", - /* type */ 7, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fqa", - /* name */ "Footnote alternate translation", - /* info */ "Used to distinguish between a quotation of the current scripture text translation, and an alternate translation.", - /* category */ "f", - /* type */ 7, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fr", - /* name */ "Footnote origin reference", - /* info */ "This is the chapter and verse or verses that note refers to.", - /* category */ "f", - /* type */ 7, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ft", - /* name */ "Footnote text", - /* info */ "The essential or explanatory text of the footnote.", - /* category */ "f", - /* type */ 7, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 4, - /* rightmargin */ 0, - /* firstlineindent */ -4, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "fv", - /* name */ "Footnote verse number", - /* info */ "A verse number within the footnote text.", - /* category */ "f", - /* type */ 7, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 1, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "h", - /* name */ "Running header", - /* info */ "Running header text for a book", - /* category */ "id", - /* type */ 0, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 1, - /* userbool3 */ 1, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "h1", - /* name */ "Deprecated running header", - /* info */ "Deprecated running header text", - /* category */ "id", - /* type */ 0, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 1, - /* userbool3 */ 1, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "h2", - /* name */ "Deprecated left running header", - /* info */ "Deprecated running header text, left side of page", - /* category */ "id", - /* type */ 0, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 1, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "h3", - /* name */ "Deprecated right running header", - /* info */ "Deprecated running header text, right side of page", - /* category */ "id", - /* type */ 0, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 1, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ib", - /* name */ "Introduction blank line", - /* info */ "May be used to explicitly indicate additional white space between paragraphs.", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 10, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "id", - /* name */ "Identification", - /* info */ "File identification information [name of file, book name, language, last edited, date etc.]", - /* category */ "id", - /* type */ 0, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 1, - /* userbool2 */ 1, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ide", - /* name */ "Encoding", - /* info */ "File encoding information. Bibledit disregards this marker, as all text in Bibledit is in UTF-8 encoding.", - /* category */ "id", - /* type */ 0, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "", - }, - { - /* marker */ "ie", - /* name */ "Introduction end", - /* info */ "Optionally included to explicitly indicate the end of the introduction material", - /* category */ "ioe", - /* type */ 0, - /* subtype */ 0, - /* fontsize */ 10, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "iex", - /* name */ "Explanatory or bridge text", - /* info */ "Introduction explanatory or bridge text, e.g. explanation of missing book in Short Old Testament)", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 4, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 3.2f, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ili", - /* name */ "Introduction list item", - /* info */ "A list entry, level 1, if single level", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 12.7f, - /* rightmargin */ 0, - /* firstlineindent */ -9.5f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ili1", - /* name */ "Introduction list item level 1", - /* info */ "A list entry, level 1, if multiple levels", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 12.7f, - /* rightmargin */ 0, - /* firstlineindent */ -9.5f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ili2", - /* name */ "Introduction list item level 2", - /* info */ "A list entry, level 2", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 19.1f, - /* rightmargin */ 0, - /* firstlineindent */ -9.5f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "im", - /* name */ "Introduction flush left paragraph", - /* info */ "Introduction prose paragraph, with no first line indent. May occur after poetry).", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imi", - /* name */ "Indented introduction flush left paragraph", - /* info */ "Introduction prose paragraph text, indented, with no first line indent", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imq", - /* name */ "Introduction flush left quote from text paragraph", - /* info */ "Introduction prose paragraph, quote from the body text, with no first line indent", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imt", - /* name */ "Introduction major title level 1", - /* info */ "Introduction major title, level 1, if single level", - /* category */ "ith", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 14, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imt1", - /* name */ "Introduction major title level 1", - /* info */ "Introduction major title, level 1, if multiple levels", - /* category */ "ith", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 14, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imt2", - /* name */ "Introduction major title level 2", - /* info */ "Introduction major title, level 2", - /* category */ "ith", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 13, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 6, - /* spaceafter */ 3, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imt3", - /* name */ "Introduction major title level 3", - /* info */ "Introduction major title, level 3", - /* category */ "ith", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 2, - /* spaceafter */ 2, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imt4", - /* name */ "Introduction major title level 4", - /* info */ "Introduction major title, level 4.", - /* category */ "ith", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 2, - /* spaceafter */ 2, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imte", - /* name */ "Introduction major title ending", - /* info */ "Used to mark a major title indicating the end of the introduction", - /* category */ "ith", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 20, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imte1", - /* name */ "Introduction major title ending level 1", - /* info */ "Used to mark a major title indicating the end of the introduction", - /* category */ "ith", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 20, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "imte2", - /* name */ "Introduction major title ending level 2", - /* info */ "Used to mark a major title indicating the end of the introduction", - /* category */ "ith", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 16, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 0, - /* spaceafter */ 2, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "io", - /* name */ "Introduction outline entry", - /* info */ "Introduction outline text, level 1, if single level", - /* category */ "ioe", - /* type */ 3, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 12.7f, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "io1", - /* name */ "Introduction outline entry Level 1", - /* info */ "Introduction outline text, level 1, if multiple levels", - /* category */ "ioe", - /* type */ 3, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 12.7f, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "io2", - /* name */ "Introduction outline entry Level 2", - /* info */ "Introduction outline text, level 2", - /* category */ "ioe", - /* type */ 3, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 19.1f, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "io3", - /* name */ "Introduction outline entry level 3", - /* info */ "Introduction outline text, level 3", - /* category */ "ioe", - /* type */ 3, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "io4", - /* name */ "Introduction outline entry level 4", - /* info */ "Introduction outline text, level 4", - /* category */ "ioe", - /* type */ 3, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 31.8f, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ior", - /* name */ "Introduction outline reference range", - /* info */ "Introduction references range for outline entry; for marking references separately", - /* category */ "ioe", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "iot", - /* name */ "Introduction outline title", - /* info */ "Introduction outline title", - /* category */ "ioe", - /* type */ 3, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ip", - /* name */ "Introduction paragraph", - /* info */ "Introduction prose paragraph", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 3.2f, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ipi", - /* name */ "Indented introduction paragraph", - /* info */ "Introduction prose paragraph, with first line indent", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 3.2f, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ipq", - /* name */ "Introduction quote from text paragraph", - /* info */ "Introduction prose paragraph, quote from the body text", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 3.2f, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ipr", - /* name */ "Introduction right-aligned paragraph", - /* info */ "Introduction prose paragraph, right aligned", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "iq", - /* name */ "Introduction poetic line", - /* info */ "Introduction poetry text, level 1, if single level", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -19.1f, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "iq1", - /* name */ "Introduction poetic line Level 1", - /* info */ "Introduction poetry text, level 1, if multiple levels", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -19.1f, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "iq2", - /* name */ "Introduction poetic line level 2", - /* info */ "Introduction poetry text, level 2", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -12.7f, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "iq3", - /* name */ "Introduction poetic line level 3", - /* info */ "Introduction poetry text, level 3", - /* category */ "ipp", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -6.4f, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "iqt", - /* name */ "Introduction quoted text", - /* info */ "Scripture quotations, or other quoted text, appearing in the introduction", - /* category */ "ioe", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "is", - /* name */ "Introduction section heading level 1", - /* info */ "Introduction section heading, level 1, if single level", - /* category */ "ith", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 14, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "is1", - /* name */ "Introduction section heading level 1", - /* info */ "Introduction section heading, level 1, if multiple levels", - /* category */ "ith", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 14, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "is2", - /* name */ "Introduction section heading level 2", - /* info */ "Introduction section heading, level 2", - /* category */ "ith", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "it", - /* name */ "Italic text", - /* info */ "A character style, use italic text", - /* category */ "cs", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "jmp", - /* name */ "Link text", - /* info */ "Optionally used for associating linking attributes to a span of text when no other character level markup is applied to the same span.", - /* category */ "sf", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 2, - /* bold */ 2, - /* underline */ 1, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#0000FF", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "k", - /* name */ "Keyword", - /* info */ "Keyword / keyterm", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "lf", - /* name */ "List footer", - /* info */ "Some lists include an introductory and concluding remark. They are an integral part of the list content, but are not list items. A list does not require either or both of these elements.", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 10, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "lh", - /* name */ "List header", - /* info */ "Some lists include an introductory and concluding remark. They are an integral part of the list content, but are not list items. A list does not require either or both of these elements.", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "li", - /* name */ "List entry", - /* info */ "A list entry, level 1, if single level", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 12.7f, - /* rightmargin */ 0, - /* firstlineindent */ -9.5f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "li1", - /* name */ "List entry level 1", - /* info */ "A list entry, level 1, if multiple levels", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 12.7f, - /* rightmargin */ 0, - /* firstlineindent */ -9.5f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "li2", - /* name */ "List entry level 2", - /* info */ "A list entry, level 2", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 19.1f, - /* rightmargin */ 0, - /* firstlineindent */ -9.5f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "li3", - /* name */ "List entry level 3", - /* info */ "A list entry, level 3", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -9.5, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "li4", - /* name */ "List entry level 4", - /* info */ "A list entry, level 4", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 31.8f, - /* rightmargin */ 0, - /* firstlineindent */ -9.5f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "lik", - /* name */ "List entry 'key' content", - /* info */ "The 'key' content will be followed by 'value' content", - /* category */ "l", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "lim", - /* name */ "Embedded list entry", - /* info */ "An out-dented paragraph meant to highlight the items of an embedded list", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 19.1f, - /* rightmargin */ 6.4f, - /* firstlineindent */ -9.5f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "lim1", - /* name */ "Embedded list entry level 1", - /* info */ "An out-dented paragraph meant to highlight the items of an embedded list, level 1", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 19.1f, - /* rightmargin */ 6.4f, - /* firstlineindent */ -9.5f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "lim2", - /* name */ "Embedded list entry level 2", - /* info */ "An out-dented paragraph meant to highlight the items of an embedded list, level 2", - /* category */ "l", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -9.5, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "lit", - /* name */ "Liturgical note", - /* info */ "A guide which tells the reader or worshipper that he should recite a prayer or recitation etc.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "litl", - /* name */ "List entry total", - /* info */ "Use in accounting lists for denoting the total component of the text within a list item", - /* category */ "l", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "liv", - /* name */ "List entry 'value' content", - /* info */ "The 'value' content follows the 'key' content", - /* category */ "l", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "liv1", - /* name */ "List entry 'value' content level 1", - /* info */ "The 'value' content follows the 'key' content, level 1", - /* category */ "l", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "m", - /* name */ "Continuation paragraph", - /* info */ "Paragraph text, with no first line indent", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mi", - /* name */ "Indented flush left paragraph", - /* info */ "Paragraph text, indented, with no first line indent, often used for discourse.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mr", - /* name */ "Major section reference range", - /* info */ "The text reference range listed under a major section heading", - /* category */ "h", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 0, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ms", - /* name */ "Major section heading", - /* info */ "A major section division heading, level 1, if single level", - /* category */ "h", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 14, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 16, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ms1", - /* name */ "Major section heading level 1", - /* info */ "A major section division heading, level 1, if multiple levels", - /* category */ "h", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 14, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 16, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ms2", - /* name */ "Major section heading level 2", - /* info */ "A major section division heading, level 2", - /* category */ "h", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 14, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 16, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mt", - /* name */ "Major title", - /* info */ "The main title of the book, if single level", - /* category */ "t", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 20, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mt1", - /* name */ "Major title level 1", - /* info */ "The main title of the book, if multiple levels", - /* category */ "t", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 20, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 2, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mt2", - /* name */ "Major title level 2", - /* info */ "A secondary title with less important information than the main title.", - /* category */ "t", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 16, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 0, - /* spaceafter */ 2, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mt3", - /* name */ "Major title level 3", - /* info */ "A secondary title, less important than the main title.", - /* category */ "t", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 16, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 2, - /* spaceafter */ 2, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mt4", - /* name */ "Major title level 4", - /* info */ "A small secondary title sometimes occurring within parentheses.", - /* category */ "t", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 2, - /* spaceafter */ 2, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mte", - /* name */ "Major title at ending", - /* info */ "The main title of the book repeated at the end of the book, if single level.", - /* category */ "t", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 20, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mte1", - /* name */ "Major title at ending level 1", - /* info */ "The main title of the book repeated at the end of the book, if multiple levels", - /* category */ "t", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 20, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "mte2", - /* name */ "Major title at ending level 2", - /* info */ "A secondary title occurring before or after the ending main title.", - /* category */ "t", - /* type */ 3, - /* subtype */ 0, - /* fontsize */ 16, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 0, - /* spaceafter */ 2, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 1, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "nb", - /* name */ "No break with previous paragraph", - /* info */ "Paragraph text, with no break from previous paragraph text, at chapter boundary.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "nd", - /* name */ "Name of God", - /* info */ "For name of God", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 1, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ndx", - /* name */ "Subject index entry", - /* info */ "Surround a word or words with this markup to indicate that it appears or should appear in the subject index.", - /* category */ "sf", - /* type */ 13, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "no", - /* name */ "Normal text", - /* info */ "May be used when a larger paragraph element is set in an alternate font style, e.g. italic, and a selected section of text should be displayed in normal text.", - /* category */ "cs", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "ord", - /* name */ "Ordinal number ending", - /* info */ "For the text portion of an ordinal number", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 1, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "p", - /* name */ "Normal paragraph", - /* info */ "Paragraph text, with first line indent", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pb", - /* name */ "Page break", - /* info */ "Page break used for new reader portions and children's bibles where content is controlled by the page.", - /* category */ "sb", - /* type */ 11, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pc", - /* name */ "Centered paragraph", - /* info */ "Paragraph text, centered, for inscription.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pi", - /* name */ "Indented paragraph", - /* info */ "Paragraph text, level 1 indent, if single level, with first line indent; often used for discourse.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pi1", - /* name */ "Indented paragraph level 1", - /* info */ "Paragraph text, level 1 indent, if multiple levels, with first line indent; often used for discourse.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pi2", - /* name */ "Indented paragraph level 2", - /* info */ "Paragraph text, level 2 indent, with first line indent; often used for discourse.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 12.7f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pi3", - /* name */ "Indented paragraph level 3", - /* info */ "Paragraph text, level 3 indent, with first line indent; often used for discourse.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 19.1f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pm", - /* name */ "Embedded text paragraph", - /* info */ "Embedded text paragraph.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pmc", - /* name */ "Embedded text closing", - /* info */ "Embedded text closing.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pmo", - /* name */ "Embedded text opening", - /* info */ "Embedded text opening.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pmr", - /* name */ "Embedded text refrain", - /* info */ "Embedded text refrain, e.g. Then all the people shall say, Amen!", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 6.4f, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pn", - /* name */ "Proper name", - /* info */ "For a proper name.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 1, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "png", - /* name */ "Geographic proper name", - /* info */ "For a geographic proper name.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 1, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "po", - /* name */ "Paragraph opening an epistle", - /* info */ "Paragraph opening an epistle or letter, without first line indent.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 4, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 3.2f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "pro", - /* name */ "Pronunciation annotation", - /* info */ "For indicating pronunciation in CJK texts. Deprecated.", - /* category */ "sf", - /* type */ 0, - /* subtype */ 9, - /* fontsize */ 10, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "q", - /* name */ "Poetic line", - /* info */ "Poetry text, level 1 indent, if single level.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 31.8f, - /* rightmargin */ 0, - /* firstlineindent */ -25.4f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "q1", - /* name */ "Poetic line level 1", - /* info */ "Poetry text, level 1 indent, if multiple levels.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 31.8f, - /* rightmargin */ 0, - /* firstlineindent */ -25.4f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "q2", - /* name */ "Poetic line level 2", - /* info */ "Poetry text, level 2 indent.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 31.8f, - /* rightmargin */ 0, - /* firstlineindent */ -19.1f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "q3", - /* name */ "Poetic line level 3", - /* info */ "Poetry text, level 3 indent.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 31.8f, - /* rightmargin */ 0, - /* firstlineindent */ -12.7f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qa", - /* name */ "Acrostic heading", - /* info */ "Poetry text, acrostic marker or heading.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qac", - /* name */ "Acrostic letter", - /* info */ "Poetry text, acrostic markup of the first character of a line of acrostic poetry.", - /* category */ "pe", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qc", - /* name */ "Centered poetic line", - /* info */ "Poetry text, centered.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qd", - /* name */ "Hebrew note", - /* info */ "A Hebrew musical performance comment similar in content to many of the Hebrew Psalm titles, but placed at the end of the poetic section.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 6.4f, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qm", - /* name */ "Embedded text poetic line", - /* info */ "Poetry text, embedded, level 1 indent, if single level.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -19.1f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qm1", - /* name */ "Embedded text poetic line level 1", - /* info */ "Poetry text, embedded, level 1 indent, if multiple levels.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -19.1f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qm2", - /* name */ "Embedded text poetic line level 2", - /* info */ "Poetry text, embedded, level 2 indent.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -12.7f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qm3", - /* name */ "Embedded text poetic line level 3", - /* info */ "Poetry text, embedded, level 3 indent.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 25.4f, - /* rightmargin */ 0, - /* firstlineindent */ -6.4f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qr", - /* name */ "Right-aligned poetic line", - /* info */ "Commonly used for a poetic refrain.", - /* category */ "pe", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qs", - /* name */ "Selah", - /* info */ "Poetry text, Selah.", - /* category */ "pe", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "qt", - /* name */ "Quoted text", - /* info */ "Old Testament quotations in the New Testament, or other quotations.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "r", - /* name */ "Parallel passage references", - /* info */ "Parallel references.", - /* category */ "h", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 0, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "rb", - /* name */ "Annotated base text", - /* info */ "Used to mark the base text being annotated with ruby characters.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "rem", - /* name */ "Remark", - /* info */ "Comments and remarks.", - /* category */ "id", - /* type */ 0, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "rq", - /* name */ "Inline quotation references", - /* info */ "A cross-reference indicating the source text for the preceding quotation.", - /* category */ "h", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 10, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "rt", - /* name */ "Ruby annotation text", - /* info */ "In the case where the annotation text is associated with only a single preceding ideogram, only the 'rt ...rt*' marker is required. The base text markup 'rb ...rb*' is optional in these cases.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 10, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "s", - /* name */ "Section heading", - /* info */ "A section heading, level 1, if single level.", - /* category */ "h", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "s1", - /* name */ "Section heading level 1", - /* info */ "A section heading, level 1, if multiple levels.", - /* category */ "h", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "s2", - /* name */ "Section heading Level 2", - /* info */ "A section heading, level 2.", - /* category */ "h", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "s3", - /* name */ "Section heading level 3", - /* info */ "A section heading, level 3.", - /* category */ "h", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 6, - /* spaceafter */ 3, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "s4", - /* name */ "Section heading level 4", - /* info */ "A section heading, level 4.", - /* category */ "h", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 6, - /* spaceafter */ 3, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sc", - /* name */ "Small-cap text", - /* info */ "A character style, for small capitalization text.", - /* category */ "cs", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 1, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sd", - /* name */ "Semantic division", - /* info */ "Vertical space used to divide the text into sections, in a manner similar to the structure added through the use of a sequence of heading texts.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 20, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 24, - /* spaceafter */ 24, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sd1", - /* name */ "Semantic division level 1", - /* info */ "Vertical space used to divide the text into sections, in a manner similar to the structure added through the use of a sequence of heading texts.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 20, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 24, - /* spaceafter */ 24, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sd2", - /* name */ "Semantic division level 2", - /* info */ "Vertical space used to divide the text into sections, in a manner similar to the structure added through the use of a sequence of heading texts.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 16, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 18, - /* spaceafter */ 18, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sd3", - /* name */ "Semantic division level 3", - /* info */ "Vertical space used to divide the text into sections, in a manner similar to the structure added through the use of a sequence of heading texts.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 16, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 12, - /* spaceafter */ 12, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sd4", - /* name */ "Semantic division level 4", - /* info */ "Vertical space used to divide the text into sections, in a manner similar to the structure added through the use of a sequence of heading texts.", - /* category */ "p", - /* type */ 3, - /* subtype */ 3, - /* fontsize */ 16, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 8, - /* spaceafter */ 8, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sig", - /* name */ "Signature of the author", - /* info */ "Signature of the author of a letter or epistle.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sls", - /* name */ "Secondary language or text source", - /* info */ "Passage of text based on a secondary language or alternate text source.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sp", - /* name */ "Speaker", - /* info */ "A heading to identify the speaker.", - /* category */ "h", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 8, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sr", - /* name */ "Section reference range", - /* info */ "The text reference range listed under a section heading.", - /* category */ "h", - /* type */ 3, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 1, - /* spacebefore */ 0, - /* spaceafter */ 4, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "sts", - /* name */ "Status", - /* info */ "Project text status tracking.", - /* category */ "id", - /* type */ 0, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tc1", - /* name */ "Table column 1 cell", - /* info */ "A table cell item, column 1.", - /* category */ "te", - /* type */ 12, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tc2", - /* name */ "Table column 2 cell", - /* info */ "A table cell item, column 2.", - /* category */ "te", - /* type */ 12, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 2, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tc3", - /* name */ "Table column 3 cell", - /* info */ "A table cell item, column 3.", - /* category */ "te", - /* type */ 12, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 3, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tc4", - /* name */ "Table column 4 cell", - /* info */ "A table cell item, column 4.", - /* category */ "te", - /* type */ 12, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 4, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tcr1", - /* name */ "Right aligned table cell column 1", - /* info */ "A table cell item, column 1, right aligned.", - /* category */ "te", - /* type */ 12, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tcr2", - /* name */ "Right aligned table cell column 2", - /* info */ "A table cell item, column 2, right aligned.", - /* category */ "te", - /* type */ 12, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 2, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tcr3", - /* name */ "Right aligned table cell column 3", - /* info */ "A table cell item, column 3, right aligned.", - /* category */ "te", - /* type */ 12, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 3, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tcr4", - /* name */ "Right aligned table cell column 4", - /* info */ "A table cell item, column 4, right aligned.", - /* category */ "te", - /* type */ 12, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 4, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "th1", - /* name */ "Table column 1 heading", - /* info */ "A table heading, column 1.", - /* category */ "te", - /* type */ 12, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "th2", - /* name */ "Table column 2 heading", - /* info */ "A table heading, column 2.", - /* category */ "te", - /* type */ 12, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 2, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "th3", - /* name */ "Table column 3 heading", - /* info */ "A table heading, column 3.", - /* category */ "te", - /* type */ 12, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 3, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "th4", - /* name */ "Table column 4 heading", - /* info */ "A table heading, column 4.", - /* category */ "te", - /* type */ 12, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 4, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "thr1", - /* name */ "Right aligned table column 1 heading", - /* info */ "A table heading, column 1, right aligned.", - /* category */ "te", - /* type */ 12, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "thr2", - /* name */ "Right aligned table column 2 heading", - /* info */ "A table heading, column 2, right aligned.", - /* category */ "te", - /* type */ 12, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 2, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "thr3", - /* name */ "Right aligned table 3 column heading", - /* info */ "A table heading, column 3, right aligned.", - /* category */ "te", - /* type */ 12, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 3, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "thr4", - /* name */ "Right aligned table column 4 heading", - /* info */ "A table heading, column 4, right aligned.", - /* category */ "te", - /* type */ 12, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 2, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 4, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tl", - /* name */ "Transliterated word", - /* info */ "Transliterated or foreign words.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "toc", - /* name */ "Table of contents", - /* info */ "Front matter table of contents.", - /* category */ "pm", - /* type */ 9, - /* subtype */ 1, - /* fontsize */ 10, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "toc1", - /* name */ "Long table of contents text", - /* info */ "Long table of contents text.", - /* category */ "id", - /* type */ 0, - /* subtype */ 4, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "toc2", - /* name */ "Short table of contents text", - /* info */ "Short table of contents text.", - /* category */ "id", - /* type */ 0, - /* subtype */ 5, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "toc3", - /* name */ "Book abbreviation", - /* info */ "Book abbreviation. Not yet supported in Bibledit.", - /* category */ "id", - /* type */ 0, - /* subtype */ 6, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "tr", - /* name */ "Table row start", - /* info */ "A new table row.", - /* category */ "te", - /* type */ 12, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 12.7f, - /* rightmargin */ 0, - /* firstlineindent */ -6.4f, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "v", - /* name */ "Verse number", - /* info */ "A verse number.", - /* category */ "cv", - /* type */ 6, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 1, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "va", - /* name */ "Alternate verse number", - /* info */ "Second or alternate verse number. For coding dual numeration in Psalms.", - /* category */ "cv", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 1, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "vp", - /* name */ "Published verse marker", - /* info */ "Published verse marker. This is a verse marking that would be used in the published text.", - /* category */ "cv", - /* type */ 0, - /* subtype */ 10, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 1, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "w", - /* name */ "Wordlist entry", - /* info */ "Surround words with this markup to indicate that it appears or should appear in the word list.", - /* category */ "sf", - /* type */ 13, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 2, - /* bold */ 2, - /* underline */ 2, - /* smallcaps */ 2, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "wa", - /* name */ "Aramaic word list entry", - /* info */ "Surround words with this markup to indicate that it appears or should appear in the Aramaic word list.", - /* category */ "sf", - /* type */ 13, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 2, - /* bold */ 2, - /* underline */ 2, - /* smallcaps */ 2, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "wg", - /* name */ "Greek word list entry", - /* info */ "A Greek word list text item.", - /* category */ "sf", - /* type */ 13, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "wh", - /* name */ "Hebrew word list entry", - /* info */ "A Hebrew word list text item.", - /* category */ "sf", - /* type */ 13, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "wj", - /* name */ "Words of Jesus", - /* info */ "For marking the words of Jesus.", - /* category */ "st", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#FF0000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "x", - /* name */ "Cross reference", - /* info */ "A list of cross references.", - /* category */ "x", - /* type */ 8, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 1, - /* userint2 */ 2, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "xdc", - /* name */ "Cross reference deuterocanonical", - /* info */ "References or other text between these markers is material to be included only in published editions that contain the Deuterocanonical books. Deprecated.", - /* category */ "x", - /* type */ 8, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 1, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "xk", - /* name */ "Cross reference keyword", - /* info */ "A keyword from the scripture translation text which the target references also refer to.", - /* category */ "x", - /* type */ 8, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "xnt", - /* name */ "Cross reference New Testament", - /* info */ "References or other text between these markers is material to be included only in published editions that contain the New Testament books.", - /* category */ "x", - /* type */ 8, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "xo", - /* name */ "Cross reference origin reference", - /* info */ "This is the chapter and verse or verses that target references are being provided for.", - /* category */ "x", - /* type */ 8, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 1, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "xop", - /* name */ "Published cross reference origin text", - /* info */ "In some texts, the content intended to be published in the position of the cross reference origin text 'xo' does not follow the typical chapter-separator-verse pattern. An origin reference following this pattern is required for validation of the cross reference location. 'xop' ...'xop*' can be used in order to supply the content intended for publishing, similar to the use of 'cp' and 'vp ...vp*'.", - /* category */ "x", - /* type */ 8, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "xot", - /* name */ "Cross reference Old Testament", - /* info */ "References or other text between these markers is material to be included only in published editions that contain the Old Testament books.", - /* category */ "x", - /* type */ 8, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "xq", - /* name */ "Cross reference quotation", - /* info */ "A cross reference quotation from the scripture text.", - /* category */ "x", - /* type */ 8, - /* subtype */ 2, - /* fontsize */ 12, - /* italic */ 1, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "xt", - /* name */ "Cross reference target references", - /* info */ "The cross reference target references.", - /* category */ "x", - /* type */ 8, - /* subtype */ 1, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 4, - /* rightmargin */ 0, - /* firstlineindent */ -4, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - { - /* marker */ "xta", - /* name */ "Target references added text", - /* info */ "Used for marking text added to the target references. This text should be ignored when identifying or linking to cross reference target references.", - /* category */ "x", - /* type */ 8, - /* subtype */ 3, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - // https://ubsicap.github.io/usfm/peripherals/index.html - { - /* marker */ "periph", - /* name */ "Peripheral", - /* info */ "Divisions for peripheral content.", - /* category */ "pm", - /* type */ 9, - /* subtype */ 10, - /* fontsize */ 10, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 0, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, - // https://ubsicap.github.io/usfm/characters/index.html?highlight=sup#sup-sup - { - /* marker */ "sup", - /* name */ "Superscript text", - /* info */ "Typically for use in critical edition footnotes.", - /* category */ "cs", - /* type */ 4, - /* subtype */ 0, - /* fontsize */ 12, - /* italic */ 0, - /* bold */ 0, - /* underline */ 0, - /* smallcaps */ 0, - /* superscript */ 1, - /* justification */ 0, - /* spacebefore */ 0, - /* spaceafter */ 0, - /* leftmargin */ 0, - /* rightmargin */ 0, - /* firstlineindent */ 0, - /* spancolumns */ 0, - /* color */ "#000000", - /* print */ 1, - /* userbool1 */ 0, - /* userbool2 */ 0, - /* userbool3 */ 0, - /* userint1 */ 0, - /* userint2 */ 0, - /* userint3 */ 0, - /* userstring1 */ "", - /* userstring2 */ "", - /* userstring3 */ "", - /* backgroundcolor */ "#FFFFFF", - }, -}; - diff --git a/database/userresources.cpp b/database/userresources.cpp deleted file mode 100644 index dac342fb9..000000000 --- a/database/userresources.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Database resilience: -// The data is stored as separate files in the filesystem. -// That is resilient enough. - - -// Returns the names of the available user-defined resources. -vector Database_UserResources::names () -{ - vector names; - vector files = filter_url_scandir (folder ()); - for (auto name : files) { - if (name.find (fragment ()) != std::string::npos) { - name.erase (0, fragment ().size ()); - name = filter_url_filename_unclean (name); - names.push_back (name); - } - } - return names; -} - - -// Removes a user-defined resource from disk. -void Database_UserResources::remove (const string& name) -{ - filter_url_unlink (file (name)); -} - - -string Database_UserResources::url (const string& name) -{ - return load (name, 0); -} - - -void Database_UserResources::url (const string& name, const string & value) -{ - save (name, 0, value); -} - - -// Returns the text fragent for a Bible book with $id. -string Database_UserResources::book (const string& name, int id) -{ - if (id < 1) return string(); - return load (name, static_cast(id)); -} - - -// Stores the text fragment for a Bible book in the database. -void Database_UserResources::book (const string& name, int id, const string & fragment) -{ - if (id > 0) save (name, static_cast(id), fragment); -} - - -// The folder for storing the user-defined resource definition files. -string Database_UserResources::folder () -{ - return filter_url_create_root_path ({database_logic_databases (), "client"}); -} - - -// The fragment that always occurs in the name of a user-defined resource definition file. -string Database_UserResources::fragment () -{ - return "user_resource_"; -} - - -// The full path of the definition file. -string Database_UserResources::file (const string& name) -{ - return filter_url_create_path ({folder (), fragment () + filter_url_filename_clean (name)}); -} - - -// Load one value from the user-defined resource definition $name. -// The value is at line number $offset. -string Database_UserResources::load (const string & name, size_t offset) -{ - string path = file (name); - string contents = filter_url_file_get_contents (path); - vector lines = filter::strings::explode (contents, '\n'); - if (offset >= lines.size ()) return string(); - return lines [offset]; -} - - -// Save one value to the user-defined resource definition $name. -// It saves the $value to line number $offset. -void Database_UserResources::save (const string & name, size_t offset, const string & value) -{ - string path = file (name); - string contents = filter_url_file_get_contents (path); - vector lines = filter::strings::explode (contents, '\n'); - while (lines.size () <= offset) lines.push_back (""); - lines [offset] = value; - contents = filter::strings::implode (lines, "\n"); - filter_url_file_put_contents (path, contents); -} diff --git a/database/userresources.h b/database/userresources.h deleted file mode 100644 index 699af3fa8..000000000 --- a/database/userresources.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_UserResources -{ -public: - static std::vector names (); - static void remove (const std::string& name); - static std::string url (const std::string& name); - static void url (const std::string& name, const std::string & value); - static std::string book (const std::string& name, int id); - static void book (const std::string& name, int id, const std::string & fragment); -private: - static std::string folder (); - static std::string fragment (); - static std::string file (const std::string& name); - static std::string load (const std::string & name, size_t offset); - static void save (const std::string & name, size_t offset, const std::string & value); -}; diff --git a/database/users.cpp b/database/users.cpp deleted file mode 100644 index 8334a2eb1..000000000 --- a/database/users.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// This database is resilient. -// The data is stored in a SQLite database. -// This part is read often, and infrequently written to. -// Due to the infrequent write operations, there is a low and acceptable chance of corruption. - - -void Database_Users::create () -{ - SqliteDatabase sql (filename ()); - sql.add ("CREATE TABLE IF NOT EXISTS users (username text, password text, level integer, email text);"); - sql.execute (); -} - - -void Database_Users::upgrade () -{ - // Several extra columns are available in older databases. - // They are not in use. - // They cannot be dropped easily in SQLite. - // Leave them for just now. - - // Add columns for LDAP authentication and for disabling an account, - // if the columns are not yet there. - SqliteDatabase sql (filename ()); - sql.add ("PRAGMA table_info (users);"); - vector columns = sql.query () ["name"]; - if (!in_array (static_cast ("ldap"), columns)) { - sql.clear (); - sql.add ("ALTER TABLE users ADD COLUMN ldap boolean;"); - sql.execute (); - } - if (!in_array (static_cast ("disabled"), columns)) { - sql.clear (); - sql.add ("ALTER TABLE users ADD COLUMN disabled boolean;"); - sql.execute (); - } -} - - -void Database_Users::trim () -{ -} - - -void Database_Users::optimize () -{ - SqliteDatabase sql (filename ()); - sql.add ("VACUUM;"); - sql.execute (); -} - - -// Add the user details to the database. -void Database_Users::add_user (string user, string password, int level, string email) -{ - { - SqliteDatabase sql (filename ()); - sql.add ("INSERT INTO users (username, level, email) VALUES ("); - sql.add (user); - sql.add (","); - sql.add (level); - sql.add (","); - sql.add (email); - sql.add (");"); - sql.execute (); - } - set_password (user, password); -} - - -// Updates the password for user. -void Database_Users::set_password (string user, string password) -{ - SqliteDatabase sql (filename ()); - sql.add ("UPDATE users SET password ="); - sql.add (md5 (password)); - sql.add ("WHERE username ="); - sql.add (user); - sql.add (";"); - sql.execute (); -} - - -// Returns true if the user and password match. -bool Database_Users::matchUserPassword (string user, string password) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT username FROM users WHERE username ="); - sql.add (user); - sql.add ("AND password ="); - sql.add (md5 (password)); - sql.add ("AND (disabled IS NULL OR disabled = 0);"); - vector result = sql.query () ["username"]; - return (!result.empty()); -} - - -// Returns true if the email and password match. -bool Database_Users::matchEmailPassword (string email, string password) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT username FROM users WHERE email ="); - sql.add (email); - sql.add ("AND password ="); - sql.add (md5 (password)); - sql.add ("AND (disabled IS NULL OR disabled = 0);"); - vector result = sql.query () ["username"]; - return (!result.empty()); -} - - -// Returns the query to execute to add a new user. -string Database_Users::add_userQuery (string user, string password, int level, string email) -{ - user = database_sqlite_no_sql_injection (user); - password = md5 (password); - email = database_sqlite_no_sql_injection (email); - string query = "INSERT INTO users (username, password, level, email) VALUES ('" + user + "', '" + password + "', " + filter::strings::convert_to_string (level) + ", '" + email + "');"; - return query; -} - - -// Returns the username that belongs to the email. -string Database_Users::getEmailToUser (string email) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT username FROM users WHERE email ="); - sql.add (email); - sql.add (";"); - vector result = sql.query () ["username"]; - if (!result.empty()) return result [0]; - return ""; -} - - -// Returns the email address that belongs to user. -string Database_Users::get_email (string user) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT email FROM users WHERE username = "); - sql.add (user); - sql.add (";"); - vector result = sql.query () ["email"]; - if (!result.empty()) return result [0]; - return ""; -} - - -// Returns true if the username exists in the database. -bool Database_Users::usernameExists (string user) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT username FROM users WHERE username ="); - sql.add (user); - sql.add (";"); - vector result = sql.query () ["username"]; - return !result.empty (); -} - - -// Returns true if the email address exists in the database. -bool Database_Users::emailExists (string email) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT username FROM users WHERE email = "); - sql.add (email); - sql.add (";"); - vector result = sql.query () ["username"]; - return !result.empty (); -} - - -// Returns the level that belongs to the user. -int Database_Users::get_level (string user) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT level FROM users WHERE username = "); - sql.add (user); - sql.add (";"); - vector result = sql.query () ["level"]; - if (!result.empty()) return filter::strings::convert_to_int (result [0]); - return Filter_Roles::guest (); -} - - -// Updates the level of a given user. -void Database_Users::set_level (string user, int level) -{ - SqliteDatabase sql (filename ()); - sql.add ("UPDATE users SET level ="); - sql.add (level); - sql.add ("WHERE username ="); - sql.add (user); - sql.add (";"); - sql.execute (); -} - - -// Remove a user from the database. -void Database_Users::removeUser (string user) -{ - SqliteDatabase sql (filename ()); - sql.add ("DELETE FROM users WHERE username ="); - sql.add (user); - sql.add (";"); - sql.execute (); -} - - -// Returns an array with the usernames of the site administrators. -vector Database_Users::getAdministrators () -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT username FROM users WHERE level ="); - sql.add (Filter_Roles::admin ()); - sql.add ("AND (disabled IS NULL OR disabled = 0);"); - vector result = sql.query () ["username"]; - return result; -} - - -// Returns the query to update a user's email address. -string Database_Users::updateEmailQuery (string user, string email) -{ - SqliteDatabase sql (filename ()); - sql.add ("UPDATE users SET email ="); - sql.add (email); - sql.add ("WHERE username ="); - sql.add (user); - sql.add (";"); - return sql.sql; -} - - -// Updates the "email" for "user". -void Database_Users::updateUserEmail (string user, string email) -{ - execute (updateEmailQuery (user, email)); -} - - -// Return an array with the available users. -vector Database_Users::get_users () -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT username FROM users;"); - vector result = sql.query () ["username"]; - return result; -} - - -// Returns the md5 hash for the $user's password. -string Database_Users::get_md5 (string user) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT password FROM users WHERE username ="); - sql.add (user); - sql.add (";"); - vector result = sql.query () ["password"]; - if (!result.empty()) return result [0]; - return ""; -} - - -// Executes the SQL fragment. -void Database_Users::execute (string sqlfragment) -{ - SqliteDatabase sql (filename ()); - sql.sql = sqlfragment; - sql.execute (); -} - - -// Set the LDAP state for the $user account $on or off. -void Database_Users::set_ldap (string user, bool on) -{ - SqliteDatabase sql (filename ()); - sql.add ("UPDATE users SET ldap ="); - sql.add (filter::strings::convert_to_int (on)); - sql.add ("WHERE username ="); - sql.add (user); - sql.add (";"); - sql.execute (); -} - - -// Get whether the $user account comes from a LDAP server. -bool Database_Users::get_ldap (string user) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT ldap FROM users WHERE username ="); - sql.add (user); - sql.add (";"); - vector result = sql.query () ["ldap"]; - if (!result.empty()) { - bool ldap_is_on = filter::strings::convert_to_bool (result [0]); - return ldap_is_on; - } - return false; -} - - -// Enable the $user account. -void Database_Users::set_enabled (string user, bool on) -{ - SqliteDatabase sql (filename ()); - sql.add ("UPDATE users SET disabled ="); - sql.add (filter::strings::convert_to_int (!on)); - sql.add ("WHERE username ="); - sql.add (user); - sql.add (";"); - sql.execute (); -} - - -// Disable the $user account. -bool Database_Users::get_enabled (string user) -{ - SqliteDatabase sql (filename ()); - sql.add ("SELECT disabled FROM users WHERE username ="); - sql.add (user); - sql.add (";"); - vector result = sql.query () ["disabled"]; - if (!result.empty()) return !filter::strings::convert_to_bool (result [0]); - return false; -} - - -// The filename of the database. -const char * Database_Users::filename () -{ - return "users"; -} diff --git a/database/users.h b/database/users.h deleted file mode 100644 index f7538332c..000000000 --- a/database/users.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Users -{ -public: - void create (); - void upgrade (); - void trim (); - void optimize (); - void add_user (std::string user, std::string password, int level, std::string email); - void set_password (std::string user, std::string password); - bool matchUserPassword (std::string user, std::string password); - bool matchEmailPassword (std::string email, std::string password); - std::string add_userQuery (std::string user, std::string password, int level, std::string email); - std::string getEmailToUser (std::string email); - std::string get_email (std::string user); - bool usernameExists (std::string user); - bool emailExists (std::string email); - int get_level (std::string user); - void set_level (std::string user, int level); - void removeUser (std::string user); - std::vector getAdministrators (); - std::string updateEmailQuery (std::string user, std::string email); - void updateUserEmail (std::string user, std::string email); - std::vector get_users (); - std::string get_md5 (std::string user); - void execute (std::string sqlfragment); - void set_ldap (std::string user, bool on); - bool get_ldap (std::string user); - void set_enabled (std::string user, bool on); - bool get_enabled (std::string user); -private: - const char * filename (); -}; diff --git a/database/usfmresources.cpp b/database/usfmresources.cpp deleted file mode 100644 index ae523f031..000000000 --- a/database/usfmresources.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// Database resilience: -// The data is stored as separate files in the filesystem. -// That is resilient enough. - - -string Database_UsfmResources::mainFolder () -{ - return filter_url_create_root_path ({database_logic_databases (), "usfmresources"}); -} - - -string Database_UsfmResources::resourceFolder (const string& name) -{ - return filter_url_create_path ({mainFolder (), name}); -} - - -string Database_UsfmResources::bookFolder (const string& name, int book) -{ - return filter_url_create_path ({resourceFolder (name), filter::strings::convert_to_string (book)}); -} - - -string Database_UsfmResources::chapterFile (const string& name, int book, int chapter) -{ - return filter_url_create_path ({bookFolder (name, book), filter::strings::convert_to_string (chapter)}); -} - - -vector Database_UsfmResources::getResources () -{ - return filter_url_scandir (mainFolder ()); -} - - -void Database_UsfmResources::deleteResource (const string& name) -{ - string path = resourceFolder (name); - // If a folder: Delete it. - filter_url_rmdir (path); - // If a file: Delete it. - filter_url_unlink (path); -} - - -void Database_UsfmResources::deleteBook (const string& name, int book) -{ - string path = bookFolder (name, book); - // If a folder: Delete it. - filter_url_rmdir (path); - // If a file: Delete it. - filter_url_unlink (path); -} - - -void Database_UsfmResources::deleteChapter (const string& name, int book, int chapter) -{ - filter_url_unlink (chapterFile (name, book, chapter)); -} - - -void Database_UsfmResources::storeChapter (const string& name, int book, int chapter, const string& usfm) -{ - string file = chapterFile (name, book, chapter); - string folder = filter_url_dirname (file); - if (!file_or_dir_exists (folder)) filter_url_mkdir (folder); - filter_url_file_put_contents (file, usfm); -} - - -vector Database_UsfmResources::getBooks (const string& name) -{ - vector books; - vector files = filter_url_scandir (resourceFolder (name)); - for (auto & book : files) books.push_back (filter::strings::convert_to_int (book)); - sort (books.begin (), books.end()); - return books; -} - - -vector Database_UsfmResources::getChapters (const string& name, int book) -{ - vector chapters; - vector folders = filter_url_scandir (bookFolder (name, book)); - for (auto & chapter : folders) chapters.push_back (filter::strings::convert_to_int (chapter)); - sort (chapters.begin(), chapters.end()); - return chapters; -} - - -string Database_UsfmResources::getUsfm (const string& name, int book, int chapter) -{ - string file = chapterFile (name, book, chapter); - string usfm = filter_url_file_get_contents (file); - return usfm; -} - - -int Database_UsfmResources::getSize (const string& name, int book, int chapter) -{ - string file = chapterFile (name, book, chapter); - return filter_url_filesize (file); -} diff --git a/database/usfmresources.h b/database/usfmresources.h deleted file mode 100644 index c1e7bcbc7..000000000 --- a/database/usfmresources.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_UsfmResources -{ -public: - std::vector getResources (); - void deleteResource (const std::string& name); - void deleteBook (const std::string& name, int book); - void deleteChapter (const std::string& name, int book, int chapter); - void storeChapter (const std::string& name, int book, int chapter, const std::string& usfm); - std::vector getBooks (const std::string& name); - std::vector getChapters (const std::string& name, int book); - std::string getUsfm (const std::string& name, int book, int chapter); - int getSize (const std::string& name, int book, int chapter); -private: - std::string mainFolder (); - std::string resourceFolder (const std::string& name); - std::string bookFolder (const std::string& name, int book); - std::string chapterFile (const std::string& name, int book, int chapter); -}; diff --git a/database/versifications.cpp b/database/versifications.cpp deleted file mode 100644 index e03c24a7f..000000000 --- a/database/versifications.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// This is a database for the versification systems. -// Resilience: It is normally not written to, so corruption is unlikely. - - -// Versification information is also available from the Bible Organisational System. -// (This system contains versification information, no mapping data.) -// See http://freely-given.org/Software/BibleOrganisationalSystem/ -// See https://github.com/openscriptures/BibleOrgSys/ - - -sqlite3 * Database_Versifications::connect () -{ - return database_sqlite_connect ("versifications"); -} - - -void Database_Versifications::create () -{ - sqlite3 * db = connect (); - string sql; - sql = - "CREATE TABLE IF NOT EXISTS names (" - " system integer," - " name text" - ");"; - database_sqlite_exec (db, sql); - sql = - "CREATE TABLE IF NOT EXISTS data (" - " system integer," - " book integer," - " chapter integer," - " verse integer" - ");"; - database_sqlite_exec (db, sql); - database_sqlite_disconnect (db); -} - - -void Database_Versifications::optimize () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_exec (db, "VACUUM;"); - database_sqlite_disconnect (db); -} - - -// Import data. -void Database_Versifications::input (const string& contents, const string& name) -{ - // Delete old system if it is there, and create new one. - erase (name); - int id = createSystem (name); - - sqlite3 * db = connect (); - database_sqlite_exec (db, "PRAGMA temp_store = MEMORY;"); - database_sqlite_exec (db, "PRAGMA synchronous = OFF;"); - database_sqlite_exec (db, "PRAGMA journal_mode = OFF;"); - database_sqlite_exec (db, "BEGIN;"); - - vector lines = filter::strings::explode (contents, '\n'); - for (auto line : lines) { - line = filter::strings::trim (line); - if (line.empty ()) continue; - // The line will be something similar to this: 1 Corinthians 1:31 - // Split the passage entry on the colon (:) to get the verse. - vector bits = filter::strings::explode(line, ':'); - if (bits.size() != 2) continue; - int verse = filter::strings::convert_to_int(bits[1]); - // Split the first bit on the spaces and get the last item as the chapter. - bits = filter::strings::explode(bits[0], ' '); - if (bits.size() < 2) continue; - int chapter = filter::strings::convert_to_int(bits[bits.size()-1]); - // Remove the last bit so it remains with the book, and get that book. - bits.pop_back(); - string passage_book_string = filter::strings::implode(bits, " "); - int book = static_cast(database::books::get_id_from_english(passage_book_string)); - // Check result. - if ((book == 0) || (chapter == 0)) { - Database_Logs::log ("Malformed versification entry: " + line); - continue; - } - // Store result. - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO data (system, book, chapter, verse) VALUES ("); - sql.add (id); - sql.add (","); - sql.add (book); - sql.add (","); - sql.add (chapter); - sql.add (","); - sql.add (verse); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - } - - database_sqlite_exec (db, "COMMIT;"); - database_sqlite_disconnect (db); -} - - -// Export data. -string Database_Versifications::output (const string& name) -{ - vector lines; - vector versification_data = getBooksChaptersVerses (name); - for (Passage & passage : versification_data) { - string line = database::books::get_english_from_id (static_cast(passage.m_book)); - line.append (" "); - line.append (filter::strings::convert_to_string (passage.m_chapter)); - line.append (":"); - line.append (passage.m_verse); - lines.push_back (line); - } - return filter::strings::implode (lines, "\n"); -} - - -// Delete a versification system. -void Database_Versifications::erase (const string& name) -{ - int id = getID (name); - - SqliteSQL sql1 = SqliteSQL (); - sql1.add ("DELETE FROM names WHERE system ="); - sql1.add (id); - sql1.add (";"); - - SqliteSQL sql2 = SqliteSQL (); - sql2.add ("DELETE FROM data WHERE system ="); - sql2.add (id); - sql2.add (";"); - - sqlite3 * db = connect (); - database_sqlite_exec (db, sql1.sql); - database_sqlite_exec (db, sql2.sql); - database_sqlite_disconnect (db); -} - - -// Returns the ID for a named versification system. -int Database_Versifications::getID (const string& name) -{ - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT system FROM names WHERE name ="); - sql.add (name); - sql.add (";"); - sqlite3 * db = connect (); - vector systems = database_sqlite_query (db, sql.sql) ["system"]; - database_sqlite_disconnect (db); - if (!systems.empty()) { - auto id = systems[0]; - return filter::strings::convert_to_int (id); - } - return 0; -} - - -// Creates a new empty versification system. -// Returns the new ID. -int Database_Versifications::createSystem (const string& name) -{ - // If the versification system already exists, return its ID. - int id = getID (name); - if (id > 0) { - return id; - } - // Get the first free ID starting from 1000 (except when creating the default systems). - id = 0; - sqlite3 * db = connect (); - vector systems = database_sqlite_query (db, "SELECT system FROM names ORDER BY system DESC LIMIT 1;") ["system"]; - for (auto & system : systems) { - id = filter::strings::convert_to_int (system); - } - id++; - if (!creating_defaults) if (id < 1000) id = 1000; - // Create the empty system. - SqliteSQL sql = SqliteSQL (); - sql.add ("INSERT INTO names VALUES ("); - sql.add (id); - sql.add (","); - sql.add (name); - sql.add (");"); - database_sqlite_exec (db, sql.sql); - database_sqlite_disconnect (db); - // Return new ID. - return id; -} - - -// Returns an array of the available versification systems. -vector Database_Versifications::getSystems () -{ - sqlite3 * db = connect (); - vector systems = database_sqlite_query (db, "SELECT name FROM names ORDER BY name ASC;") ["name"]; - database_sqlite_disconnect (db); - return systems; -} - - -// Returns the books, chapters, verses for the given versification system. -vector Database_Versifications::getBooksChaptersVerses (const string& name) -{ - vector data; - int id = getID (name); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT book, chapter, verse FROM data WHERE system ="); - sql.add (id); - sql.add ("ORDER BY book, chapter, verse ASC;"); - sqlite3 * db = connect (); - map > result = database_sqlite_query (db, sql.sql); - database_sqlite_disconnect (db); - vector books = result ["book"]; - vector chapters = result ["chapter"]; - vector verses = result ["verse"]; - for (unsigned int i = 0; i < books.size (); i++) { - Passage passage; - passage.m_book = filter::strings::convert_to_int (books [i]); - passage.m_chapter = filter::strings::convert_to_int (chapters [i]); - passage.m_verse = verses [i]; - data.push_back (passage); - } - return data; -} - - -vector Database_Versifications::getBooks (const string& name) -{ - vector books; - int id = getID (name); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT book FROM data WHERE system ="); - sql.add (id); - sql.add ("ORDER BY book ASC;"); - sqlite3 * db = connect (); - vector sbooks = database_sqlite_query (db, sql.sql) ["book"]; - database_sqlite_disconnect (db); - for (auto & book : sbooks) { - books.push_back (filter::strings::convert_to_int (book)); - } - return books; -} - - -// This returns all the chapters in book of versification system name. -// include0: Includes chapter 0 also. -vector Database_Versifications::getChapters (const string& name, int book, bool include0) -{ - vector chapters; - if (include0) chapters.push_back (0); - int id = this->getID (name); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT chapter FROM data WHERE system ="); - sql.add (id); - sql.add ("AND book ="); - sql.add (book); - sql.add ("ORDER BY chapter ASC;"); - sqlite3 * db = connect (); - vector schapters = database_sqlite_query (db, sql.sql) ["chapter"]; - database_sqlite_disconnect (db); - for (auto & chapter : schapters) { - chapters.push_back (filter::strings::convert_to_int (chapter)); - } - return chapters; -} - - -vector Database_Versifications::getVerses (const string& name, int book, int chapter) -{ - vector verses; - int id = getID (name); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT verse FROM data WHERE system ="); - sql.add (id); - sql.add ("AND book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("ORDER BY verse ASC;"); - sqlite3 * db = connect (); - vector sverses = database_sqlite_query (db, sql.sql) ["verse"]; - database_sqlite_disconnect (db); - for (auto & verse : sverses) { - int maxverse = filter::strings::convert_to_int (verse); - for (int i = 0; i <= maxverse; i++) { - verses.push_back (i); - } - } - // Put verse 0 in chapter 0. - if (chapter == 0) verses.push_back (0); - return verses; -} - - -void Database_Versifications::defaults () -{ - sqlite3 * db = connect (); - database_sqlite_exec (db, "DELETE FROM names WHERE system < 1000;"); - database_sqlite_exec (db, "DELETE FROM data WHERE system < 1000;"); - database_sqlite_disconnect (db); - - creating_defaults = true; - vector names = versification_logic_names (); - for (auto name : names) { - // Read the file contents. - string contents = versification_logic_data (name); - // Due to a need of obfuscating "Bible" and similar, - // If a versification system is called "Staten Bible", - // it will be stored in the file system as "Staten Bb", - // so here deobfuscate the word "Bb", - // and give the full word "Bible" instead. - name = locale_logic_deobfuscate (name); - // Parse it and store it in the database. - input (contents, name); - } - creating_defaults = false; -} - - -// This returns all possible books in any versification system. -vector Database_Versifications::getMaximumBooks () -{ - vector books; - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT book FROM data ORDER BY book ASC;"); - sqlite3 * db = connect (); - vector sbooks = database_sqlite_query (db, sql.sql) ["book"]; - database_sqlite_disconnect (db); - for (auto & book : sbooks) { - books.push_back (filter::strings::convert_to_int (book)); - } - return books; -} - - -// This returns all possible chapters in a book of any versification system. -vector Database_Versifications::getMaximumChapters (int book) -{ - vector chapters; - chapters.push_back (0); - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT chapter FROM data WHERE book ="); - sql.add (book); - sql.add ("ORDER BY chapter ASC;"); - sqlite3 * db = connect (); - vector schapters = database_sqlite_query (db, sql.sql) ["chapter"]; - database_sqlite_disconnect (db); - for (auto & chapter : schapters) { - chapters.push_back (filter::strings::convert_to_int (chapter)); - } - return chapters; -} - - -// This returns all possible verses in a book / chapter of any versification system. -vector Database_Versifications::getMaximumVerses (int book, int chapter) -{ - vector verses; - SqliteSQL sql = SqliteSQL (); - sql.add ("SELECT DISTINCT verse FROM data WHERE book ="); - sql.add (book); - sql.add ("AND chapter ="); - sql.add (chapter); - sql.add ("ORDER BY verse ASC;"); - sqlite3 * db = connect (); - vector sverses = database_sqlite_query (db, sql.sql) ["verse"]; - database_sqlite_disconnect (db); - for (auto & verse : sverses) { - int maxverse = filter::strings::convert_to_int (verse); - for (int i = 0; i <= maxverse; i++) { - verses.push_back (i); - } - } - // Put verse 0 in chapter 0. - if (chapter == 0) verses.push_back (0); - return verses; -} diff --git a/database/versifications.h b/database/versifications.h deleted file mode 100644 index 677d4da53..000000000 --- a/database/versifications.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Database_Versifications -{ -public: - void create (); - void defaults (); - void optimize (); - void input (const std::string& contents, const std::string& name); - std::string output (const std::string& name); - void erase (const std::string& name); - int getID (const std::string& name); - int createSystem (const std::string& name); - std::vector getSystems (); - std::vector getBooksChaptersVerses (const std::string& name); - std::vector getBooks (const std::string& name); - std::vector getChapters (const std::string& name, int book, bool include0 = false); - std::vector getVerses (const std::string& name, int book, int chapter); - std::vector getMaximumBooks (); - std::vector getMaximumChapters (int book); - std::vector getMaximumVerses (int book, int chapter); -private: - sqlite3 * connect (); - bool creating_defaults = false; -}; diff --git a/database/volatile.cpp b/database/volatile.cpp deleted file mode 100644 index da3f5255d..000000000 --- a/database/volatile.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// Database resilience: It is stored in the plain filesystem in the temporal location. - - -string Database_Volatile::getValue (int id, const string& key) -{ - return filter_url_file_get_contents (filename (id, key)); -} - - -void Database_Volatile::setValue (int id, const string& key, const string& value) -{ - filter_url_file_put_contents (filename (id, key), value); -} - - -string Database_Volatile::filename (int id, string key) -{ - string identifier = filter_url_clean_filename (filter::strings::convert_to_string (id)); - key = filter_url_clean_filename (key); - string path = filter_url_create_root_path ({filter_url_temp_dir (), "volatile__" + identifier + "__" + key}); - return path; -} diff --git a/database/volatile.h b/database/volatile.h deleted file mode 100644 index dbce817f2..000000000 --- a/database/volatile.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Database_Volatile -{ -public: - static std::string getValue (int id, const std::string& key); - static void setValue (int id, const std::string& key, const std::string& value); -private: - static std::string filename (int id, std::string key); -}; diff --git a/demo/logic.cpp b/demo/logic.cpp deleted file mode 100644 index ee66bf990..000000000 --- a/demo/logic.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -/* - - A demo installation is an open installation. - Any user is always considered to be logged in as admin. - - In October 2015 the demo began to often refuse web connections. - It appears that the server keeps running most of the times, but also crashed often during certain periods. - - The number of parallel connections was traced to see if that was the cause. - The parallel connection count was mostly 0, at times 1, and higher at rare occassions. - So this should be excluded as the cause. - - Continuous crashes of the server are the likely cause. - The page requests are now being logged to see what happens. - After logging them, it appears that the crash often comes after /resource/get - - Next a crash handler was installed, which gives some sort of backtrace in the Journal. - This showed one crash during the nights. The crash was fixed. - - */ - - -// Returns true if the credentials are correct for a demo installation. -bool demo_acl (string user, string pass) -{ - if (config::logic::demo_enabled ()) { - if (user == session_admin_credentials ()) { - if ((pass == session_admin_credentials ()) || (pass == md5 (session_admin_credentials ()))) { - return true; - } - } - } - return false; -} - - -// Returns a warning in case the client is connected to the open demo server. -string demo_client_warning () -{ - string warning {}; - if (client_logic_client_enabled ()) { - string address = Database_Config_General::getServerAddress (); - if (address == demo_address () || address == demo_address_secure ()) { - int port = Database_Config_General::getServerPort (); - if (port == demo_port () || port == demo_port_secure ()) { - warning.append (translate("You are connected to a public demo of Bibledit Cloud.")); - warning.append (" "); - warning.append (translate("Everybody can modify the data on that server.")); - warning.append (" "); - warning.append (translate("After send and receive your data will reflect the data on the server.")); - } - } - } - return warning; -} - - -// Cleans and resets the data in the Bibledit installation. -void demo_clean_data () -{ - Database_Logs::log ("Cleaning up the demo data"); - - - Webserver_Request webserver_request {}; - - - // Set user to the demo credentials (admin). - // This is the user who is always logged-in in a demo installation. - webserver_request.session_logic ()->set_username (session_admin_credentials ()); - - - // Delete empty stylesheet that may have been there. - webserver_request.database_styles()->revokeWriteAccess ("", styles_logic_standard_sheet ()); - webserver_request.database_styles()->deleteSheet (""); - styles_sheets_create_all (); - - - // Set both stylesheets to "Standard" for all Bibles. - vector bibles = webserver_request.database_bibles()->get_bibles (); - for (const auto & bible : bibles) { - Database_Config_Bible::setExportStylesheet (bible, styles_logic_standard_sheet ()); - Database_Config_Bible::setEditorStylesheet (bible, styles_logic_standard_sheet ()); - } - - - // Regenerate versification databases. - setup_generate_versification_databases (); - - - // Set the site language to "Default" - Database_Config_General::setSiteLanguage (string()); - - - // Ensure the default users are there. - map users = { - pair ("guest", Filter_Roles::guest ()), - pair ("member", Filter_Roles::member ()), - pair ("consultant", Filter_Roles::consultant ()), - pair ("translator", Filter_Roles::translator ()), - pair ("manager", Filter_Roles::manager ()), - pair (session_admin_credentials (), Filter_Roles::admin ()) - }; - for (const auto & element : users) { - if (!webserver_request.database_users ()->usernameExists (element.first)) { - webserver_request.database_users ()->add_user(element.first, element.first, element.second, ""); - } - webserver_request.database_users ()->set_level (element.first, element.second); - } - - - // Create / update sample Bible. - if (config::logic::default_bibledit_configuration ()) { - demo_create_sample_bible (); - } - - - // Create sample notes. - if (config::logic::default_bibledit_configuration ()) { - demo_create_sample_notes (webserver_request); - } - - - // Create samples for the workspaces. - if (config::logic::default_bibledit_configuration ()) { - demo_create_sample_workspaces (webserver_request); - } - - - // Set navigator to John 3:16. - if (config::logic::default_bibledit_configuration ()) { - Ipc_Focus::set (webserver_request, 43, 3, 16); - } - - - // Set and/or trim resources to display. - // Too many resources crash the demo: Limit the amount. - vector resources = webserver_request.database_config_user()->getActiveResources (); - bool reset_resources {false}; - size_t max_resource {25}; - if (resources.size () > max_resource) reset_resources = true; - // Check if all the current resource exists in the default. - vector defaults = demo_logic_default_resources (); - for (const auto & name : defaults) { - if (!in_array (name, resources)) reset_resources = true; - } - if (reset_resources) { - resources = demo_logic_default_resources (); - webserver_request.database_config_user()->setActiveResources (resources); - } - - - // No flipped basic <> advanded mode. - webserver_request.database_config_user ()->setBasicInterfaceMode (false); -} - - -// The name of the sample Bible. -string demo_sample_bible_name () -{ - return "Sample"; -} - - -// Creates a sample Bible. -// Creating a Sample Bible used to take a relatively long time, in particular on low power devices. -// The new and current method does a simple copy operation and that is fast. -void demo_create_sample_bible () -{ - Database_Logs::log ("Creating sample Bible"); - - // Remove and create the sample Bible. - Database_Bibles database_bibles {}; - database_bibles.delete_bible (demo_sample_bible_name ()); - database_bibles.create_bible (demo_sample_bible_name ()); - - // Remove index for the sample Bible. - search_logic_delete_bible (demo_sample_bible_name ()); - - // Copy the sample Bible data and search index into place. - vector rowids = Database_Sample::get (); - for (auto rowid : rowids) { - string file {}; - string data {}; - Database_Sample::get (rowid, file, data); - // Remove the "./" from the start. - file.erase (0, 2); - // Since the filename contains the foward slash for on Linux, - // and since Windows needs the backslash as directory separator, - // replace these on Windows. - file = filter_url_update_directory_separator_if_windows (file); - // The name of the Sample Bible should be part of the filename. - // If that is not the case, - // * it means that Bibledit uses a different name for the Sample Bible, - // * and the file needs an update. - size_t pos = file.find(demo_sample_bible_name()); - if (pos == std::string::npos) { - string filename = "Sample"; - file = filter::strings::replace(filename, demo_sample_bible_name(), file); - } - // Proceed with the path. - file = filter_url_create_root_path ({file}); - string path = filter_url_dirname (file); - if (!file_or_dir_exists (path)) filter_url_mkdir (path); - filter_url_file_put_contents (file, data); - } - - Database_Logs::log ("Sample Bible was created"); -} - - -// Prepares a sample Bible. -// The output will be in database "sample". -// This data is intended for quickly creating a sample Bible. -// This way it is fast even on low power devices. -void demo_prepare_sample_bible () -{ - Database_Bibles database_bibles {}; - Database_Sample::create (); - // Remove the sample Bible plus all related data. - database_bibles.delete_bible (demo_sample_bible_name ()); - search_logic_delete_bible (demo_sample_bible_name ()); - // Create a new sample Bible. - database_bibles.create_bible (demo_sample_bible_name ()); - // Location of the source USFM files for the sample Bible. - string directory = filter_url_create_root_path ({"demo"}); - vector files = filter_url_scandir (directory); - for (auto file : files) { - // Process only USFM files, skipping others. - if (filter_url_get_extension (file) == "usfm") { - // Read the USFM and clean it up. - file = filter_url_create_path ({directory, file}); - string usfm = filter_url_file_get_contents (file); - usfm = filter::strings::collapse_whitespace (usfm); - // Import the USFM into the sample Bible. - vector book_chapter_data = filter::usfm::usfm_import (usfm, styles_logic_standard_sheet ()); - for (const auto & data : book_chapter_data) { - int book = data.m_book; - if (book) { - // There is license information at the top of each USFM file. - // This results in a book with number 0. - // This book gets skipped here, so the license information is skipped as well. - int chapter {data.m_chapter}; - string usfm2 {data.m_data}; - bible_logic::store_chapter (demo_sample_bible_name (), book, chapter, usfm2); - } - } - } - } - // Copy the Bible data to the sample database. - directory = database_bibles.bible_folder (demo_sample_bible_name ()); - files.clear (); - filter_url_recursive_scandir (directory, files); - for (const auto & file : files) { - if (!filter_url_is_dir (file)) { - string data = filter_url_file_get_contents (file); - Database_Sample::store (file, data); - } - } - // Copy the search index data to the sample database. - directory = search_logic_index_folder (); - files.clear (); - filter_url_recursive_scandir (directory, files); - for (const auto & file : files) { - if (file.find (demo_sample_bible_name ()) != std::string::npos) { - string data = filter_url_file_get_contents (file); - Database_Sample::store (file, data); - } - } - // The sample Bible is now in the standard location and editable by the users: Remove it. - database_bibles.delete_bible (demo_sample_bible_name ()); - // Same for the search index. - search_logic_delete_bible (demo_sample_bible_name ()); - // Clean up the remaining artifacts that were created along the way. -#ifdef HAVE_CLOUD - [[maybe_unused]] int result; - result = system ("find . -path '*logbook/15*' -delete"); - result = system ("find . -name state.sqlite -delete"); - result = system ("find . -name 'Sample.*' -delete"); -#endif -} - - -// Create sample notes. -void demo_create_sample_notes (Webserver_Request& webserver_request) -{ - Database_Notes database_notes (webserver_request); - vector identifiers = database_notes.get_identifiers (); - if (identifiers.size () < 10) { - for (int i = 1; i <= 10; i++) { - database_notes.store_new_note (demo_sample_bible_name (), i, i, i, "Sample Note " + filter::strings::convert_to_string (i), "Sample Contents for note " + filter::strings::convert_to_string (i), false); - } - } -} - - -string demo_workspace () -{ - return "Translation"; -} - - -void demo_create_sample_workspaces (Webserver_Request& webserver_request) -{ - map urls {}; - map widths {}; - for (int i = 0; i < 15; i++) { - string url {}; - string width {}; - if (i == 0) { - url = editusfm_index_url (); - width = "45%"; - } - if (i == 1) { - url = resource_index_url (); - width = "45%"; - } - urls [i] = url; - widths [i] = width; - } - map row_heights = { - pair (0, "90%"), - pair (1, ""), - pair (2, "") - }; - - webserver_request.database_config_user()->setActiveWorkspace ("USFM"); - workspace_set_urls (webserver_request, urls); - workspace_set_widths (webserver_request, widths); - workspace_set_heights (webserver_request, row_heights); - - urls[0] = editone2_index_url (); - urls[1] = resource_index_url (); - - webserver_request.database_config_user()->setActiveWorkspace (demo_workspace ()); - workspace_set_urls (webserver_request, urls); - workspace_set_widths (webserver_request, widths); - workspace_set_heights (webserver_request, row_heights); -} - - -vector demo_logic_default_resources () -{ - vector resources {}; - if (config::logic::default_bibledit_configuration ()) { - // Add a few resources that are also safe in an obfuscated version. - resources = { - demo_sample_bible_name (), - resource_logic_violet_divider () - }; - // For demo purposes, add some more resources to show-case some of the capabilities. - if (config::logic::demo_enabled ()) { - resources.push_back (resource_external_biblehub_interlinear_name ()); - resources.push_back (resource_external_net_bible_name ()); - resources.push_back (SBLGNT_NAME); - } - } - // Done. - return resources; -} diff --git a/demo/logic.h b/demo/logic.h deleted file mode 100644 index e93152979..000000000 --- a/demo/logic.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -bool demo_acl (std::string user, std::string pass); - -// Returns the address of the current demo server. -constexpr std::string_view demo_address () {return "http://bibledit.org";} -constexpr std::string_view demo_address_secure () {return "https://bibledit.org";} - -// The port number of the current demo server. -constexpr int demo_port () {return 8090;} -constexpr int demo_port_secure () {return 8091;} - -std::string demo_client_warning (); -void demo_clean_data (); -std::string demo_sample_bible_name (); -void demo_create_sample_bible (); -void demo_prepare_sample_bible (); -void demo_create_sample_notes (Webserver_Request& webserver_request); -std::string demo_workspace (); -void demo_create_sample_workspaces (Webserver_Request& webserver_request); -std::vector demo_logic_default_resources (); diff --git a/developer/delay.cpp b/developer/delay.cpp deleted file mode 100644 index c126e0aeb..000000000 --- a/developer/delay.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -const char * developer_delay_url () -{ - return "developer/delay"; -} - - -bool developer_delay_acl ([[maybe_unused]] Webserver_Request& webserver_request) -{ - return true; -} - - -string developer_delay ([[maybe_unused]] Webserver_Request& webserver_request) -{ - // Here is a delay routine that waits multiple seconds before sending the reponse. - // The purpose is to test timeouts of the website live monitors. - //this_thread::sleep_for(chrono::seconds(10)); - // Done. - return "OK"; -} diff --git a/developer/delay.h b/developer/delay.h deleted file mode 100644 index edbfec1c1..000000000 --- a/developer/delay.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -const char * developer_delay_url (); -bool developer_delay_acl (Webserver_Request& webserver_request); -std::string developer_delay (Webserver_Request& webserver_request); diff --git a/developer/index.cpp b/developer/index.cpp deleted file mode 100644 index e3606f3a3..000000000 --- a/developer/index.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#ifndef HAVE_CLIENT -#include -#include -#include -#include -#endif -#include -#include -#include -#include -#include -using namespace std; - - -const char * developer_index_url () -{ - return "developer/index"; -} - - -bool developer_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::admin ()); -} - - -string developer_index (Webserver_Request& webserver_request) -{ - if (webserver_request.query.count ("log")) { - string message = webserver_request.query ["log"]; - std::cerr << message << std::endl; - return string(); - } - - string page {}; - - Assets_Header header = Assets_Header ("Development", webserver_request); - header.notify_it_on (); - page = header.run (); - - Assets_View view {}; - - string code {}; - - string debug = webserver_request.query ["debug"]; - - // It is cleaner and easier to move the following task to the binary ./generate. - if (debug == "etcbc4download") { - // sources_etcbc4_download (); - view.set_variable ("success", "Task disabled"); - } - - // It is cleaner and easier to move the following task to the binary ./generate. - if (debug == "etcbc4parse") { - //sources_etcbc4_parse (); - view.set_variable ("success", "Task disabled"); - } - - // It is cleaner and easier to move the following task to the binary ./generate. - if (debug == "parsekjv") { - //sources_kjv_parse (); - view.set_variable ("success", "Task disabled"); - } - - // It is cleaner and easier to move the following task to the binary ./generate. - if (debug == "parsemorphgnt") { - // sources_morphgnt_parse (); - view.set_variable ("success", "Task disabled"); - } - - // It is cleaner and easier to move the following task to the binary ./generate. - if (debug == "parsehebrewlexicon") { - //sources_hebrewlexicon_parse (); - view.set_variable ("success", "Task disabled"); - //view.set_variable ("success", "Task running"); - } - - if (debug == "crash") { - // Make a bad pointer. - // int *foo = (int*)-1; - // Cause segmentation fault. - // printf ("%d\n", *foo); - view.set_variable ("success", "Task disabled"); - } - - if (debug == "receive") { - tasks_logic_queue (RECEIVEEMAIL); - view.set_variable ("success", "Receiving email and running tasks that send mail"); - } - - if (debug == "ipv6") { - view.set_variable ("success", "Fetching data via IPv6"); - string error {}; - string response = filter_url_http_request_mbed ("http://ipv6.google.com", error, {}, "", true); - page.append (response); - view.set_variable ("error", error); - } - - if (debug == "ipv6s") { - view.set_variable ("success", "Securely fetching data via IPv6"); - string error {}; - string response = filter_url_http_request_mbed ("https://ipv6.google.com", error, {}, "", true); - page.append (response); - view.set_variable ("error", error); - } - - if (debug == "maintain") { - tasks_logic_queue (MAINTAINDATABASE); - view.set_variable ("success", "Starting to maintain the databases"); - } - - if (debug == "accordance") { - string reference = bibledit_get_reference_for_accordance (); - view.set_variable ("success", "Accordance reference: " + reference); - bibledit_put_reference_from_accordance("PSA 3:2"); - } - - if (debug == "changes") { - developer_logic_import_changes (); - view.set_variable ("success", "Task was done see Journal"); - } - - view.set_variable ("code", code); - - page += view.render ("developer", "index"); - page += assets_page::footer (); - - return page; -} diff --git a/developer/index.h b/developer/index.h deleted file mode 100644 index 713ea6eb3..000000000 --- a/developer/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -const char * developer_index_url (); -bool developer_index_acl (Webserver_Request& webserver_request); -std::string developer_index (Webserver_Request& webserver_request); diff --git a/developer/logic.cpp b/developer/logic.cpp deleted file mode 100644 index 0947b6fdf..000000000 --- a/developer/logic.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - - -// Internal function declarations. -void developer_logic_import_changes_save (std::string bible, int book, int chapter, int verse, std::string& text); - - -std::mutex log_network_mutex {}; -std::vector log_network_cache {}; - - -void developer_logic_log_network_write () -{ - if (!log_network_cache.empty ()) { - log_network_mutex.lock (); - std::string lines {}; - for (const auto& line : log_network_cache) { - lines.append (line); - lines.append ("\n"); - } - log_network_cache.clear (); - log_network_mutex.unlock (); - const std::string path = filter_url_create_root_path ({filter_url_temp_dir(), "log-network.csv"}); - if (!file_or_dir_exists (path)) { - filter_url_file_put_contents_append (path, "date,IPaddress,URL,query,username\n"); - } - filter_url_file_put_contents_append (path, lines); - } -} - - -Developer_Logic_Tracer::Developer_Logic_Tracer(Webserver_Request& webserver_request) -{ - seconds1 = filter::date::seconds_since_epoch (); - microseconds1 = filter::date::numerical_microseconds(); - rfc822 = filter::date::rfc822 (seconds1); - remote_address = webserver_request.remote_address; - request_get = webserver_request.get; - for (const auto& element : webserver_request.query) { - request_query.append(" "); - request_query.append(element.first); - request_query.append("="); - request_query.append(element.second); - } - username = webserver_request.session_logic()->currentUser(); -} - - -Developer_Logic_Tracer::~Developer_Logic_Tracer() -{ - int seconds2 = filter::date::seconds_since_epoch(); - int microseconds2 = filter::date::numerical_microseconds(); - int microseconds = (seconds2 - seconds1) * 1000000 + microseconds2 - microseconds1; - std::vector bits = {rfc822, filter::strings::convert_to_string (microseconds), request_get, request_query, username}; - std::string entry = filter::strings::implode(bits, ","); - log_network_mutex.lock(); - log_network_cache.push_back(entry); - log_network_mutex.unlock(); -} - - -void developer_logic_import_changes_save (std::string bible, int book, int chapter, int verse, std::string& text) -{ - std::cout << "saving verse " << verse << std::endl; - std::cout << text << std::endl; - if (text.empty()) { - return; - } - - Webserver_Request webserver_request {}; - std::string explanation = "import changes"; - const std::string message = filter::usfm::safely_store_verse (webserver_request, bible, book, chapter, verse, text, explanation, false); - if (!message.empty()) Database_Logs::log (message); - text.clear (); -} - - -void developer_logic_import_changes () -{ - std::string home_path = "."; - char * home = getenv ("HOME"); - if (home) - home_path = home; - const std::string file_path = filter_url_create_path ({home_path, "Desktop", "changes.usfm"}); - const std::string bible = "test"; - Database_Logs::log ("Import changes from " + file_path + " into Bible " + bible); - Database_Bibles database_bibles {}; - const std::vector bibles = database_bibles.get_bibles (); - if (!in_array(bible, bibles)) { - Database_Logs::log ("Cannot locate Bible " + bible); - return; - } - if (!file_or_dir_exists (file_path)) { - Database_Logs::log ("Cannot locate " + file_path); - return; - } - const std::string contents = filter_url_file_get_contents(file_path); - const std::vector lines = filter::strings::explode(contents, "\n"); - - const std::vector book_ids = database::books::get_ids (); - - Passage passage (bible, 0, 0, std::string()); - std::string text {}; - - for (auto line : lines) { - if (line.empty()) continue; - - book_id book {book_id::_unknown}; - int chapter {-1}; - int verse {-1}; - - // Locate and extract the book identifier. - for (const auto book_num : book_ids) { - std::string s = database::books::get_english_from_id(static_cast(book_num)); - const size_t pos = line.find(s); - if (pos != 3) continue; - book = book_num; - line.erase (0, pos + s.length()); - break; - } - - // Extract chapter and verse. - bool passage_found {false}; - if (book != book_id::_unknown) { - size_t pos = line.find (":"); - if (pos != std::string::npos) { - const std::vector bits = filter::strings::explode(line.substr (0, pos), "."); - if (bits.size() == 2) { - chapter = filter::strings::convert_to_int(filter::strings::trim(bits[0])); - verse = filter::strings::convert_to_int(filter::strings::trim(bits[1])); - line.erase (0, pos + 2); - passage_found = (book != book_id::_unknown) && (chapter >= 0) && (verse >= 0); - } - } - } - - // If a new passage was found: - // 1. Save the accumulated text to the existing passage. - // 2. Update the passage to point to the new one. - if (passage_found) { - developer_logic_import_changes_save (passage.m_bible, passage.m_book, passage.m_chapter, filter::strings::convert_to_int (passage.m_verse), text); - passage = Passage(bible, static_cast(book), chapter, filter::strings::convert_to_string(verse)); - } - // Accumulate the text. - if (!text.empty()) text.append ("\n"); - //if (verse == 1) text.append ("\\p\n"); - text.append(line); - - } - - developer_logic_import_changes_save (passage.m_bible, passage.m_book, passage.m_chapter, filter::strings::convert_to_int (passage.m_verse), text); - -} diff --git a/developer/logic.h b/developer/logic.h deleted file mode 100644 index 5634a9e2e..000000000 --- a/developer/logic.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -void developer_logic_log_network_write (); - -class Developer_Logic_Tracer -{ -public: - Developer_Logic_Tracer(Webserver_Request& webserver_request); - ~Developer_Logic_Tracer(); - int seconds1 {0}; - int microseconds1 {0}; - std::string rfc822 {}; - std::string remote_address {}; - std::string request_get {}; - std::string request_query {}; - std::string username {}; -}; - -void developer_logic_import_changes (); diff --git a/dialog/books.cpp b/dialog/books.cpp deleted file mode 100644 index 07b68433f..000000000 --- a/dialog/books.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - - -// Constructs a Bible books selection dialog -// $action - GET action to take: Will be added to the base url upon selection. -// $inclusions - vector of book IDs to include, empty vector does nothing. -// $exclusions - vector of book IDs to exclude, empty vector does nothing. -Dialog_Books::Dialog_Books (std::string url, std::string header, std::string info_top, std::string info_bottom, std::string action, std::vector inclusions, std::vector exclusions) -{ - base_url = url; - assets_view.set_variable ("header", header); - assets_view.set_variable ("info_top", info_top); - assets_view.set_variable ("info_bottom", info_bottom); - selection_action = action; - include = inclusions; - exclude = exclusions; -} - - -Dialog_Books::~Dialog_Books () -{ -} - - -// Add "parameter" and "value" to be added in the base query, or base url. -// If any $query is passed, if Cancel is clicked in this dialog, it should go go back -// to the original caller page with the $query added. -// Same for when a selection is made: It adds the $query to the page where to go. -void Dialog_Books::add_query (std::string parameter, std::string value) -{ - base_url = filter_url_build_http_query (base_url, parameter, value); -} - - -std::string Dialog_Books::run () -{ - assets_view.set_variable ("base_url", base_url); - - std::vector book_ids {}; - { - std::vector book_enums = database::books::get_ids (); - for (const auto book : book_enums) book_ids.push_back(static_cast(book)); - } - if (!include.empty ()) { - book_ids = include; - } - if (!exclude.empty()) { - std::vector ids; - for (const auto & book_id : book_ids) { - if (find (exclude.begin(), exclude.end(), book_id) == exclude.end ()) { - ids.push_back (book_id); - } - } - book_ids = ids; - } - - std::stringstream book_block; - for (const auto & id : book_ids) { - book_block << "" << database::books::get_english_from_id (static_cast(id)) << "\n"; - } - assets_view.set_variable ("book_block", book_block.str()); - - std::string page = assets_view.render ("dialog", "books"); - page += assets_page::footer (); - return page; -} diff --git a/dialog/books.h b/dialog/books.h deleted file mode 100644 index 5ec16e51a..000000000 --- a/dialog/books.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include - -class Dialog_Books -{ -public: - Dialog_Books (std::string url, std::string header, std::string info_top, std::string info_bottom, std::string action, std::vector inclusions, std::vector exclusions); - ~Dialog_Books (); - Dialog_Books (const Dialog_Books&) = delete; - Dialog_Books operator=(const Dialog_Books&) = delete; - void add_query (std::string parameter, std::string value); - std::string run (); -private: - Assets_View assets_view {}; - std::string base_url {}; - std::string selection_action {}; - std::vector include {}; - std::vector exclude {}; -}; diff --git a/dialog/color.cpp b/dialog/color.cpp deleted file mode 100644 index 3ce8ca31d..000000000 --- a/dialog/color.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -using namespace std; - - -Dialog_Color::Dialog_Color (string url, string question) -{ - base_url = url; - assets_view.set_variable ("question", question); -} - - -Dialog_Color::~Dialog_Color () -{ -} - - -// Add "parameter" and "value" to be added in the base query, or base url. -// If any $query is passed, if Cancel is clicked in this dialog, it should go go back -// to the original caller page with the $query added. -// Same for when a selection is made: It adds the $query to the page where to go. -void Dialog_Color::add_query (string parameter, string value) -{ - base_url = filter_url_build_http_query (base_url, parameter, value); -} - - -string Dialog_Color::run () -{ - assets_view.set_variable ("base_url", base_url); - string page = assets_view.render ("dialog", "color"); - page += assets_page::footer (); - return page; -} diff --git a/dialog/color.h b/dialog/color.h deleted file mode 100644 index 09182377a..000000000 --- a/dialog/color.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include - -class Dialog_Color -{ -public: - Dialog_Color (std::string url, std::string question); - ~Dialog_Color (); - Dialog_Color(const Dialog_Color&) = delete; - Dialog_Color operator=(const Dialog_Color&) = delete; - void add_query (std::string parameter, std::string value); - std::string run (); -private: - Assets_View assets_view {}; - std::string base_url {}; -}; diff --git a/dialog/entry.cpp b/dialog/entry.cpp deleted file mode 100644 index bc48bd949..000000000 --- a/dialog/entry.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// Entry dialog constructor -// $url : The base URL of the page. -// $query : A map with query variables, e.g. ("search" => "bibledit"). -// If any $query is passed, if Cancel is clicked in this dialog, it should go go back -// to the original caller page with the $query added. Same for Ok, it would post -// the value entered, but also add the $query to the url. -// $question: The question to be asked. -// $value : The initial value to be put into the entry. -// $submit : Name of POST request to submit the information. -// $help : Help information explaining to the user what's going on. -Dialog_Entry::Dialog_Entry (string url, string question, string value, string submit, string help) -{ - Assets_View * view = new Assets_View (); - base_url = url; - assets_view.set_variable ("question", question); - assets_view.set_variable ("value", value); - assets_view.set_variable ("submit", submit); - assets_view.set_variable ("help", help); -} - - -Dialog_Entry::~Dialog_Entry () -{ -} - - -void Dialog_Entry::add_query (string parameter, string value) -{ - base_url = filter_url_build_http_query (base_url, parameter, value); -} - - -string Dialog_Entry::run () -{ - assets_view.set_variable ("base_url", base_url); - string page =assets_view.render ("dialog", "entry"); - page += assets_page::footer (); - return page; -} diff --git a/dialog/entry.h b/dialog/entry.h deleted file mode 100644 index 34b1e09d2..000000000 --- a/dialog/entry.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Dialog_Entry -{ -public: - Dialog_Entry (std::string url, std::string question, std::string value, std::string submit, std::string help); - ~Dialog_Entry (); - Dialog_Entry(const Dialog_Entry&) = delete; - Dialog_Entry operator=(const Dialog_Entry&) = delete; - void add_query (std::string parameter, std::string value); - std::string run (); -private: - Assets_View assets_view {}; - std::string base_url {}; -}; diff --git a/dialog/list.cpp b/dialog/list.cpp deleted file mode 100644 index 8404bfe30..000000000 --- a/dialog/list.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Entry dialog constructor -// $url: The base URL of the page. -// $question: The question to be asked. -// $info_top : Information. -// $info_bottom: Information. -// $post: causes the result to be sent via the POST method rather than the default GET method. -Dialog_List::Dialog_List (string url, string question, string info_top, string info_bottom, bool post) -{ - base_url = url; - assets_view.set_variable ("question", question); - if (info_top == "") info_top = translate("Here are the various options:"); - assets_view.set_variable ("info_top", info_top); - if (info_bottom == "") info_bottom = translate("Please pick one."); - assets_view.set_variable ("info_bottom", info_bottom); - post_result = post; -} - - -Dialog_List::~Dialog_List () -{ -} - - -// Add "parameter" and "value" to be added in the base query, or base url. -// If any $query is passed, if Cancel is clicked in this dialog, it should go go back -// to the original caller page with the $query added. -// Same for when a selection is made: It adds the $query to the page where to go. -void Dialog_List::add_query (string parameter, string value) -{ - base_url = filter_url_build_http_query (base_url, parameter, value); -} - - -void Dialog_List::add_row (string text, string parameter, string value) -{ - if (!list_block.empty ()) list_block.append ("\n"); - list_block.append ("
  • "); - if (post_result) { - list_block.append ("\n"); - list_block.append (R"(
    )" + "\n"); - list_block.append (R"()" + text + "\n"); - list_block.append (R"()" + "\n"); - list_block.append ("
    \n"); - } else { - string href = filter_url_build_http_query (base_url, parameter, value); - list_block.append (R"()" + text + ""); - } - list_block.append ("
  • "); -} - - -string Dialog_List::run () -{ - assets_view.set_variable ("base_url", base_url); - assets_view.set_variable ("list_block", list_block); - string page = assets_view.render ("dialog", "list"); - page += assets_page::footer (); - return page; -} diff --git a/dialog/list.h b/dialog/list.h deleted file mode 100644 index 2258a00d5..000000000 --- a/dialog/list.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Dialog_List -{ -public: - Dialog_List (std::string url, std::string question, std::string info_top, std::string info_bottom, bool post = false); - ~Dialog_List (); - Dialog_List(const Dialog_List&) = delete; - Dialog_List operator=(const Dialog_List&) = delete; - void add_query (std::string parameter, std::string value); - void add_row (std::string text, std::string parameter, std::string value); - std::string run (); -private: - Assets_View assets_view {}; - std::string base_url {}; - std::string list_block {}; - bool post_result {false}; -}; diff --git a/dialog/list2.cpp b/dialog/list2.cpp deleted file mode 100644 index ef9bf5cce..000000000 --- a/dialog/list2.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright (©) 2021 Aranggi Toar. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -using namespace std; - - -// Generate the option tags based on the inserted key and its value. -string Options_To_Select::add_selection (string text, string value, string html) -{ - if (value == "") { - html.append (""); - } else { - html.append (""); - } - - return html; -} - - -// Mark the current selected option's option tag. -string Options_To_Select::mark_selected (string value, string html) -{ - string new_value = "value='" + value + "'"; - size_t new_pos = html.find (new_value) + new_value.length (); - string mark = " selected"; - - if (html.find (mark) != std::string::npos) { - html.erase (html.find (mark), mark.length ()); - } - - html.insert (new_pos, mark); - - return html; -} diff --git a/dialog/list2.h b/dialog/list2.h deleted file mode 100644 index 34f3f209a..000000000 --- a/dialog/list2.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright (©) 2021 Aranggi Toar. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Options_To_Select -{ -public: - static std::string add_selection (std::string text, std::string value, std::string html); - static std::string mark_selected (std::string value, std::string html); -}; diff --git a/dialog/upload.cpp b/dialog/upload.cpp deleted file mode 100644 index 109f4e2cf..000000000 --- a/dialog/upload.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include - - -// Dialog that enables the user to upload a file. -// $url: The url of the page where to go to on clicking Cancel or Upload. -// $question: The question to ask. -Dialog_Upload::Dialog_Upload (std::string url, std::string question) -{ - base_url = url; - assets_view.set_variable ("question", question); -} - - -Dialog_Upload::~Dialog_Upload () -{ -} - - -// Adds a query to the URL for going to the page on clicking Upload. -void Dialog_Upload::add_upload_query (std::string parameter, std::string value) -{ - upload_query [parameter] = value; -} - - -std::string Dialog_Upload::run () -{ - std::string import; - for (const auto & element : upload_query) { - import = filter_url_build_http_query (base_url, element.first, element.second); - } - assets_view.set_variable ("import", import); - assets_view.set_variable ("cancel", base_url); - std::string page = assets_view.render ("dialog", "upload"); - page += assets_page::footer (); - return page; -} diff --git a/dialog/upload.h b/dialog/upload.h deleted file mode 100644 index 069765b2f..000000000 --- a/dialog/upload.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include - -class Dialog_Upload -{ -public: - Dialog_Upload (std::string url, std::string question); - ~Dialog_Upload (); - Dialog_Upload(const Dialog_Upload&) = delete; - Dialog_Upload operator=(const Dialog_Upload&) = delete; - void add_upload_query (std::string parameter, std::string value); - std::string run (); -private: - Assets_View assets_view {}; - std::string base_url {}; - std::map upload_query {}; -}; diff --git a/dialog/yes.cpp b/dialog/yes.cpp deleted file mode 100644 index 6e5369a53..000000000 --- a/dialog/yes.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include - - -// Dialog that asks the user for confirmation to perform an action. -// $url: The url of the page where to go to on clicking Cancel or Yes. -// $question: The question to ask. -Dialog_Yes::Dialog_Yes (std::string url, std::string question) -{ - base_url = url; - assets_view.set_variable ("question", question); -} - - -Dialog_Yes::~Dialog_Yes () -{ -} - - -// Adds a query to the URL for going to the page on clicking Cancel or Yes. -void Dialog_Yes::add_query (std::string parameter, std::string value) -{ - base_url = filter_url_build_http_query (base_url, parameter, value); -} - - -std::string Dialog_Yes::run () -{ - std::string yes = filter_url_build_http_query (base_url, "confirm", "yes"); - std::string cancel = filter_url_build_http_query (base_url, "confirm", "cancel"); - assets_view.set_variable ("yes", yes); - assets_view.set_variable ("cancel", cancel); - std::string page = assets_view.render ("dialog", "yes"); - page += assets_page::footer (); - return page; -} - diff --git a/dialog/yes.h b/dialog/yes.h deleted file mode 100644 index e774507b3..000000000 --- a/dialog/yes.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include - -class Dialog_Yes -{ -public: - Dialog_Yes (std::string url, std::string question); - ~Dialog_Yes (); - Dialog_Yes(const Dialog_Yes&) = delete; - Dialog_Yes operator=(const Dialog_Yes&) = delete; - void add_query (std::string parameter, std::string value); - std::string run (); -private: - Assets_View assets_view {}; - std::string base_url {}; -}; diff --git a/dtl/Diff.hpp b/dtl/Diff.hpp deleted file mode 100755 index 2286a088e..000000000 --- a/dtl/Diff.hpp +++ /dev/null @@ -1,695 +0,0 @@ -/** - dtl -- Diff Template Library - - In short, Diff Template Library is distributed under so called "BSD license", - - Copyright (c) 2015 Tatsuhiko Kubo - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the authors nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* If you use this library, you must include dtl.hpp only. */ - -#ifndef DTL_DIFF_H -#define DTL_DIFF_H - -#pragma clang diagnostic ignored "-Wsign-conversion" - - -namespace dtl { - - /** - * diff class template - * sequence must support random_access_iterator. - */ - template , typename comparator = Compare< elem > > - class Diff - { - private : - dtl_typedefs(elem, sequence) - sequence A; - sequence B; - size_t M; - size_t N; - size_t delta; - size_t offset; - long long *fp; - long long editDistance; - Lcs< elem > lcs; - Ses< elem > ses; - editPath path; - editPathCordinates pathCordinates; - bool swapped; - bool huge; - bool trivial; - bool editDistanceOnly; - uniHunkVec uniHunks; - comparator cmp; - public : - Diff () {} - - Diff (const sequence& a, - const sequence& b) : A(a), B(b), ses(false) { - init(); - } - - Diff (const sequence& a, - const sequence& b, - bool deletesFirst) : A(a), B(b), ses(deletesFirst) { - init(); - } - - Diff (const sequence& a, - const sequence& b, - const comparator& comp) : A(a), B(b), ses(false), cmp(comp) { - init(); - } - - Diff (const sequence& a, - const sequence& b, - bool deleteFirst, - const comparator& comp) : A(a), B(b), ses(deleteFirst), cmp(comp) { - init(); - } - - ~Diff() {} - - long long getEditDistance () const { - return editDistance; - } - - Lcs< elem > getLcs () const { - return lcs; - } - - elemVec getLcsVec () const { - return lcs.getSequence(); - } - - Ses< elem > getSes () const { - return ses; - } - - uniHunkVec getUniHunks () const { - return uniHunks; - } - - /* These should be deprecated */ - bool isHuge () const { - return huge; - } - - void onHuge () { - this->huge = true; - } - - void offHuge () { - this->huge = false; - } - - bool isUnserious () const { - return trivial; - } - - void onUnserious () { - this->trivial = true; - } - - void offUnserious () { - this->trivial = false; - } - - void onOnlyEditDistance () { - this->editDistanceOnly = true; - } - - /* These are the replacements for the above */ - bool hugeEnabled () const { - return huge; - } - - void enableHuge () { - this->huge = true; - } - - void disableHuge () { - this->huge = false; - } - - bool trivialEnabled () const { - return trivial; - } - - void enableTrivial () const { - this->trivial = true; - } - - void disableTrivial () { - this->trivial = false; - } - - void editDistanceOnlyEnabled () { - this->editDistanceOnly = true; - } - - /** - * patching with Unified Format Hunks - */ - sequence uniPatch (const sequence& seq) { - elemList seqLst(seq.begin(), seq.end()); - sesElemVec shunk; - sesElemVec_iter vsesIt; - elemList_iter lstIt = seqLst.begin(); - long long inc_dec_total = 0; - long long gap = 1; - for (uniHunkVec_iter it=uniHunks.begin();it!=uniHunks.end();++it) { - joinSesVec(shunk, it->common[0]); - joinSesVec(shunk, it->change); - joinSesVec(shunk, it->common[1]); - it->a += inc_dec_total; - inc_dec_total += it->inc_dec_count; - for (long long i=0;ia - gap;++i) { - ++lstIt; - } - gap = it->a + it->b + it->inc_dec_count; - vsesIt = shunk.begin(); - while (vsesIt!=shunk.end()) { - switch (vsesIt->second.type) { - case SES_ADD : - seqLst.insert(lstIt, vsesIt->first); - break; - case SES_DELETE : - if (lstIt != seqLst.end()) { - lstIt = seqLst.erase(lstIt); - } - break; - case SES_COMMON : - if (lstIt != seqLst.end()) { - ++lstIt; - } - break; - default : - // no fall-through - break; - } - ++vsesIt; - } - shunk.clear(); - } - - sequence patchedSeq(seqLst.begin(), seqLst.end()); - return patchedSeq; - } - - /** - * patching with Shortest Edit Script (SES) - */ - sequence patch (const sequence& seq) const { - sesElemVec sesSeq = ses.getSequence(); - elemList seqLst(seq.begin(), seq.end()); - elemList_iter lstIt = seqLst.begin(); - for (sesElemVec_iter sesIt=sesSeq.begin();sesIt!=sesSeq.end();++sesIt) { - switch (sesIt->second.type) { - case SES_ADD : - seqLst.insert(lstIt, sesIt->first); - break; - case SES_DELETE : - lstIt = seqLst.erase(lstIt); - break; - case SES_COMMON : - ++lstIt; - break; - default : - // no through - break; - } - } - sequence patchedSeq(seqLst.begin(), seqLst.end()); - return patchedSeq; - } - - /** - * compose Longest Common Subsequence and Shortest Edit Script. - * The algorithm implemented here is based on "An O(NP) Sequence Comparison Algorithm" - * described by Sun Wu, Udi Manber and Gene Myers - */ - void compose() { - - if (isHuge()) { - pathCordinates.reserve(MAX_CORDINATES_SIZE); - } - - long long p = -1; - fp = new long long[M + N + 3]; - fill(&fp[0], &fp[M + N + 3], -1); - path = editPath(M + N + 3); - fill(path.begin(), path.end(), -1); - ONP: - do { - ++p; - for (long long k=-p;k<=static_cast(delta)-1;++k) { - fp[k+offset] = snake(k, fp[k-1+offset]+1, fp[k+1+offset]); - } - for (long long k=static_cast(delta)+p;k>=static_cast(delta)+1;--k) { - fp[k+offset] = snake(k, fp[k-1+offset]+1, fp[k+1+offset]); - } - fp[delta+offset] = snake(static_cast(delta), fp[delta-1+offset]+1, fp[delta+1+offset]); - } while (fp[delta+offset] != static_cast(N) && pathCordinates.size() < MAX_CORDINATES_SIZE); - - editDistance += static_cast(delta) + 2 * p; - long long r = path[delta+offset]; - P cordinate; - editPathCordinates epc(0); - - // recording edit distance only - if (editDistanceOnly) { - delete[] this->fp; - return; - } - - while(r != -1) { - cordinate.x = pathCordinates[(size_t)r].x; - cordinate.y = pathCordinates[(size_t)r].y; - epc.push_back(cordinate); - r = pathCordinates[(size_t)r].k; - } - - // record Longest Common Subsequence & Shortest Edit Script - if (!recordSequence(epc)) { - pathCordinates.resize(0); - epc.resize(0); - p = -1; - goto ONP; - } - delete[] this->fp; - } - - /** - * print difference between A and B as an SES - */ - template < typename stream > - void printSES (stream& out) const { - sesElemVec ses_v = ses.getSequence(); - for_each(ses_v.begin(), ses_v.end(), ChangePrinter< sesElem, stream >(out)); - } - - void printSES (ostream& out = cout) const { - printSES< ostream >(out); - } - - /** - * print differences given an SES - */ - template < typename stream > - void printSES (const Ses< elem >& s, stream& out) { - sesElemVec ses_v = s.getSequence(); - for_each(ses_v.begin(), ses_v.end(), ChangePrinter< sesElem, stream >(out)); - } - - void printSES (const Ses< elem >& s, ostream& out = cout) { - printSES< ostream >(s, out); - } - - /** - * print difference between A and B as an SES with custom printer - */ - template < typename stream, template < typename SEET, typename STRT > class PT > - void printSES (stream& out) const { - sesElemVec ses_v = ses.getSequence (); - for_each (ses_v.begin (), ses_v.end(), PT < sesElem, stream > (out)); - } - - /** - * print difference between A and B in the Unified Format - */ - template < typename stream > - void printUnifiedFormat (stream& out) const { - for_each(uniHunks.begin(), uniHunks.end(), UniHunkPrinter< sesElem, stream >(out)); - } - - void printUnifiedFormat (ostream& out = cout) const { - printUnifiedFormat< ostream >(out); - } - - /** - * print unified format difference with given unified format hunks - */ - template < typename stream > - void printUnifiedFormat (const uniHunkVec& hunks, stream& out) { - for_each(hunks.begin(), hunks.end(), UniHunkPrinter< sesElem >(out)); - } - - void printUnifiedFormat (const uniHunkVec& hunks, ostream& out = cout) { - printUnifiedFormat< ostream >(hunks, out); - } - - /** - * compose Unified Format Hunks from Shortest Edit Script - */ - void composeUnifiedHunks () { - sesElemVec common[2]; - sesElemVec change; - sesElemVec ses_v = ses.getSequence(); - long long l_cnt = 1; - long long length = distance(ses_v.begin(), ses_v.end()); - long long middle = 0; - bool isMiddle, isAfter; - elemInfo einfo; - long long a, b, c, d; // @@ -a,b +c,d @@ - long long inc_dec_count = 0; - uniHunk< sesElem > hunk; - sesElemVec adds; - sesElemVec deletes; - - isMiddle = isAfter = false; - a = b = c = d = 0; - - for (sesElemVec_iter it=ses_v.begin();it!=ses_v.end();++it, ++l_cnt) { - einfo = it->second; - switch (einfo.type) { - case SES_ADD : - middle = 0; - ++inc_dec_count; - adds.push_back(*it); - if (!isMiddle) isMiddle = true; - if (isMiddle) ++d; - if (l_cnt >= length) { - joinSesVec(change, deletes); - joinSesVec(change, adds); - isAfter = true; - } - break; - case SES_DELETE : - middle = 0; - --inc_dec_count; - deletes.push_back(*it); - if (!isMiddle) isMiddle = true; - if (isMiddle) ++b; - if (l_cnt >= length) { - joinSesVec(change, deletes); - joinSesVec(change, adds); - isAfter = true; - } - break; - case SES_COMMON : - ++b;++d; - if (common[1].empty() && adds.empty() && deletes.empty() && change.empty()) { - if (static_cast(common[0].size()) < DTL_CONTEXT_SIZE) { - if (a == 0 && c == 0) { - if (!wasSwapped()) { - a = einfo.beforeIdx; - c = einfo.afterIdx; - } else { - a = einfo.afterIdx; - c = einfo.beforeIdx; - } - } - common[0].push_back(*it); - } else { - rotate(common[0].begin(), common[0].begin() + 1, common[0].end()); - common[0].pop_back(); - common[0].push_back(*it); - ++a;++c; - --b;--d; - } - } - if (isMiddle && !isAfter) { - ++middle; - joinSesVec(change, deletes); - joinSesVec(change, adds); - change.push_back(*it); - if (middle >= DTL_SEPARATE_SIZE || l_cnt >= length) { - isAfter = true; - } - adds.clear(); - deletes.clear(); - } - break; - default : - // no through - break; - } - // compose unified format hunk - if (isAfter && !change.empty()) { - sesElemVec_iter cit = it; - long long cnt = 0; - for (long long i=0;isecond.type == SES_COMMON) { - ++cnt; - } - } - if (cnt < DTL_SEPARATE_SIZE && l_cnt < length) { - middle = 0; - isAfter = false; - continue; - } - if (static_cast(common[0].size()) >= DTL_SEPARATE_SIZE) { - long long c0size = static_cast(common[0].size()); - rotate(common[0].begin(), - common[0].begin() + (size_t)c0size - DTL_SEPARATE_SIZE, - common[0].end()); - for (long long i=0;i - Ses< elem > composeSesFromStream (stream& st) - { - elem line; - Ses< elem > ret; - long long x_idx, y_idx; - x_idx = y_idx = 1; - while (getline(st, line)) { - elem mark(line.begin(), line.begin() + 1); - elem e(line.begin() + 1, line.end()); - if (mark == SES_MARK_DELETE) { - ret.addSequence(e, x_idx, 0, SES_DELETE); - ++x_idx; - } else if (mark == SES_MARK_ADD) { - ret.addSequence(e, y_idx, 0, SES_ADD); - ++y_idx; - } else if (mark == SES_MARK_COMMON) { - ret.addSequence(e, x_idx, y_idx, SES_COMMON); - ++x_idx; - ++y_idx; - } - } - return ret; - } - - private : - /** - * initialize - */ - void init () { - M = distance(A.begin(), A.end()); - N = distance(B.begin(), B.end()); - if (M < N) { - swapped = false; - } else { - swap(A, B); - swap(M, N); - swapped = true; - } - editDistance = 0; - delta = N - M; - offset = M + 1; - huge = false; - trivial = false; - editDistanceOnly = false; - fp = nullptr; - } - - /** - * search shortest path and record the path - */ - long long snake(const long long& k, const long long& above, const long long& below) { - long long r = above > below ? path[(size_t)k-1+offset] : path[(size_t)k+1+offset]; - long long y = max(above, below); - long long x = y - k; - while ((size_t)x < M && (size_t)y < N && (swapped ? cmp.impl(B[(size_t)y], A[(size_t)x]) : cmp.impl(A[(size_t)x], B[(size_t)y]))) { - ++x;++y; - } - - path[(size_t)k+offset] = static_cast(pathCordinates.size()); - if (!editDistanceOnly) { - P p; - p.x = x;p.y = y;p.k = r; - pathCordinates.push_back(p); - } - return y; - } - - /** - * record SES and LCS - */ - bool recordSequence (const editPathCordinates& v) { - sequence_const_iter x(A.begin()); - sequence_const_iter y(B.begin()); - long long x_idx, y_idx; // line number for Unified Format - long long px_idx, py_idx; // cordinates - bool complete = false; - x_idx = y_idx = 1; - px_idx = py_idx = 0; - for (size_t i=v.size()-1;!complete;--i) { - while(px_idx < v[i].x || py_idx < v[i].y) { - if (v[i].y - v[i].x > py_idx - px_idx) { - if (!wasSwapped()) { - ses.addSequence(*y, 0, y_idx, SES_ADD); - } else { - ses.addSequence(*y, y_idx, 0, SES_DELETE); - } - ++y; - ++y_idx; - ++py_idx; - } else if (v[i].y - v[i].x < py_idx - px_idx) { - if (!wasSwapped()) { - ses.addSequence(*x, x_idx, 0, SES_DELETE); - } else { - ses.addSequence(*x, 0, x_idx, SES_ADD); - } - ++x; - ++x_idx; - ++px_idx; - } else { - if (!wasSwapped()) { - lcs.addSequence(*x); - ses.addSequence(*x, x_idx, y_idx, SES_COMMON); - } else { - lcs.addSequence(*y); - ses.addSequence(*y, y_idx, x_idx, SES_COMMON); - } - ++x; - ++y; - ++x_idx; - ++y_idx; - ++px_idx; - ++py_idx; - } - } - if (i == 0) complete = true; - } - - if (x_idx > static_cast(M) && y_idx > static_cast(N)) { - // all recording succeeded - } else { - // trivial difference - if (trivialEnabled()) { - if (!wasSwapped()) { - recordOddSequence(x_idx, M, x, SES_DELETE); - recordOddSequence(y_idx, N, y, SES_ADD); - } else { - recordOddSequence(x_idx, M, x, SES_ADD); - recordOddSequence(y_idx, N, y, SES_DELETE); - } - return true; - } - - // nontrivial difference - sequence A_(A.begin() + (size_t)x_idx - 1, A.end()); - sequence B_(B.begin() + (size_t)y_idx - 1, B.end()); - A = A_; - B = B_; - M = distance(A.begin(), A.end()); - N = distance(B.begin(), B.end()); - delta = N - M; - offset = M + 1; - delete[] fp; - fp = new long long[M + N + 3]; - fill(&fp[0], &fp[M + N + 3], -1); - fill(path.begin(), path.end(), -1); - return false; - } - return true; - } - - /** - * record odd sequence in SES - */ - void inline recordOddSequence (long long idx, long long length, sequence_const_iter it, const edit_t et) { - while(idx < length){ - ses.addSequence(*it, idx, 0, et); - ++it; - ++idx; - ++editDistance; - } - ses.addSequence(*it, idx, 0, et); - ++editDistance; - } - - /** - * join SES vectors - */ - void inline joinSesVec (sesElemVec& s1, sesElemVec& s2) const { - if (!s2.empty()) { - for (sesElemVec_iter vit=s2.begin();vit!=s2.end();++vit) { - s1.push_back(*vit); - } - } - } - - /** - * check if the sequences have been swapped - */ - bool inline wasSwapped () const { - return swapped; - } - - }; -} - -#endif // DTL_DIFF_H diff --git a/dtl/Diff3.hpp b/dtl/Diff3.hpp deleted file mode 100755 index 29b5c6c99..000000000 --- a/dtl/Diff3.hpp +++ /dev/null @@ -1,246 +0,0 @@ - -/** - dtl -- Diff Template Library - - In short, Diff Template Library is distributed under so called "BSD license", - - Copyright (c) 2015 Tatsuhiko Kubo - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the authors nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* If you use this library, you must include dtl.hpp only. */ - -#ifndef DTL_DIFF3_H -#define DTL_DIFF3_H - -namespace dtl { - - /** - * diff3 class template - * sequence must support random_access_iterator. - */ - template , typename comparator = Compare< elem > > - class Diff3 - { - private: - dtl_typedefs(elem, sequence) - sequence A; - sequence B; - sequence C; - sequence S; - Diff< elem, sequence, comparator > diff_ba; - Diff< elem, sequence, comparator > diff_bc; - bool conflict; - elem csepabegin; - elem csepa; - elem csepaend; - public : - Diff3 () {} - Diff3 (const sequence& a, - const sequence& b, - const sequence& c) : A(a), B(b), C(c), - diff_ba(b, a), diff_bc(b, c), - conflict(false) {} - - ~Diff3 () {} - - bool isConflict () const { - return conflict; - } - - sequence getMergedSequence () const { - return S; - } - - /** - * merge changes B and C into A - */ - bool merge () { - if (diff_ba.getEditDistance() == 0) { // A == B - if (diff_bc.getEditDistance() == 0) { // A == B == C - S = B; - return true; - } - S = C; - return true; - } else { // A != B - if (diff_bc.getEditDistance() == 0) { // A != B == C - S = A; - return true; - } else { // A != B != C - S = merge_(); - if (isConflict()) { // conflict occured - return false; - } - } - } - return true; - } - - /** - * compose differences - */ - void compose () { - diff_ba.compose(); - diff_bc.compose(); - } - - private : - /** - * merge implementation - */ - sequence merge_ () { - elemVec seq; - Ses< elem > ses_ba = diff_ba.getSes(); - Ses< elem > ses_bc = diff_bc.getSes(); - sesElemVec ses_ba_v = ses_ba.getSequence(); - sesElemVec ses_bc_v = ses_bc.getSequence(); - sesElemVec_iter ba_it = ses_ba_v.begin(); - sesElemVec_iter bc_it = ses_bc_v.begin(); - sesElemVec_iter ba_end = ses_ba_v.end(); - sesElemVec_iter bc_end = ses_bc_v.end(); - - while (!isEnd(ba_end, ba_it) || !isEnd(bc_end, bc_it)) { - while (true) { - if (!isEnd(ba_end, ba_it) && - !isEnd(bc_end, bc_it) && - ba_it->first == bc_it->first && - ba_it->second.type == SES_COMMON && - bc_it->second.type == SES_COMMON) { - // do nothing - } else { - break; - } - if (!isEnd(ba_end, ba_it)) seq.push_back(ba_it->first); - else if (!isEnd(bc_end, bc_it)) seq.push_back(bc_it->first); - forwardUntilEnd(ba_end, ba_it); - forwardUntilEnd(bc_end, bc_it); - } - if (isEnd(ba_end, ba_it) || isEnd(bc_end, bc_it)) break; - if ( ba_it->second.type == SES_COMMON - && bc_it->second.type == SES_DELETE) { - forwardUntilEnd(ba_end, ba_it); - forwardUntilEnd(bc_end, bc_it); - } else if (ba_it->second.type == SES_COMMON && - bc_it->second.type == SES_ADD) { - seq.push_back(bc_it->first); - forwardUntilEnd(bc_end, bc_it); - } else if (ba_it->second.type == SES_DELETE && - bc_it->second.type == SES_COMMON) { - forwardUntilEnd(ba_end, ba_it); - forwardUntilEnd(bc_end, bc_it); - } else if (ba_it->second.type == SES_DELETE && - bc_it->second.type == SES_DELETE) { - if (ba_it->first == bc_it->first) { - forwardUntilEnd(ba_end, ba_it); - forwardUntilEnd(bc_end, bc_it); - } else { - // conflict - conflict = true; - return B; - } - } else if (ba_it->second.type == SES_DELETE && - bc_it->second.type == SES_ADD) { - // conflict - conflict = true; - return B; - } else if (ba_it->second.type == SES_ADD && - bc_it->second.type == SES_COMMON) { - seq.push_back(ba_it->first); - forwardUntilEnd(ba_end, ba_it); - } else if (ba_it->second.type == SES_ADD && - bc_it->second.type == SES_DELETE) { - // conflict - conflict = true; - return B; - } else if (ba_it->second.type == SES_ADD && - bc_it->second.type == SES_ADD) { - if (ba_it->first == bc_it->first) { - seq.push_back(ba_it->first); - forwardUntilEnd(ba_end, ba_it); - forwardUntilEnd(bc_end, bc_it); - } else { - // conflict - conflict = true; - return B; - } - } - } - - if (isEnd(ba_end, ba_it)) { - addDecentSequence(bc_end, bc_it, seq); - } else if (isEnd(bc_end, bc_it)) { - addDecentSequence(ba_end, ba_it, seq); - } - - sequence mergedSeq(seq.begin(), seq.end()); - return mergedSeq; - } - - /** - * join elem vectors - */ - void inline joinElemVec (elemVec& s1, elemVec& s2) const { - if (!s2.empty()) { - for (elemVec_iter vit=s2.begin();vit!=s2.end();++vit) { - s1.push_back(*vit); - } - } - } - - /** - * check if sequence is at end - */ - template - bool inline isEnd (const T_iter& end, const T_iter& it) const { - return it == end ? true : false; - } - - /** - * increment iterator until iterator is at end - */ - template - void inline forwardUntilEnd (const T_iter& end, T_iter& it) const { - if (!isEnd(end, it)) ++it; - } - - /** - * add elements whose SES's type is ADD - */ - void inline addDecentSequence (const sesElemVec_iter& end, sesElemVec_iter& it, elemVec& seq) const { - while (!isEnd(end, it)) { - if (it->second.type == SES_ADD) seq.push_back(it->first); - ++it; - } - } - - }; -} - -#endif // DTL_DIFF3_H diff --git a/dtl/Lcs.hpp b/dtl/Lcs.hpp deleted file mode 100755 index e47c2381a..000000000 --- a/dtl/Lcs.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/** - dtl -- Diff Template Library - - In short, Diff Template Library is distributed under so called "BSD license", - - Copyright (c) 2015 Tatsuhiko Kubo - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the authors nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* If you use this library, you must include dtl.hpp only. */ - -#ifndef DTL_LCS_H -#define DTL_LCS_H - -namespace dtl { - - /** - * Longest Common Subsequence template class - */ - template - class Lcs : public Sequence< elem > - { - public : - Lcs () {} - ~Lcs () {} - }; -} - -#endif // DTL_LCS_H diff --git a/dtl/Sequence.hpp b/dtl/Sequence.hpp deleted file mode 100755 index eeab0ed77..000000000 --- a/dtl/Sequence.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/** - dtl -- Diff Template Library - - In short, Diff Template Library is distributed under so called "BSD license", - - Copyright (c) 2015 Tatsuhiko Kubo - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the authors nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* If you use this library, you must include dtl.hpp only. */ - -#ifndef DTL_SEQUENCE_H -#define DTL_SEQUENCE_H - -namespace dtl { - - /** - * sequence class template - */ - template - class Sequence - { - public : - typedef vector< elem > elemVec; - Sequence () {} - virtual ~Sequence () {} - - elemVec getSequence () const { - return sequence; - } - void addSequence (elem e) { - sequence.push_back(e); - } - protected : - elemVec sequence; - }; -} - -#endif // DTL_SEQUENCE_H diff --git a/dtl/Ses.hpp b/dtl/Ses.hpp deleted file mode 100755 index 281144e06..000000000 --- a/dtl/Ses.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/** - dtl -- Diff Template Library - - In short, Diff Template Library is distributed under so called "BSD license", - - Copyright (c) 2015 Tatsuhiko Kubo - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the authors nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* If you use this library, you must include dtl.hpp only. */ - -#ifndef DTL_SES_H -#define DTL_SES_H - -namespace dtl { - - /** - * Shortest Edit Script template class - */ - template - class Ses : public Sequence< elem > - { - private : - typedef pair< elem, elemInfo > sesElem; - typedef vector< sesElem > sesElemVec; - public : - - Ses () : onlyAdd(true), onlyDelete(true), onlyCopy(true), deletesFirst(false) { - nextDeleteIdx = 0; - } - Ses (bool moveDel) : onlyAdd(true), onlyDelete(true), onlyCopy(true), deletesFirst(moveDel) { - nextDeleteIdx = 0; - } - ~Ses () {} - - bool isOnlyAdd () const { - return onlyAdd; - } - - bool isOnlyDelete () const { - return onlyDelete; - } - - bool isOnlyCopy () const { - return onlyCopy; - } - - bool isOnlyOneOperation () const { - return isOnlyAdd() || isOnlyDelete() || isOnlyCopy(); - } - - bool isChange () const { - return !onlyCopy; - } - - using Sequence< elem >::addSequence; - void addSequence (elem e, long long beforeIdx, long long afterIdx, const edit_t type) { - elemInfo info; - info.beforeIdx = beforeIdx; - info.afterIdx = afterIdx; - info.type = type; - sesElem pe(e, info); - if (!deletesFirst) { - sequence.push_back(pe); - } - switch (type) { - case SES_DELETE: - onlyCopy = false; - onlyAdd = false; - if (deletesFirst) { - sequence.insert(sequence.begin() + nextDeleteIdx, pe); - nextDeleteIdx++; - } - break; - case SES_COMMON: - onlyAdd = false; - onlyDelete = false; - if (deletesFirst) { - sequence.push_back(pe); - nextDeleteIdx = sequence.size(); - } - break; - case SES_ADD: - onlyDelete = false; - onlyCopy = false; - if (deletesFirst) { - sequence.push_back(pe); - } - break; - } - } - - sesElemVec getSequence () const { - return sequence; - } - private : - sesElemVec sequence; - bool onlyAdd; - bool onlyDelete; - bool onlyCopy; - bool deletesFirst; - size_t nextDeleteIdx; - }; -} - -#endif // DTL_SES_H diff --git a/dtl/dtl.hpp b/dtl/dtl.hpp deleted file mode 100755 index b6231ba79..000000000 --- a/dtl/dtl.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/** - dtl -- Diff Template Library - - In short, Diff Template Library is distributed under so called "BSD license", - - Copyright (c) 2015 Tatsuhiko Kubo - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the authors nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef DTL_H -#define DTL_H - -#include "variables.hpp" -#include "functors.hpp" -#include "Sequence.hpp" -#include "Lcs.hpp" -#include "Ses.hpp" -#include "Diff.hpp" -#include "Diff3.hpp" - -#endif // DTL_H diff --git a/dtl/functors.hpp b/dtl/functors.hpp deleted file mode 100755 index a4da5e5f4..000000000 --- a/dtl/functors.hpp +++ /dev/null @@ -1,137 +0,0 @@ -/** - dtl -- Diff Template Library - - In short, Diff Template Library is distributed under so called "BSD license", - - Copyright (c) 2015 Tatsuhiko Kubo - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the authors nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* If you use this library, you must include dtl.hpp only. */ - -#ifndef DTL_FUNCTORS_H -#define DTL_FUNCTORS_H - -namespace dtl { - - /** - * printer class template - */ - template - class Printer - { - public : - Printer () : out_(cout) {} - Printer (stream& out) : out_(out) {} - virtual ~Printer () {} - virtual void operator() (const sesElem& se) const = 0; - protected : - stream& out_; - }; - - /** - * common element printer class template - */ - template - class CommonPrinter : public Printer < sesElem, stream > - { - public : - CommonPrinter () : Printer < sesElem, stream > () {} - CommonPrinter (stream& out) : Printer < sesElem, stream > (out) {} - ~CommonPrinter () {} - void operator() (const sesElem& se) const { - this->out_ << SES_MARK_COMMON << se.first << endl; - } - }; - - /** - * ses element printer class template - */ - template - class ChangePrinter : public Printer < sesElem, stream > - { - public : - ChangePrinter () : Printer < sesElem, stream > () {} - ChangePrinter (stream& out) : Printer < sesElem, stream > (out) {} - ~ChangePrinter () {} - void operator() (const sesElem& se) const { - switch (se.second.type) { - case SES_ADD: - this->out_ << SES_MARK_ADD << se.first << endl; - break; - case SES_DELETE: - this->out_ << SES_MARK_DELETE << se.first << endl; - break; - case SES_COMMON: - this->out_ << SES_MARK_COMMON << se.first << endl; - break; - } - } - }; - - /** - * unified format element printer class template - */ - template - class UniHunkPrinter - { - public : - UniHunkPrinter () : out_(cout) {} - UniHunkPrinter (stream& out) : out_(out) {} - ~UniHunkPrinter () {} - void operator() (const uniHunk< sesElem >& hunk) const { - out_ << "@@" - << " -" << hunk.a << "," << hunk.b - << " +" << hunk.c << "," << hunk.d - << " @@" << endl; - - for_each(hunk.common[0].begin(), hunk.common[0].end(), CommonPrinter< sesElem, stream >(out_)); - for_each(hunk.change.begin(), hunk.change.end(), ChangePrinter< sesElem, stream >(out_)); - for_each(hunk.common[1].begin(), hunk.common[1].end(), CommonPrinter< sesElem, stream >(out_)); - } - private : - stream& out_; - }; - - /** - * compare class template - */ - template - class Compare - { - public : - Compare () {} - virtual ~Compare () {} - virtual inline bool impl (const elem& e1, const elem& e2) const { - return e1 == e2; - } - }; -} - -#endif // DTL_FUNCTORS_H diff --git a/dtl/variables.hpp b/dtl/variables.hpp deleted file mode 100755 index cbf5a54e6..000000000 --- a/dtl/variables.hpp +++ /dev/null @@ -1,142 +0,0 @@ -/** - dtl -- Diff Template Library - - In short, Diff Template Library is distributed under so called "BSD license", - - Copyright (c) 2015 Tatsuhiko Kubo - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the authors nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* If you use this library, you must include dtl.hpp only. */ - -#ifndef DTL_VARIABLES_H -#define DTL_VARIABLES_H - -#include -#include -#include -#include -#include - -namespace dtl { - - using std::vector; - using std::string; - using std::pair; - using std::ostream; - using std::list; - using std::for_each; - using std::distance; - using std::fill; - using std::cout; - using std::endl; - using std::rotate; - using std::swap; - using std::max; - - /** - * version string - */ - const string version = "1.19"; - - /** - * type of edit for SES - */ - typedef int edit_t; - const edit_t SES_DELETE = -1; - const edit_t SES_COMMON = 0; - const edit_t SES_ADD = 1; - - /** - * mark of SES - */ -#define SES_MARK_DELETE "-" -#define SES_MARK_COMMON " " -#define SES_MARK_ADD "+" - - /** - * info for Unified Format - */ - typedef struct eleminfo { - long long beforeIdx; // index of prev sequence - long long afterIdx; // index of after sequence - edit_t type; // type of edit(Add, Delete, Common) - bool operator==(const eleminfo& other) const{ - return (this->beforeIdx == other.beforeIdx && this->afterIdx == other.afterIdx && this->type == other.type); - } - } elemInfo; - - const long long DTL_SEPARATE_SIZE = 3; - const long long DTL_CONTEXT_SIZE = 3; - - /** - * cordinate for registering route - */ - typedef struct Point { - long long x; // x cordinate - long long y; // y cordinate - long long k; // vertex - } P; - - /** - * limit of cordinate size - */ - const unsigned long long MAX_CORDINATES_SIZE = 2000000; - - typedef vector< long long > editPath; - typedef vector< P > editPathCordinates; - - /** - * Structure of Unified Format Hunk - */ - template - struct uniHunk { - long long a, b, c, d; // @@ -a,b +c,d @@ - vector< sesElem > common[2]; // anteroposterior commons on changes - vector< sesElem > change; // changes - long long inc_dec_count; // count of increace and decrease - }; - -#define dtl_typedefs(elem, sequence) \ - typedef pair< elem, elemInfo > sesElem; \ - typedef vector< sesElem > sesElemVec; \ - typedef vector< uniHunk< sesElem > > uniHunkVec; \ - typedef list< elem > elemList; \ - typedef vector< elem > elemVec; \ - typedef typename uniHunkVec::iterator uniHunkVec_iter; \ - typedef typename sesElemVec::iterator sesElemVec_iter; \ - typedef typename elemList::iterator elemList_iter; \ - typedef typename sequence::iterator sequence_iter; \ - typedef typename sequence::const_iterator sequence_const_iter; \ - typedef typename elemVec::iterator elemVec_iter; - - -} - -#endif // DTL_VARIABLES_H diff --git a/edit/edit.cpp b/edit/edit.cpp deleted file mode 100644 index adf1c60cd..000000000 --- a/edit/edit.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string edit_edit_url () -{ - return "edit/edit"; -} - - -bool edit_edit_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [read, write] = access_bible::any (webserver_request); - return read; -} - - -string edit_edit (Webserver_Request& webserver_request) -{ - string passage_query = webserver_request.query ["passage"]; - Passage passage = filter_integer_to_passage (filter::strings::convert_to_int (passage_query)); - Ipc_Focus::set (webserver_request, passage.m_book, passage.m_chapter, filter::strings::convert_to_int (passage.m_verse)); - Navigation_Passage::record_history (webserver_request, passage.m_book, passage.m_chapter, filter::strings::convert_to_int (passage.m_verse)); - - // Check whether a Bible editor is alive. - int timestamp = webserver_request.database_config_user()->getLiveBibleEditor (); - bool alive = (timestamp > (filter::date::seconds_since_epoch () - 5)); - - if (alive) - return translate ("The passage has been opened in the existing Bible editor"); - - return R"()" + translate ("Open a Bible editor to edit the passage") + ""; -} diff --git a/edit/edit.h b/edit/edit.h deleted file mode 100644 index 8b41fbe30..000000000 --- a/edit/edit.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_edit_url (); -bool edit_edit_acl (Webserver_Request& webserver_request); -std::string edit_edit (Webserver_Request& webserver_request); diff --git a/edit/id.cpp b/edit/id.cpp deleted file mode 100644 index 4a5e3ed32..000000000 --- a/edit/id.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string edit_id_url () -{ - return "edit/id"; -} - - -bool edit_id_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string edit_id (Webserver_Request& webserver_request) -{ - // Update the timestamp indicating that the Bible editor is alive. - webserver_request.database_config_user()->setLiveBibleEditor (filter::date::seconds_since_epoch ()); - - string bible = webserver_request.query ["bible"]; - int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.query ["chapter"]); - int id = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - return filter::strings::convert_to_string (id); -} diff --git a/edit/id.h b/edit/id.h deleted file mode 100644 index 8f3f779e2..000000000 --- a/edit/id.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_id_url (); -bool edit_id_acl (Webserver_Request& webserver_request); -std::string edit_id (Webserver_Request& webserver_request); diff --git a/edit/index.cpp b/edit/index.cpp deleted file mode 100644 index 57c6011ef..000000000 --- a/edit/index.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string edit_index_url () -{ - return "edit/index"; -} - - -bool edit_index_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return write; -} - - -std::string edit_index (Webserver_Request& webserver_request) -{ - const bool touch = webserver_request.session_logic ()->touchEnabled (); - - - if (webserver_request.query.count ("switchbook") && webserver_request.query.count ("switchchapter")) { - const int switchbook = filter::strings::convert_to_int (webserver_request.query ["switchbook"]); - const int switchchapter = filter::strings::convert_to_int (webserver_request.query ["switchchapter"]); - int switchverse = 1; - if (webserver_request.query.count ("switchverse")) - switchverse = filter::strings::convert_to_int (webserver_request.query ["switchverse"]); - Ipc_Focus::set (webserver_request, switchbook, switchchapter, switchverse); - Navigation_Passage::record_history (webserver_request, switchbook, switchchapter, switchverse); - } - - - // Set the user chosen Bible as the current Bible. - if (webserver_request.post.count ("bibleselect")) { - const std::string bibleselect = webserver_request.post ["bibleselect"]; - webserver_request.database_config_user ()->setBible (bibleselect); - // Going to another Bible, ensure that the focused book exists there. - int book = Ipc_Focus::getBook (webserver_request); - const std::vector books = webserver_request.database_bibles()->get_books (bibleselect); - if (find (books.begin(), books.end(), book) == books.end()) { - if (!books.empty ()) book = books [0]; - else book = 0; - Ipc_Focus::set (webserver_request, book, 1, 1); - } - return std::string(); - } - - - std::string page{}; - - - Assets_Header header = Assets_Header (translate("Edit"), webserver_request); - header.set_navigator (); - header.set_editor_stylesheet (); - if (touch) header.jquery_touch_on (); - header.notify_it_on (); - header.add_bread_crumb (menu_logic_translate_menu (), menu_logic_translate_text ()); - page = header.run (); - - - Assets_View view{}; - - - // Active Bible, and check access. - // Or if the user have used query to preset the active Bible, get the preset Bible. - // Set the chosen Bible on the option HTML tag. - std::string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - if (webserver_request.query.count ("bible")) - bible = access_bible::clamp (webserver_request, webserver_request.query ["bible"]); - std::string bible_html{}; - const std::vector bibles = access_bible::bibles (webserver_request); - for (const auto& selectable_bible : bibles) { - bible_html = Options_To_Select::add_selection (selectable_bible, selectable_bible, bible_html); - } - view.set_variable ("bibleoptags", Options_To_Select::mark_selected (bible, bible_html)); - view.set_variable ("bible", bible); - - - // Store the active Bible in the page's javascript. - view.set_variable ("navigationCode", Navigation_Passage::code (bible)); - - - // Create the script. - // Quote the text to be sure it's a legal Javascript string. - // https://github.com/bibledit/cloud/issues/900 - std::stringstream script_stream {}; - script_stream << "var editorChapterLoaded = " << quoted(locale_logic_text_loaded ()) << ";\n"; - script_stream << "var editorChapterUpdating = " << quoted(locale_logic_text_updating ()) << ";\n"; - script_stream << "var editorChapterUpdated = " << quoted(locale_logic_text_updated ()) << ";\n"; - script_stream << "var editorWillSave = " << quoted(locale_logic_text_will_save ()) << ";\n"; - script_stream << "var editorChapterSaving = " << quoted(locale_logic_text_saving ()) << ";\n"; - script_stream << "var editorChapterSaved = " << quoted(locale_logic_text_saved ()) << ";\n"; - script_stream << "var editorChapterRetrying = " << quoted(locale_logic_text_retrying ()) << ";\n"; - script_stream << "var editorChapterVerseUpdatedLoaded = " << quoted(locale_logic_text_reload ()) << ";\n"; - script_stream << "var verticalCaretPosition = " << webserver_request.database_config_user ()->getVerticalCaretPosition () << ";\n"; - script_stream << "var verseSeparator = " << quoted(Database_Config_General::getNotesVerseSeparator ()) << ";\n"; - std::string script = script_stream.str(); - config::logic::swipe_enabled (webserver_request, script); - view.set_variable ("script", script); - - - const std::string clss = Filter_Css::getClass (bible); - const std::string font = fonts::logic::get_text_font (bible); - const int current_theme_index = webserver_request.database_config_user ()->getCurrentTheme (); - const int direction = Database_Config_Bible::getTextDirection (bible); - const int lineheight = Database_Config_Bible::getLineHeight (bible); - const int letterspacing = Database_Config_Bible::getLetterSpacing (bible); - std::string versebeam_current_theme = Filter_Css::theme_picker (current_theme_index, 5); - if (versebeam_current_theme.empty()) - versebeam_current_theme = "versebeam"; - view.set_variable ("versebeam_theme_color", versebeam_current_theme); - view.set_variable ("editor_theme_color", Filter_Css::theme_picker (current_theme_index, 2)); - view.set_variable ("active_editor_theme_color", Filter_Css::theme_picker (current_theme_index, 3)); - view.set_variable ("custom_class", clss); - view.set_variable ("custom_css", Filter_Css::get_css (clss, fonts::logic::get_font_path (font), - direction, lineheight, letterspacing)); - - - // In basic mode the editor has no controls and fewer indicators. - // In basic mode, the user can just edit text, and cannot style it. - const bool basic_mode = config::logic::basic_mode (webserver_request); - if (!basic_mode) view.enable_zone ("advancedmode"); - - - // Whether to enable fast Bible editor switching. - if (!basic_mode && webserver_request.database_config_user ()->getFastEditorSwitchingAvailable ()) { - view.enable_zone ("fastswitcheditor"); - } - - - // Whether to enable the styles button. - if (webserver_request.database_config_user ()->getEnableStylesButtonVisualEditors ()) { - view.enable_zone ("stylesbutton"); - } - - - page += view.render ("edit", "index"); - - - page += assets_page::footer (); - - - return page; -} - - -/* - Tests for the Bible editor: - * Autosave on going to another passage. - * Autosave on document unload. - * Autosave shortly after any change. - * Automatic reload when another user updates the chapter on the server. - * Position caret at correct verse. - * Scroll caret into view. - */ diff --git a/edit/index.h b/edit/index.h deleted file mode 100644 index 3b98bfd43..000000000 --- a/edit/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_index_url (); -bool edit_index_acl (Webserver_Request& webserver_request); -std::string edit_index (Webserver_Request& webserver_request); diff --git a/edit/load.cpp b/edit/load.cpp deleted file mode 100644 index 854fe6ecf..000000000 --- a/edit/load.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string edit_load_url () -{ - return "edit/load"; -} - - -bool edit_load_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return write; -} - - -string edit_load (Webserver_Request& webserver_request) -{ - string bible = webserver_request.query ["bible"]; - int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.query ["chapter"]); - string unique_id = webserver_request.query ["id"]; - - // Store a copy of the USFM loaded in the editor for later reference. - storeLoadedUsfm2 (webserver_request, bible, book, chapter, unique_id); - - string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - - string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - Editor_Usfm2Html editor_usfm2html; - editor_usfm2html.load (usfm); - editor_usfm2html.stylesheet (stylesheet); - editor_usfm2html.run (); - - string html = editor_usfm2html.get (); - - // To make editing empty verses easier, convert spaces to non-breaking spaces, so they appear in the editor. - if (filter::usfm::contains_empty_verses (usfm)) { - string search = " "; - string replace = "" + filter::strings::unicode_non_breaking_space_entity () + ""; - html = filter::strings::replace (search, replace, html); - } - - string user = webserver_request.session_logic ()->currentUser (); - bool write = access_bible::book_write (webserver_request, user, bible, book); - - return checksum_logic::send (html, write); -} diff --git a/edit/load.h b/edit/load.h deleted file mode 100644 index b9e3d4c1e..000000000 --- a/edit/load.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_load_url (); -bool edit_load_acl (Webserver_Request& webserver_request); -std::string edit_load (Webserver_Request& webserver_request); diff --git a/edit/logic.cpp b/edit/logic.cpp deleted file mode 100644 index f7b63ee25..000000000 --- a/edit/logic.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -string edit2_logic_volatile_key (string bible, int book, int chapter, string editor) -{ - string key; - key.append (bible); - key.append (" "); - key.append (filter::strings::fill (filter::strings::convert_to_string (book), 2, '0')); - key.append (" "); - key.append (filter::strings::fill (filter::strings::convert_to_string (chapter), 3, '0')); - key.append (" "); - key.append (editor); - return key; -} - - -void storeLoadedUsfm2 (Webserver_Request& webserver_request, string bible, int book, int chapter, string editor, [[maybe_unused]] const char * message) -{ - int userid = filter::strings::user_identifier (webserver_request); - - string key = edit2_logic_volatile_key (bible, book, chapter, editor); - - string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - Database_Volatile::setValue (userid, key, usfm); -} - - -string getLoadedUsfm2 (Webserver_Request& webserver_request, string bible, int book, int chapter, string editor) -{ - int userid = filter::strings::user_identifier (webserver_request); - - string key = edit2_logic_volatile_key (bible, book, chapter, editor); - - string usfm = Database_Volatile::getValue (userid, key); - - return usfm; -} diff --git a/edit/logic.h b/edit/logic.h deleted file mode 100644 index 3b5cc4807..000000000 --- a/edit/logic.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -void storeLoadedUsfm2 (Webserver_Request& webserver_request, std::string bible, int book, int chapter, std::string editor, const char * message = ""); -std::string getLoadedUsfm2 (Webserver_Request& webserver_request, std::string bible, int book, int chapter, std::string editor); diff --git a/edit/navigate.cpp b/edit/navigate.cpp deleted file mode 100644 index cbdd01b14..000000000 --- a/edit/navigate.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string edit_navigate_url () -{ - return "edit/navigate"; -} - - -bool edit_navigate_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return write; -} - - -std::string edit_navigate (Webserver_Request& webserver_request) -{ - const std::string bible = webserver_request.query ["bible"]; - const int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - const int chapter = filter::strings::convert_to_int (webserver_request.query ["chapter"]); - - - // At first the browser used the rangy library to get the offset of the caret. - // But the rangy library provides the offset relative to the element that contains the caret, - // not relative to the main editor element. - // Therefore a pure Javascript implementation was Googled for and implemented. - // This provides the offset of the caret relative to the
    . - const size_t offset = static_cast (filter::strings::convert_to_int (webserver_request.query ["offset"])); - - - const std::string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - const std::string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - - Editor_Usfm2Html editor_usfm2html; - editor_usfm2html.load (usfm); - editor_usfm2html.stylesheet (stylesheet); - editor_usfm2html.run (); - - - // The caret offset should be in the main text body. - // If it is in a note body, skip the verse updating. - if (offset > editor_usfm2html.m_text_tength) return std::string(); - - - // Get the number of verses in the USFM. - // This covers combined verses also. - int last_offset {0}; - const std::vector verses = filter::usfm::get_verse_numbers (usfm); - for (int i = 0; i < static_cast(verses.size ()); i++) { - if (editor_usfm2html.m_verse_start_offsets.count (i)) { - last_offset = editor_usfm2html.m_verse_start_offsets [i]; - } else { - editor_usfm2html.m_verse_start_offsets [i] = last_offset; - } - } - - - // Get the starting offsets for each verse. - std::vector starting_offsets{}; - for (int i = 0; i < static_cast (verses.size ()); i++) { - starting_offsets.push_back (static_cast(editor_usfm2html.m_verse_start_offsets [i])); - } - starting_offsets.push_back (editor_usfm2html.m_text_tength); - - - // Get the ending offsets for each verse. - std::vector ending_offsets; - for (size_t i = 0; i < verses.size (); i++) { - size_t offset2 = starting_offsets [i]; - for (size_t i2 = 0; i2 < starting_offsets.size (); i2++) { - if (starting_offsets [i2] > offset2) { - offset2 = starting_offsets [i2]; - break; - } - } - ending_offsets.push_back (offset2 - 1); - } - - - // If the offset is between the focused verse's min and max values, then do nothing. - int verse = Ipc_Focus::getVerse (webserver_request); - for (size_t i = 0; i < verses.size (); i++) { - if (verse == verses[i]) { - if (offset >= starting_offsets [i]) { - if (offset <= ending_offsets [i]) { - return std::string(); - } - } - } - } - - - // Look for the verse that matches the offset. - verse = -1; - for (const auto& element : editor_usfm2html.m_verse_start_offsets) { - int key = element.first; - size_t value = static_cast (element.second); - if (offset >= value) { - // A verse number was found. - verse = key; - } - } - - - // Only act if a verse was found - if (verse >= 0) { - // Only update navigation in case the verse changed. - // This avoids unnecessary focus operations in the clients. - if (verse != Ipc_Focus::getVerse (webserver_request)) { - Ipc_Focus::set (webserver_request, book, chapter, verse); - } - // The editor should scroll the verse into view, - // because the caret is in the Bible text. - return filter::strings::convert_to_string (verse); - // If the caret were in the notes area, - // then the editor should not scroll the verse into view. - } - - - return std::string(); -} diff --git a/edit/navigate.h b/edit/navigate.h deleted file mode 100644 index c33725b0b..000000000 --- a/edit/navigate.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_navigate_url (); -bool edit_navigate_acl (Webserver_Request& webserver_request); -std::string edit_navigate (Webserver_Request& webserver_request); diff --git a/edit/position.cpp b/edit/position.cpp deleted file mode 100644 index 8e72b0fbd..000000000 --- a/edit/position.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string edit_position_url () -{ - return "edit/position"; -} - - -bool edit_position_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return write; -} - - -std::string edit_position (Webserver_Request& webserver_request) -{ - // Get Bible: If an empty Bible is given, bail out. - const std::string bible = webserver_request.query ["bible"]; - if (bible.empty ()) - return std::string(); - // Get book: If no book is given: Bail out. - const int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - if (!book) return std::string(); - // Get chapter. - const int chapter = filter::strings::convert_to_int (webserver_request.query ["chapter"]); - - - const std::string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - const std::string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - const int verse = Ipc_Focus::getVerse (webserver_request); - - - Editor_Usfm2Html editor_usfm2html; - editor_usfm2html.load (usfm); - editor_usfm2html.stylesheet (stylesheet); - editor_usfm2html.run (); - - int starting_offset = 0; - int ending_offset = 0; - // To deal with a combined verse, go through the offsets, and pick the correct one. - for (auto element : editor_usfm2html.m_verse_start_offsets) { - const int vs = element.first; - const int offset = element.second; - if (vs <= verse) - starting_offset = offset; - if (ending_offset == 0) { - if (vs > verse) { - ending_offset = offset; - } - } - } - if (verse) { - starting_offset += static_cast (filter::strings::convert_to_string (verse).length () + 1); - } - if (ending_offset) { - ending_offset--; - } else { - ending_offset = static_cast(editor_usfm2html.m_text_tength); - } - - std::string data = filter::strings::convert_to_string (starting_offset); - data.append ("\n"); - data.append (filter::strings::convert_to_string (ending_offset)); - - return data; -} diff --git a/edit/position.h b/edit/position.h deleted file mode 100644 index eca3f84a8..000000000 --- a/edit/position.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_position_url (); -bool edit_position_acl (Webserver_Request& webserver_request); -std::string edit_position (Webserver_Request& webserver_request); diff --git a/edit/preview.cpp b/edit/preview.cpp deleted file mode 100644 index 6b7e1b798..000000000 --- a/edit/preview.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string edit_preview_url () -{ - return "edit/preview"; -} - - -bool edit_preview_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string edit_preview (Webserver_Request& webserver_request) -{ - bool touch = webserver_request.session_logic ()->touchEnabled (); - bool timeout = webserver_request.query.count ("timeout"); - string caller = webserver_request.query ["caller"]; - - string page; - - Assets_Header header = Assets_Header (translate("Preview"), webserver_request); - header.set_navigator (); - header.set_editor_stylesheet (); - if (touch) header.jquery_touch_on (); - header.add_bread_crumb (menu_logic_translate_menu (), menu_logic_translate_text ()); - if (timeout) header.refresh (5, "../" + caller + "/index"); - page = header.run (); - - Assets_View view; - - // Get active Bible, and check read access to it. - // If needed, change Bible to one it has read access to. - string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - - string cls = Filter_Css::getClass (bible); - string font = fonts::logic::get_text_font (bible); - int direction = Database_Config_Bible::getTextDirection (bible); - int lineheight = Database_Config_Bible::getLineHeight (bible); - int letterspacing = Database_Config_Bible::getLetterSpacing (bible); - view.set_variable ("custom_class", cls); - view.set_variable ("custom_css", Filter_Css::get_css (cls, - fonts::logic::get_font_path (font), - direction, - lineheight, - letterspacing)); - - int book = Ipc_Focus::getBook (webserver_request); - int chapter = Ipc_Focus::getChapter (webserver_request); - - string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - - string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - Editor_Usfm2Html editor_usfm2html; - editor_usfm2html.load (usfm); - editor_usfm2html.stylesheet (stylesheet); - editor_usfm2html.set_preview(); - editor_usfm2html.run (); - - string html = editor_usfm2html.get (); - view.set_variable ("html", html); - - if (timeout) { - view.enable_zone ("timeout"); - view.set_variable ("caller", caller); - } - - // Store the active Bible in the page's javascript. - view.set_variable ("navigationCode", Navigation_Passage::code (bible)); - - page += view.render ("edit", "preview"); - - page += assets_page::footer (); - - return page; -} diff --git a/edit/preview.h b/edit/preview.h deleted file mode 100644 index d37fd72d5..000000000 --- a/edit/preview.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_preview_url (); -bool edit_preview_acl (Webserver_Request& webserver_request); -std::string edit_preview (Webserver_Request& webserver_request); diff --git a/edit/save.cpp b/edit/save.cpp deleted file mode 100644 index 401967c19..000000000 --- a/edit/save.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string edit_save_url () -{ - return "edit/save"; -} - - -bool edit_save_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string edit_save (Webserver_Request& webserver_request) -{ - bool post_complete = (webserver_request.post.count ("bible") && webserver_request.post.count ("book") && webserver_request.post.count ("chapter") && webserver_request.post.count ("html") && webserver_request.post.count ("checksum")); - if (!post_complete) { - return translate("Insufficient information"); - } - - string bible = webserver_request.post["bible"]; - int book = filter::strings::convert_to_int (webserver_request.post["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.post["chapter"]); - string html = webserver_request.post["html"]; - string checksum = webserver_request.post["checksum"]; - string unique_id = webserver_request.post ["id"]; - - if (checksum_logic::get (html) != checksum) { - webserver_request.response_code = 409; - return translate("Checksum error"); - } - - html = filter_url_tag_to_plus (html); - html = filter::strings::trim (html); - - if (html.empty ()) { - Database_Logs::log (translate ("There was no text.") + " " + translate ("Nothing was saved.") + " " + translate ("The original text of the chapter was reloaded.")); - return translate("Nothing to save"); - } - - if (!filter::strings::unicode_string_is_valid (html)) { - Database_Logs::log ("The text was not valid Unicode UTF-8. The chapter could not saved and has been reverted to the last good version."); - return translate("Save failure"); - } - - if (!access_bible::book_write (webserver_request, string(), bible, book)) { - return translate("No write access"); - } - - string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - - Editor_Html2Usfm editor_export; - editor_export.load (html); - editor_export.stylesheet (stylesheet); - editor_export.run (); - string user_usfm = editor_export.get (); - - string ancestor_usfm = getLoadedUsfm2 (webserver_request, bible, book, chapter, unique_id); - - vector book_chapter_text = filter::usfm::usfm_import (user_usfm, stylesheet); - if (book_chapter_text.size () != 1) { - Database_Logs::log (translate ("User tried to save something different from exactly one chapter.")); - return translate("Incorrect chapter"); - } - - int book_number = book_chapter_text[0].m_book; - int chapter_number = book_chapter_text[0].m_chapter; - user_usfm = book_chapter_text[0].m_data; - bool chapter_ok = (((book_number == book) || (book_number == 0)) && (chapter_number == chapter)); - if (!chapter_ok) { - return translate("Incorrect chapter") + " " + filter::strings::convert_to_string (chapter_number); - } - - // Collect some data about the changes for this user - // and for a possible merge of the user's data with the server's data. - string username = webserver_request.session_logic()->currentUser (); - [[maybe_unused]] int oldID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - string server_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - string newText = user_usfm; - string oldText = ancestor_usfm; - - // Safekeep the USFM to save for later. - string change = user_usfm; - - // Merge if the ancestor is there and differs from what's in the database. - vector conflicts; - if (!ancestor_usfm.empty ()) { - if (server_usfm != ancestor_usfm) { - // Prioritize the user's USFM. - user_usfm = filter_merge_run (ancestor_usfm, server_usfm, user_usfm, true, conflicts); - Database_Logs::log (translate ("Merging chapter.")); - } - } - - // Check on the merge. - filter_merge_add_book_chapter (conflicts, book, chapter); - bible_logic::merge_irregularity_mail ({username}, conflicts); - - // Check whether the USFM on disk has changed compared to the USFM that was loaded in the editor. - // If there's a difference, email the user. - // Although a merge was done, still, it's good to alert the user on this. - // The rationale is that if Bible text was saved through Send/receive, - // or if another user saved Bible text, - // it's worth to check on this. - // Because the user's editor may not yet have loaded this updated Bible text. - // https://github.com/bibledit/cloud/issues/340 - if (ancestor_usfm != server_usfm) { - bible_logic::recent_save_email (bible, book, chapter, username, ancestor_usfm, server_usfm); - } - - // Safely store the chapter. - string explanation; - string message = filter::usfm::safely_store_chapter (webserver_request, bible, book, chapter, user_usfm, explanation); - bible_logic::unsafe_save_mail (message, explanation, username, user_usfm, book, chapter); - - // If an error message was given, then return that message to the browser. - if (!message.empty ()) return message; - - // In server configuration, store details for the user's changes. -#ifdef HAVE_CLOUD - int newID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - Database_Modifications database_modifications; - database_modifications.recordUserSave (username, bible, book, chapter, oldID, oldText, newID, newText); - if (sendreceive_git_repository_linked (bible)) { - Database_Git::store_chapter (username, bible, book, chapter, oldText, newText); - } - rss_logic_schedule_update (username, bible, book, chapter, oldText, newText); -#endif - - // Store a copy of the USFM loaded in the editor for later reference. - storeLoadedUsfm2 (webserver_request, bible, book, chapter, unique_id); - - // Convert the stored USFM to html. - // This converted html should be the same as the saved html. - // If it differs, signal the browser to reload the chapter. - // This also cares for renumbering and cleaning up any added or removed footnotes. - Editor_Usfm2Html editor_usfm2html; - editor_usfm2html.load (user_usfm); - editor_usfm2html.stylesheet (stylesheet); - editor_usfm2html.run (); - string converted_html = editor_usfm2html.get (); - // Convert to XML for comparison. - // Remove spaces before comparing. - // Goal: Entering a space in the editor does not cause a reload. - html = filter::strings::html2xml (html); - html = filter::strings::replace (" ", "", html); - html = filter::strings::replace (filter::strings::unicode_non_breaking_space_entity (), "", html); - filter::strings::replace_between (html, "<", ">", ""); - converted_html = filter::strings::html2xml (converted_html); - converted_html = filter::strings::replace (" ", "", converted_html); - converted_html = filter::strings::replace (filter::strings::unicode_non_breaking_space_entity (), "", converted_html); - filter::strings::replace_between (converted_html, "<", ">", ""); - // If round trip conversion differs, send a known string to the browser, - // to signal the browser to reload the reformatted chapter. - if (html != converted_html) return locale_logic_text_reformat (); - - return locale_logic_text_saved (); -} diff --git a/edit/save.h b/edit/save.h deleted file mode 100644 index 871c11cf2..000000000 --- a/edit/save.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_save_url (); -bool edit_save_acl (Webserver_Request& webserver_request); -std::string edit_save (Webserver_Request& webserver_request); diff --git a/edit/styles.cpp b/edit/styles.cpp deleted file mode 100644 index b61af6f74..000000000 --- a/edit/styles.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string edit_styles_url () -{ - return "edit/styles"; -} - - -bool edit_styles_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string edit_styles (Webserver_Request& webserver_request) -{ - if (webserver_request.query.count ("style")) { - string style = webserver_request.query["style"]; - Editor_Styles::recordUsage (webserver_request, style); - string action = Editor_Styles::getAction (webserver_request, style); - return style + "\n" + action; - } - - - if (webserver_request.query.count ("all")) { - return Editor_Styles::getAll (webserver_request); - } - - - return Editor_Styles::getRecentlyUsed (webserver_request); -} - diff --git a/edit/styles.h b/edit/styles.h deleted file mode 100644 index c3aa818d4..000000000 --- a/edit/styles.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_styles_url (); -bool edit_styles_acl (Webserver_Request& webserver_request); -std::string edit_styles (Webserver_Request& webserver_request); diff --git a/edit/update.cpp b/edit/update.cpp deleted file mode 100644 index 8db7b47a8..000000000 --- a/edit/update.cpp +++ /dev/null @@ -1,409 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string edit_update_url () -{ - return "edit/update"; -} - - -bool edit_update_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string edit_update (Webserver_Request& webserver_request) -{ - // Whether the update is good to go. - bool good2go = true; - - - // The messages to return. - vector messages; - - - // Check the relevant bits of information. - if (good2go) { - bool parameters_ok = true; - if (!webserver_request.post.count ("bible")) parameters_ok = false; - if (!webserver_request.post.count ("book")) parameters_ok = false; - if (!webserver_request.post.count ("chapter")) parameters_ok = false; - if (!webserver_request.post.count ("loaded")) parameters_ok = false; - if (!webserver_request.post.count ("edited")) parameters_ok = false; - if (!parameters_ok) { - messages.push_back (translate("Don't know what to update")); - good2go = false; - } - } - - - // Get the relevant bits of information. - string bible; - int book = 0; - int chapter = 0; - string loaded_html; - string edited_html; - string checksum1; - string checksum2; - string unique_id; - if (good2go) { - bible = webserver_request.post["bible"]; - book = filter::strings::convert_to_int (webserver_request.post["book"]); - chapter = filter::strings::convert_to_int (webserver_request.post["chapter"]); - loaded_html = webserver_request.post["loaded"]; - edited_html = webserver_request.post["edited"]; - checksum1 = webserver_request.post["checksum1"]; - checksum2 = webserver_request.post["checksum2"]; - unique_id = webserver_request.post ["id"]; - } - - - // Checksums of the loaded and edited html. - if (good2go) { - if (checksum_logic::get (loaded_html) != checksum1) { - webserver_request.response_code = 409; - messages.push_back (translate ("Checksum error")); - good2go = false; - } - } - if (good2go) { - if (checksum_logic::get (edited_html) != checksum2) { - webserver_request.response_code = 409; - messages.push_back (translate ("Checksum error")); - good2go = false; - } - } - - - // Decode html encoded in javascript, and clean it. - loaded_html = filter_url_tag_to_plus (loaded_html); - edited_html = filter_url_tag_to_plus (edited_html); - loaded_html = filter::strings::trim (loaded_html); - edited_html = filter::strings::trim (edited_html); - - - // Check on valid UTF-8. - if (good2go) { - if (!filter::strings::unicode_string_is_valid (loaded_html) || !filter::strings::unicode_string_is_valid (edited_html)) { - messages.push_back (translate ("Cannot update: Needs Unicode")); - good2go = false; - } - } - - - bool bible_write_access = false; - if (good2go) { - bible_write_access = access_bible::book_write (webserver_request, string(), bible, book); - } - - - string stylesheet; - if (good2go) { - stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - } - - - // Collect some data about the changes for this user. - string username = webserver_request.session_logic()->currentUser (); -#ifdef HAVE_CLOUD - int oldID = 0; - if (good2go) { - oldID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - } -#endif - string old_chapter_usfm; - if (good2go) { - old_chapter_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - } - - - // Determine what version of USFM to save to the chapter. - // Later in the code, it will do a three-way merge, to obtain that USFM. - // This needs the loaded USFM as the ancestor, - // the edited USFM as a change-set, - // and the existing USFM as a prioritized change-set. - string loaded_chapter_usfm; - if (good2go) { - Editor_Html2Usfm editor_export; - editor_export.load (loaded_html); - editor_export.stylesheet (stylesheet); - editor_export.run (); - loaded_chapter_usfm = editor_export.get (); - } - string edited_chapter_usfm; - if (good2go) { - Editor_Html2Usfm editor_export; - editor_export.load (edited_html); - editor_export.stylesheet (stylesheet); - editor_export.run (); - edited_chapter_usfm = editor_export.get (); - } - string existing_chapter_usfm = filter::strings::trim (old_chapter_usfm); - - - // Check that the edited USFM contains no more than, and exactly the same as, - // the book and chapter that was loaded in the editor. - if (good2go && bible_write_access) { - vector book_chapter_text = filter::usfm::usfm_import (edited_chapter_usfm, stylesheet); - if (book_chapter_text.size () != 1) { - Database_Logs::log (translate ("A user tried to save something different from exactly one chapter")); - messages.push_back (translate("Incorrect chapter")); - } - int book_number = book_chapter_text[0].m_book; - int chapter_number = book_chapter_text[0].m_chapter; - edited_chapter_usfm = book_chapter_text[0].m_data; - bool chapter_ok = (((book_number == book) || (book_number == 0)) && (chapter_number == chapter)); - if (!chapter_ok) { - messages.push_back (translate("Incorrect chapter") + " " + filter::strings::convert_to_string (chapter_number)); - } - } - - - // Set a flag if there is a reason to save the editor text, since it was edited. - // This is important because the same routine is used for saving the editor text - // as well as updating the editor text. - // So if the text in the editor was not changed, it should not save it, - // as saving the editor text would overwrite saves made by other(s). - bool text_was_edited = (loaded_chapter_usfm != edited_chapter_usfm); - - - // Do a three-way merge if needed. - // There's a need for this if there were user-edits, - // and if the USFM on the server differs from the USFM loaded in the editor. - // The three-way merge reconciles those differences. - if (good2go && bible_write_access && text_was_edited) { - if (loaded_chapter_usfm != existing_chapter_usfm) { - vector conflicts; - // Do a merge while giving priority to the USFM already in the chapter. - string merged_chapter_usfm = filter_merge_run (loaded_chapter_usfm, edited_chapter_usfm, existing_chapter_usfm, true, conflicts); - // Mail the user if there is a merge anomaly. - bible_logic::optional_merge_irregularity_email (bible, book, chapter, username, loaded_chapter_usfm, edited_chapter_usfm, merged_chapter_usfm); - filter_merge_add_book_chapter (conflicts, book, chapter); - bible_logic::merge_irregularity_mail ({username}, conflicts); - // Let the merged data now become the edited data (so it gets saved properly). - edited_chapter_usfm = merged_chapter_usfm; - } - } - - - // Check whether the USFM on disk has changed compared to the USFM that was loaded in the editor. - // If there's a difference, email the user. - // Although a merge was done, still, it's good to alert the user on this. - // The rationale is that if Bible text was saved through Send/receive, - // or if another user saved Bible text, - // it's worth to check on this. - // Because the user's editor may not yet have loaded this updated Bible text. - // https://github.com/bibledit/cloud/issues/340 - // The above is no longer needed since the chapter editor does no longer "load" text. - // Instead of loading text, the existing text gets updated. - // The message below will no longer be given. - // It might cause confusion more than it clarifies. - //if (good2go && bible_write_access && text_was_edited) { - //if (loaded_chapter_usfm != existing_chapter_usfm) { - //bible_logic::recent_save_email (bible, book, chapter, username, loaded_chapter_usfm, existing_chapter_usfm); - //} - //} - - - // Collapse any double spaces in the USFM to save. - // https://github.com/bibledit/cloud/issues/711 - // If there's double spaces removed here, - // then later in this code, the editor will load that text. - if (good2go && bible_write_access && text_was_edited) { - edited_chapter_usfm = filter::strings::collapse_whitespace(edited_chapter_usfm); - } - - // Safely store the chapter. - string explanation; - string message; - if (good2go && bible_write_access && text_was_edited) { - message = filter::usfm::safely_store_chapter (webserver_request, bible, book, chapter, edited_chapter_usfm, explanation); - bible_logic::unsafe_save_mail (message, explanation, username, edited_chapter_usfm, book, chapter); - if (!message.empty ()) messages.push_back (message); - } - - - // The new chapter identifier and new chapter USFM. - int newID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - string new_chapter_usfm; - if (good2go) { - new_chapter_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - } - - - if (good2go && bible_write_access && text_was_edited) { - // If storing the chapter worked out well, there's no message to display. - if (message.empty ()) { -#ifdef HAVE_CLOUD - // The Cloud stores details of the user's changes. - Database_Modifications database_modifications; - database_modifications.recordUserSave (username, bible, book, chapter, oldID, old_chapter_usfm, newID, new_chapter_usfm); - if (sendreceive_git_repository_linked (bible)) { - Database_Git::store_chapter (username, bible, book, chapter, old_chapter_usfm, new_chapter_usfm); - } - rss_logic_schedule_update (username, bible, book, chapter, old_chapter_usfm, new_chapter_usfm); -#endif - // Feedback to user. - messages.push_back (locale_logic_text_saved ()); - } else { - // Feedback about anomaly to user. - messages.push_back (message); - } - } - - - // If there's no message at all, return at least something to the editor. - if (messages.empty ()) messages.push_back (locale_logic_text_saved ()); - - - // The response to send to back to the editor. - string response; - string separator = "#_be_#"; - // The response starts with the save message(s) if any. - // The message(s) contain information about save success or failure. - // Send it to the browser for display to the user. - response.append (filter::strings::implode (messages, " | ")); - - - // Add separator and the new chapter identifier to the response. - response.append (separator); - response.append (filter::strings::convert_to_string (newID)); - - - // The main purpose of the following block of code is this: - // To send the differences between what the editor has now and what the server has now. - // The purpose of sending the differences to the editor is this: - // The editor can update its contents, so the editor will have what the server has. - // This is the format to send the changes in: - // insert - position - text - format - // delete - position - if (good2go) { - // Determine the server's current chapter content, and the editor's current chapter content. - string editor_html (edited_html); - string server_html; - { - Editor_Usfm2Html editor_usfm2html; - editor_usfm2html.load (new_chapter_usfm); - editor_usfm2html.stylesheet (stylesheet); - editor_usfm2html.run (); - server_html = editor_usfm2html.get (); - } - vector positions; - vector sizes; - vector operators; - vector content; - bible_logic::html_to_editor_updates (editor_html, server_html, positions, sizes, operators, content); - // Encode the condensed differences for the response to the Javascript editor. - for (size_t i = 0; i < positions.size(); i++) { - response.append ("#_be_#"); - response.append (filter::strings::convert_to_string (positions[i])); - response.append ("#_be_#"); - string operation = operators[i]; - response.append (operation); - if (operation == bible_logic::insert_operator ()) { - string text = content[i]; - string character = filter::strings::unicode_string_substr (text, 0, 1); - response.append ("#_be_#"); - response.append (character); - size_t length = filter::strings::unicode_string_length (text); - string format = filter::strings::unicode_string_substr (text, 1, length - 1); - response.append ("#_be_#"); - response.append (format); - // Also add the size of the character in UTF-16 format, 2-bytes or 4 bytes, as size 1 or 2. - response.append ("#_be_#"); - response.append (filter::strings::convert_to_string (sizes[i])); - } - else if (operation == bible_logic::delete_operator ()) { - // When deleting a UTF-16 character encoded in 4 bytes, - // then the size in Quilljs is 2 instead of 1. - // So always give the size when deleting a character. - response.append ("#_be_#"); - response.append (filter::strings::convert_to_string (sizes[i])); - } - else if (operation == bible_logic::format_paragraph_operator ()) { - response.append ("#_be_#"); - response.append (content[i]); - } - else if (operation == bible_logic::format_character_operator ()) { - response.append ("#_be_#"); - response.append (content[i]); - } - } - } - - // Things to try out in the C++ and Javacript update routines. - - // Test changing the format of the first paragraph. - - // Test changing the format of the second paragraph. - - // Test changing the format of the last paragraph. - - // Test deleting an entire paragraph. - - // Test adding a character to a formatted word, to see if the character format gets transferred properly. - - // Test that if this editor is the second or higher one in a workspace, - // it is read-only. And updating the editor's contents does not grab focus. - - // Test inserting and updating 4-byte UTF-16 characters like the 😀. - - // Test continued typing during serious network latency. - - // Test using the Cloud together with client devices with send and receive. - - bool write = access_bible::book_write (webserver_request, username, bible, book); - response = checksum_logic::send (response, write); - - // Ready. - //this_thread::sleep_for(chrono::seconds(5)); - return response; -} diff --git a/edit/update.h b/edit/update.h deleted file mode 100644 index c51e25446..000000000 --- a/edit/update.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string edit_update_url (); -bool edit_update_acl (Webserver_Request& webserver_request); -std::string edit_update (Webserver_Request& webserver_request); diff --git a/editone2/index.cpp b/editone2/index.cpp deleted file mode 100644 index 3caba77cf..000000000 --- a/editone2/index.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editone2_index_url () -{ - return "editone2/index"; -} - - -bool editone2_index_acl (Webserver_Request& webserver_request) -{ - // Default minimum role for getting access. - int minimum_role = Filter_Roles::translator (); - if (Filter_Roles::access_control (webserver_request, minimum_role)) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string editone2_index (Webserver_Request& webserver_request) -{ - bool touch = webserver_request.session_logic ()->touchEnabled (); - - if (webserver_request.query.count ("switchbook") && webserver_request.query.count ("switchchapter")) { - int switchbook = filter::strings::convert_to_int (webserver_request.query ["switchbook"]); - int switchchapter = filter::strings::convert_to_int (webserver_request.query ["switchchapter"]); - Ipc_Focus::set (webserver_request, switchbook, switchchapter, 1); - Navigation_Passage::record_history (webserver_request, switchbook, switchchapter, 1); - } - - // Set the user chosen Bible as the current Bible. - if (webserver_request.post.count ("bibleselect")) { - string bibleselect = webserver_request.post ["bibleselect"]; - webserver_request.database_config_user ()->setBible (bibleselect); - return string(); - } - - string page; - - Assets_Header header = Assets_Header (translate("Edit verse"), webserver_request); - header.set_navigator (); - header.set_editor_stylesheet (); - if (touch) header.jquery_touch_on (); - header.notify_it_on (); - header.add_bread_crumb (menu_logic_translate_menu (), menu_logic_translate_text ()); - page = header.run (); - - Assets_View view; - - // Get active Bible, and check read access to it. - // Or if the user have used query to preset the active Bible, get the preset Bible. - // If needed, change Bible to one it has read access to. - // Set the chosen Bible on the option HTML tag. - string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - if (webserver_request.query.count ("bible")) bible = access_bible::clamp (webserver_request, webserver_request.query ["bible"]); - string bible_html; - vector bibles = access_bible::bibles (webserver_request); - for (auto selectable_bible : bibles) { - bible_html = Options_To_Select::add_selection (selectable_bible, selectable_bible, bible_html); - } - view.set_variable ("bibleoptags", Options_To_Select::mark_selected (bible, bible_html)); - view.set_variable ("bible", bible); - - // Store the active Bible in the page's javascript. - view.set_variable ("navigationCode", Navigation_Passage::code (bible)); - - // Create the script, quote the strings to ensure it's legal Javascript. - stringstream script_stream {}; - script_stream << "var oneverseEditorVerseLoaded = " << quoted(locale_logic_text_loaded ()) << ";\n"; - script_stream << "var oneverseEditorVerseUpdating = " << quoted(locale_logic_text_updating ()) << ";\n"; - script_stream << "var oneverseEditorVerseUpdated = " << quoted(locale_logic_text_updated ()) << ";\n"; - script_stream << "var oneverseEditorWillSave = " << quoted(locale_logic_text_will_save ()) << ";\n"; - script_stream << "var oneverseEditorVerseSaving = " << quoted(locale_logic_text_saving ()) << ";\n"; - script_stream << "var oneverseEditorVerseSaved = " << quoted(locale_logic_text_saved ()) << ";\n"; - script_stream << "var oneverseEditorVerseRetrying = " << quoted(locale_logic_text_retrying ()) << ";\n"; - script_stream << "var oneverseEditorVerseUpdatedLoaded = " << quoted(locale_logic_text_reload ()) << ";\n"; - int verticalCaretPosition = webserver_request.database_config_user ()->getVerticalCaretPosition (); - script_stream << "var verticalCaretPosition = " << verticalCaretPosition << ";\n"; - script_stream << "var verseSeparator = " << quoted(Database_Config_General::getNotesVerseSeparator ()) << ";\n"; - string script {script_stream.str()}; - config::logic::swipe_enabled (webserver_request, script); - view.set_variable ("script", script); - - string custom_class = Filter_Css::getClass (bible); - string font = fonts::logic::get_text_font (bible); - int current_theme_index = webserver_request.database_config_user ()->getCurrentTheme (); - int direction = Database_Config_Bible::getTextDirection (bible); - int lineheight = Database_Config_Bible::getLineHeight (bible); - int letterspacing = Database_Config_Bible::getLetterSpacing (bible); - view.set_variable ("editor_theme_color", Filter_Css::theme_picker (current_theme_index, 2)); - view.set_variable ("active_editor_theme_color", Filter_Css::theme_picker (current_theme_index, 3)); - view.set_variable ("custom_class", custom_class); - string custom_css = Filter_Css::get_css (custom_class, - fonts::logic::get_font_path (font), - direction, lineheight, letterspacing); - view.set_variable ("custom_css", custom_css); - - - // Whether to enable fast Bible editor switching. - if (webserver_request.database_config_user ()->getFastEditorSwitchingAvailable ()) { - view.enable_zone ("fastswitcheditor"); - } - - // Whether to enable the styles button. - if (webserver_request.database_config_user ()->getEnableStylesButtonVisualEditors ()) { - view.enable_zone ("stylesbutton"); - } - - page += view.render ("editone2", "index"); - - page += assets_page::footer (); - - return page; -} - -// Tests for the editor: -// * Autosave on going to another passage. -// * Autosave on document unload. -// * Autosave shortly after any change. -// * Save the + sign of a note. -// * No loss of white space right after the verse number. diff --git a/editone2/index.h b/editone2/index.h deleted file mode 100644 index 4d8fc5543..000000000 --- a/editone2/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editone2_index_url (); -bool editone2_index_acl (Webserver_Request& webserver_request); -std::string editone2_index (Webserver_Request& webserver_request); diff --git a/editone2/load.cpp b/editone2/load.cpp deleted file mode 100644 index 435eaae1a..000000000 --- a/editone2/load.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -using namespace pugi; - - -string editone2_load_url () -{ - return "editone2/load"; -} - - -bool editone2_load_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string editone2_load (Webserver_Request& webserver_request) -{ - string bible = webserver_request.query ["bible"]; - int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.query ["chapter"]); - int verse = filter::strings::convert_to_int (webserver_request.query ["verse"]); - string unique_id = webserver_request.query ["id"]; - - string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - - string chapter_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - vector verses = filter::usfm::get_verse_numbers (chapter_usfm); - int highest_verse = 0; - if (!verses.empty ()) highest_verse = verses.back (); - - // The Quill-based editor removes empty paragraphs at the end. - // Therefore do not include them. - string editable_usfm = filter::usfm::get_verse_text_quill (chapter_usfm, verse); - - string prefix_usfm = filter::usfm::get_verse_range_text (chapter_usfm, 0, verse - 1, editable_usfm, true); - string suffix_usfm = filter::usfm::get_verse_range_text (chapter_usfm, verse + 1, highest_verse, editable_usfm, true); - - // Store a copy of the USFM loaded in the editor for later reference. - // Note that this verse editor has been tested that it uses the correct sequence - // while storing this snapshot. - // When the user goes to another verse in the editor, the system follows this sequence: - // 1. It saves the edited text in the current verse. - // 2. It updates the chapter snapshot. - // 3. It loads the other verse. - // 4. It updates the chapter snapshot. - storeLoadedUsfm2 (webserver_request, bible, book, chapter, unique_id); - - string prefix_html; - string not_used; - editone_logic_prefix_html (prefix_usfm, stylesheet, prefix_html, not_used); - - // The focused editable verse also has any footnotes contained in that verse. - // It is convenient to have the footnote as near as possible to the verse text. - // This is helpful for editing the verse and note. - string focused_verse_html; - editone_logic_editable_html (editable_usfm, stylesheet, focused_verse_html); - - string suffix_html; - editone_logic_suffix_html ("", suffix_usfm, stylesheet, suffix_html); - - // If the verse was empty, ensure that it has a non-breaking space as the last character, - // for easier text entry in the verse. - string plain_text = filter::strings::html2text (focused_verse_html); - plain_text = filter::strings::trim (plain_text); - string vs = filter::strings::convert_to_string (verse); - bool editable_verse_is_empty = plain_text == vs; - if (editable_verse_is_empty) { - string search = "

    "; - string replace = "" + filter::strings::unicode_non_breaking_space_entity () + "

    "; - focused_verse_html = filter::strings::replace (search, replace, focused_verse_html); - } - - // Moves any notes from the prefix to the suffix. - editone_logic_move_notes_v2 (prefix_html, suffix_html); - - string data; - data.append (prefix_html); - data.append ("#_be_#"); - data.append (focused_verse_html); - data.append ("#_be_#"); - data.append (suffix_html); - - string user = webserver_request.session_logic ()->currentUser (); - bool write = access_bible::book_write (webserver_request, user, bible, book); - data = checksum_logic::send (data, write); - - return data; -} diff --git a/editone2/load.h b/editone2/load.h deleted file mode 100644 index 60b0e811d..000000000 --- a/editone2/load.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editone2_load_url (); -bool editone2_load_acl (Webserver_Request& webserver_request); -std::string editone2_load (Webserver_Request& webserver_request); diff --git a/editone2/logic.cpp b/editone2/logic.cpp deleted file mode 100644 index b2a96e187..000000000 --- a/editone2/logic.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -void editone_logic_prefix_html (string usfm, string stylesheet, string& html, string& last_p_style) -{ - if (!usfm.empty ()) { - Editor_Usfm2Html editor_usfm2html; - editor_usfm2html.load (usfm); - editor_usfm2html.stylesheet (stylesheet); - editor_usfm2html.run (); - html = editor_usfm2html.get (); - // No identical id's in the same DOM. - html = filter::strings::replace (R"( id="notes")", R"( id="prefixnotes")", html); - // The last paragraph style in this USFM fragment, the prefix to the editable fragment. - // If the last paragraph has any content in it, - // for correct visual representation of the editable fragment, that follows this, - // clear that style. - last_p_style = editor_usfm2html.m_current_paragraph_style; - if (!editor_usfm2html.m_current_paragraph_content.empty ()) last_p_style.clear (); - } -} - - -void editone_logic_editable_html (string usfm, string stylesheet, string& html) -{ - if (!usfm.empty ()) { - Editor_Usfm2Html editor_usfm2html; - editor_usfm2html.load (usfm); - editor_usfm2html.stylesheet (stylesheet); - editor_usfm2html.run (); - html = editor_usfm2html.get (); - } -} - - -void editone_logic_suffix_html (string editable_last_p_style, string usfm, string stylesheet, string& html) -{ - if (!usfm.empty ()) { - Editor_Usfm2Html editor_usfm2html; - editor_usfm2html.load (usfm); - editor_usfm2html.stylesheet (stylesheet); - editor_usfm2html.run (); - html = editor_usfm2html.get (); - // No identical id in the same DOM. - html = filter::strings::replace (R"( id="notes")", R"( id="suffixnotes")", html); - } - - // If the first paragraph of the suffix does not have a paragraph style applied, - // apply the last paragraph style of the focused verse to the first paragraph of the suffix. - // For example, html like this: - //

    7 For Yahweh knows the way of the righteous,

    but the way of the wicked shall perish.

    - // ... will become like this: - //

    7For Yahweh knows the way of the righteous,

    but the way of the wicked shall perish.

    - if (!html.empty ()) { - if (!editable_last_p_style.empty ()) { - xml_document document; - html = filter::strings::html2xml (html); - document.load_string (html.c_str(), parse_ws_pcdata_single); - xml_node p_node = document.first_child (); - string p_style = p_node.attribute ("class").value (); - if (p_style.empty ()) { - p_node.append_attribute ("class") = editable_last_p_style.c_str (); - } - stringstream output; - document.print (output, "", format_raw); - html = output.str (); - } - } -} - - -string editone_logic_html_to_usfm (string stylesheet, string html) -{ - // It used to convert XML entities to normal characters. - // For example, it used to convert "<" to "<". - // But doing this too early in the conversion chain led to the following problem: - // The XML parser was taking the "<" character as part of an XML element. - // It than didn't find the closing ">" marker, and then complained about parsing errors. - // And it dropped whatever followed the "<" marker. - // So it now no longer unescapes the XML special characters this early in the chain. - // It does it much later now, before saving the USFM that the converter produces. - - // Convert special spaces to normal ones. - html = filter::strings::any_space_to_standard_space (html); - - // Convert the html back to USFM in the special way for editing one verse. - string usfm = editor_export_verse_quill (stylesheet, html); - - // Done. - return usfm; -} - - -// Move the notes from the $prefix to the $suffix. -void editone_logic_move_notes_v2 (string & prefix, string & suffix) -{ - // No input: Ready. - if (prefix.empty ()) return; - - // Do a html to xml conversion to avoid a mismatched tag error. - prefix = filter::strings::html2xml (prefix); - - // Load the prefix. - xml_document document; - document.load_string (prefix.c_str(), parse_ws_pcdata_single); - - // The notes separator class. - const char * b_notes_class = "b-notes"; - - // Iterate over the document to find: - // - the possible notes separator. - // - any possible subsequent note nodes. - bool within_notes = false; - xml_node prefix_separator_node; - vector prefix_note_nodes; - for (xml_node p_node : document.children ()) { - if (within_notes) { - prefix_note_nodes.push_back (p_node); - } - string cls = p_node.attribute ("class").value (); - if (cls == b_notes_class) { - within_notes = true; - prefix_separator_node = p_node; - } - } - - // No notes: Ready. - if (prefix_note_nodes.empty()) return; - - // Get the note(s) text from the note node(s). - // Remove the note node(s) from the prefix. - // Remove the notes separator node from the prefix. - string notes_text; - for (xml_node p_node : prefix_note_nodes) { - stringstream ss; - p_node.print (ss, "", format_raw); - string note = ss.str (); - notes_text.append (note); - document.remove_child (p_node); - } - document.remove_child (prefix_separator_node); - - // Convert the XML document back to a possibly cleaned prefix without notes. - { - stringstream ss; - document.print (ss, "", format_raw); - prefix = ss.str (); - } - - // Do a html to xml conversion in the suffix to avoid a mismatched tag error. - suffix = filter::strings::html2xml (suffix); - - // Load the suffix. - document.load_string (suffix.c_str(), parse_ws_pcdata_single); - - // Iterate over the document to find the possible notes separator. - xml_node suffix_separator_node; - for (xml_node p_node : document.children ()) { - string cls = p_node.attribute ("class").value (); - if (cls == b_notes_class) { - suffix_separator_node = p_node; - } - } - - // If there's no notes container, add it. - if (!suffix_separator_node) { - suffix_separator_node = document.append_child ("p"); - suffix_separator_node.append_attribute ("class") = b_notes_class; - suffix_separator_node.append_child ("br"); - } - - // Contain the prefix's notes and add them to the suffix's notes container. - suffix_separator_node.append_buffer (notes_text.c_str (), notes_text.size ()); - - // Convert the DOM to suffix text. - { - stringstream ss; - document.print (ss, "", format_raw); - suffix = ss.str (); - } -} - - diff --git a/editone2/logic.h b/editone2/logic.h deleted file mode 100644 index 5b8a1c212..000000000 --- a/editone2/logic.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -void editone_logic_prefix_html (std::string usfm, std::string stylesheet, std::string & html, std::string & last_p_style); -void editone_logic_editable_html (std::string usfm, std::string stylesheet, std::string & html); -void editone_logic_suffix_html (std::string editable_last_p_style, std::string usfm, std::string stylesheet, std::string & html); -std::string editone_logic_html_to_usfm (std::string stylesheet, std::string html); -void editone_logic_move_notes_v2 (std::string & prefix, std::string & suffix); diff --git a/editone2/save.cpp b/editone2/save.cpp deleted file mode 100644 index 580ee7972..000000000 --- a/editone2/save.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editone2_save_url () -{ - return "editone2/save"; -} - - -bool editone2_save_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string editone2_save (Webserver_Request& webserver_request) -{ - // Check on information about where to save the verse. - bool save = (webserver_request.post.count ("bible") && webserver_request.post.count ("book") && webserver_request.post.count ("chapter") && webserver_request.post.count ("verse") && webserver_request.post.count ("html")); - if (!save) { - return translate("Don't know where to save"); - } - - - string bible = webserver_request.post["bible"]; - int book = filter::strings::convert_to_int (webserver_request.post["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.post["chapter"]); - int verse = filter::strings::convert_to_int (webserver_request.post["verse"]); - string html = webserver_request.post["html"]; - string checksum = webserver_request.post["checksum"]; - string unique_id = webserver_request.post ["id"]; - - - // Checksum. - if (checksum_logic::get (html) != checksum) { - webserver_request.response_code = 409; - return translate ("Checksum error"); - } - - - // Decode html encoded in javascript. - html = filter_url_tag_to_plus (html); - - - // Check there's anything to save at all. - html = filter::strings::trim (html); - if (html.empty ()) { - return translate ("Nothing to save"); - } - - - // Check on valid UTF-8. - if (!filter::strings::unicode_string_is_valid (html)) { - return translate ("Cannot save: Needs Unicode"); - } - - - if (!access_bible::book_write (webserver_request, string(), bible, book)) { - return translate ("No write access"); - } - - - string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - - - string verse_usfm = editone_logic_html_to_usfm (stylesheet, html); - - - // Collect some data about the changes for this user. - string username = webserver_request.session_logic()->currentUser (); -#ifdef HAVE_CLOUD - int oldID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); -#endif - string old_chapter_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - - // If the most recent save operation on this chapter - // caused the chapter to be different, email the user, - // suggesting to check if the user's edit came through. - // The rationale is that if Bible text was saved through Send/receive, - // or if another user saved Bible text, - // it's worth to check on this. - // Because the user's editor may not yet have loaded this updated Bible text. - // https://github.com/bibledit/cloud/issues/340 - string loaded_usfm = getLoadedUsfm2 (webserver_request, bible, book, chapter, unique_id); - if (loaded_usfm != old_chapter_usfm) { - bible_logic::recent_save_email (bible, book, chapter, username, loaded_usfm, old_chapter_usfm); - } - - - // Safely store the verse. - string explanation; - string message = filter::usfm::safely_store_verse (webserver_request, bible, book, chapter, verse, verse_usfm, explanation, true); - bible_logic::unsafe_save_mail (message, explanation, username, verse_usfm, book, chapter); - // If storing the verse worked out well, there's no message to display. - if (message.empty ()) { - // Get the chapter text now, that is, after the save operation completed. - string new_chapter_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - // Check whether the text on disk was changed while the user worked with the older copy. - if (!loaded_usfm.empty () && (loaded_usfm != old_chapter_usfm)) { - // Do a merge for better editing reliability. - vector conflicts; - // Prioritize the USFM already in the chapter. - new_chapter_usfm = filter_merge_run (loaded_usfm, new_chapter_usfm, old_chapter_usfm, true, conflicts); - webserver_request.database_bibles()->store_chapter (bible, book, chapter, new_chapter_usfm); - Database_Logs::log (translate ("Merging chapter.")); - } -#ifdef HAVE_CLOUD - // The Cloud stores details of the user's changes. - int newID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - Database_Modifications database_modifications; - database_modifications.recordUserSave (username, bible, book, chapter, oldID, old_chapter_usfm, newID, new_chapter_usfm); - if (sendreceive_git_repository_linked (bible)) { - Database_Git::store_chapter (username, bible, book, chapter, old_chapter_usfm, new_chapter_usfm); - } - rss_logic_schedule_update (username, bible, book, chapter, old_chapter_usfm, new_chapter_usfm); -#endif - - - // Store a copy of the USFM now saved as identical to what's loaded in the editor for later reference. - storeLoadedUsfm2 (webserver_request, bible, book, chapter, unique_id); - - return locale_logic_text_saved (); - } - - - // The message contains information about save failure. - // Send it to the browser for display to the user. - return message; -} diff --git a/editone2/save.h b/editone2/save.h deleted file mode 100644 index 89d8c095a..000000000 --- a/editone2/save.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editone2_save_url (); -bool editone2_save_acl (Webserver_Request& webserver_request); -std::string editone2_save (Webserver_Request& webserver_request); diff --git a/editone2/update.cpp b/editone2/update.cpp deleted file mode 100644 index 45d6bfee0..000000000 --- a/editone2/update.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editone2_update_url () -{ - return "editone2/update"; -} - - -bool editone2_update_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string editone2_update (Webserver_Request& webserver_request) -{ - // Whether the update is good to go. - bool good2go = true; - - - // The message(s) to return. - vector messages; - - - // Check the relevant bits of information. - if (good2go) { - bool parameters_ok = true; - if (!webserver_request.post.count ("bible")) parameters_ok = false; - if (!webserver_request.post.count ("book")) parameters_ok = false; - if (!webserver_request.post.count ("chapter")) parameters_ok = false; - if (!webserver_request.post.count ("verse")) parameters_ok = false; - if (!webserver_request.post.count ("loaded")) parameters_ok = false; - if (!webserver_request.post.count ("edited")) parameters_ok = false; - if (!parameters_ok) { - messages.push_back (translate("Don't know what to update")); - good2go = false; - } - } - - - // Get the relevant bits of information. - string bible; - int book = 0; - int chapter = 0; - int verse = 0; - string loaded_html; - string edited_html; - string checksum1; - string checksum2; - string unique_id; - if (good2go) { - bible = webserver_request.post["bible"]; - book = filter::strings::convert_to_int (webserver_request.post["book"]); - chapter = filter::strings::convert_to_int (webserver_request.post["chapter"]); - verse = filter::strings::convert_to_int (webserver_request.post["verse"]); - loaded_html = webserver_request.post["loaded"]; - edited_html = webserver_request.post["edited"]; - checksum1 = webserver_request.post["checksum1"]; - checksum2 = webserver_request.post["checksum2"]; - unique_id = webserver_request.post ["id"]; - } - - - // Checksums of the loaded and edited html. - if (good2go) { - if (checksum_logic::get (loaded_html) != checksum1) { - webserver_request.response_code = 409; - messages.push_back (translate ("Checksum error")); - good2go = false; - } - } - if (good2go) { - if (checksum_logic::get (edited_html) != checksum2) { - webserver_request.response_code = 409; - messages.push_back (translate ("Checksum error")); - good2go = false; - } - } - - - // Decode html encoded in javascript, and clean it. - loaded_html = filter_url_tag_to_plus (loaded_html); - edited_html = filter_url_tag_to_plus (edited_html); - loaded_html = filter::strings::trim (loaded_html); - edited_html = filter::strings::trim (edited_html); - - - // Check on valid UTF-8. - if (good2go) { - if (!filter::strings::unicode_string_is_valid (loaded_html) || !filter::strings::unicode_string_is_valid (edited_html)) { - messages.push_back (translate ("Cannot update: Needs Unicode")); - good2go = false; - } - } - - - bool bible_write_access = false; - if (good2go) { - bible_write_access = access_bible::book_write (webserver_request, string(), bible, book); - } - - - string stylesheet; - if (good2go) { - stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - } - - - // Collect some data about the changes for this user. - string username = webserver_request.session_logic()->currentUser (); -#ifdef HAVE_CLOUD - int oldID = 0; - if (good2go) oldID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); -#endif - string old_chapter_usfm; - if (good2go) old_chapter_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - - // Determine what (composed) version of USFM to save to the chapter. - // Do a three-way merge to obtain that USFM. - // This needs the loaded USFM as the ancestor, - // the edited USFM as a change-set, - // and the existing USFM as a prioritized change-set. - string loaded_verse_usfm = editone_logic_html_to_usfm (stylesheet, loaded_html); - string edited_verse_usfm = editone_logic_html_to_usfm (stylesheet, edited_html); - string existing_verse_usfm = filter::usfm::get_verse_text_quill (old_chapter_usfm, verse); - existing_verse_usfm = filter::strings::trim (existing_verse_usfm); - - - // Set a flag if there is a reason to save the editor text, since it was edited. - // This is important because the same routine is used for saving editor text - // as well as updating the editor text. - // So if the text in the editor was not changed, it should not save it, - // as saving the editor text would overwrite saves made by other(s). - bool text_was_edited = (loaded_verse_usfm != edited_verse_usfm); - - - // Do a three-way merge if needed. - // There's a need for this if there were user-edits, - // and if the USFM on the server differs from the USFM loaded in the editor. - // The three-way merge reconciles those differences. - if (good2go && bible_write_access && text_was_edited) { - if (loaded_verse_usfm != existing_verse_usfm) { - vector conflicts; - // Do a merge while giving priority to the USFM already in the chapter. - string merged_verse_usfm = filter_merge_run (loaded_verse_usfm, edited_verse_usfm, existing_verse_usfm, true, conflicts); - // Mail the user if there is a merge anomaly. - filter_merge_add_book_chapter (conflicts, book, chapter); - bible_logic::optional_merge_irregularity_email (bible, book, chapter, username, loaded_verse_usfm, edited_verse_usfm, merged_verse_usfm); - // Let the merged data now become the edited data (so it gets saved properly). - edited_verse_usfm = merged_verse_usfm; - } - } - - - // Collapse any double spaces in the USFM to save. - // https://github.com/bibledit/cloud/issues/711 - // If there's double spaces removed here, - // then later in this code, the editor will load that text. - if (good2go && bible_write_access && text_was_edited) { - edited_verse_usfm = filter::strings::collapse_whitespace(edited_verse_usfm); - } - - - // Safely store the verse. - string explanation; - string message; - if (good2go && bible_write_access && text_was_edited) { - message = filter::usfm::safely_store_verse (webserver_request, bible, book, chapter, verse, edited_verse_usfm, explanation, true); - bible_logic::unsafe_save_mail (message, explanation, username, edited_verse_usfm, book, chapter); - } - - - // The new chapter identifier and new chapter USFM. - int newID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - string new_chapter_usfm; - if (good2go) { - new_chapter_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - } - - - if (good2go && bible_write_access && text_was_edited) { - // If storing the verse worked out well, there's no message to display. - if (message.empty ()) { -#ifdef HAVE_CLOUD - // The Cloud stores details of the user's changes. - Database_Modifications database_modifications; - database_modifications.recordUserSave (username, bible, book, chapter, oldID, old_chapter_usfm, newID, new_chapter_usfm); - if (sendreceive_git_repository_linked (bible)) { - Database_Git::store_chapter (username, bible, book, chapter, old_chapter_usfm, new_chapter_usfm); - } - rss_logic_schedule_update (username, bible, book, chapter, old_chapter_usfm, new_chapter_usfm); -#endif - // Feedback to user. - messages.push_back (locale_logic_text_saved ()); - } else { - // Feedback about anomaly to user. - messages.push_back (message); - } - } - - - // If there's no message at all, return at least something to the editor. - if (messages.empty ()) messages.push_back (locale_logic_text_updated()); - - - // The response to send to back to the editor. - string response; - string separator = "#_be_#"; - // The response starts with the save message(s) if any. - // The message(s) contain information about save success or failure. - // Send it to the browser for display to the user. - response.append (filter::strings::implode (messages, " | ")); - - - // Add separator and the new chapter identifier to the response. - response.append (separator); - response.append (filter::strings::convert_to_string (newID)); - - - // The main purpose of the following block of code is this: - // To send the differences between what the editor has now and what the server has now. - // The purpose of sending the differences to the editor is this: - // The editor can update its contents, so the editor will have what the server has. - // This is the format to send the changes in: - // insert - position - text - format - // delete - position - if (good2go) { - // Determine the server's current verse content, and the editor's current verse content. - string editor_html (edited_html); - string server_html; - { - string verse_usfm = filter::usfm::get_verse_text_quill (new_chapter_usfm, verse); - editone_logic_editable_html (verse_usfm, stylesheet, server_html); - } - vector positions; - vector sizes; - vector operators; - vector content; - bible_logic::html_to_editor_updates (editor_html, server_html, positions, sizes, operators, content); - // Encode the condensed differences for the response to the Javascript editor. - for (size_t i = 0; i < positions.size(); i++) { - response.append ("#_be_#"); - response.append (filter::strings::convert_to_string (positions[i])); - response.append ("#_be_#"); - string operation = operators[i]; - response.append (operation); - if (operation == bible_logic::insert_operator ()) { - string text = content[i]; - string character = filter::strings::unicode_string_substr (text, 0, 1); - response.append ("#_be_#"); - response.append (character); - size_t length = filter::strings::unicode_string_length (text); - string format = filter::strings::unicode_string_substr (text, 1, length - 1); - response.append ("#_be_#"); - response.append (format); - // Also add the size of the character in UTF-16 format, 2-bytes or 4 bytes, as size 1 or 2. - response.append ("#_be_#"); - response.append (filter::strings::convert_to_string (sizes[i])); - } - else if (operation == bible_logic::delete_operator ()) { - // When deleting a UTF-16 character encoded in 4 bytes, - // then the size in Quilljs is 2 instead of 1. - // So always give the size when deleting a character. - response.append ("#_be_#"); - response.append (filter::strings::convert_to_string (sizes[i])); - } - else if (operation == bible_logic::format_paragraph_operator ()) { - response.append ("#_be_#"); - response.append (content[i]); - } - else if (operation == bible_logic::format_character_operator ()) { - response.append ("#_be_#"); - response.append (content[i]); - } - } - } - - // Things to try out in the C++ and Javacript update routines. - - // Test changing the format of the first paragraph. - - // Test changing the format of the second paragraph. - - // Test changing the format of the last paragraph. - - // Test deleting an entire paragraph. - - // Test adding a character to a formatted word, to see if the character format gets transferred properly. - - // Test that if this editor is the second or higher one in a workspace, - // it is read-only. And updating the editor's contents does not grab focus. - - // Test inserting and updating 4-byte UTF-16 characters like the 😀. - - // Test continued typing during serious network latency. - - // Test using the Cloud together with client devices with send and receive. - - bool write = access_bible::book_write (webserver_request, username, bible, book); - response = checksum_logic::send (response, write); - - // Ready. - //this_thread::sleep_for(chrono::seconds(60)); - return response; -} diff --git a/editone2/update.h b/editone2/update.h deleted file mode 100644 index b27969d43..000000000 --- a/editone2/update.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editone2_update_url (); -bool editone2_update_acl (Webserver_Request& webserver_request); -std::string editone2_update (Webserver_Request& webserver_request); diff --git a/editone2/verse.cpp b/editone2/verse.cpp deleted file mode 100644 index 675cff292..000000000 --- a/editone2/verse.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editone2_verse_url () -{ - return "editone2/verse"; -} - - -bool editone2_verse_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string editone2_verse (Webserver_Request& webserver_request) -{ - // Only act if a verse was found - string sverse = webserver_request.query ["verse"]; - if (!sverse.empty ()) { - - - // Only update navigation in case the verse changed. - // This avoids unnecessary focus operations in the clients. - int iverse = filter::strings::convert_to_int (sverse); - if (iverse != Ipc_Focus::getVerse (webserver_request)) { - int book = Ipc_Focus::getBook (webserver_request); - int chapter = Ipc_Focus::getChapter (webserver_request); - Ipc_Focus::set (webserver_request, book, chapter, iverse); - } - } - - - return ""; -} diff --git a/editone2/verse.h b/editone2/verse.h deleted file mode 100644 index 01c8fb5fb..000000000 --- a/editone2/verse.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editone2_verse_url (); -bool editone2_verse_acl (Webserver_Request& webserver_request); -std::string editone2_verse (Webserver_Request& webserver_request); diff --git a/editor/html2format.cpp b/editor/html2format.cpp deleted file mode 100644 index a128d6cc3..000000000 --- a/editor/html2format.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void Editor_Html2Format::load (string html) -{ - // The web editor may insert non-breaking spaces. Convert them to normal spaces. - html = filter::strings::replace (filter::strings::unicode_non_breaking_space_entity (), " ", html); - - // The web editor produces
    and other elements following the HTML specs, - // but the pugixml XML parser needs
    and similar elements. - html = filter::strings::html2xml (html); - - string xml = "" + html + ""; - // Parse document such that all whitespace is put in the DOM tree. - // See http://pugixml.org/docs/manual.html for more information. - // It is not enough to only parse with parse_ws_pcdata_single, it really needs parse_ws_pcdata. - // This is significant for, for example, the space after verse numbers, among other cases. - xml_parse_result result = document.load_string (xml.c_str(), parse_ws_pcdata); - // Log parsing errors. - pugixml_utils_error_logger (&result, xml); -} - - -void Editor_Html2Format::run () -{ - preprocess (); - process (); - postprocess (); -} - - -void Editor_Html2Format::process () -{ - // Iterate over the children to retrieve the "p" elements, then process them. - xml_node body = document.first_child (); - for (xml_node node : body.children()) { - // Process the node. - processNode (node); - } -} - - -void Editor_Html2Format::processNode (xml_node node) -{ - switch (node.type ()) { - case node_element: - { - // Skip a note with class "ql-cursor" because that is an internal Quill node. - // The user didn't insert it. - string classs = node.attribute("class").value(); - if (classs == "ql-cursor") break; - // Process node normally. - openElementNode (node); - for (xml_node child : node.children()) { - processNode (child); - } - closeElementNode (node); - break; - } - case node_pcdata: - { - // Add the text with the current character format to the containers. - string text = node.text ().get (); - texts.push_back(text); - formats.push_back(current_character_format); - break; - } - case node_null: - case node_document: - case node_cdata: - case node_comment: - case node_pi: - case node_declaration: - case node_doctype: - default: - { - string nodename = node.name (); - Database_Logs::log ("XML node " + nodename + " not handled while saving editor text"); - break; - } - } -} - - -void Editor_Html2Format::openElementNode (xml_node node) -{ - // The tag and class names of this element node. - string tagName = node.name (); - string className = update_quill_class (node.attribute ("class").value ()); - - if (tagName == "p") - { - // In the editor, it may occur that the p element does not have a class. - // Use the 'p' class in such a case. - if (className.empty ()) className = "p"; - texts.push_back("\n"); - formats.push_back(className); - // A new line starts: Clear the character formatting. - current_character_format.clear(); - } - - if (tagName == "span") - { - openInline (className); - } -} - - -void Editor_Html2Format::closeElementNode (xml_node node) -{ - // The tag and class names of this element node. - string tagName = node.name (); - string className = update_quill_class (node.attribute ("class").value ()); - - if (tagName == "p") - { - // While editing it happens that the p element does not have a class. - // Use the 'p' class in such cases. - if (className.empty()) className = "p"; - // Clear active character styles. - current_character_format.clear(); - } - - if (tagName == "span") - { - // End of span: Clear character formatting. - current_character_format.clear(); - } -} - - -void Editor_Html2Format::openInline (string className) -{ - current_character_format = className; -} - - -void Editor_Html2Format::preprocess () -{ - texts.clear(); - formats.clear(); -} - - -void Editor_Html2Format::postprocess () -{ -} - - -string Editor_Html2Format::update_quill_class (string classname) -{ - classname = filter::strings::replace (quill_logic_class_prefix_block (), "", classname); - classname = filter::strings::replace (quill_logic_class_prefix_inline (), "", classname); - return classname; -} diff --git a/editor/html2format.h b/editor/html2format.h deleted file mode 100644 index e96c45778..000000000 --- a/editor/html2format.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop - -using namespace pugi; - -class Editor_Html2Format -{ -public: - void load (std::string html); - void run (); - std::vector texts {}; - std::vector formats {}; -private: - xml_document document {}; // DOMDocument holding the html. - void preprocess (); - void postprocess (); - void process (); - void processNode (xml_node node); - void openElementNode (xml_node node); - void closeElementNode (xml_node node); - void openInline (std::string className); - std::string update_quill_class (std::string classname); - std::string current_character_format {}; -}; diff --git a/editor/html2usfm.cpp b/editor/html2usfm.cpp deleted file mode 100644 index 95afe164e..000000000 --- a/editor/html2usfm.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void Editor_Html2Usfm::load (string html) -{ - // The web editor may insert non-breaking spaces. Convert them to normal spaces. - html = filter::strings::replace (filter::strings::unicode_non_breaking_space_entity (), " ", html); - - // The web editor produces
    and other elements following the HTML specs, - // but the pugixml XML parser needs
    and similar elements. - html = filter::strings::html2xml (html); - - string xml = "" + html + ""; - // Parse document such that all whitespace is put in the DOM tree. - // See http://pugixml.org/docs/manual.html for more information. - // It is not enough to only parse with parse_ws_pcdata_single, it really needs parse_ws_pcdata. - // This is significant for, for example, the space after verse numbers, among other cases. - xml_parse_result result = document.load_string (xml.c_str(), parse_ws_pcdata); - // Log parsing errors. - pugixml_utils_error_logger (&result, xml); -} - - -void Editor_Html2Usfm::stylesheet (string stylesheet) -{ - styles.clear (); - noteOpeners.clear (); - characterStyles.clear (); - Database_Styles database_styles; - vector markers = database_styles.getMarkers (stylesheet); - // Load the style information into the object. - for (string & marker : markers) { - Database_Styles_Item style = database_styles.getMarkerData (stylesheet, marker); - styles [marker] = style; - // Get markers that should not have endmarkers. - bool suppress = false; - int type = style.type; - int subtype = style.subtype; - if (type == StyleTypeVerseNumber) suppress = true; - if (type == StyleTypeFootEndNote) { - suppress = true; - if (subtype == FootEndNoteSubtypeFootnote) noteOpeners.insert (marker); - if (subtype == FootEndNoteSubtypeEndnote) noteOpeners.insert (marker); - if (subtype == FootEndNoteSubtypeContentWithEndmarker) suppress = false; - if (subtype == FootEndNoteSubtypeParagraph) suppress = false; - } - if (type == StyleTypeCrossreference) { - suppress = true; - if (subtype == CrossreferenceSubtypeCrossreference) noteOpeners.insert (marker); - if (subtype == CrossreferenceSubtypeContentWithEndmarker) suppress = false; - } - if (type == StyleTypeTableElement) suppress = true; - if (suppress) suppressEndMarkers.insert (marker); - } -} - - -void Editor_Html2Usfm::run () -{ - preprocess (); - process (); - postprocess (); -} - - -void Editor_Html2Usfm::process () -{ - // Iterate over the children to retrieve the "p" elements, then process them. - xml_node body = document.first_child (); - for (xml_node node : body.children()) { - // Do not process the notes
    or

    and beyond - // because it is at the end of the text body, - // and note-related data has already been extracted from it. - string classs = update_quill_class (node.attribute ("class").value ()); - if (classs == "notes") break; - // Process the node. - processNode (node); - } -} - - -string Editor_Html2Usfm::get () -{ - // Generate the USFM as one string. - string usfm = filter::strings::implode (output, "\n"); - - usfm = cleanUSFM (usfm); - - return usfm; -} - - -void Editor_Html2Usfm::processNode (xml_node node) -{ - switch (node.type ()) { - case node_element: - { - // Skip a note with class "ql-cursor" because that is an internal Quill node. - // The user didn't insert it. - string classs = node.attribute("class").value(); - if (classs == "ql-cursor") break; - // Process this node. - openElementNode (node); - for (xml_node child : node.children()) { - processNode (child); - } - closeElementNode (node); - break; - } - case node_pcdata: - { - // Add the text to the current USFM line. - string text = node.text ().get (); - currentLine += text; - break; - } - case node_null: - case node_document: - case node_comment: - case node_pi: - case node_declaration: - case node_doctype: - case node_cdata: - default: - { - string nodename = node.name (); - Database_Logs::log ("XML node " + nodename + " not handled while saving editor text"); - break; - } - } -} - - -void Editor_Html2Usfm::openElementNode (xml_node node) -{ - // The tag and class names of this element node. - string tagName = node.name (); - string className = update_quill_class (node.attribute ("class").value ()); - - if (tagName == "p") - { - // While editing, it may occur that the p element does not have a class. - // Use the 'p' class in such cases. - if (className.empty ()) className = "p"; - if (className == "mono") { - // Class 'mono': The editor has the full USFM in the text. - mono = true; - } else { - // Start the USFM line with a marker with the class name. - currentLine += filter::usfm::get_opening_usfm (className); - } - } - - if (tagName == "span") - { - if (className == "v") { - // Handle the verse. - flushLine (); - openInline (className); - } - else if (className.empty ()) { - // Normal text is wrapped in elements without a class attribute. - } else if (className.substr (0, 8) == "notecall") { - // Note in Quill-based editor. - processNoteCitation (node); - } else { - // Handle remaining class attributes for inline text. - openInline (className); - } - } - - if (tagName == "a") - { - processNoteCitation (node); - } -} - - -void Editor_Html2Usfm::closeElementNode (xml_node node) -{ - // The tag and class names of this element node. - string tagName = node.name (); - string className = update_quill_class (node.attribute ("class").value ()); - - if (tagName == "p") - { - // While editing it happens that the p element does not have a class. - // Use the 'p' class in such cases. - if (className == "") className = "p"; - - if (noteOpeners.find (className) != noteOpeners.end()) { - // Deal with note closers. - currentLine += filter::usfm::get_closing_usfm (className); - } else { - // Normally a p element closes the USFM line. - flushLine (); - mono = false; - // Clear active character styles. - characterStyles.clear(); - } - } - - if (tagName == "span") - { - // Do nothing for monospace elements, because the USFM would be the text nodes only. - if (mono) return; - // Do nothing without a class. - if (className.empty()) return; - // Do nothing with a note caller. - if (className.substr (0, 8) == "notecall") return; - // Do nothing if no endmarkers are supposed to be produced. - if (suppressEndMarkers.find (className) != suppressEndMarkers.end()) return; - // Add closing USFM, optionally closing embedded tags in reverse order. - char separator = '0'; - vector classes = filter::strings::explode (className, separator); - characterStyles = filter::strings::array_diff (characterStyles, classes); - reverse (classes.begin(), classes.end()); - for (unsigned int offset = 0; offset < classes.size(); offset++) { - bool embedded = (classes.size () > 1) && (offset == 0); - if (!characterStyles.empty ()) embedded = true; - currentLine += filter::usfm::get_closing_usfm (classes [offset], embedded); - lastNoteStyle.clear(); - } - } - - if (tagName == "a") - { - // Do nothing for note citations in the text. - } -} - - -void Editor_Html2Usfm::openInline (string className) -{ - // It has been observed that the elements of the character styles may be embedded, like so: - // The - // Lord God - // is calling you. - char separator = '0'; - vector classes = filter::strings::explode (className, separator); - for (unsigned int offset = 0; offset < classes.size(); offset++) { - bool embedded = (characterStyles.size () + offset) > 0; - string marker = classes[offset]; - bool add_opener = true; - if (processingNote) { - // If the style within the note has already been opened before, - // do not open the same style again. - // https://github.com/bibledit/cloud/issues/353 - if (marker == lastNoteStyle) add_opener = false; - lastNoteStyle = marker; - } else { - lastNoteStyle.clear (); - } - if (add_opener) - currentLine += filter::usfm::get_opening_usfm (marker, embedded); - } - // Store active character styles in some cases. - bool store = true; - if (suppressEndMarkers.find (className) != suppressEndMarkers.end ()) store = false; - if (processingNote) store = false; - if (store) { - characterStyles.insert (characterStyles.end(), classes.begin(), classes.end()); - } -} - - -void Editor_Html2Usfm::processNoteCitation (xml_node node) -{ - // Remove the note citation from the main text body. - // It means that this: - // 1 - // becomes this: - // - xml_node child = node.first_child (); - node.remove_child (child); - - // Get more information about the note to retrieve. - // - string id = node.attribute ("class").value (); - id = filter::strings::replace ("call", "body", id); - - // Sample footnote body. - //

    1 + notetext

    - // Retrieve the element from it. - // This was initially done through an XPath expression: - // http://www.grinninglizard.com/tinyxml2docs/index.html - // But XPath crashed on Android with libxml2. - // Therefore now it iterates over all the nodes to find the required element. - // After moving to pugixml, the XPath expression could have been used again, but this was not done. - xml_node note_p_element = get_note_pointer (document.first_child (), id); - if (note_p_element) { - - // It now has the

    . - // Remove the first element. - // So we remain with: - //

    + 2 Joh. 1.1

    - { - xml_node node2 = note_p_element.first_child(); - string name = node2.name (); - if (name != "span") { - // Normally the is the first child in the

    that is a note. - // But the user may have typed some text there. - // If so, then the is the second child of the

    . - // This code cares for that situation. - node2 = node2.next_sibling(); - name = node2.name(); - } - note_p_element.remove_child (node2); - } - - // Preserve active character styles in the main text, and reset them for the note. - vector preservedCharacterStyles = characterStyles; - characterStyles.clear(); - - // Process this 'p' element. - processingNote = true; - processNode (note_p_element); - processingNote = false; - - // Restore the active character styles for the main text. - characterStyles = preservedCharacterStyles; - - // Remove this element so it can't be processed again. - xml_node parent = note_p_element.parent (); - parent.remove_child (note_p_element); - - } else { - Database_Logs::log ("Discarding note with id " + id); - } -} - - -string Editor_Html2Usfm::cleanUSFM (string usfm) -{ - // Replace a double space after a note opener. - for (string noteOpener : noteOpeners) { - string opener = filter::usfm::get_opening_usfm (noteOpener); - usfm = filter::strings::replace (opener + " ", opener, usfm); - } - - // Unescape special XML characters. - usfm = filter::strings::unescape_special_xml_characters (usfm); - - // Done. - return usfm; -} - - -void Editor_Html2Usfm::preprocess () -{ - output.clear (); - currentLine.clear (); - mono = false; -} - - -void Editor_Html2Usfm::flushLine () -{ - if (!currentLine.empty ()) { - // Trim so that '\p ' becomes '\p', for example. - currentLine = filter::strings::trim (currentLine); - // No longer doing the above - // because it would remove a space intentionally added to the end of a line. - // Instead it now only does a left trim instead of the full trim. - // currentLine = filter::strings::ltrim (currentLine); - output.push_back (currentLine); - currentLine.clear (); - } -} - - -void Editor_Html2Usfm::postprocess () -{ - // Flush any last USFM line being built. - flushLine (); -} - - -// Retrieves a pointer to a relevant footnote element in the XML. -xml_node Editor_Html2Usfm::get_note_pointer (xml_node body, string id) -{ - // The note wrapper node to look for. - xml_node p_note_wrapper; - - // Check that there's a node to start with. - if (!body) return p_note_wrapper; - - // Assert that the node is given. - if (string(body.name ()) != "body") return p_note_wrapper; - - // Some of the children of the node will be the note wrappers. - // Consider this XML: - // - //

    text

    - //

    - //

    1 + foot

    - //

    note

    - // - // There is node

    . - // Any children of following the above node are all note wrappers. - // Here the code is going to get the correct note wrapper node. - // In addition to finding the correct p node, it also looks for subsequent p nodes - // that belong to the main p node. - // See issue https://github.com/bibledit/cloud/issues/444. - // It handles a situation that the user presses while in a note. - // The solution is to include the next p node too if it belongs to the correct note wrapper p node. - bool within_matching_p_node = false; - for (xml_node p_body_child : body.children ()) { - xml_node span_notebody = p_body_child.first_child(); - string name = span_notebody.name (); - if (name != "span") { - // Normally the is the first child in the

    that is a note. - // But the user may have typed some text there. - // If so, then the is the second child of the

    . - // This code cares for that situation. - span_notebody = span_notebody.next_sibling(); - name = span_notebody.name(); - } - if (name == "span") { - string classs = span_notebody.attribute ("class").value (); - if (classs.substr (0, 10) == id.substr(0, 10)) { - if (classs == id) { - within_matching_p_node = true; - } else { - within_matching_p_node = false; - } - } - } - if (within_matching_p_node) { - if (!p_note_wrapper) { - p_note_wrapper = p_body_child; - } else { - for (xml_node child = p_body_child.first_child(); child; child = child.next_sibling()) { - p_note_wrapper.append_copy(child); - } - } - } - } - - // If a note wrapper was found, return that. - // If nothing was found, the note wrapper is null. - return p_note_wrapper; -} - - -string Editor_Html2Usfm::update_quill_class (string classname) -{ - classname = filter::strings::replace (quill_logic_class_prefix_block (), "", classname); - classname = filter::strings::replace (quill_logic_class_prefix_inline (), "", classname); - return classname; -} - - -// This function takes the html from a Quill-based editor that edits one verse, -// and converts it to USFM. -// It properly deals with cases when a verse does not start a new paragraph. -string editor_export_verse_quill (string stylesheet, string html) -{ - // When the $html starts with a paragraph without a style, - // put a recognizable style there. - string style = "oneversestyle"; - size_t pos = html.find ("

    "); - if (pos == 0) { - html.insert (2, R"( class=")" + quill_logic_class_prefix_block () + style + R"(")"); - } - - // Convert html to USFM. - Editor_Html2Usfm editor_export; - editor_export.load (html); - editor_export.stylesheet (stylesheet); - editor_export.run (); - string usfm = editor_export.get (); - - // Remove that recognizable style converted to USFM. - usfm = filter::strings::replace (R"(\)" + style, string(), usfm); - usfm = filter::strings::trim (usfm); - - return usfm; -} diff --git a/editor/html2usfm.h b/editor/html2usfm.h deleted file mode 100644 index 171082eeb..000000000 --- a/editor/html2usfm.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop - -using namespace pugi; - -class Editor_Html2Usfm -{ -public: - void load (std::string html); - void stylesheet (std::string stylesheet); - void run (); - std::string get (); -private: - xml_document document {}; // DOMDocument holding the html. - std::map styles {}; // Style information. - std::vector output {}; // Output USFM. - std::string currentLine {}; // Growing current USFM line. - bool mono {false}; // Monospace font. - std::set suppressEndMarkers {}; // Markers which should not have endmarkers, e.g. \v does not have \v* - std::set noteOpeners {}; - std::vector characterStyles {}; // Active character styles. - bool processingNote {false}; // Note processing flag. - std::string lastNoteStyle {}; // The most recent style opened inside a note. - void preprocess (); - void flushLine (); - void postprocess (); - void process (); - void processNode (xml_node node); - void openElementNode (xml_node node); - void closeElementNode (xml_node node); - void openInline (std::string className); - void processNoteCitation (xml_node node); - std::string cleanUSFM (std::string usfm); - xml_node get_note_pointer (xml_node body, std::string id); - std::string update_quill_class (std::string classname); -}; - -std::string editor_export_verse_quill (std::string stylesheet, std::string html); diff --git a/editor/id.cpp b/editor/id.cpp deleted file mode 100644 index 5826c7c36..000000000 --- a/editor/id.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editor_id_url () -{ - return "editor/id"; -} - - -bool editor_id_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string editor_id (Webserver_Request& webserver_request) -{ - // Update the timestamp indicating that the Bible editor is alive. - webserver_request.database_config_user()->setLiveBibleEditor (filter::date::seconds_since_epoch ()); - - - string bible = webserver_request.query ["bible"]; - int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.query ["chapter"]); - int id = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - return filter::strings::convert_to_string (id); -} diff --git a/editor/id.h b/editor/id.h deleted file mode 100644 index 63ae615c2..000000000 --- a/editor/id.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editor_id_url (); -bool editor_id_acl (Webserver_Request& webserver_request); -std::string editor_id (Webserver_Request& webserver_request); diff --git a/editor/select.cpp b/editor/select.cpp deleted file mode 100644 index 2fdb7c236..000000000 --- a/editor/select.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include

    -#include -#include -#include -#include -using namespace std; - - -string editor_select_url () -{ - return "editor/select"; -} - - -bool editor_select_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) return true; - auto [ read, write ] = access_bible::any (webserver_request); - return write; -} - - -string editor_select (Webserver_Request& webserver_request) -{ - string page; - Assets_Header header = Assets_Header (translate("Select editor"), webserver_request); - page = header.run(); - Assets_View view; - - vector urls; - - if (edit_index_acl (webserver_request)) { - if (menu_logic_editor_enabled (webserver_request, true, true)) { - string label = menu_logic_editor_menu_text (true, true); - string url = edit_index_url (); - view.add_iteration ("editor", { pair ("url", url), pair ("label", label) } ); - urls.push_back (url); - } - } - - if (editone2_index_acl (webserver_request)) { - if (menu_logic_editor_enabled (webserver_request, true, false)) { - string label = menu_logic_editor_menu_text (true, false); - string url = editone2_index_url (); - view.add_iteration ("editor", { pair ("url", url), pair ("label", label) } ); - urls.push_back (url); - } - } - - if (editusfm_index_acl (webserver_request)) { - if (menu_logic_editor_enabled (webserver_request, false, true)) { - string label = menu_logic_editor_menu_text (false, true); - string url = editusfm_index_url (); - view.add_iteration ("editor", { pair ("url", url), pair ("label", label) } ); - urls.push_back (url); - } - } - - // Checking on whether to switch to another editor, through the keyboard shortcut. - string from = webserver_request.query ["from"]; - from.append ("/"); - if (!from.empty ()) { - if (!urls.empty ()) { - urls.push_back (urls[0]); - bool match = false; - for (auto url : urls) { - if (match) { - redirect_browser (webserver_request, url); - return ""; - } - if (url.find (from) == 0) match = true; - } - } - } - - page += view.render ("editor", "select"); - page += assets_page::footer (); - return page; -} diff --git a/editor/select.h b/editor/select.h deleted file mode 100644 index 56dad7f59..000000000 --- a/editor/select.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editor_select_url (); -bool editor_select_acl (Webserver_Request& webserver_request); -std::string editor_select (Webserver_Request& webserver_request); diff --git a/editor/style.cpp b/editor/style.cpp deleted file mode 100644 index 45c61c6cf..000000000 --- a/editor/style.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editor_style_url () -{ - return "editor/style"; -} - - -bool editor_style_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string editor_style (Webserver_Request& webserver_request) -{ - if (webserver_request.query.count ("style")) { - string style = webserver_request.query["style"]; - Editor_Styles::recordUsage (webserver_request, style); - string action = Editor_Styles::getAction (webserver_request, style); - return style + "\n" + action; - } - - - if (webserver_request.query.count ("all")) { - return Editor_Styles::getAll (webserver_request); - } - - - return Editor_Styles::getRecentlyUsed (webserver_request); -} - diff --git a/editor/style.h b/editor/style.h deleted file mode 100644 index bd9176df6..000000000 --- a/editor/style.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editor_style_url (); -bool editor_style_acl (Webserver_Request& webserver_request); -std::string editor_style (Webserver_Request& webserver_request); diff --git a/editor/styles.cpp b/editor/styles.cpp deleted file mode 100644 index f99c8b85d..000000000 --- a/editor/styles.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -using namespace std; -using namespace pugi; - - -string Editor_Styles::getRecentlyUsed (Webserver_Request& webserver_request) -{ - string bible = webserver_request.database_config_user()->getBible (); - string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - - // The recent styles. - string s_styles = webserver_request.database_config_user()->getRecentlyAppliedStyles (); - vector styles = filter::strings::explode (s_styles, ' '); - string fragment = translate("Select style") + ": "; - for (unsigned int i = 0; i < styles.size(); i++) { - if (i) fragment += " | "; - string marker = styles [i]; - Database_Styles_Item data = webserver_request.database_styles()->getMarkerData (stylesheet, marker); - if (data.marker.empty ()) continue; - string name = data.name + " (" + marker + ")"; - string info = data.info; - xml_document document; - xml_node a_node = document.append_child("a"); - a_node.append_attribute("href") = marker.c_str(); - a_node.append_attribute("title") = info.c_str(); - a_node.append_attribute("unselectable") = "on"; - a_node.append_attribute("class") = "unselectable"; - a_node.append_attribute("tabindex") = "-1"; - a_node.text().set(name.c_str()); - stringstream ss; - document.print(ss, "", format_raw); - fragment.append (ss.str()); - } - - // Links for cancelling and for all styles. - fragment += " "; - fragment += R"([)" + translate("cancel") + "]"; - fragment += " "; - fragment += R"([)" + translate("all") + "]"; - - return fragment; -} - - -string Editor_Styles::getAll (Webserver_Request& webserver_request) -{ - string bible = webserver_request.database_config_user()->getBible (); - string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - - // The styles. - map data = webserver_request.database_styles()->getMarkersAndNames (stylesheet); - - vector lines; - - lines.push_back (R"("); - - // Link for cancelling. - lines.push_back (" "); - lines.push_back (R"([)" + translate("cancel") + "]"); - - string html = filter::strings::implode (lines, "\n"); - - return html; -} - - -void Editor_Styles::recordUsage (Webserver_Request& webserver_request, string style) -{ - if (style == "") return; - string s_styles = webserver_request.database_config_user()->getRecentlyAppliedStyles (); - vector styles = filter::strings::explode (s_styles, ' '); - // Erase the style. - styles.erase (remove (styles.begin(), styles.end(), style), styles.end()); - // Add the style to he front of the vector. - styles.insert (styles.begin(), style); - // Clip the amount of styles to remember. - if (styles.size () > 8) { - styles.pop_back (); - } - s_styles = filter::strings::implode (styles, " "); - webserver_request.database_config_user()->setRecentlyAppliedStyles (s_styles); -} - - -string Editor_Styles::getAction (Webserver_Request& webserver_request, string style) -{ - string bible = webserver_request.database_config_user()->getBible (); - string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - Database_Styles_Item data = webserver_request.database_styles()->getMarkerData (stylesheet, style); - int type = data.type; - int subtype = data.subtype; - - switch (type) - { - case StyleTypeIdentifier: - switch (subtype) - { - case IdentifierSubtypePublishedVerseMarker: - return character (); - default: - return mono (); - } - break; - case StyleTypeNotUsedComment: - return mono (); - case StyleTypeNotUsedRunningHeader: - return mono (); - case StyleTypeStartsParagraph: - return paragraph (); - case StyleTypeInlineText: - return character (); - case StyleTypeChapterNumber: - return paragraph (); - case StyleTypeVerseNumber: - return character (); - case StyleTypeFootEndNote: - { - switch (subtype) - { - case FootEndNoteSubtypeFootnote: - case FootEndNoteSubtypeEndnote: - return note (); - case FootEndNoteSubtypeContent: - case FootEndNoteSubtypeContentWithEndmarker: - return character (); - case FootEndNoteSubtypeStandardContent: - case FootEndNoteSubtypeParagraph: - return character (); - default: - return unknown (); - } - break; - } - case StyleTypeCrossreference: - { - switch (subtype) - { - case CrossreferenceSubtypeCrossreference: - return note (); - case CrossreferenceSubtypeContent: - case CrossreferenceSubtypeContentWithEndmarker: - return character (); - case CrossreferenceSubtypeStandardContent: - return character (); - default: - return unknown (); - } - break; - } - case StyleTypePeripheral: - return mono (); - case StyleTypePicture: - return mono (); - case StyleTypePageBreak: - return unknown (); - case StyleTypeTableElement: - { - switch (subtype) - { - case TableElementSubtypeRow: - case TableElementSubtypeHeading: - case TableElementSubtypeCell: - default: - return mono (); - } - break; - } - case StyleTypeWordlistElement: - { - return character (); - } - default: - return unknown (); - } -} - - -string Editor_Styles::unknown () -{ - return "u"; -} - - -string Editor_Styles::paragraph () -{ - return "p"; -} - - -string Editor_Styles::character () -{ - return "c"; -} - - -string Editor_Styles::mono () -{ - return "m"; -} - - -string Editor_Styles::note () -{ - return "n"; -} - diff --git a/editor/styles.h b/editor/styles.h deleted file mode 100644 index 4eb92d26c..000000000 --- a/editor/styles.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -class Editor_Styles -{ -public: - static std::string getRecentlyUsed (Webserver_Request& webserver_request); - static std::string getAll (Webserver_Request& webserver_request); - static void recordUsage (Webserver_Request& webserver_request, std::string style); - static std::string getAction (Webserver_Request& webserver_request, std::string style); -private: - static std::string unknown (); - static std::string paragraph (); - static std::string character (); - static std::string mono (); - static std::string note (); -}; diff --git a/editor/usfm2html.cpp b/editor/usfm2html.cpp deleted file mode 100644 index fe6deae23..000000000 --- a/editor/usfm2html.cpp +++ /dev/null @@ -1,750 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - - -void Editor_Usfm2Html::load (std::string usfm) -{ - // Clean up. - usfm = filter::strings::trim (usfm); - usfm.append ("\n"); - // Separate it into markers and text. - // Load it into the object. - m_markers_and_text = filter::usfm::get_markers_and_text (usfm); - m_markers_and_text_pointer = 0; -} - - -void Editor_Usfm2Html::stylesheet (std::string stylesheet) -{ - Database_Styles database_styles; - m_styles.clear(); - std::vector markers = database_styles.getMarkers (stylesheet); - // Load the style information into the object. - for (const auto& marker : markers) { - Database_Styles_Item style = database_styles.getMarkerData (stylesheet, marker); - m_styles [marker] = style; - if (style.type == StyleTypeFootEndNote) { - if (style.subtype == FootEndNoteSubtypeStandardContent) { - m_standard_content_marker_foot_end_note = style.marker; - } - } - if (style.type == StyleTypeCrossreference) { - if (style.subtype == CrossreferenceSubtypeStandardContent) { - m_standard_content_marker_cross_reference = style.marker; - } - } - m_note_citations.evaluate_style(style); - } -} - - -void Editor_Usfm2Html::run () -{ - preprocess (); - process (); - postprocess (); -} - - -std::string Editor_Usfm2Html::get () -{ - close_paragraph (); - - // If there are notes, move the notes
    or

    after everything else. - // (It has the


    or
    as a child). - const long int count = std::distance (m_notes_node.begin (), m_notes_node.end ()); - if (count > 1) { - m_body_node.append_move (m_notes_node); - } - - // A Quill-based editor does not work with embedded

    elements. - // Move the notes out of their parent and append them to the end of the main body. - while (xml_node note = m_notes_node.first_child ().next_sibling ()) { - m_body_node.append_move (note); - } - - // Get the html code, including body, without head. - std::stringstream output {}; - m_body_node.print (output, "", format_raw); - std::string html = output.str (); - - // Remain with the stuff within the elements. - size_t pos = html.find (""); - if (pos != std::string::npos) { - html.erase (0, pos + 6); - pos = html.find (""); - if (pos != std::string::npos) { - html.erase (pos); - } - } - - // Currently the XML library produces hexadecimal character entities. - // This is unwanted behaviour: Convert them to normal characters. - html = filter::strings::convert_xml_character_entities_to_characters (html); - - // Result. - return html; -} - - -void Editor_Usfm2Html::preprocess () -{ - m_current_paragraph_style.clear (); - m_current_paragraph_content.clear (); - m_current_text_styles.clear(); - m_note_count = 0; - m_current_note_text_styles.clear(); - m_text_tength = 0; - m_verse_start_offsets = { std::pair (0, 0) }; - m_current_p_open = false; - m_note_p_open = false; - - // XPath crashes on Android with libxml2 2.9.2 compiled through the Android NDK. - // After the move to pugixml, this no longer applies. - - m_body_node = m_document.append_child ("body"); - - // Create notes xml node. - // It comes at the start of the document. - // (Later, it will either be deleted, or moved to the end). - std::string notes_value = "notes"; - m_notes_node = m_document.append_child ("p"); - notes_value.insert (0, quill_logic_class_prefix_block ()); - m_notes_node.append_attribute ("class") = notes_value.c_str (); - m_notes_node.text().set(filter::strings::non_breaking_space_u00A0().c_str()); -} - - -void Editor_Usfm2Html::process () -{ - m_markers_and_text_pointer = 0; - size_t markersAndTextCount = m_markers_and_text.size(); - for (m_markers_and_text_pointer = 0; m_markers_and_text_pointer < markersAndTextCount; m_markers_and_text_pointer++) { - std::string currentItem = m_markers_and_text[m_markers_and_text_pointer]; - if (filter::usfm::is_usfm_marker (currentItem)) - { - // Store indicator whether the marker is an opening marker. - bool is_opening_marker = filter::usfm::is_opening_marker (currentItem); - bool isEmbeddedMarker = filter::usfm::is_embedded_marker (currentItem); - // Clean up the marker, so we remain with the basic version, e.g. 'id'. - std::string marker = filter::usfm::get_marker (currentItem); - // Handle preview mode: Strip word-level attributes. - if (m_preview) if (is_opening_marker) filter::usfm::remove_word_level_attributes (marker, m_markers_and_text, m_markers_and_text_pointer); - - if (m_styles.count (marker)) - { - Database_Styles_Item style = m_styles [marker]; - switch (style.type) - { - case StyleTypeIdentifier: - { - if (style.subtype == IdentifierSubtypePublishedVerseMarker) { - // Treat the \vp ...\vp* marker as inline text. - if (is_opening_marker) { - open_text_style (style, isEmbeddedMarker); - } else { - close_text_style (isEmbeddedMarker); - } - } else { - // Any other identifier: Plain text. - close_text_style (false); - output_as_is (marker, is_opening_marker); - } - break; - } - case StyleTypeNotUsedComment: - case StyleTypeNotUsedRunningHeader: - { - close_text_style (false); - output_as_is (marker, is_opening_marker); - break; - } - case StyleTypeStartsParagraph: - { - close_text_style (false); - close_paragraph (); - new_paragraph (marker); - break; - } - case StyleTypeInlineText: - { - if (is_opening_marker) { - // Be sure the road ahead is clear. - if (road_is_clear ()) { - open_text_style (style, isEmbeddedMarker); - } else { - add_text (filter::usfm::get_opening_usfm (marker)); - } - } else { - close_text_style (isEmbeddedMarker); - } - break; - } - case StyleTypeChapterNumber: - { - close_text_style (false); - close_paragraph (); - new_paragraph (marker); - break; - } - case StyleTypeVerseNumber: - { - // Close any existing text style. - close_text_style (false); - // Output the space before the verse number in case the paragraph already has some text. - if (!m_current_paragraph_content.empty()) { - add_text (" "); - } - // Open verse style, record verse/length, add verse number, close style again, and add a space. - open_text_style (style, false); - std::string textFollowingMarker = filter::usfm::get_text_following_marker (m_markers_and_text, m_markers_and_text_pointer); - std::string number = filter::usfm::peek_verse_number (textFollowingMarker); - m_verse_start_offsets [filter::strings::convert_to_int (number)] = static_cast(m_text_tength); - add_text (number); - close_text_style (false); - add_text (" "); - // If there was any text following the \v marker, remove the verse number, - // put the remainder back into the object, and update the pointer. - if (textFollowingMarker != "") { - size_t pos = textFollowingMarker.find (number); - if (pos != std::string::npos) { - textFollowingMarker = textFollowingMarker.substr (pos + number.length()); - } - textFollowingMarker = filter::strings::ltrim (textFollowingMarker); - m_markers_and_text [m_markers_and_text_pointer] = textFollowingMarker; - m_markers_and_text_pointer--; - } - break; - } - case StyleTypeFootEndNote: - { - switch (style.subtype) - { - case FootEndNoteSubtypeFootnote: - case FootEndNoteSubtypeEndnote: - { - close_text_style (false); - if (is_opening_marker) { - const std::string caller = m_note_citations.get (style.marker, "+"); - add_note (caller, marker, false); - } else { - close_current_note (); - } - break; - } - case FootEndNoteSubtypeStandardContent: - case FootEndNoteSubtypeContent: - case FootEndNoteSubtypeContentWithEndmarker: - { - if (is_opening_marker) { - open_text_style (style, isEmbeddedMarker); - } else { - close_text_style (isEmbeddedMarker); - } - break; - } - case FootEndNoteSubtypeParagraph: - default: - { - close_text_style (false); - break; - } - } - break; - } - case StyleTypeCrossreference: - { - switch (style.subtype) - { - case CrossreferenceSubtypeCrossreference: - { - close_text_style (false); - if (is_opening_marker) { - const std::string caller = m_note_citations.get (style.marker, "+"); - add_note (caller, marker, false); - } else { - close_current_note (); - } - break; - } - case CrossreferenceSubtypeContent: - case CrossreferenceSubtypeContentWithEndmarker: - case CrossreferenceSubtypeStandardContent: - { - if (is_opening_marker) { - open_text_style (style, isEmbeddedMarker); - } else { - close_text_style (isEmbeddedMarker); - } - break; - } - default: - { - close_text_style (false); - break; - } - } - break; - } - case StyleTypePeripheral: - { - close_text_style (false); - output_as_is (marker, is_opening_marker); - break; - } - case StyleTypePicture: - { - close_text_style (false); - output_as_is (marker, is_opening_marker); - break; - } - case StyleTypePageBreak: - { - close_text_style (false); - output_as_is (marker, is_opening_marker); - break; - } - case StyleTypeTableElement: - { - close_text_style (false); - switch (style.subtype) - { - case TableElementSubtypeRow: - { - output_as_is (marker, is_opening_marker); - break; - } - case TableElementSubtypeHeading: - case TableElementSubtypeCell: - { - open_text_style (style, false); - break; - } - default: - { - open_text_style (style, false); - break; - } - } - break; - } - case StyleTypeWordlistElement: - { - if (is_opening_marker) { - open_text_style (style, false); - } else { - close_text_style (false); - } - break; - } - default: - { - // This marker is known in the stylesheet, but not yet implemented here. - close_text_style (false); - output_as_is (marker, is_opening_marker); - break; - } - } - } else { - // This is a marker unknown in the stylesheet. - close_text_style (false); - output_as_is (marker, is_opening_marker); - } - } else { - // Here is no marker. Treat it as text. - if (m_note_opened) { - add_note_text (currentItem); - } else { - add_text (currentItem); - } - } - } -} - - -void Editor_Usfm2Html::postprocess () -{ -} - - -void Editor_Usfm2Html::output_as_is (std::string marker, bool is_opening_marker) -{ - // Output the marker in monospace font. - if (is_opening_marker) { - // Add opening marker as it is. - close_paragraph (); - new_paragraph ("mono"); - add_text (filter::usfm::get_opening_usfm (marker)); - } else { - // Add closing marker to existing paragraph. - add_text (filter::usfm::get_closing_usfm (marker)); - } -} - - -void Editor_Usfm2Html::new_paragraph (std::string style) -{ - // Handle new paragraph. - m_current_p_node = m_body_node.append_child ("p"); - m_current_p_open = true; - if (!style.empty()) { - std::string style2 (style); - style2.insert (0, quill_logic_class_prefix_block ()); - m_current_p_node.append_attribute ("class") = style2.c_str(); - } - m_current_paragraph_style = style; - m_current_paragraph_content.clear(); - // A Quill-based editor assigns a length of one to a new line. - // Skip the first line. - if (m_first_line_done) m_text_tength++; - m_first_line_done = true; -} - - -void Editor_Usfm2Html::close_paragraph () -{ - // Deal with a blank line. - // If the paragraph is empty, add a
    to it. - // This is how the Quill editor naturally represents a new empty line. - // This causes that empty paragraph to be displayed properly in the Quill editor. - // This
    is also needed for live editor updates. - if (m_current_p_open) { - if (m_current_paragraph_content.empty()) { - m_current_p_node.append_child("br"); - } - } -} - - -// This opens a text style. -// $style: the array containing the style variables. -// $embed: boolean: Whether to open embedded / nested style. -void Editor_Usfm2Html::open_text_style (Database_Styles_Item & style, bool embed) -{ - const std::string marker = style.marker; - if (m_note_opened) { - if (!embed) m_current_note_text_styles.clear(); - m_current_note_text_styles.push_back (marker); - } else { - if (!embed) m_current_text_styles.clear(); - m_current_text_styles.push_back (marker); - } -} - - -// This closes any open text style. -// $embed: boolean: Whether to close embedded character style. -void Editor_Usfm2Html::close_text_style (bool embed) -{ - if (m_note_opened) { - if (!m_current_note_text_styles.empty ()) m_current_note_text_styles.pop_back (); - if (!embed) m_current_note_text_styles.clear (); - } else { - if (!m_current_text_styles.empty()) m_current_text_styles.pop_back(); - if (!embed) m_current_text_styles.clear (); - } -} - - -// This function adds text to the current paragraph. -// $text: The text to add. -void Editor_Usfm2Html::add_text (std::string text) -{ - if (text != "") { - if (!m_current_p_open) { - new_paragraph (); - } - xml_node spanDomElement = m_current_p_node.append_child ("span"); - spanDomElement.text ().set (text.c_str()); - if (!m_current_text_styles.empty ()) { - // Take character style(s) as specified in this object. - std::string textstyle {}; - for (const auto& style : m_current_text_styles) { - if (!textstyle.empty ()) { - // The Quill library is fussy about class names. - // It accepts class="i-add" but not class="i-add-nd". It fails on that second hyphen. - // It also does not accept an underscore as part of the class name. - // That causes the whole class to be removed. - // Right now the way to deal with a class with two styles is like this "i-add0nd". - // It has one hyphen. And a "0" to separate the two styles. - textstyle.append ("0"); - } - textstyle.append (style); - } - textstyle.insert (0, quill_logic_class_prefix_inline ()); - spanDomElement.append_attribute ("class") = textstyle.c_str(); - } - m_current_paragraph_content.append (text); - } - m_text_tength += filter::strings::unicode_string_length (text); -} - - -// This function adds a note to the current paragraph. -// $citation: The text of the note citation. -// $style: Style name for the paragraph in the note body. -// $endnote: Whether this is a footnote and cross reference (false), or an endnote (true). -void Editor_Usfm2Html::add_note (std::string citation, std::string style, [[maybe_unused]] bool endnote) -{ - // Be sure the road ahead is clear. - if (!road_is_clear ()) { - add_text (filter::usfm::get_opening_usfm (style)); - return; - } - - // Ensure that a paragraph is open, so that the note can be added to it. - if (!m_current_p_open) { - new_paragraph (); - } - - m_note_count++; - m_note_opened = true; - - // Add the link with all relevant data for the note citation. - add_notel_link (m_current_p_node, m_note_count, "call", citation); - - // Open a paragraph element for the note body. - m_note_p_node = m_notes_node.append_child ("p"); - m_note_p_open = true; - std::string cls (style); - cls.insert (0, quill_logic_class_prefix_block ()); - m_note_p_node.append_attribute ("class") = cls.c_str(); - - close_text_style (false); - - // Add the link with all relevant data for the note body. - add_notel_link (m_note_p_node, m_note_count, "body", citation); - - // Add a space. - add_note_text (" "); - - // Update the text length of the text body, excluding the note. - m_text_tength += filter::strings::unicode_string_length (citation); -} - - -// This function adds text to the current footnote. -// $text: The text to add. -void Editor_Usfm2Html::add_note_text (std::string text) -{ - if (text.empty ()) return; - if (!m_note_p_open) { - add_note ("?", ""); - } - xml_node spanDomElement = m_note_p_node.append_child ("span"); - spanDomElement.text ().set (text.c_str()); - if (!m_current_note_text_styles.empty()) { - // Take character style(s) as specified in this object. - std::string classs; - classs = filter::strings::implode (m_current_note_text_styles, "0"); - classs.insert (0, quill_logic_class_prefix_inline ()); - spanDomElement.append_attribute ("class") = classs.c_str(); - } -} - - -// This function closes the current footnote. -void Editor_Usfm2Html::close_current_note () -{ - // If a note was opened, close that, else close the standard text. - close_text_style (false); - m_note_p_open = false; - m_note_opened = false; -} - - -// This adds a link as a mechanism to connect body text with a note body. -// $domNode: The DOM node where to add the link to. -// $identifier: The link's identifier. -// $style: A style for the note citation, and one for the note body. -// $text: The link's text. -// It also deals with a Quill-based editor, in a slightly different way. -void Editor_Usfm2Html::add_notel_link (xml_node domNode, int identifier, std::string style, std::string text) -{ - xml_node aDomElement = domNode.append_child ("span"); - std::string cls = "i-note" + style + filter::strings::convert_to_string (identifier); - aDomElement.append_attribute ("class") = cls.c_str(); - aDomElement.text ().set (text.c_str()); -} - - -// Returns true if the road ahead is clear for the current marker. -bool Editor_Usfm2Html::road_is_clear () -{ - // Determine the input. - std::string input_marker; - bool input_opener = false; - bool input_embedded = false; - int input_type = 0; - int input_subtype = 0; - { - std::string currentItem = m_markers_and_text[m_markers_and_text_pointer]; - if (!filter::usfm::is_usfm_marker (currentItem)) return true; - input_opener = filter::usfm::is_opening_marker (currentItem); - input_embedded = filter::usfm::is_embedded_marker (currentItem); - std::string marker = filter::usfm::get_marker (currentItem); - input_marker = marker; - if (!m_styles.count (marker)) return true; - Database_Styles_Item style = m_styles [marker]; - input_type = style.type; - input_subtype = style.subtype; - } - - // Determine the road ahead. - std::vector markers; - std::vector types; - std::vector subtypes; - std::vector openers; - std::vector embeddeds; - - bool end_chapter_reached = false; - { - bool done = false; - size_t markersAndTextCount = m_markers_and_text.size(); - for (size_t pointer = m_markers_and_text_pointer + 1; pointer < markersAndTextCount; pointer++) { - if (done) continue; - std::string currentItem = m_markers_and_text[pointer]; - if (filter::usfm::is_usfm_marker (currentItem)) - { - std::string marker = filter::usfm::get_marker (currentItem); - if (m_styles.count (marker)) - { - Database_Styles_Item style = m_styles [marker]; - markers.push_back (marker); - types.push_back (style.type); - subtypes.push_back (style.subtype); - openers.push_back (filter::usfm::is_opening_marker (currentItem)); - embeddeds.push_back (filter::usfm::is_embedded_marker (currentItem)); - // Don't go beyond the next verse marker. - if (style.type == StyleTypeVerseNumber) done = true; - } - } - } - if (!done) end_chapter_reached = true; - } - - // Go through the road ahead, and assess it. - for (size_t i = 0; i < types.size (); i++) { - - std::string marker = markers [i]; - int type = types [i]; - int subtype = subtypes [i]; - int opener = openers [i]; - int embedded = embeddeds [i]; - - if (embedded) {} - - // The input is a note opener. - if (input_type == StyleTypeFootEndNote) { - if (input_opener) { - if ((input_subtype == FootEndNoteSubtypeFootnote) || (input_subtype == FootEndNoteSubtypeEndnote)) { - // Encounters note closer: road is clear. - // Encounters another note opener: blocker. - if (type == StyleTypeFootEndNote) { - if ((subtype == FootEndNoteSubtypeFootnote) || (subtype == FootEndNoteSubtypeEndnote)) { - if (opener) return false; - else return true; - } - } - // Encounters a verse: blocker. - if (type == StyleTypeVerseNumber) return false; - // Encounters cross reference opener: blocker. - // Other \x.. markup is allowed. - if (type == StyleTypeCrossreference) { - if (subtype == CrossreferenceSubtypeCrossreference) { - return false; - } - } - } - } - } - - // The input is a cross reference opener. - if (input_type == StyleTypeCrossreference) { - if (input_opener) { - if (input_subtype == CrossreferenceSubtypeCrossreference) { - // Encounters xref closer: road is clear. - // Encounters another xref opener: blocker. - if (type == StyleTypeCrossreference) { - if (subtype == CrossreferenceSubtypeCrossreference) { - if (opener) return false; - else return true; - } - } - // Encounters a verse: blocker. - if (type == StyleTypeVerseNumber) return false; - // Encounters foot- or endnote opener: blocker. - // Other \f.. markup is allowed. - if (type == StyleTypeFootEndNote) { - if ((subtype == FootEndNoteSubtypeFootnote) || (subtype == FootEndNoteSubtypeEndnote)) { - return false; - } - } - } - } - } - - // The input to check the road ahead for is an inline text opener, non-embedded, like "\add ". - if (input_type == StyleTypeInlineText) { - // If the input is embedded, declare the road ahead to be clear. - if (input_embedded) return true; - if (input_opener && !input_embedded) { - if (type == StyleTypeInlineText) { - if (embedded) { - // An embedded inline marker is OK: Road ahead is clear. - return true; - } else { - // It it encounters another non-embedded inline opening marker, that's a blocker. - if (opener) return false; - // If it finds a matching closing marker: OK. - if (input_marker == marker) { - if (!opener) return true; - } - } - } - // The inline text opener encounters a verse: blocker. - if (type == StyleTypeVerseNumber) return false; - // The inline text opener encounters a paragraph: blocker. - if (type == StyleTypeStartsParagraph) return false; - } - } - - } - - // Nothing clearing the way was found, and if it reached the end of the chapter, that's a blocker. - if (end_chapter_reached) return false; - - // No blockers found: The road is clear. - return true; -} - - -void Editor_Usfm2Html::set_preview () -{ - m_preview = true; -} diff --git a/editor/usfm2html.h b/editor/usfm2html.h deleted file mode 100644 index f9cd1f3ea..000000000 --- a/editor/usfm2html.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -#include - -using namespace pugi; - -class Editor_Usfm2Html -{ -public: - void load (std::string usfm); - void stylesheet (std::string stylesheet); - void run (); - std::string get (); - size_t m_text_tength {0}; - std::map m_verse_start_offsets {}; - std::string m_current_paragraph_style {}; - std::string m_current_paragraph_content {}; - void set_preview (); -private: - std::vector m_markers_and_text {}; // Strings alternating between USFM and text. - unsigned int m_markers_and_text_pointer {0}; - - // All the style information. - std::map m_styles {}; - - // XML nodes. - xml_document m_document {}; - xml_node m_body_node {}; - xml_node m_notes_node {}; - - // Standard content markers for notes. - std::string m_standard_content_marker_foot_end_note {}; - std::string m_standard_content_marker_cross_reference {}; - - xml_node m_current_p_node {}; // The current p node. - bool m_current_p_open {false}; - std::vector m_current_text_styles {}; - - int m_note_count {0}; - xml_node m_note_p_node {}; // The p DOM element of the current footnote, if any. - bool m_note_p_open {false}; - std::vector m_current_note_text_styles {}; - - // The note citations. - filter::note::citations m_note_citations {}; - - // Whether note is open. - bool m_note_opened {false}; - - // Lengths and offsets. - bool m_first_line_done {false}; - - // Whether it runs in preview-mode. - bool m_preview { false }; - - void preprocess (); - void process (); - void postprocess (); - void output_as_is (std::string marker, bool is_opening_marker); - void new_paragraph (std::string style = std::string()); - void close_paragraph (); - void open_text_style (Database_Styles_Item & style, bool embed); - void close_text_style (bool embed); - void add_text (std::string text); - void add_note (std::string citation, std::string style, bool endnote = false); - void add_note_text (std::string text); - void close_current_note (); - void add_notel_link (xml_node domNode, int identifier, std::string style, std::string text); - - bool road_is_clear (); -}; diff --git a/editusfm/focus.cpp b/editusfm/focus.cpp deleted file mode 100644 index a7096d8e7..000000000 --- a/editusfm/focus.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editusfm_focus_url () -{ - return "editusfm/focus"; -} - - -bool editusfm_focus_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -// Returns two numerical positions: A starting one, and an ending one. -// These two are for positioning the caret in the editor. -// The caret should be at or be moved to a position between these two. -string editusfm_focus (Webserver_Request& webserver_request) -{ - string bible = webserver_request.query ["bible"]; - int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.query ["chapter"]); - string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - int verse = Ipc_Focus::getVerse (webserver_request); - int startingOffset = filter::usfm::versenumber_to_offset (usfm, verse); - int endingOffset = startingOffset; - // The following deals with a combined verse. - for (int i = 1; i < 25; i++) { - if (startingOffset == endingOffset) { - endingOffset = filter::usfm::versenumber_to_offset (usfm, verse + i); - if (endingOffset > startingOffset) endingOffset--; - } - } - string data = filter::strings::convert_to_string (startingOffset) + " " + filter::strings::convert_to_string (endingOffset); - return data; -} - diff --git a/editusfm/focus.h b/editusfm/focus.h deleted file mode 100644 index 3b84b6247..000000000 --- a/editusfm/focus.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editusfm_focus_url (); -bool editusfm_focus_acl (Webserver_Request& webserver_request); -std::string editusfm_focus (Webserver_Request& webserver_request); diff --git a/editusfm/index.cpp b/editusfm/index.cpp deleted file mode 100644 index ef7167c22..000000000 --- a/editusfm/index.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include

    -#include -#include -#include -#include -#include - - -std::string editusfm_index_url () -{ - return "editusfm/index"; -} - - -bool editusfm_index_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return write; -} - - -std::string editusfm_index (Webserver_Request& webserver_request) -{ - const bool touch = webserver_request.session_logic ()->touchEnabled (); - - - if (webserver_request.query.count ("switchbook") && webserver_request.query.count ("switchchapter")) { - const std::string switchbook = webserver_request.query ["switchbook"]; - const std::string switchchapter = webserver_request.query ["switchchapter"]; - const int book = filter::strings::convert_to_int (switchbook); - const int chapter = filter::strings::convert_to_int (switchchapter); - Ipc_Focus::set (webserver_request, book, chapter, 1); - Navigation_Passage::record_history (webserver_request, book, chapter, 1); - } - - - // Set the user chosen Bible as the current Bible. - if (webserver_request.post.count ("bibleselect")) { - const std::string bibleselect = webserver_request.post ["bibleselect"]; - webserver_request.database_config_user ()->setBible (bibleselect); - return std::string(); - } - - - std::string page{}; - - Assets_Header header = Assets_Header (translate("Edit USFM"), webserver_request); - header.set_navigator (); - header.add_bread_crumb (menu_logic_translate_menu (), menu_logic_translate_text ()); - if (touch) - header.jquery_touch_on (); - header.notify_it_on (); - page = header.run (); - Assets_View view; - - - // Get active Bible, and check read access to it. - // Or if the user have used query to preset the active Bible, get the preset Bible. - // If needed, change Bible to one it has read access to. - // Set the chosen Bible on the option HTML tag. - std::string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - if (webserver_request.query.count ("bible")) - bible = access_bible::clamp (webserver_request, webserver_request.query ["bible"]); - std::string bible_html; - const std::vector bibles = access_bible::bibles (webserver_request); - for (const auto& selectable_bible : bibles) { - bible_html = Options_To_Select::add_selection (selectable_bible, selectable_bible, bible_html); - } - view.set_variable ("bibleoptags", Options_To_Select::mark_selected (bible, bible_html)); - view.set_variable ("bible", bible); - - - // Store the active Bible in the page's javascript. - view.set_variable ("navigationCode", Navigation_Passage::code (bible)); - - - const int verticalCaretPosition = webserver_request.database_config_user ()->getVerticalCaretPosition (); - std::stringstream ss{}; - ss << "var usfmEditorChapterLoaded = " << quoted(locale_logic_text_loaded ()) << ";" << std::endl; - ss << "var usfmEditorWillSave = " << quoted(locale_logic_text_will_save ()) << ";" << std::endl; - ss << "var usfmEditorChapterSaving = " << quoted(locale_logic_text_saving ()) << ";" << std::endl; - ss << "var usfmEditorChapterSaved = " << quoted(locale_logic_text_saved ()) << ";" << std::endl; - ss << "var usfmEditorChapterRetrying = " << quoted(locale_logic_text_retrying ()) << ";" << std::endl; - ss << "var usfmEditorVerseUpdatedLoaded = " << quoted(locale_logic_text_reload ()) << ";" << std::endl; - ss << "var usfmEditorWriteAccess = true;" << std::endl; - ss << "var verticalCaretPosition = " << verticalCaretPosition << ";" << std::endl; - std::string script = ss.str(); - config::logic::swipe_enabled (webserver_request, script); - view.set_variable ("script", script); - - - const std::string cls = Filter_Css::getClass (bible); - const std::string font = fonts::logic::get_text_font (bible); - const int current_theme_index = webserver_request.database_config_user ()->getCurrentTheme (); - const int direction = Database_Config_Bible::getTextDirection (bible); - const int lineheight = Database_Config_Bible::getLineHeight (bible); - const int letterspacing = Database_Config_Bible::getLetterSpacing (bible); - view.set_variable ("editor_theme_color", Filter_Css::theme_picker (current_theme_index, 2)); - view.set_variable ("active_editor_theme_color", Filter_Css::theme_picker (current_theme_index, 3)); - view.set_variable ("custom_class", cls); - view.set_variable ("custom_css", Filter_Css::get_css (cls, fonts::logic::get_font_path (font), - direction, lineheight, letterspacing)); - - // Whether to enable fast Bible editor switching. - if (webserver_request.database_config_user ()->getFastEditorSwitchingAvailable ()) { - view.enable_zone ("fastswitcheditor"); - } - - page += view.render ("editusfm", "index"); - - - page += assets_page::footer (); - - - return page; -} - - -// Tests for the USFM editor: -// * Autosave on going to another passage. -// * Autosave on document unload. -// * Autosave shortly after any change. diff --git a/editusfm/index.h b/editusfm/index.h deleted file mode 100644 index deab09ae5..000000000 --- a/editusfm/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editusfm_index_url (); -bool editusfm_index_acl (Webserver_Request& webserver_request); -std::string editusfm_index (Webserver_Request& webserver_request); diff --git a/editusfm/load.cpp b/editusfm/load.cpp deleted file mode 100644 index 30f860213..000000000 --- a/editusfm/load.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editusfm_load_url () -{ - return "editusfm/load"; -} - - -bool editusfm_load_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string editusfm_load (Webserver_Request& webserver_request) -{ - string bible = webserver_request.query ["bible"]; - int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.query ["chapter"]); - string unique_id = webserver_request.query ["id"]; - - // Store a copy of the USFM loaded in the editor for later reference. - storeLoadedUsfm2 (webserver_request, bible, book, chapter, unique_id); - - string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - // Escape the XML special characters so they load properly in the editor. - usfm = filter::strings::escape_special_xml_characters (usfm); - - string user = webserver_request.session_logic ()->currentUser (); - bool write = access_bible::book_write (webserver_request, user, bible, book); - - return checksum_logic::send (usfm, write); -} diff --git a/editusfm/load.h b/editusfm/load.h deleted file mode 100644 index 0acb5ea7e..000000000 --- a/editusfm/load.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editusfm_load_url (); -bool editusfm_load_acl (Webserver_Request& webserver_request); -std::string editusfm_load (Webserver_Request& webserver_request); diff --git a/editusfm/offset.cpp b/editusfm/offset.cpp deleted file mode 100644 index f40ddc626..000000000 --- a/editusfm/offset.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editusfm_offset_url () -{ - return "editusfm/offset"; -} - - -bool editusfm_offset_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -// This receives the position of the caret in the editor, -// and translates that to a verse number, -// and focuses that verse number. -string editusfm_offset (Webserver_Request& webserver_request) -{ - string bible = webserver_request.query ["bible"]; - int book = filter::strings::convert_to_int (webserver_request.query ["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.query ["chapter"]); - unsigned int offset = static_cast (filter::strings::convert_to_int (webserver_request.query ["offset"])); - string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - vector verses = filter::usfm::offset_to_versenumber (usfm, offset); - // Only update navigation in case the verse differs. - // This avoids unnecessary focus operations in the clients. - if (!in_array (Ipc_Focus::getVerse (webserver_request), verses)) { - if (!verses.empty ()) { - Ipc_Focus::set (webserver_request, book, chapter, verses[0]); - } - } - return ""; -} - diff --git a/editusfm/offset.h b/editusfm/offset.h deleted file mode 100644 index 4b525cf8e..000000000 --- a/editusfm/offset.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editusfm_offset_url (); -bool editusfm_offset_acl (Webserver_Request& webserver_request); -std::string editusfm_offset (Webserver_Request& webserver_request); diff --git a/editusfm/save.cpp b/editusfm/save.cpp deleted file mode 100644 index 35f61bba8..000000000 --- a/editusfm/save.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string editusfm_save_url () -{ - return "editusfm/save"; -} - - -bool editusfm_save_acl (Webserver_Request& webserver_request) -{ - if (Filter_Roles::access_control (webserver_request, Filter_Roles::translator ())) - return true; - auto [ read, write ] = access_bible::any (webserver_request); - return read; -} - - -string editusfm_save (Webserver_Request& webserver_request) -{ - string bible = webserver_request.post["bible"]; - int book = filter::strings::convert_to_int (webserver_request.post["book"]); - int chapter = filter::strings::convert_to_int (webserver_request.post["chapter"]); - string usfm = webserver_request.post["usfm"]; - string checksum = webserver_request.post["checksum"]; - string unique_id = webserver_request.post ["id"]; - - - if (webserver_request.post.count ("bible") && webserver_request.post.count ("book") && webserver_request.post.count ("chapter") && webserver_request.post.count ("usfm")) { - if (checksum_logic::get (usfm) == checksum) { - usfm = filter_url_tag_to_plus (usfm); - usfm = filter::strings::trim (usfm); - // Collapse multiple spaces in the USFM into one space. - // https://github.com/bibledit/cloud/issues/711 - usfm = filter::strings::collapse_whitespace(usfm); - if (!usfm.empty ()) { - if (filter::strings::unicode_string_is_valid (usfm)) { - string stylesheet = Database_Config_Bible::getEditorStylesheet (bible); - vector book_chapter_text = filter::usfm::usfm_import (usfm, stylesheet); - if (!book_chapter_text.empty()) { - filter::usfm::BookChapterData data = book_chapter_text[0]; - int book_number = data.m_book; - int chapter_number = data.m_chapter; - string chapter_data_to_save = data.m_data; - if (((book_number == book) || (book_number == 0)) && (chapter_number == chapter)) { - // The USFM loaded into the editor. - string ancestor_usfm = getLoadedUsfm2 (webserver_request, bible, book, chapter, unique_id); - // Collect some data about the changes for this user. - string username = webserver_request.session_logic()->currentUser (); - [[maybe_unused]] int oldID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - string oldText = ancestor_usfm; - string newText = chapter_data_to_save; - // Merge if the ancestor is there and differs from what's in the database. - vector conflicts; - // The USFM now on disk. - string server_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - if (!ancestor_usfm.empty ()) { - if (server_usfm != ancestor_usfm) { - // Prioritize the USFM to save. - chapter_data_to_save = filter_merge_run (ancestor_usfm, server_usfm, chapter_data_to_save, true, conflicts); - Database_Logs::log (translate ("Merging and saving chapter.")); - } - } - - // Check on the merge. - filter_merge_add_book_chapter (conflicts, book, chapter); - bible_logic::merge_irregularity_mail ({username}, conflicts); - - // If the USFM on disk is different from the USFM that was sent to the editor, - // email the user, - // suggesting to check if the user's edit came through. - // The rationale is that if Bible text was saved through Send/receive, - // or if another user saved Bible text, - // it's worth to check on this. - // Because the user's editor may not yet have loaded this updated Bible text. - // https://github.com/bibledit/cloud/issues/340 - if (ancestor_usfm != server_usfm) { - bible_logic::recent_save_email (bible, book, chapter, username, ancestor_usfm, server_usfm); - } - - - // Check on write access. - if (access_bible::book_write (webserver_request, string(), bible, book)) { - // Safely store the chapter. - string explanation; - string message = filter::usfm::safely_store_chapter (webserver_request, bible, book, chapter, chapter_data_to_save, explanation); - bible_logic::unsafe_save_mail (message, explanation, username, chapter_data_to_save, book, chapter); - if (message.empty()) { -#ifndef HAVE_CLIENT - // Server configuration: Store details for the user's changes. - int newID = webserver_request.database_bibles()->get_chapter_id (bible, book, chapter); - Database_Modifications database_modifications; - database_modifications.recordUserSave (username, bible, book, chapter, oldID, oldText, newID, newText); - if (sendreceive_git_repository_linked (bible)) { - Database_Git::store_chapter (username, bible, book, chapter, oldText, newText); - } - rss_logic_schedule_update (username, bible, book, chapter, oldText, newText); -#endif - // Store a copy of the USFM loaded in the editor for later reference. - storeLoadedUsfm2 (webserver_request, bible, book, chapter, unique_id); - return locale_logic_text_saved (); - } - return message; - } else { - return translate("No write access"); - } - } else { - Database_Logs::log ("The following data could not be saved and was discarded: " + chapter_data_to_save); - return translate("Passage mismatch"); - } - } - } else { - Database_Logs::log ("The text was not valid Unicode UTF-8. The chapter could not saved and has been reverted to the last good version."); - return translate("Needs Unicode"); - } - } else { - Database_Logs::log ("There was no text. Nothing was saved. The original text of the chapter was reloaded."); - return translate("Nothing to save"); - } - } else { - webserver_request.response_code = 409; - return translate("Checksum error"); - } - } else { - return translate("Nothing to save"); - } - return translate ("Confusing data"); -} diff --git a/editusfm/save.h b/editusfm/save.h deleted file mode 100644 index 48677a304..000000000 --- a/editusfm/save.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string editusfm_save_url (); -bool editusfm_save_acl (Webserver_Request& webserver_request); -std::string editusfm_save (Webserver_Request& webserver_request); diff --git a/email/index.cpp b/email/index.cpp deleted file mode 100644 index ebba70dee..000000000 --- a/email/index.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string email_index_url () -{ - return "email/index"; -} - - -bool email_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::admin ()); -} - - -string email_index (Webserver_Request& webserver_request) -{ - string page; - - Assets_Header header = Assets_Header (translate("Mail"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - page = header.run (); - - Assets_View view; - - // Site name and email. - if (webserver_request.post ["email"] != "") { - bool form_is_valid = true; - string sitename = webserver_request.post ["sitename"]; - string sitemail = webserver_request.post ["sitemail"]; - if (sitemail.length () > 0) { - if (!filter_url_email_is_valid (sitemail)) { - form_is_valid = false; - view.set_variable ("site_name_error", translate("The email address does not appear to be valid")); - } - } - if (form_is_valid) { - Database_Config_General::setSiteMailName (sitename); - Database_Config_General::setSiteMailAddress (sitemail); - view.set_variable ("site_name_success", translate("The name and email address were saved")); - } - } - view.set_variable ("sitename", Database_Config_General::getSiteMailName ()); - view.set_variable ("sitemail", Database_Config_General::getSiteMailAddress ()); - - // Email retrieval. - if (webserver_request.post ["retrieve"] != "") { - string storagehost = webserver_request.post ["storagehost"]; - string storageusername = webserver_request.post ["storageusername"]; - string storagepassword = webserver_request.post ["storagepassword"]; - string storagesecurity = webserver_request.post ["storagesecurity"]; - string storageport = webserver_request.post ["storageport"]; - Database_Config_General::setMailStorageHost (storagehost); - Database_Config_General::setMailStorageUsername (storageusername); - Database_Config_General::setMailStoragePassword (storagepassword); - Database_Config_General::setMailStorageProtocol (storagesecurity); - Database_Config_General::setMailStoragePort (storageport); - string storage_success = translate("The details were saved."); - string storage_error; - int mailcount = email_receive_count (storage_error, true); - if (storage_error.empty ()) { - storage_success.append (" "); - storage_success.append (translate("The account was accessed successfully.")); - storage_success.append (" "); - storage_success.append (translate ("Messages on server:")); - storage_success.append (" "); - storage_success.append (filter::strings::convert_to_string (mailcount)); - storage_success.append ("."); - } - view.set_variable ("storage_success", storage_success); - view.set_variable ("storage_error", storage_error); - } - view.set_variable ("storagehost", Database_Config_General::getMailStorageHost ()); - view.set_variable ("storageusername", Database_Config_General::getMailStorageUsername ()); - view.set_variable ("storagepassword", Database_Config_General::getMailStoragePassword ()); - if (Database_Config_General::getMailStorageProtocol () == "POP3S") view.set_variable ("storagepop3s", R"(selected="selected")"); - view.set_variable ("storageport", Database_Config_General::getMailStoragePort ()); - - // Sending email. - if (webserver_request.post ["send"] != "") { - string sendhost = webserver_request.post ["sendhost"]; - string sendauthentication = webserver_request.post ["sendauthentication"]; - string sendusername = webserver_request.post ["sendusername"]; - string sendpassword = webserver_request.post ["sendpassword"]; - string sendsecurity = webserver_request.post ["sendsecurity"]; - string sendport = webserver_request.post ["sendport"]; - Database_Config_General::setMailSendHost (sendhost); - Database_Config_General::setMailSendUsername (sendusername); - Database_Config_General::setMailSendPassword (sendpassword); - Database_Config_General::setMailSendPort (sendport); - string send_success = translate("The details were saved."); - string send_error; - string send_debug; - string result = email_send (Database_Config_General::getSiteMailAddress(), Database_Config_General::getSiteMailName(), "Test", "This is to check sending email.", true); - if (result.empty()) { - send_success.append (" "); - send_success.append ("For checking sending email, a test email was sent out to the account above:"); - send_success.append (" "); - send_success.append (Database_Config_General::getSiteMailAddress()); - } else { - send_error = result; - } - view.set_variable ("send_success", send_success);; - view.set_variable ("send_error", send_error); - view.set_variable ("send_debug", send_debug); - } - view.set_variable ("sendhost", Database_Config_General::getMailSendHost ()); - view.set_variable ("sendusername", Database_Config_General::getMailSendUsername ()); - view.set_variable ("sendpassword", Database_Config_General::getMailSendPassword ()); - view.set_variable ("sendport", Database_Config_General::getMailSendPort ()); - - page += view.render ("email", "index"); - - page += assets_page::footer (); - - return page; -} - - -/* - -The more recent versions of the VMime library can access Gmail in a more secure manner than libcurl can. -The VMime library also can extract the plain text message easily, -in case the message consists of various parts. -If necessary, the Cloud version of Bibledit can use this VMime library -for sending, receiving and processing email. - -*/ diff --git a/email/index.h b/email/index.h deleted file mode 100644 index d4d79d0e1..000000000 --- a/email/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string email_index_url (); -bool email_index_acl (Webserver_Request& webserver_request); -std::string email_index (Webserver_Request& webserver_request); diff --git a/email/receive.cpp b/email/receive.cpp deleted file mode 100644 index 7092956c8..000000000 --- a/email/receive.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#ifndef HAVE_CLIENT -#include -#endif -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void email_receive () -{ -#ifdef HAVE_CLOUD - // Bail out when the mail storage host has not been defined, rather than giving an error message. - if (Database_Config_General::getMailStorageHost () == "") return; - - // One email receiver runs at a time. - if (config_globals_mail_receive_running) return; - config_globals_mail_receive_running = true; - // Once this flag is set, the coder should be careful not to exit from the function - // without clearin this flag. - - // Email count. - string error; - int emailcount = email_receive_count (error); - // Messages start at number 1 instead of 0. - for (int i = 1; i <= emailcount; i++) { - - Webserver_Request webserver_request; - Confirm_Worker confirm_worker = (webserver_request); - Notes_Logic notes_logic (webserver_request); - - error.clear (); - string message = email_receive_message (error); - if (error.empty ()) { - - // Extract "from" and subject, and clean body. - string from; - string subject; - string body; - filter_mail_dissect (message, from, subject, body); - - Database_Logs::log ("Processing email from " + from + " with subject " + subject); - - if (confirm_worker.handleEmail (from, subject, body)) { - } - else if (notes_logic.handleEmailComment (from, subject, body)) { - } - else if (notes_logic.handleEmailNew (from, subject, body)) { - } - else { - Database_Logs::log ("Could not allocate email from " + from + ", subject " + subject); - Database_Logs::log (body); - } - - } else { - Database_Logs::log ("Error retrieving mail: " + error); - } - - } - - config_globals_mail_receive_running = false; -#endif -} - - -struct cstring { - char *ptr; - size_t len; -}; - - -void init_string (cstring *s) { - s->len = 0; - s->ptr = static_cast(malloc(s->len+1)); - s->ptr[0] = '\0'; -} - - -size_t writefunc(void *ptr, size_t size, size_t nmemb, cstring *s) -{ - size_t new_len = s->len + size*nmemb; - s->ptr = static_cast(realloc (s->ptr, new_len+1)); - memcpy(s->ptr+s->len, ptr, size*nmemb); - s->ptr[new_len] = '\0'; - s->len = new_len; - return size*nmemb; -} - - -string url () -{ - string url; - const char * pop3s = "POP3S"; - if (Database_Config_General::getMailStorageProtocol() == pop3s) url.append (pop3s); - else url.append ("pop3"); - url.append ("://"); - url.append (Database_Config_General::getMailStorageHost ()); - url.append (":"); - url.append (Database_Config_General::getMailStoragePort ()); - return url; -} - - -// Returns how many emails are waiting in the mail storage host's POP3 email inbox. -int email_receive_count (string& error, bool verbose) -{ -#ifdef HAVE_CLIENT - error = "Not implemented with embedded http library"; - if (verbose) {} - return 0; -#endif - -#ifdef HAVE_CLOUD - CURL *curl; - CURLcode res = CURLE_OK; - - cstring s; - init_string (&s); - - curl = curl_easy_init (); - - curl_easy_setopt (curl, CURLOPT_USERNAME, Database_Config_General::getMailStorageUsername ().c_str()); - curl_easy_setopt (curl, CURLOPT_PASSWORD, Database_Config_General::getMailStoragePassword ().c_str()); - - curl_easy_setopt (curl, CURLOPT_URL, url ().c_str()); - - curl_easy_setopt (curl, CURLOPT_USE_SSL, static_cast(CURLUSESSL_ALL)); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0); - - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefunc); - - curl_easy_setopt (curl, CURLOPT_WRITEDATA, &s); - - if (verbose) { - curl_easy_setopt (curl, CURLOPT_DEBUGFUNCTION, filter_url_curl_debug_callback); - curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); - } - - // Some servers need this validation. - curl_easy_setopt (curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); - - filter_url_curl_set_timeout (curl); - - res = curl_easy_perform (curl); - - int mailcount = 0; - - if (res == CURLE_OK) { - if (s.ptr) { - string response = s.ptr; - response = filter::strings::trim (response); - mailcount = static_cast(filter::strings::explode (response, '\n').size()); - } - } else { - error = curl_easy_strerror (res); - } - - if (s.ptr) free (s.ptr); - - curl_easy_cleanup (curl); - - return mailcount; -#endif -} - - -string email_receive_message (string& error) -{ -#ifdef HAVE_CLIENT - error = "Not implemented with embedded http library"; - return ""; -#endif - -#ifdef HAVE_CLOUD - CURL *curl; - CURLcode res = CURLE_OK; - - cstring s; - init_string (&s); - - curl = curl_easy_init (); - - curl_easy_setopt (curl, CURLOPT_USERNAME, Database_Config_General::getMailStorageUsername ().c_str()); - curl_easy_setopt (curl, CURLOPT_PASSWORD, Database_Config_General::getMailStoragePassword ().c_str()); - - string message_url = url () + "/1"; - curl_easy_setopt (curl, CURLOPT_URL, message_url.c_str()); - - curl_easy_setopt (curl, CURLOPT_USE_SSL, static_cast(CURLUSESSL_ALL)); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0); - - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefunc); - - curl_easy_setopt (curl, CURLOPT_WRITEDATA, &s); - - // Some servers need this validation. - curl_easy_setopt (curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); - - filter_url_curl_set_timeout (curl); - - res = curl_easy_perform (curl); - - string body {}; - - if (res == CURLE_OK) { - if (s.ptr) body = s.ptr; - } else { - error = curl_easy_strerror (res); - } - - // Set the DELE command. - curl_easy_setopt (curl, CURLOPT_CUSTOMREQUEST, "DELE"); - - // Do not perform a transfer as DELE returns no data. - curl_easy_setopt (curl, CURLOPT_NOBODY, 1L); - - // Perform the custom request. - res = curl_easy_perform(curl); - - if (s.ptr) free (s.ptr); - - curl_easy_cleanup (curl); - - return body; -#endif -} diff --git a/email/receive.h b/email/receive.h deleted file mode 100644 index 11d1c111f..000000000 --- a/email/receive.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -void email_receive (); -int email_receive_count (std::string& error, bool verbose = false); -std::string email_receive_message (std::string& error); diff --git a/email/send.cpp b/email/send.cpp deleted file mode 100644 index 3c792ba01..000000000 --- a/email/send.cpp +++ /dev/null @@ -1,408 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_CLOUD -#include -#endif -#include -#include -#include -#include -#include -#include -using namespace std; - - -void email_send () -{ - // No more than one email send process to run simultaneously. - if (config_globals_mail_send_running) return; - config_globals_mail_send_running = true; - - // The databases involved. - Webserver_Request webserver_request; - Database_Mail database_mail (webserver_request); - Database_Users database_users; - - vector mails = database_mail.getMailsToSend (); - for (auto id : mails) { - - // Get all details of the mail. - Database_Mail_Item details = database_mail.get (id); - string username = details.username; - string email = database_users.get_email (username); - string subject = details.subject; - string body = details.body; - -#ifdef HAVE_CLIENT - - // On a client, set the email to the username before sending the email to the Cloud for further distribution. - email = username; - -#else - - // In the Cloud, if this username was not found, it could be that the email was addressed to a non-user, - // and that the To: address was actually contained in the username. - if (email.empty()) { - email = username; - username.clear(); - } - - // In the Cloud, if the email address validates, ok, else remove this mail from the queue and log the action. - if (!filter_url_email_is_valid (email)) { - database_mail.erase (id); - Database_Logs::log ("Email to " + email + " was deleted because of an invalid email address"); - continue; - } - -#endif - - // If there had been a crash while sending an email, - // log this email and erase it. - // Do not attempt to send it again as it would cause the crash again in an endless loop. - if (config_globals_has_crashed_while_mailing) { - database_mail.erase (id); - Database_Logs::log ("Email to " + email + " with subject \"" + subject + "\" was deleted because it has caused a crash"); - config_globals_has_crashed_while_mailing = false; - continue; - } - - // Send the email. - string result = email_send (email, username, subject, body); - if (result.empty ()) { - database_mail.erase (id); - stringstream ss; - ss << "Email to " << email << " with subject " << quoted(subject) << " was "; - result = ss.str(); -#ifdef HAVE_CLOUD - result.append ("sent successfully"); -#endif -#ifdef HAVE_CLIENT - result.append ("queued for sending through the Cloud"); -#endif - Database_Logs::log (result, Filter_Roles::manager ()); - } else { - // Special handling of cases that the smart host denied login. - bool login_denied = result == "Login denied"; - // Write result to logbook. - result.insert (0, "Email to " + email + " could not be sent - reason: "); - Database_Logs::log (result, Filter_Roles::manager ()); - // If the login was denied, then postpone all emails queued for sending, - // rather than trying to send them all, and have them all cause a 'login denied' error. - if (login_denied) { - vector ids = database_mail.getAllMails (); - for (auto id2 : ids) { - database_mail.postpone (id2); - } - Database_Logs::log ("Postponing sending " + filter::strings::convert_to_string (ids.size()) + " emails", Filter_Roles::manager ()); - break; - } else { - database_mail.postpone (id); - } - } - } - - config_globals_mail_send_running = false; -} - - -static vector payload_text; - - -struct upload_status { - size_t lines_read; -}; - - -#ifdef HAVE_CLIENT -#else -static size_t payload_source (void *ptr, size_t size, size_t nmemb, void *userp) -{ - upload_status *upload_ctx = static_cast (userp); - const char *data; - - if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) { - return 0; - } - - if (upload_ctx->lines_read >= payload_text.size()) { - return 0; - } - - data = payload_text[upload_ctx->lines_read].c_str(); - - size_t len = strlen(data); - memcpy(ptr, data, len); - upload_ctx->lines_read++; - - return len; -} -#endif - - -// Sends the email as specified by the parameters. -// If all went well, it returns an empty string. -// In case of failure, it returns the error message. -string email_send ([[maybe_unused]] string to_mail, - string to_name, - string subject, - string body, - [[maybe_unused]] bool verbose) -{ - // Truncate huge emails because libcurl crashes on it. - size_t length = body.length (); - if (length > 100000) { - body = "This email was " + filter::strings::convert_to_string (length) + " bytes long. It was too long, and could not be sent."; - } - - // Deal with empty subject. - if (subject.empty ()) subject = translate ("Bibledit"); - -#ifdef HAVE_CLIENT - - if (!client_logic_client_enabled ()) { - return ""; - } - - Webserver_Request webserver_request; - Sync_Logic sync_logic (webserver_request); - - map post; - post ["n"] = filter::strings::bin2hex (to_name); - post ["s"] = subject; - post ["b"] = body; - - string address = Database_Config_General::getServerAddress (); - int port = Database_Config_General::getServerPort (); - string url = client_logic_url (address, port, sync_mail_url ()); - - string error; - string response = sync_logic.post (post, url, error); - - if (!error.empty ()) { - Database_Logs::log ("Failure sending email: " + error, Filter_Roles::guest ()); - } - - return error; - -#else - - string from_mail = Database_Config_General::getSiteMailAddress (); - string from_name = Database_Config_General::getSiteMailName (); - - CURL *curl; - CURLcode res = CURLE_OK; - curl_slist * recipients {nullptr}; - upload_status upload_ctx; - - upload_ctx.lines_read = 0; - - int seconds = filter::date::seconds_since_epoch (); - payload_text.clear(); - string payload; - payload = "Date: " + filter::strings::convert_to_string (filter::date::numerical_year (seconds)) + "/" + filter::strings::convert_to_string (filter::date::numerical_month (seconds)) + "/" + filter::strings::convert_to_string (filter::date::numerical_month_day (seconds)) + " " + filter::strings::convert_to_string (filter::date::numerical_hour (seconds)) + ":" + filter::strings::convert_to_string (filter::date::numerical_minute (seconds)) + "\n"; - payload_text.push_back (payload); - payload = "To: <" + to_mail + "> " + to_name + "\n"; - payload_text.push_back (payload); - payload = "From: <" + from_mail + "> " + from_name + "\n"; - payload_text.push_back (payload); - string site = from_mail; - size_t pos = site.find ("@"); - if (pos != std::string::npos) site = site.substr (pos); - payload = "Message-ID: <" + md5 (filter::strings::convert_to_string (filter::strings::rand (0, 1000000))) + site + ">\n"; - payload_text.push_back (payload); - payload = "Subject: " + subject + "\n"; - payload_text.push_back (payload); - payload_text.push_back ("Mime-version: 1.0\n"); - payload_text.push_back (R"(Content-Type: multipart/alternative; boundary="------------010001060501040600060905")"); - // Empty line to divide headers from body, see RFC5322. - payload_text.push_back ("\n"); - // Plain text part. - payload_text.push_back ("--------------010001060501040600060905\n"); - payload_text.push_back ("Content-Type: text/plain; charset=utf-8\n"); - payload_text.push_back ("Content-Transfer-Encoding: 7bit\n"); - payload_text.push_back ("\n"); - payload_text.push_back ("Plain text message.\n"); - payload_text.push_back ("--------------010001060501040600060905\n"); - payload_text.push_back ("Content-Type: text/html; charset=\"utf-8\"\n"); - payload_text.push_back ("Content-Transfer-Encoding: 8bit\n"); - payload_text.push_back ("\n"); - payload_text.push_back ("\n"); - payload_text.push_back ("\n"); - payload_text.push_back ("\n"); - payload_text.push_back ("\n"); - payload_text.push_back ("\n"); - payload_text.push_back ("\n"); - payload_text.push_back ("\n"); - vector bodylines = filter::strings::explode (body, '\n'); - for (auto & line : bodylines) { - if (filter::strings::trim (line).empty ()) payload_text.push_back (" "); - else payload_text.push_back (line); - payload_text.push_back ("\n"); - } - payload_text.push_back (""); - payload_text.push_back ("\n"); - // Empty line. - payload_text.push_back ("\n"); - - curl = curl_easy_init(); - /* Set username and password */ - string username = Database_Config_General::getMailSendUsername(); - string password = Database_Config_General::getMailSendPassword(); - curl_easy_setopt(curl, CURLOPT_USERNAME, username.c_str()); - curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str()); - - /* This is the URL for your mailserver. Note the use of port 587 here, - * instead of the normal SMTP port (25). Port 587 is commonly used for - * secure mail submission (see RFC4403), but you should use whatever - * matches your server configuration. */ - string smtp = "smtp://"; - smtp.append (Database_Config_General::getMailSendHost()); - smtp.append (":"); - string port = Database_Config_General::getMailSendPort(); - smtp.append (port); - curl_easy_setopt(curl, CURLOPT_URL, smtp.c_str()); - - /* In this example, we'll start with a plain text connection, and upgrade - * to Transport Layer Security (TLS) using the STARTTLS command. Be careful - * of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer - * will continue anyway - see the security discussion in the libcurl - * tutorial for more details. */ - if (port != "25") curl_easy_setopt(curl, CURLOPT_USE_SSL, static_cast(CURLUSESSL_ALL)); - - /* If your server doesn't have a valid certificate, then you can disable - * part of the Transport Layer Security protection by setting the - * CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false). - */ - // curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - // curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); - /* - * That is, in general, a bad idea. It is still better than sending your - * authentication details in plain text though. - * Instead, you should get the issuer certificate (or the host certificate - * if the certificate is self-signed) and add it to the set of certificates - * that are known to libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See - * docs/SSLCERTS for more information. */ - //curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem"); - - /* Note that this option isn't strictly required, omitting it will result in - * libcurl sending the MAIL FROM command with empty sender data. All - * autoresponses should have an empty reverse-path, and should be directed - * to the address in the reverse-path which triggered them. Otherwise, they - * could cause an endless loop. See RFC 5321 Section 4.5.5 for more details. - */ - curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from_mail.c_str()); - - /* Add the recipients, in this particular case they correspond to the - * To: addressee in the header, but they could be any kind of recipient. */ - recipients = curl_slist_append(recipients, to_mail.c_str()); - curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients); - - /* We're using a callback function to specify the payload (the headers and - * body of the message). You could just use the CURLOPT_READDATA option to - * specify a FILE pointer to read from. */ - curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source); - curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx); - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - - // Since the traffic will be encrypted, it is very useful to turn on debug - // information within libcurl to see what is happening during the transfer. - if (verbose) { - curl_easy_setopt (curl, CURLOPT_DEBUGFUNCTION, filter_url_curl_debug_callback); - curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); - } - - // Timeout values. - filter_url_curl_set_timeout (curl); - - /* Send the message */ - res = curl_easy_perform(curl); - - /* Check for errors */ - string result; - if (res != CURLE_OK) result = curl_easy_strerror (res); - - /* Free the list of recipients */ - curl_slist_free_all(recipients); - - /* Always cleanup */ - curl_easy_cleanup(curl); - - return result; -#endif -} - - -void email_schedule (string to, string subject, string body, int time) -{ - // Schedule the mail for sending. - Webserver_Request webserver_request; - Database_Mail database_mail (webserver_request); - database_mail.send (to, subject, body, time); - // Schedule a task to send the scheduled mail right away. - tasks_logic_queue (SENDEMAIL); -} - - -// If the email sending and receiving has not yet been (completely) set up, -// it returns information about that. -// If everything's OK, it returns nothing. -string email_setup_information (bool require_send, bool require_receive) -{ -#ifdef HAVE_CLIENT - (void) require_send; - (void) require_receive; -#endif -#ifdef HAVE_CLOUD - bool incomplete = false; - if (Database_Config_General::getSiteMailName ().empty ()) incomplete = true; - if (Database_Config_General::getSiteMailAddress ().empty ()) incomplete = true; - if (require_receive) { - if (Database_Config_General::getMailStorageHost ().empty ()) incomplete = true; - if (Database_Config_General::getMailStorageUsername ().empty ()) incomplete = true; - if (Database_Config_General::getMailStoragePassword ().empty ()) incomplete = true; - if (Database_Config_General::getMailStorageProtocol ().empty ()) incomplete = true; - if (Database_Config_General::getMailStoragePort ().empty ()) incomplete = true; - } - if (require_send) { - if (Database_Config_General::getMailSendHost ().empty ()) incomplete = true; - if (Database_Config_General::getMailSendUsername ().empty ()) incomplete = true; - if (Database_Config_General::getMailSendPassword ().empty ()) incomplete = true; - if (Database_Config_General::getMailSendPort ().empty ()) incomplete = true; - } - if (incomplete) { - string msg1 = translate ("Cannot send email yet."); - string msg2 = translate ("The emailer is not yet set up."); - return msg1 + R"( )" + msg2 + ""; - } -#endif - return string(); -} diff --git a/email/send.h b/email/send.h deleted file mode 100644 index 5d4909d7e..000000000 --- a/email/send.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -void email_send (); -std::string email_send (std::string to_mail, std::string to_name, std::string subject, std::string body, bool verbose = false); -void email_schedule (std::string to, std::string subject, std::string body, int time = 0); -std::string email_setup_information (bool require_send, bool require_receive); diff --git a/esword/text.cpp b/esword/text.cpp deleted file mode 100644 index a137c27bd..000000000 --- a/esword/text.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Class for creating e-Sword documents. - - -Esword_Text::Esword_Text (string bible) -{ - currentBook = 0; - currentChapter = 0; - currentVerse = 0; - currentText = ""; - bible = database_sqlite_no_sql_injection (bible); - sql.push_back ("PRAGMA foreign_keys=OFF;"); - sql.push_back ("PRAGMA synchronous=OFF;"); - sql.push_back ("CREATE TABLE Details (Description NVARCHAR(255), Abbreviation NVARCHAR(50), Comments TEXT, Version INT, Font NVARCHAR(50), Unicode BOOL, RightToLeft BOOL, OT BOOL, NT BOOL, Apocrypha BOOL, Strong BOOL);"); - sql.push_back ("INSERT INTO Details VALUES ('" + bible + "', '" + bible + "', '" + bible + "', 1, 'UNICODE', 1, 0, 1, 1, 0, 0);"); - sql.push_back ("CREATE TABLE Bible (Book INT, Chapter INT, Verse INT, Scripture TEXT);"); -} - - -void Esword_Text::flushCache () -{ - string text = filter::strings::trim (currentText); - if (!text.empty ()) { - string unicode; - size_t length = filter::strings::unicode_string_length (text); - for (size_t pos = 0; pos < length; pos++) { - string s = filter::strings::unicode_string_substr (text, pos, 1); - int codepoint = filter::strings::unicode_string_convert_to_codepoint (s); - unicode.append ("\\u" + filter::strings::convert_to_string (codepoint) + "?"); - } - int book = currentBook; - int chapter = currentChapter; - int verse = currentVerse; - string statement = "INSERT INTO Bible VALUES (" + filter::strings::convert_to_string (book) + ", " + filter::strings::convert_to_string (chapter) + ", " + filter::strings::convert_to_string (verse) + ", '" + unicode + "');"; - sql.push_back (statement); - } - currentText.clear (); -} - - -void Esword_Text::newBook (int book) -{ - flushCache (); - currentBook = book; - newChapter (0); -} - - -void Esword_Text::newChapter (int chapter) -{ - flushCache (); - currentChapter = chapter; - currentVerse = 0; -} - - -void Esword_Text::newVerse (int verse) -{ - flushCache (); - currentVerse = verse; -} - - -void Esword_Text::add_text (string text) -{ - if (text != "") currentText += text; -} - - -// This finalizes the SQL script. -void Esword_Text::finalize () -{ - flushCache (); - // Add the final SQL statements. - sql.push_back ("CREATE INDEX BookChapterVerseIndex ON Bible (Book, Chapter, Verse);"); -} - - -// This creates the eSword module. -// $filename: the name of the file to create. -void Esword_Text::createModule (string filename) -{ - flushCache (); - sqlite3 * db = database_sqlite_connect_file (filename); - for (string statement : sql) { - database_sqlite_exec (db, statement); - } - database_sqlite_disconnect (db); -} - - -vector Esword_Text::get_sql () -{ - return sql; -} - diff --git a/esword/text.h b/esword/text.h deleted file mode 100644 index 5c4f8300e..000000000 --- a/esword/text.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Esword_Text -{ -public: - Esword_Text (std::string bible); - void flushCache (); - void newBook (int book); - void newChapter (int chapter); - void newVerse (int verse); - void add_text (std::string text); - void finalize (); - void createModule (std::string filename); - std::vector get_sql (); -private: - int currentBook {0}; - int currentChapter {0}; - int currentVerse {0}; - std::string currentText {}; - std::vector sql {}; // Contains the generated SQL. -}; diff --git a/executable/bibledit.cpp b/executable/bibledit.cpp deleted file mode 100644 index 091e07a5d..000000000 --- a/executable/bibledit.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#ifdef HAVE_LIBPROC -#include -#endif -#ifdef HAVE_EXECINFO -#include -#endif -#include -#ifdef HAVE_WINDOWS -#include -#endif -#include -using namespace std; - -// Fix for architecture hurd-i386 that does not define MAXPATHLEN. -#ifndef MAXPATHLEN -#define MAXPATHLEN 1024 -#endif - - -static void sigint_handler ([[maybe_unused]] int s) -{ - // When pressing Ctrl-C, the system outputs a "^C". - // It is cleaner to write a new line after that. - std::cout << std::endl; - // Initiate server(s) shutdown. - bibledit_stop_library (); -} - - -static string backtrace_path () -{ - return filter_url_create_root_path ({filter_url_temp_dir (), "backtrace.txt"}); -} - - -#ifdef HAVE_EXECINFO -// http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes -// To add linker flag -rdynamic is essential. -[[ noreturn ]] -static void sigsegv_handler ([[maybe_unused]] int sig) -{ - // Information. - std::cout << "Segmentation fault, writing backtrace to " << backtrace_path () << std::endl; - - // Get void*'s for all entries on the stack - void *array[20]; - int size = backtrace (array, 20); - - // Write entries to file (to be logged next time bibledit starts). - int fd = open (backtrace_path ().c_str (), O_WRONLY|O_CREAT, 0666); - backtrace_symbols_fd (array, size, fd); - close (fd); - - exit (1); -} -#endif - - -#ifdef HAVE_WINDOWS -void my_invalid_parameter_handler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) { - wstring wexpression(expression); - string sexpression(wexpression.begin(), wexpression.end()); - wstring wfunction(function); - string sfunction(wfunction.begin(), wfunction.end()); - wstring wfile (file); - string sfile(wfile.begin(), wfile.end()); - Database_Logs::log ("Invalid parameter detected in function " + sfunction + " in file " + sfile + " line " + filter::strings::convert_to_string ((size_t)line) + " expression " + sexpression + "."); -} -#endif - - -int main ([[maybe_unused]] int argc, [[maybe_unused]] char **argv) -{ - // Ctrl-C initiates a clean shutdown sequence, so there's no memory leak. - signal (SIGINT, sigint_handler); - - -#ifdef HAVE_EXECINFO - // Handler for logging segmentation fault. - signal (SIGSEGV, sigsegv_handler); -#endif - - -#ifdef HAVE_WINDOWS - // Set our own invalid parameter handler for on Windows. - _set_invalid_parameter_handler(my_invalid_parameter_handler); - // Disable the message box for assertions on Windows. - _CrtSetReportMode(_CRT_ASSERT, 0); -#endif - - - // Get the executable path and derive the document root from it. - string webroot {}; -#ifndef HAVE_WINDOWS - { - // The following works on Linux but not on macOS: - char *linkname = static_cast (malloc (256)); - memset (linkname, 0, 256); // valgrind uninitialized value(s) - [[maybe_unused]] auto result = readlink ("/proc/self/exe", linkname, 256); - webroot = filter_url_dirname (linkname); - free (linkname); - } -#endif -#ifdef HAVE_LIBPROC - { - // The following works on Linux and on macOS: - pid_t pid = getpid (); - char pathbuf [2048]; - int ret = proc_pidpath (pid, pathbuf, sizeof (pathbuf)); - if (ret > 0 ) { - webroot = filter_url_dirname (pathbuf); - } - } -#endif -#ifdef HAVE_WINDOWS - { - // Getting the web root on Windows. - // The following gets the path to the server.exe. - // char buf[MAX_PATH] = { 0 }; - // DWORD ret = GetModuleFileNameA(nullptr, buf, MAX_PATH); - // While developing, the .exe runs in folder Debug or Release, and not in the expected folder. - // Therefore it's better to take the path of the current directory. - wchar_t buffer[MAX_PATH]; - GetCurrentDirectory (MAX_PATH, buffer); - char chars[MAX_PATH]; - char def_char = ' '; - WideCharToMultiByte (CP_ACP, 0, buffer, -1, chars, MAX_PATH, &def_char, nullptr); - webroot = chars; - } -#endif -#ifdef HAVE_CLOUD - // The following is for the Cloud configuration only: - { - // Get home folder and working directory. - string home_folder; - const char * home_env_ptr = getenv ("HOME"); - if (home_env_ptr) home_folder = home_env_ptr; - string workingdirectory; - char cwd [MAXPATHLEN]; - if (getcwd(cwd, sizeof(cwd)) != nullptr) workingdirectory = cwd; - // If the web root folder, derived from the binary, is the same as the current directory, - // it means that the binary is started from a Cloud installation in user space. - // The web root folder is okay as it is. - if (webroot != workingdirectory) { - // If the web root is the home folder, it should be updated, - // because it is undesirable to have all the data in the home folder. - // If the web root is the package prefix, it should be updated, - // because it now runs the binary installed in /usr/bin. - if ((webroot == home_folder) || (webroot.find (PACKAGE_PREFIX_DIR) == 0)) { - // Update web root to ~/bibledit or ~/bibledit-cloud. - webroot = filter_url_create_path ({home_folder, filter_url_basename (PACKAGE_DATA_DIR)}); - } - } - } -#endif - // The $ make install will copy the data files to /usr/share/bibledit. - // That is the package data directory. - // Bibledit will copy this to the webroot upon first run for a certain version number. - // If this directory is empty, it won't copy anything. - // That would be okay if it runs in a user folder like ~/bibledit or similar. - // Read the package directory from config.h. - bibledit_initialize_library (PACKAGE_DATA_DIR, webroot.c_str()); - - - // Start the Bibledit library. - bibledit_start_library (); - bibledit_log ("The server started"); - std::cout << "Listening on http://localhost:" << config::logic::http_network_port () << std::endl; - std::cout << "Press Ctrl-C to quit" << std::endl; - - - // Log possible backtrace from a previous crash. - string backtrace = filter_url_file_get_contents (backtrace_path ()); - filter_url_unlink (backtrace_path ()); - if (!backtrace.empty ()) { - Database_Logs::log ("Backtrace of the last segmentation fault:"); - vector lines = filter::strings::explode (backtrace, '\n'); - for (auto & line : lines) { - Database_Logs::log (line); - // Set a flag if the backtrace appears to be caused while sending email. - if (line.find ("email_send") != std::string::npos) config_globals_has_crashed_while_mailing = true; - } - } - - - // Keep running till Bibledit stops or gets interrupted. - while (bibledit_is_running ()) { } - - - // Shut the library down. - bibledit_shutdown_library (); - - - // Done. - return EXIT_SUCCESS; -} diff --git a/executable/bibledit.h b/executable/bibledit.h deleted file mode 100644 index 660108917..000000000 --- a/executable/bibledit.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -int main (int argc, char **argv); diff --git a/executable/generate.cpp b/executable/generate.cpp deleted file mode 100644 index 2f722cb4a..000000000 --- a/executable/generate.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -int main (int argc, char **argv) -{ - std::cout << "Data Generator " << config::logic::version () << std::endl; - - if (argc < 2) { - std::cerr << "Please pass the document root folder as the first argument" << std::endl; - return EXIT_FAILURE; - } - config_globals_document_root = argv [1]; - std::cout << "Document root folder: " << config_globals_document_root << std::endl; - if (!file_or_dir_exists (config_globals_document_root)) { - std::cerr << "Please pass an existing document root folder" << std::endl; - return EXIT_FAILURE; - } - - if (argc < 3) { - std::cerr << "Please pass a command as the second argument" << std::endl; - return EXIT_FAILURE; - } - string command = argv [2]; - - string i18n_command {"i18n"}; - string locale_command {"locale"}; - string sample_bible_command {"samplebible"}; - string mappings_command {"mappings"}; - string versifications_command {"versifications"}; - string morphhb_command {"morphhb"}; - string oshb_command {"oshb"}; - string stylesheet_command {"styles"}; - string abbott_smith_command {"abbott-smith"}; - - if (command == i18n_command) { - - std::cout << "Translating untranslated GUI texts through Google Translate" << std::endl; - i18n_logic_augment_via_google_translate (); - - } else if (command == locale_command) { - - std::cout << "Generating locale databases from the *.po files in folder locale" << std::endl; - setup_generate_locale_databases (true); - - } else if (command == sample_bible_command) { - - std::cout << "Generating the sample Bible" << std::endl; - demo_prepare_sample_bible (); - - } else if (command == mappings_command) { - - std::cout << "Generating the verse mappings database" << std::endl; - setup_generate_verse_mapping_databases (); - - } else if (command == versifications_command) { - - std::cout << "Generating the versifications database" << std::endl; - setup_generate_versification_databases (); - - } else if (command == morphhb_command) { - - std::cout << "Parsing Open Scriptures Hebrew with limited morphology into the morphhb database" << std::endl; - sources_morphhb_parse (); - - } else if (command == oshb_command) { - - std::cout << "Parsing Open Scriptures Hebrew Bible with morphology into the oshb database" << std::endl; - sources_oshb_parse (); - - } else if (command == stylesheet_command) { - - std::cout << "Parsing style values and importing them into the default styles" << std::endl; - sources_styles_parse (); - - } else if (command == abbott_smith_command) { - - std::cout << "Parsing Abbott-Smith's Manual Greek Lexicon into the abbottsmith database" << std::endl; - sources_abbott_smith_parse (); - - } else { - - std::cerr << "This command is unknown" << std::endl; - std::cerr << "The following commands are supported:" << std::endl; - std::cerr << i18n_command << ": Translate untranslated GUI texts through Google Translate" << std::endl; - std::cerr << locale_command << ": Generate locale databases from the *.po files in folder locale" << std::endl; - std::cerr << sample_bible_command << ": Generate the sample Bible" << std::endl; - std::cerr << mappings_command << ": Generate the default verse mappings database" << std::endl; - std::cerr << versifications_command << ": Generate the default versifications database" << std::endl; - std::cerr << morphhb_command << ": Parse Open Scriptures Hebrew with limited morphology into the morphhb database" << std::endl; - std::cerr << oshb_command << ": Parse Open Scriptures Hebrew Bible with morphology into the oshb database" << std::endl; - std::cerr << stylesheet_command << ": Parse style values and import them into the default styles" << std::endl; - std::cout << abbott_smith_command << ": Parse Abbott-Smith's Manual Greek Lexicon into the abbottsmith database" << std::endl; - - return EXIT_FAILURE; - - } - - return EXIT_SUCCESS; -} diff --git a/executable/generate.h b/executable/generate.h deleted file mode 100644 index 660108917..000000000 --- a/executable/generate.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -int main (int argc, char **argv); diff --git a/export/bibledropbox.cpp b/export/bibledropbox.cpp deleted file mode 100644 index 2cf664c1e..000000000 --- a/export/bibledropbox.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_bibledropbox (string user, string bible) -{ - Webserver_Request request; - Database_Bibles database_bibles; - Database_Users database_users; - - - string tag = translate ("Submit to the Bible Drop Box") + ": "; - Database_Logs::log (tag + bible, Filter_Roles::translator ()); - - - // Temporal USFM directory. - string directory = filter_url_tempfile (); - filter_url_mkdir (directory); - - - // Take the USFM from the Bible database. - // Generate one USFM file per book. - vector books = database_bibles.get_books (bible); - for (auto book : books) { - - - // The USFM data of the current book. - string bookdata; - - - // Collect the USFM for all chapters in this book. - vector chapters = database_bibles.get_chapters (bible, book); - for (auto chapter : chapters) { - // Get the USFM code for the current chapter. - string usfm = database_bibles.get_chapter (bible, book, chapter); - usfm = filter::strings::trim (usfm); - // Add the chapter USFM code to the book's USFM code. - bookdata.append (usfm); - bookdata.append ("\n"); - } - - - // The filename for the USFM for this book. - string filename = export_logic::base_book_filename (bible, book); - string path = filter_url_create_path ({directory, filename + ".usfm"}); - - - // Save. - filter_url_file_put_contents (path, bookdata); - } - - - // Compress USFM files into one zip file. - string zipfile = filter_url_create_path ({directory, export_logic::base_book_filename (bible, 0) + ".zip"}); - - string archive = filter_archive_zip_folder (directory); - filter_url_rename (archive, zipfile); - - // Here is the submission form as of July 2018: - /* -
    -

    Your name:

    -

    Your email address:

    -

    Language/Project name:

    -

    Main task (please check one or both):

    -

    (STILL COMING) Thoroughly CHECK the submitted Bible

    -

            The following help the software to know your expectations (optional): -
              New Testament is finished: - -
              Old Testament is finished: - -
              Deuterocanon books are finished: - -
              All submitted books are finished: - -

    -

    CONVERT/EXPORT the submitted Bible -
            e.g., to USFM, USX, OSIS, Sword module, HTML, etc., etc.

    -

            The following exports use heavy processing so have to be explicitly requested: -
              PhotoBible - export (for cheap, non-Java cellphones): - -
              ODF - exports (for LibreOffice, OpenOffice, etc.): - -
              PDF - exports (via TeX or lout): - -

    -

    What is your main goal here (optional, but helps us):

    -

    Zip file containing your Bible file(s) (preferably in UTF-8 encoding):

    -

    Text file containing your Bible metadata (recommended):

    -

    I have the authority to submit this data:

    -

    -
    - */ - - - // Bible Drop Box submission URL. - string url = "http://freely-given.org/Software/BibleDropBox/SubmitAction.phtml"; - - - // Form values to POST. - map post; - post ["nameLine"] = user + " through " PACKAGE_STRING; - post ["emailLine"] = database_users.get_email (user); - post ["projectLine"] = bible; - post ["permission"] = "Yes"; - post ["goalLine"] = translate ("Bible translation through Bibledit"); - post ["doExports"] = "Yes"; - // Just one request: Is it possible to make the Bibledit submission system default to turning off the three check-boxes for the tasks that take heavy processing on The Bible Drop Box: PhotoBible, ODFs using the Python interface to LibreOffice (which is slow compared to the Pathway method of creating the XML files directly), and PDF exports (via TeX). If the user is only after, say a Sword module, it's quite a heavy cost to wastefully produce these other exports. - //post ["photoBible"] = "Yes"; - //post ["odfs"] = "Yes"; - //post ["pdfs"] = "Yes"; - post ["submit"] = "Submit"; - - // Submission and response. - string error; - string response = filter_url_http_upload (url, post, zipfile, error); - if (!error.empty ()) { - Database_Logs::log (tag + error, Filter_Roles::translator ()); - email_schedule (user, "Error submitting to the Bible Drop Box", error); - } - size_t pos = response.find (""); - if (pos != std::string::npos) { - response.insert (pos + 6, R"()"); - } - email_schedule (user, "Result of your submission to the Bible Drop Box", response); - - - // Done. - Database_Logs::log (tag + translate("Ready"), Filter_Roles::translator ()); -} diff --git a/export/bibledropbox.h b/export/bibledropbox.h deleted file mode 100644 index 5247b7b6f..000000000 --- a/export/bibledropbox.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_bibledropbox (std::string user, std::string bible); diff --git a/export/esword.cpp b/export/esword.cpp deleted file mode 100644 index 83fe306b9..000000000 --- a/export/esword.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_esword (string bible, bool log) -{ - string directory = filter_url_create_path ({export_logic::bible_directory (bible), "esword"}); - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - - - string filename = filter_url_create_path ({directory, "bible.bblx"}); - - - if (file_or_dir_exists (filename)) filter_url_unlink (filename); - - - Database_Bibles database_bibles; - - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - Filter_Text filter_text_bible = Filter_Text (bible); - filter_text_bible.esword_text = new Esword_Text (bible); - vector books = database_bibles.get_books (bible); - for (auto book : books) { - vector chapters = database_bibles.get_chapters (bible, book); - for (auto chapter : chapters) { - string chapter_data = database_bibles.get_chapter (bible, book, chapter); - filter_text_bible.add_usfm_code (chapter_data); - } - } - filter_text_bible.run (stylesheet); - filter_text_bible.esword_text->finalize (); - filter_text_bible.esword_text->createModule (filename); - - - Database_State::clearExport (bible, 0, export_logic::export_esword); - - - if (log) Database_Logs::log (translate("Exported to e-Sword") + " " + bible, Filter_Roles::translator ()); -} diff --git a/export/esword.h b/export/esword.h deleted file mode 100644 index e3de36bb5..000000000 --- a/export/esword.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_esword (std::string bible, bool log); diff --git a/export/html.cpp b/export/html.cpp deleted file mode 100644 index 84ea08fa7..000000000 --- a/export/html.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_html_book (string bible, int book, bool log) -{ - // Create folders for the html export. - string directory = filter_url_create_path ({export_logic::bible_directory (bible), "html"}); - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - - - // Filename for the html file. - string basename = export_logic::base_book_filename (bible, book); - string filename_html = filter_url_create_path ({directory, basename + ".html"}); - string stylesheet_css = filter_url_create_path ({directory, "stylesheet.css"}); - - - Database_Bibles database_bibles; - Database_BibleImages database_bibleimages; - - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - // Create stylesheet. - Styles_Sheets styles_sheets; - styles_sheets.create (stylesheet, stylesheet_css, false, bible); - - - // Copy font to the output directory. - string font = fonts::logic::get_text_font (bible); - if (!font.empty ()) { - if (fonts::logic::font_exists (font)) { - string fontpath = fonts::logic::get_font_path (font); - string contents = filter_url_file_get_contents (fontpath); - fontpath = filter_url_create_path ({directory, font}); - filter_url_file_put_contents (fontpath, contents); - } - } - - - Filter_Text filter_text = Filter_Text (bible); - filter_text.html_text_standard = new HtmlText (translate("Bible")); - filter_text.html_text_standard->custom_class = Filter_Css::getClass (bible); - if (Database_Config_Bible::getExportHtmlNotesOnHover(bible)) { - filter_text.html_text_standard->have_popup_notes(); - } - - - // Load one book. - vector chapters = database_bibles.get_chapters (bible, book); - for (auto chapter : chapters) { - // Get the USFM for this chapter. - string usfm = database_bibles.get_chapter (bible, book, chapter); - usfm = filter::strings::trim (usfm); - // Use small chunks of USFM at a time for much better performance. - filter_text.add_usfm_code (usfm); - } - - - // Convert the USFM. - filter_text.run (stylesheet); - - - // Save the html file. - filter_text.html_text_standard->save (filename_html); - - - // Save any images that were included. - for (auto src : filter_text.image_sources) { - string contents = database_bibleimages.get(src); - string filename = filter_url_create_path ({directory, src}); - filter_url_file_put_contents(filename, contents); - } - - - // Clear the flag for this export. - Database_State::clearExport (bible, book, export_logic::export_html); - - - if (log) Database_Logs::log (translate("Exported to html") + ": " + bible + " " + database::books::get_english_from_id (static_cast(book)), Filter_Roles::translator ()); -} diff --git a/export/html.h b/export/html.h deleted file mode 100644 index 5dce12e89..000000000 --- a/export/html.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_html_book (std::string bible, int book, bool log); diff --git a/export/index.cpp b/export/index.cpp deleted file mode 100644 index 4ced4ae7b..000000000 --- a/export/index.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_index () -{ - Database_Bibles database_bibles; - vector bibles = database_bibles.get_bibles (); - - - // Go through all sub directories of the exports directory. - // Remove subdirectories if their corresponding Bible no longer exists in the system. - string directory = export_logic::main_directory (); - vector files = filter_url_scandir (directory); - for (auto & file : files) { - if (in_array (file, bibles)) continue; - filter_url_rmdir (filter_url_create_path ({directory, file})); - Database_Logs::log ("Removing exported Bible " + file, Filter_Roles::translator ()); - } - - - // Schedule the relevant Bibles for export. - for (auto bible : bibles) { - - if (Database_State::getExport (bible, 0, export_logic::export_needed)) { - - Database_State::clearExport (bible, 0, export_logic::export_needed); - vector books = database_bibles.get_books (bible); - // Book 0 flags export of the whole Bible (this is not relevant to all export types). - books.push_back (0); - for (auto book : books) { - for (int format = export_logic::export_needed + 1; format < export_logic::export_end; format++) { - Database_State::setExport (bible, book, format); - } - } - - Database_Logs::log ("Exporting Bible " + bible, Filter_Roles::translator ()); - - if (Database_Config_Bible::getExportWebDuringNight (bible)) { - export_logic::schedule_web (bible, false); - export_logic::schedule_web_index (bible, false); - } - - if (Database_Config_Bible::getExportHtmlDuringNight (bible)) { - export_logic::schedule_html (bible, false); - } - - if (Database_Config_Bible::getExportUsfmDuringNight (bible)) { - export_logic::schedule_usfm (bible, false); - } - - if (Database_Config_Bible::getExportTextDuringNight (bible)) { - export_logic::schedule_text_and_basic_usfm (bible, false); - } - - if (Database_Config_Bible::getExportOdtDuringNight (bible)) { - export_logic::schedule_open_document (bible, false); - } - - if (Database_Config_Bible::getGenerateInfoDuringNight (bible)) { - export_logic::schedule_info (bible, false); - } - - if (Database_Config_Bible::getExportESwordDuringNight (bible)) { - export_logic::schedule_e_sword (bible, false); - } - - if (Database_Config_Bible::getExportOnlineBibleDuringNight (bible)) { - export_logic::schedule_online_bible (bible, false); - } - - } - } -} diff --git a/export/index.h b/export/index.h deleted file mode 100644 index 916d5703b..000000000 --- a/export/index.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_index (); diff --git a/export/info.cpp b/export/info.cpp deleted file mode 100644 index 7e37e188b..000000000 --- a/export/info.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_info (string bible, bool log) -{ - // Create folders for the information. - string directory = filter_url_create_path ({export_logic::bible_directory (bible), "info"}); - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - - - // Filenames for the various types of OpenDocument files. - string informationdFilename = filter_url_create_path ({directory, "information.html"}); - string falloutFilename = filter_url_create_path ({directory, "fallout.html"}); - - - Database_Bibles database_bibles; - - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - Filter_Text filter_text = Filter_Text (bible); - - - vector books = database_bibles.get_books (bible); - for (auto book : books) { - vector chapters = database_bibles.get_chapters (bible, book); - for (auto chapter : chapters) { - string usfm = database_bibles.get_chapter (bible, book, chapter); - usfm = filter::strings::trim (usfm); - // Use small chunks of USFM at a time for much better performance. - filter_text.add_usfm_code (usfm); - } - } - - - // Go through USFM to find the info and fallout. - filter_text.run (stylesheet); - - - // Save files. - filter_text.produceInfoDocument (informationdFilename); - filter_text.produceFalloutDocument (falloutFilename); - - - // Clear the flag for this export. - Database_State::clearExport (bible, 0, export_logic::export_info); - - - if (log) Database_Logs::log (translate("Documents with information and fallout were created") + " " + bible, Filter_Roles::translator ()); -} diff --git a/export/info.h b/export/info.h deleted file mode 100644 index a1b40681b..000000000 --- a/export/info.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_info (std::string bible, bool log); diff --git a/export/logic.cpp b/export/logic.cpp deleted file mode 100644 index 5a1f9426f..000000000 --- a/export/logic.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Schedule all Bibles for exports. -void export_logic::schedule_all () -{ - tasks_logic_queue (EXPORTALL); -} - - -// Schedule a Bible book for export to text and basic USFM format. -// $bible: Bible. -// $book: book. -void export_logic::schedule_text_and_basic_usfm (const string & bible, bool log) -{ - Database_Bibles database_bibles; - vector books = database_bibles.get_books (bible); - for (auto book : books) { - tasks_logic_queue (EXPORTTEXTUSFM, {bible, filter::strings::convert_to_string (book), filter::strings::convert_to_string (log)}); - } -} - - -// Schedule a Bible for export to USFM format. -void export_logic::schedule_usfm (const string & bible, bool log) -{ - tasks_logic_queue (EXPORTUSFM, {bible, filter::strings::convert_to_string (log)}); -} - - -// Schedule export to OpenDocument. -// $bible: Bible. -void export_logic::schedule_open_document (const string & bible, bool log) -{ - // Get the available books in the Bible. - Database_Bibles database_bibles; - vector books = database_bibles.get_books (bible); - // Export the books, one OpenDocument file per book. - for (auto book : books) { - tasks_logic_queue (EXPORTODT, {bible, filter::strings::convert_to_string (book), filter::strings::convert_to_string (log)}); - } - // Export the whole Bible to one OpenDocument file. - tasks_logic_queue (EXPORTODT, {bible, "0", filter::strings::convert_to_string (log)}); -} - - -// Schedule creation info documents. -// $bible: Bible. -void export_logic::schedule_info (const string & bible, bool log) -{ - tasks_logic_queue (EXPORTINFO, {bible, filter::strings::convert_to_string (log)}); -} - - -// Schedule export to html. -// $bible: Bible. -void export_logic::schedule_html (const string & bible, bool log) -{ - Database_Bibles database_bibles; - vector books = database_bibles.get_books (bible); - for (auto book : books) { - tasks_logic_queue (EXPORTHTML, {bible, filter::strings::convert_to_string (book), filter::strings::convert_to_string (log)}); - } -} - - -// Schedule export to web. -// $bible: Bible. -void export_logic::schedule_web (const string & bible, bool log) -{ - Database_Bibles database_bibles; - vector books = database_bibles.get_books (bible); - for (auto book : books) { - tasks_logic_queue (EXPORTWEBMAIN, {bible, filter::strings::convert_to_string (book), filter::strings::convert_to_string (log)}); - } -} - - -// Schedule export to web index. -// $bible: Bible. -void export_logic::schedule_web_index (const string & bible, bool log) -{ - tasks_logic_queue (EXPORTWEBINDEX, {bible, filter::strings::convert_to_string (log)}); -} - - -void export_logic::schedule_online_bible (const string & bible, bool log) -{ - tasks_logic_queue (EXPORTONLINEBIBLE, {bible, filter::strings::convert_to_string (log)}); -} - - -void export_logic::schedule_e_sword (const string & bible, bool log) -{ - tasks_logic_queue (EXPORTESWORD, {bible, filter::strings::convert_to_string (log)}); -} - - -// The main exports directory. -string export_logic::main_directory () -{ - return filter_url_create_root_path ({"exports"}); -} - - -// A Bible's export directory. -string export_logic::bible_directory (const string & bible) -{ - return filter_url_create_path ({main_directory (), bible}); -} - - -// Directory for the USFM. -// $type: -// 0: directory for the full USFM. -// 1: directory for the basic USFM. -// 2: root USFM directory. -string export_logic::usfm_directory (const string & bible, int type) -{ - string directory = filter_url_create_path ({bible_directory (bible), "usfm"}); - switch (type) { - case 0: directory = filter_url_create_path ({directory, "full"}); break; - case 1: directory = filter_url_create_path ({directory, "basic"}); break; - default: break; - } - return directory; -} - - -string export_logic::web_directory (const string & bible) -{ - return filter_url_create_path ({bible_directory (bible), "web"}); -} - - -string export_logic::web_back_link_directory (const string & bible) -{ - return "/exports/" + bible + "/web/"; -} - - -// Provides the base book file name, e.g. 01_Genesis. -// Or 00_Bible for an entire Bible when $book = 0; -// Takes in account the order of the books, possibly modified by the user. -string export_logic::base_book_filename (const string & bible, int book) -{ - string filename; - if (book) { - // The file name has a number that indicates the defined order of the book. - // See https://github.com/bibledit/cloud/issues/810 - // Localize the English book name: https://github.com/bibledit/cloud/issues/241 - vector ordered_books = filter_passage_get_ordered_books (bible); - vector::iterator iterator; - iterator = find(ordered_books.begin(), ordered_books.end(), book); - if (iterator != ordered_books.end()) { - long order = iterator - ordered_books.begin() + 1; - filename = filter::strings::fill (to_string (order), 2, '0'); - filename.append ("_"); - } - filename.append (translate (database::books::get_english_from_id (static_cast(book)))); - } else { - // Whole Bible. - filename = "00_" + translate ("Bible"); - } - - // Done. - return filename; -} - - diff --git a/export/logic.h b/export/logic.h deleted file mode 100644 index 6a33bc0f1..000000000 --- a/export/logic.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - - -#include - - -namespace export_logic { - -void schedule_all (); -void schedule_text_and_basic_usfm (const std::string & bible, bool log); -void schedule_usfm (const std::string & bible, bool log); -void schedule_open_document (const std::string & bible, bool log); -void schedule_info (const std::string & bible, bool log); -void schedule_html (const std::string & bible, bool log); -void schedule_web (const std::string & bible, bool log); -void schedule_web_index (const std::string & bible, bool log); -void schedule_online_bible (const std::string & bible, bool log); -void schedule_e_sword (const std::string & bible, bool log); -std::string main_directory (); -std::string bible_directory (const std::string & bible); -std::string usfm_directory (const std::string & bible, int type); -std::string web_directory (const std::string & bible); -std::string web_back_link_directory (const std::string & bible); -std::string base_book_filename (const std::string & bible, int book); -constexpr int export_needed { 0 }; -constexpr int export_text_and_basic_usfm { 1 }; -constexpr int export_full_usfm { 2 }; -constexpr int export_opendocument { 3 }; -constexpr int export_info { 4 }; -constexpr int export_html { 5 }; -constexpr int export_web { 6 }; -constexpr int export_web_index { 7 }; -constexpr int export_online_bible { 8 }; -constexpr int export_esword { 9 }; -constexpr int export_end { 10 }; - -}; // End of namespace. - - diff --git a/export/odt.cpp b/export/odt.cpp deleted file mode 100644 index c064d992a..000000000 --- a/export/odt.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_odt_book (string bible, int book, bool log) -{ - // Create folders for the OpenDocument export. - string directory = filter_url_create_path ({export_logic::bible_directory (bible), "opendocument"}); - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - - - // Filenames for the various types of OpenDocument files. - string basename = export_logic::base_book_filename (bible, book); - string standardFilename = filter_url_create_path ({directory, basename + "_standard.odt"}); - string textOnlyFilename = filter_url_create_path ({directory, basename + "_text_only.odt"}); - string textAndCitationsFilename = filter_url_create_path ({directory, basename + "_text_and_note_citations.odt"}); - string notesFilename = filter_url_create_path ({directory, basename + "_notes.odt"}); - - - Database_Bibles database_bibles; - Database_BibleImages database_bibleimages; - - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - Filter_Text filter_text = Filter_Text (bible); - filter_text.odf_text_standard = new odf_text (bible); - filter_text.odf_text_text_only = new odf_text (bible); - filter_text.odf_text_text_and_note_citations = new odf_text (bible); - filter_text.odf_text_notes = new odf_text (bible); - - - if (book == 0) { - // Load entire Bible, ordered. - vector books = filter_passage_get_ordered_books (bible); - for (auto book2 : books) { - vector chapters = database_bibles.get_chapters (bible, book2); - for (auto chapter : chapters) { - string usfm = database_bibles.get_chapter (bible, book2, chapter); - usfm = filter::strings::trim (usfm); - // Use small chunks of USFM at a time for much better performance. - filter_text.add_usfm_code (usfm); - } - } - } else { - // Load one book. - vector chapters = database_bibles.get_chapters (bible, book); - for (auto chapter : chapters) { - string usfm = database_bibles.get_chapter (bible, book, chapter); - usfm = filter::strings::trim (usfm); - // Use small chunks of USFM at a time for much better performance. - filter_text.add_usfm_code (usfm); - } - } - - - // Convert the USFM to OpenDocument. - filter_text.run (stylesheet); - - - // Save text files and optionally the images included in the text. - filter_text.odf_text_standard->save (standardFilename); - filter_text.odf_text_text_only->save (textOnlyFilename); - filter_text.odf_text_text_and_note_citations->save (textAndCitationsFilename); - filter_text.odf_text_notes->save (notesFilename); - for (auto src : filter_text.image_sources) { - string contents = database_bibleimages.get(src); - string path = filter_url_create_path ({directory, src}); - filter_url_file_put_contents(path, contents); - } - - - // Securing the OpenDocument export implies that the exported files are zipped and secured with a password. - // It uses the external zip binary. - bool secure = Database_Config_Bible::getSecureOdtExport (bible); - string password = Database_Config_Bible::getExportPassword (bible); - string basefile = filter_url_basename (standardFilename); - filter_url_unlink (standardFilename + ".zip"); - if (secure) { - filter_shell_run (directory, "zip", {"-P", password, basefile + ".zip", basefile}, nullptr, nullptr); - filter_url_unlink (standardFilename); - } - basefile = filter_url_basename (textOnlyFilename); - filter_url_unlink (textOnlyFilename + ".zip"); - if (secure) { - filter_shell_run (directory, "zip", {"-P", password, basefile + ".zip", basefile}, nullptr, nullptr); - filter_url_unlink (textOnlyFilename); - } - basefile = filter_url_basename (textAndCitationsFilename); - filter_url_unlink (textAndCitationsFilename + ".zip"); - if (secure) { - filter_shell_run (directory, "zip", {"-P", password, basefile + ".zip", basefile}, nullptr, nullptr); - filter_url_unlink (textAndCitationsFilename); - } - basefile = filter_url_basename (notesFilename); - filter_url_unlink (notesFilename + ".zip"); - if (secure) { - filter_shell_run (directory, "zip", {"-P", password, basefile + ".zip", basefile}, nullptr, nullptr); - filter_url_unlink (notesFilename); - } - - - // Clear the flag that indicated this export. - Database_State::clearExport (bible, book, export_logic::export_opendocument); - - - if (log) { - string bookname; - if (book) bookname = database::books::get_english_from_id (static_cast(book)); - else bookname = translate ("whole Bible"); - Database_Logs::log (translate("Exported to OpenDocument files") + " " + bible + " " + bookname, Filter_Roles::translator ()); - } -} diff --git a/export/odt.h b/export/odt.h deleted file mode 100644 index 42cf0150a..000000000 --- a/export/odt.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_odt_book (std::string bible, int book, bool log); diff --git a/export/onlinebible.cpp b/export/onlinebible.cpp deleted file mode 100644 index 217d7bcc7..000000000 --- a/export/onlinebible.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_onlinebible (string bible, bool log) -{ - string directory = filter_url_create_path ({export_logic::bible_directory (bible), "onlinebible"}); - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - - - string filename = filter_url_create_path ({directory, "bible.exp"}); - - - Database_Bibles database_bibles; - - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - Filter_Text filter_text_bible = Filter_Text (bible); - filter_text_bible.onlinebible_text = new OnlineBible_Text (); - vector books = database_bibles.get_books (bible); - for (auto book : books) { - vector chapters = database_bibles.get_chapters (bible, book); - for (auto chapter : chapters) { - string chapter_data = database_bibles.get_chapter (bible, book, chapter); - chapter_data = filter::strings::trim (chapter_data); - filter_text_bible.add_usfm_code (chapter_data); - } - } - filter_text_bible.run (stylesheet); - filter_text_bible.onlinebible_text->save (filename); - - - Database_State::clearExport (bible, 0, export_logic::export_online_bible); - - - if (log) Database_Logs::log (translate("Exported to Online Bible") + " " + bible, Filter_Roles::translator ()); -} diff --git a/export/onlinebible.h b/export/onlinebible.h deleted file mode 100644 index 616b4e515..000000000 --- a/export/onlinebible.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_onlinebible (std::string bible, bool log); diff --git a/export/textusfm.cpp b/export/textusfm.cpp deleted file mode 100644 index 2c36b8e13..000000000 --- a/export/textusfm.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_text_usfm_book (string bible, int book, bool log) -{ - // Create folders for the clear text and the basic USFM exports. - string usfmDirectory = export_logic::usfm_directory (bible, 1); - if (!file_or_dir_exists (usfmDirectory)) filter_url_mkdir (usfmDirectory); - string textDirectory = filter_url_create_path ({export_logic::bible_directory (bible), "text"}); - if (!file_or_dir_exists (textDirectory)) filter_url_mkdir (textDirectory); - - - // Filenames for text and usfm. - string usfmFilename = filter_url_create_path ({usfmDirectory, export_logic::base_book_filename (bible, book) + ".usfm"}); - string textFilename = filter_url_create_path ({textDirectory, export_logic::base_book_filename (bible, book) + ".txt"}); - - - Database_Bibles database_bibles; - - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - Filter_Text filter_text_book = Filter_Text (bible); - filter_text_book.text_text = new Text_Text (); - - - // Basic USFM. - if (file_or_dir_exists (usfmFilename)) filter_url_unlink (usfmFilename); - string basicUsfm = "\\id " + database::books::get_usfm_from_id (static_cast(book)) + "\n"; - filter_url_file_put_contents_append (usfmFilename, basicUsfm); - - - vector chapters = database_bibles.get_chapters (bible, book); - for (auto chapter : chapters) { - - - // The text filter for this chapter. - Filter_Text filter_text_chapter = Filter_Text (bible); - - - // Basic USFM for this chapter. - filter_text_chapter.initializeHeadingsAndTextPerVerse (false); - - - // Get the USFM code for the current chapter. - string chapter_data = database_bibles.get_chapter (bible, book, chapter); - chapter_data = filter::strings::trim (chapter_data); - - - // Add the chapter's USFM code to the Text_* filter for the book, and for the chapter. - // Use small chunks of USFM at a time. This provides much better performance. - filter_text_book.add_usfm_code (chapter_data); - filter_text_chapter.add_usfm_code (chapter_data); - - - // Convert the chapter - filter_text_chapter.run (stylesheet); - - - // Deal with basic USFM. - if (chapter > 0) { - map verses_text = filter_text_chapter.getVersesText (); - basicUsfm = "\\c " + filter::strings::convert_to_string (chapter) + "\n"; - basicUsfm += "\\p\n"; - for (auto element : verses_text) { - int verse = element.first; - string text = element.second; - basicUsfm += "\\v " + filter::strings::convert_to_string (verse) + " " + text + "\n"; - } - filter_url_file_put_contents_append (usfmFilename, basicUsfm); - } - - - } - - - // Convert the book. - filter_text_book.run (stylesheet); - - - // Save the text export. - filter_text_book.text_text->save (textFilename); - - - // Clear the flag that indicated this export. - Database_State::clearExport (bible, book, export_logic::export_text_and_basic_usfm); - - - if (log) Database_Logs::log (translate("Exported to basic USFM and text") + ": " + bible + " " + database::books::get_english_from_id (static_cast(book)), Filter_Roles::translator ()); -} diff --git a/export/textusfm.h b/export/textusfm.h deleted file mode 100644 index 6935c8933..000000000 --- a/export/textusfm.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_text_usfm_book (std::string bible, int book, bool log); diff --git a/export/usfm.cpp b/export/usfm.cpp deleted file mode 100644 index b3b3f96ef..000000000 --- a/export/usfm.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_usfm (string bible, bool log) -{ - Database_Bibles database_bibles; - - - // Root USFM directory, plus info file. - string usfmDirectory = export_logic::usfm_directory (bible, 2); - if (!file_or_dir_exists (usfmDirectory)) filter_url_mkdir (usfmDirectory); - string infopath = filter_url_create_root_path ({"export", "usfm.html"}); - string infocontents = filter_url_file_get_contents (infopath); - infopath = filter_url_create_path ({usfmDirectory, "readme.html"}); - filter_url_file_put_contents (infopath, infocontents); - - - // USFM directories - string usfmDirectoryFull = export_logic::usfm_directory (bible, 0); - if (!file_or_dir_exists (usfmDirectoryFull)) filter_url_mkdir (usfmDirectoryFull); - - - // Take the USFM from the Bible database. - // Generate one USFM file per book. - - - vector books = database_bibles.get_books (bible); - for (auto book : books) { - - - // If the USFM output is zipped, the zipping process removes the individual USFM files, - // which means that they are no longer found, which triggers a new export. - - - // The USFM data of the current book. - string bookUsfmDataFull; - - - // Collect the USFM for all chapters in this book. - vector chapters = database_bibles.get_chapters (bible, book); - for (auto chapter : chapters) { - // Get the USFM code for the current chapter. - string chapter_data = database_bibles.get_chapter (bible, book, chapter); - chapter_data = filter::strings::trim (chapter_data); - // Add the chapter USFM code to the book's USFM code. - bookUsfmDataFull += chapter_data; - bookUsfmDataFull += "\n"; - } - - - // Save the USFM of this book to a file with a localized name. - string base_book_filename = export_logic::base_book_filename (bible, book); - string path = filter_url_create_path ({usfmDirectoryFull, base_book_filename + ".usfm"}); - filter_url_file_put_contents (path, bookUsfmDataFull); - - - // Clear the flag that indicated this export. - Database_State::clearExport (bible, book, export_logic::export_full_usfm); - - - if (log) Database_Logs::log (translate("Exported to USFM") + ": " + bible + " " + database::books::get_english_from_id (static_cast(book)), Filter_Roles::translator ()); - } - - - // Base name of the zip file. - string zipfile = export_logic::base_book_filename (bible, 0) + ".zip"; - string zippath = filter_url_create_path ({usfmDirectoryFull, zipfile}); - - - // Compress USFM files into one zip file. - filter_url_unlink (zippath); - string archive = filter_archive_zip_folder (usfmDirectoryFull); - filter_url_rename (archive, zippath); - - - if (Database_Config_Bible::getSecureUsfmExport (bible)) { - // Securing the full USFM export means that there will be one zip file secured with a password. - // This zip file contains all exported USFM data. - // All other files will be removed. - // It uses the external zip binary. - vector files = filter_url_scandir (usfmDirectoryFull); - for (auto file : files) { - if (file != zipfile) filter_url_unlink (filter_url_create_path ({usfmDirectoryFull, file})); - } - string password = Database_Config_Bible::getExportPassword (bible); - string output, error; - filter_shell_run (usfmDirectoryFull, "zip", {"-P", password, "bible.zip", zipfile}, &output, &error); - filter_url_unlink (zippath); - filter_url_rename (filter_url_create_path ({usfmDirectoryFull, "bible.zip"}), zippath); - } - - - // Clear the flag that indicated this export. - Database_State::clearExport (bible, 0, export_logic::export_full_usfm); - - - if (log) Database_Logs::log (translate("Exported to USFM") + ": " + bible + " " + translate("All books"), Filter_Roles::translator ()); -} diff --git a/export/usfm.h b/export/usfm.h deleted file mode 100644 index c4cd67887..000000000 --- a/export/usfm.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_usfm (std::string bible, bool log); diff --git a/export/web.cpp b/export/web.cpp deleted file mode 100644 index 1f43dc1fe..000000000 --- a/export/web.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void export_web_book (string bible, int book, bool log) -{ - const string directory = export_logic::web_directory (bible); - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - - - Database_Bibles database_bibles {}; - Database_BibleImages database_bibleimages {}; - - - const string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - const string feedback_email = Database_Config_Bible::getExportFeedbackEmail (bible); - - - // Copy font to the output directory. - const string font = fonts::logic::get_text_font (bible); - if (!font.empty ()) { - if (fonts::logic::font_exists (font)) { - string fontpath = fonts::logic::get_font_path (font); - const string contents = filter_url_file_get_contents (fontpath); - fontpath = filter_url_create_path ({directory, font}); - filter_url_file_put_contents (fontpath, contents); - } - } - - - const string backLinkPath {export_logic::web_back_link_directory (bible)}; - - - const string bibleBookText = bible + " " + database::books::get_english_from_id (static_cast(book)); - - - // Web index file for the book. - HtmlText html_text_rich_book_index (bibleBookText); - Html_Header htmlHeader = Html_Header (html_text_rich_book_index); - htmlHeader.search_back_link (backLinkPath + filter_url_html_file_name_bible ("", book), translate("Go back to") + " " + bibleBookText); - htmlHeader.create ({ - pair (bible, filter_url_html_file_name_bible ()), - pair (translate (database::books::get_english_from_id (static_cast(book))), filter_url_html_file_name_bible ()) - }); - html_text_rich_book_index.new_paragraph ("navigationbar"); - html_text_rich_book_index.add_text ("|"); - - - // Go through the chapters of this book. - const vector chapters = database_bibles.get_chapters (bible, book); - for (size_t c = 0; c < chapters.size(); c++) { - const int chapter = chapters [c]; - const bool is_first_chapter = (c == 0); - const bool is_last_chapter = (c == chapters.size() - 1); - - // The text filter for this chapter. - Filter_Text filter_text_chapter = Filter_Text (bible); - - // Get the USFM for the chapter. - string usfm = database_bibles.get_chapter (bible, book, chapter); - // Trim it. - usfm = filter::strings::trim (usfm); - // Use small chunks of USFM at a time for much better performance. - filter_text_chapter.add_usfm_code (usfm); - - // Interlinked web data for one chapter. - filter_text_chapter.html_text_linked = new HtmlText (translate("Bible")); - filter_text_chapter.html_text_linked->custom_class = Filter_Css::getClass (bible); - - // Create breadcrumbs and navigator for the chapter. - Html_Header html_header = Html_Header (*filter_text_chapter.html_text_linked); - html_header.search_back_link (backLinkPath + filter_url_html_file_name_bible ("", book, chapter), translate("Go back to") + " " + bibleBookText + " " + filter::strings::convert_to_string (chapter)); - vector > breadcrumbs_navigator; - breadcrumbs_navigator.push_back (pair (bible, filter_url_html_file_name_bible ())); - breadcrumbs_navigator.push_back (pair (translate (database::books::get_english_from_id (static_cast(book))), filter_url_html_file_name_bible ())); - if (!is_first_chapter) { - breadcrumbs_navigator.push_back (pair ("«", filter_url_html_file_name_bible ("", book, chapter - 1))); - } - breadcrumbs_navigator.push_back (pair (filter::strings::convert_to_string (chapter), filter_url_html_file_name_bible ("", book))); - if (!is_last_chapter) { - breadcrumbs_navigator.push_back (pair ("»", filter_url_html_file_name_bible ("", book, chapter + 1))); - } - // Optionally add a link for giving feedback by email. - if (!feedback_email.empty ()) { - breadcrumbs_navigator.push_back (pair ("|", "")); - string subject = translate ("Comment on") + " " + bible + " " + database::books::get_english_from_id (static_cast(book)) + " " + filter::strings::convert_to_string (chapter); - subject = filter::strings::replace (" ", "%20", subject); - string link = "mailto:" + feedback_email + "?Subject=" + subject; - breadcrumbs_navigator.push_back (pair (translate ("Feedback"), link)); - } - html_header.create (breadcrumbs_navigator); - - // Create interlinked html for the chapter. - filter_text_chapter.run (stylesheet); - filter_text_chapter.html_text_linked->save (filter_url_html_file_name_bible (directory, book, chapter)); - - html_text_rich_book_index.add_link (html_text_rich_book_index.current_p_node, filter_url_html_file_name_bible ("", book, chapter), "", filter::strings::convert_to_string (chapter), "", " " + filter::strings::convert_to_string (chapter) + " "); - html_text_rich_book_index.add_text ("|"); - - // Save any images that were included. - for (auto src : filter_text_chapter.image_sources) { - string contents = database_bibleimages.get(src); - string filename = filter_url_create_path ({directory, src}); - filter_url_file_put_contents(filename, contents); - } - } - - - // Save the book index. - html_text_rich_book_index.save (filter_url_html_file_name_bible (directory, book)); - - - // Clear the flag for this export. - Database_State::clearExport (bible, book, export_logic::export_web); - - - if (log) { - Database_Logs::log (translate("Exported to web") + ": " + bible + " " + database::books::get_english_from_id (static_cast(book)), Filter_Roles::translator ()); - } -} - - -void export_web_index (string bible, bool log) -{ - // Create folders for the web export. - string directory = export_logic::web_directory (bible); - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - - - // Filenames for the web file and stylesheet. - string indexFile = filter_url_create_path ({directory, "index.html"}); - string index00 = filter_url_create_path ({directory, "00_index.html"}); - string filecss = filter_url_create_path ({directory, "stylesheet.css"}); - - - Database_Bibles database_bibles; - - - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - - // Create stylesheet. - Styles_Sheets styles_sheets; - styles_sheets.create (stylesheet, filecss, false, bible); - - - string backLinkPath = export_logic::web_back_link_directory (bible); - - - // Main index file. - HtmlText html_text_rich_bible_index (bible); - // On top are the breadcrumbs, starting with a clickable Bible name. - Html_Header htmlHeader = Html_Header (html_text_rich_bible_index); - htmlHeader.search_back_link (backLinkPath + filter_url_html_file_name_bible (), translate("Go back to Bible")); - htmlHeader.create ({ pair (bible, filter_url_html_file_name_bible ())}); - - - // Prepare for the list of books in de html index file. - html_text_rich_bible_index.new_paragraph ("navigationbar"); - html_text_rich_bible_index.add_text (" |"); - - - // Go through the Bible books. - vector books = database_bibles.get_books (bible); - for (auto book : books) { - // Add this book to the main web index. - html_text_rich_bible_index.add_link (html_text_rich_bible_index.current_p_node, filter_url_html_file_name_bible ("", book), "", translate (database::books::get_english_from_id (static_cast(book))), "", " " + translate (database::books::get_english_from_id (static_cast(book))) + " "); - html_text_rich_bible_index.add_text ("|"); - } - - - // Save index file for the interlinked web export. - html_text_rich_bible_index.save (indexFile); - html_text_rich_bible_index.save (index00); - - - // Lens image supporting search. - string lenspath = filter_url_create_root_path ({"webbb", "lens.png"}); - string contents = filter_url_file_get_contents (lenspath); - lenspath = filter_url_create_path ({directory, "lens.png"}); - filter_url_file_put_contents (lenspath, contents); - - - // Clear the flag that indicated this export. - Database_State::clearExport (bible, 0, export_logic::export_web_index); - - - if (log) Database_Logs::log (translate("Exported to web") + ": " + bible + " Index", Filter_Roles::translator ()); -} diff --git a/export/web.h b/export/web.h deleted file mode 100644 index 2cc00ad18..000000000 --- a/export/web.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void export_web_book (std::string bible, int book, bool log); -void export_web_index (std::string bible, bool log); diff --git a/filter/UriCodec.cpp b/filter/UriCodec.cpp deleted file mode 100644 index cf924aad6..000000000 --- a/filter/UriCodec.cpp +++ /dev/null @@ -1,168 +0,0 @@ - -/** - * Uri encode and decode (RFC1630, RFC1738, RFC2396) - * http://www.codeguru.com/cpp/cpp/algorithms/strings/article.php/c12759/URI-Encoding-and-Decoding.htm - * - * Copyright 2006 (C) by Jin Qing - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma GCC diagnostic ignored "-Wconversion" - -#ifdef OLDCODE -const char HEX2DEC[256] = -{ - /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - /* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1, - - /* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - - /* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - - /* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1 -}; -#endif - -const unsigned char HEX2DEC[256] = -{ - /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - /* 0 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 2 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, - - /* 4 */ 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 5 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 6 */ 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 7 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - - /* 8 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 9 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* A */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* B */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - - /* C */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* D */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* E */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* F */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 -}; - -std::string UriDecode(const std::string & sSrc) -{ - // Note from RFC1630: "Sequences which start with a percent sign - // but are not followed by two hexadecimal characters (0-9, A-F) are reserved - // for future extension" - - const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); - const int SRC_LEN = (int)sSrc.length(); - const unsigned char * const SRC_END = pSrc + SRC_LEN; - const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%' - - char * const pStart = new char[SRC_LEN]; - char * pEnd = pStart; - - while (pSrc < SRC_LAST_DEC) - { - if (*pSrc == '%') - { - char dec1, dec2; - if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)]) - && -1 != (dec2 = HEX2DEC[*(pSrc + 2)])) - { - *pEnd++ = (dec1 << 4) + dec2; - pSrc += 3; - continue; - } - } - - *pEnd++ = *pSrc++; - } - - // the last 2- chars - while (pSrc < SRC_END) - *pEnd++ = *pSrc++; - - std::string sResult(pStart, pEnd); - delete [] pStart; - return sResult; -} - -// Only alphanum is safe. -const char SAFE[256] = -{ - /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, - - /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, - /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, - /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, - /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, - - /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - - /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 -}; - -std::string UriEncode(const std::string & sSrc) -{ - const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; - const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); - const int SRC_LEN = (int)sSrc.length(); - unsigned char * const pStart = new unsigned char[SRC_LEN * 3]; - unsigned char * pEnd = pStart; - const unsigned char * const SRC_END = pSrc + SRC_LEN; - - for (; pSrc < SRC_END; ++pSrc) - { - if (SAFE[*pSrc]) - *pEnd++ = *pSrc; - else - { - // escape this char - *pEnd++ = '%'; - *pEnd++ = DEC2HEX[*pSrc >> 4]; - *pEnd++ = DEC2HEX[*pSrc & 0x0F]; - } - } - - std::string sResult((char *)pStart, (char *)pEnd); - delete [] pStart; - return sResult; -} diff --git a/filter/archive.cpp b/filter/archive.cpp deleted file mode 100644 index 8ae555405..000000000 --- a/filter/archive.cpp +++ /dev/null @@ -1,448 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Work around old Microsoft macro definitions. -#undef max -#undef min - - -// Compresses a $folder into zip format. -// Returns the path to the compressed archive it created. -string filter_archive_zip_folder (string folder) -{ -#ifdef HAVE_CLOUD - return filter_archive_zip_folder_shell_internal (folder); -#endif -#ifdef HAVE_CLIENT - return filter_archive_zip_folder_miniz_internal (folder); -#endif -} - - -// Compresses a $folder into zip format. -// Returns the path to the compressed archive it created. -string filter_archive_zip_folder_shell_internal (string folder) -{ - if (!file_or_dir_exists (folder)) return string(); - string zippedfile = filter_url_tempfile () + ".zip"; -#ifdef HAVE_CLOUD - string logfile = filter_url_tempfile () + ".log"; - folder = filter_url_escape_shell_argument (folder); - string command = "cd " + folder + " && zip -r " + zippedfile + " * > " + logfile + " 2>&1"; - int return_var; - // Run the command. - return_var = system (command.c_str()); - if (return_var != 0) { - filter_url_unlink (zippedfile); - zippedfile.clear(); - string errors = filter_url_file_get_contents (logfile); - Database_Logs::log (errors); - } -#endif - return zippedfile; -} - - -// Compresses a $folder into zip format. -// Returns the path to the compressed archive it created. -string filter_archive_zip_folder_miniz_internal (string folder) -{ - if (!file_or_dir_exists (folder)) { - return ""; - } - string zippedfile = filter_url_tempfile () + ".zip"; - vector paths; - filter_url_recursive_scandir (folder, paths); - for (auto path : paths) { - bool is_dir = filter_url_is_dir (path); - string file = path.substr (folder.size () + 1); -#ifdef HAVE_WINDOWS - // The file names in Windows will be backslashes (\) at this point. - // But the mzip library, in its current configuration, works with forward slashes (/). - // So the code below, in case of Windows, updates the type of slashes. - file = filter::strings::replace (DIRECTORY_SEPARATOR, "/", file); -#endif - mz_bool status; - if (is_dir) { - file.append ("/"); - status = mz_zip_add_mem_to_archive_file_in_place(zippedfile.c_str(), file.c_str(), nullptr, 0, "", 0, MZ_DEFAULT_LEVEL); - } else { - string contents = filter_url_file_get_contents (path); - status = mz_zip_add_mem_to_archive_file_in_place (zippedfile.c_str(), file.c_str(), contents.c_str(), contents.size(), "", 0, MZ_DEFAULT_LEVEL); - } - if (!status) { - Database_Logs::log ("mz_zip_add_mem_to_archive_file_in_place failed for " + path); - return ""; - } - } - return zippedfile; -} - - -// Uncompresses a zip archive identified by $file. -// Returns the path to the folder it created. -string filter_archive_unzip (string file) -{ -#ifdef HAVE_CLOUD - return filter_archive_unzip_shell_internal (file); -#endif -#ifdef HAVE_CLIENT - return filter_archive_unzip_miniz_internal (file); -#endif -} - - -// Uncompresses a zip archive identified by $file. -// Returns the path to the folder it created. -string filter_archive_unzip_shell_internal ([[maybe_unused]] string file) -{ - string folder = filter_url_tempfile (); -#ifdef HAVE_CLOUD - filter_url_mkdir (folder); - folder.append (DIRECTORY_SEPARATOR); - string logfile = filter_url_tempfile () + ".log"; - file = filter_url_escape_shell_argument (file); - string command = "unzip -o -d " + folder + " " + file + " > " + logfile + " 2>&1"; - // Run the command. - int return_var = system (command.c_str()); - if (return_var != 0) { - filter_url_rmdir (folder); - folder.clear(); - string errors = filter_url_file_get_contents (logfile); - Database_Logs::log (errors); - } else { - // Set free permissions after unzipping. - command = "chmod -R 0777 " + folder; - [[maybe_unused]] int result = system (command.c_str ()); - } -#endif - return folder; -} - - -// Uncompresses the $zipfile. -// Returns the path to the folder it created. -string filter_archive_unzip_miniz_internal (string zipfile) -{ - // Directory where to unzip the archive. - string folder = filter_url_tempfile (); - filter_url_mkdir (folder); - - // Covers the entire process. - bool error = false; - - // Open the zip archive. - mz_bool status; - mz_zip_archive zip_archive; - memset (&zip_archive, 0, sizeof (zip_archive)); - status = mz_zip_reader_init_file(&zip_archive, zipfile.c_str(), 0); - if (status) { - - // Iterate over the files in the archive. - unsigned filecount = mz_zip_reader_get_num_files (&zip_archive); - for (unsigned i = 0; i < filecount; i++) { - - // If there was an error, skip processing further files. - if (error) continue; - - // Get information about this file. - mz_zip_archive_file_stat file_stat; - status = mz_zip_reader_file_stat (&zip_archive, i, &file_stat); - if (status) { - - string filename = filter_url_create_path ({folder, file_stat.m_filename}); - // The miniz library returns Unix directory separators above. - // So in case of Windows, convert them to Windows ones. - string fixed_filename = filter_url_update_directory_separator_if_windows (filename); - - if (mz_zip_reader_is_file_a_directory (&zip_archive, i)) { - // Create this directory. - if (!file_or_dir_exists (fixed_filename)) filter_url_mkdir (fixed_filename); - } else { - /* Code that extracts file contents memory, if needed. - size_t filesize = file_stat.m_uncomp_size; - std::cout << filename << " " << filesize << std::endl; - void * buff = operator new (filesize); - if (buff) { - status = mz_zip_reader_extract_to_mem (&zip_archive, i, buff, filesize, 0); - if (status) { - string contents (static_cast(buff), filesize); - } else { - // "mz_zip_reader_extract_to_mem failure for " + filename + " in " + zipfile; - error = true; - } - operator delete (buff); - } else { - // "failure to allocate buffer for file extraction"; - error = true; - } - */ - - // Ensure this file's folder exists. - string dirname = filter_url_dirname (fixed_filename); - if (!file_or_dir_exists (dirname)) filter_url_mkdir (dirname); - // Extract this file. - status = mz_zip_reader_extract_to_file (&zip_archive, i, fixed_filename.c_str(), 0); - if (!status) { - Database_Logs::log ("mz_zip_reader_extract_to_file failure for file " + filename + " in " + zipfile); - error = true; - } - } - - } else { - Database_Logs::log ("mz_zip_reader_file_stat failed for " + zipfile); - error = true; - } - } - - // Close the archive, freeing any resources it was using. - mz_zip_reader_end (&zip_archive); - - } else { - Database_Logs::log ("mz_zip_reader_init_file failed for " + zipfile); - error = true; - } - - // If there was an error, return nothing, to indicate that uncompression has failed. - if (error) folder.clear (); - - // The folder where the files were unpacked. - return folder; -} - - -// Compresses a file identified by $filename into gzipped tar format. -// Returns the path to the compressed archive it created. -string filter_archive_tar_gzip_file (string filename) -{ - string tarball = filter_url_tempfile () + ".tar.gz"; - string dirname = filter_url_escape_shell_argument (filter_url_dirname (filename)); - string basename = filter_url_escape_shell_argument (filter_url_basename (filename)); - string logfile = filter_url_tempfile () + ".log"; - string command = "cd " + dirname + " && tar -czf " + tarball + " " + basename + " > " + logfile + " 2>&1"; - int return_var; -#ifdef HAVE_IOS - // Crashes on iOS. - return_var = 1; -#else - // Run the command. - return_var = system (command.c_str()); -#endif - if (return_var != 0) { - filter_url_unlink (tarball); - tarball.clear(); - string errors = filter_url_file_get_contents (logfile); - Database_Logs::log (errors); - } - return tarball; -} - - -// Compresses a $folder into gzipped tar format. -// Returns the path to the compressed archive it created. -string filter_archive_tar_gzip_folder (string folder) -{ - string tarball = filter_url_tempfile () + ".tar.gz"; - folder = filter_url_escape_shell_argument (folder); - string logfile = filter_url_tempfile () + ".log"; - string command = "cd " + folder + " && tar -czf " + tarball + " . > " + logfile + " 2>&1"; - int return_var; -#ifdef HAVE_IOS - // Crashes on iOS. - return_var = 1; -#else - // Run the command. - return_var = system (command.c_str()); -#endif - if (return_var != 0) { - filter_url_unlink (tarball); - tarball.clear(); - string errors = filter_url_file_get_contents (logfile); - Database_Logs::log (errors); - } - return tarball; -} - - -// Uncompresses a .tar.gz archive identified by $file. -// Returns the path to the folder it created. -string filter_archive_untar_gzip (string file) -{ - file = filter_url_escape_shell_argument (file); - string folder = filter_url_tempfile (); - filter_url_mkdir (folder); - folder.append (DIRECTORY_SEPARATOR); - string logfile = filter_url_tempfile () + ".log"; - string command = "cd " + folder + " && tar zxf " + file + " > " + logfile + " 2>&1"; - int return_var; -#ifdef HAVE_IOS - // Crashes on iOS. - return_var = 1; -#else - // Run the command. - return_var = system (command.c_str()); -#endif - if (return_var != 0) { - filter_url_rmdir (folder); - folder.clear(); - string errors = filter_url_file_get_contents (logfile); - Database_Logs::log (errors); - } - return folder; -} - - -// Uncompresses a known archive identified by $file. -// Returns the path to the folder it created. -string filter_archive_uncompress (string file) -{ - int type = filter_archive_is_archive (file); - if (type == 1) { - return filter_archive_untar_gzip (file); - } - if (type == 2) { - return filter_archive_unzip (file); - } - return ""; -} - - -// Returns 0 if it is not an archive that Bibledit supports. -// Else returns 1, 2, 3... depending on the type of archive. -int filter_archive_is_archive (string file) -{ - // Tar (.tar) archives, including those compressed with gzip (.tar.gz, .tgz), bzip (.tar.bz, .tbz), bzip2 (.tar.bz2, .tbz2), compress (.tar.Z, .taz), lzop (.tar.lzo, .tzo) and lzma (.tar.lzma) - // Zip archives (.zip) - // Jar archives (.jar, .ear, .war) - // 7z archives (.7z) - // iso9660 CD images (.iso) - // Lha archives (.lzh) - // Single files compressed with gzip (.gz), bzip (.bz), bzip2 (.bz2), compress (.Z), lzop (.lzo) and lzma (.lzma) - string suffix = filter_url_get_extension (file); - if ((suffix == "tar.gz") || (suffix == "gz") || (suffix == "tgz")) { - return 1; - } - if ((suffix == "zip")) { - return 2; - } - if ((suffix == "tar.bz") || (suffix == "tbz") || (suffix == "tar.bz2") || (suffix == "tbz2")) { - return 0; - } - return 0; -} - - -// Create a tarball at $tarpath with input $files from $directory. -string filter_archive_microtar_pack (string tarpath, string directory, vector files) -{ - mtar_t tar; - int res; - - // Open archive for writing. - res = mtar_open (&tar, tarpath.c_str(), "w"); - if (res != MTAR_ESUCCESS) return mtar_strerror (res); - - // Iterate over the files. - for (auto file : files) { - // Full path. - string path = filter_url_create_path ({directory, file}); - // Skip directories. - if (filter_url_is_dir (path)) continue; - // Read the file's data. - string data = filter_url_file_get_contents (path); - // Write the file's name to the tarball. - res = mtar_write_file_header(&tar, file.c_str(), static_cast (data.length ())); - if (res != MTAR_ESUCCESS) return mtar_strerror (res); - // Write the file's data to the tarball. - res = mtar_write_data(&tar, data.c_str(), static_cast (data.length ())); - if (res != MTAR_ESUCCESS) return mtar_strerror (res); - } - - // Finalize: This needs to be the last thing done before closing. - res = mtar_finalize(&tar); - if (res != MTAR_ESUCCESS) return mtar_strerror (res); - - // Close archive. - res = mtar_close(&tar); - if (res != MTAR_ESUCCESS) return mtar_strerror (res); - - // OK, done :) - return ""; -} - - -// Unpack the tarball at $tarpath and store the individual files at $outputpath. -string filter_archive_microtar_unpack (string tarball, string directory) -{ - mtar_t tar; - mtar_header_t h; - int res; - - // Open archive for reading. - res = mtar_open (&tar, tarball.c_str(), "r"); - if (res != MTAR_ESUCCESS) return mtar_strerror (res); - - // Read all file names. - vector files; - while ((mtar_read_header(&tar, &h)) != MTAR_ENULLRECORD) { - files.push_back (h.name); - mtar_next(&tar); - } - - // Create directory if needed. - if (!file_or_dir_exists (directory)) filter_url_mkdir (directory); - - // Unpack all files and save them. - for (auto file : files) { - // Find the file's information. - res = mtar_find (&tar, file.c_str(), &h); - if (res != MTAR_ESUCCESS) return mtar_strerror (res); - // Read the file's data. - char *p = static_cast (calloc(1, h.size + 1)); - res = mtar_read_data(&tar, p, h.size); - if (res != MTAR_ESUCCESS) return mtar_strerror (res); - string data (p, h.size); - free(p); - // If the file contains a directory, ensure that directory exists. - string dirname = filter_url_dirname (file); - if (dirname != ".") { - dirname = filter_url_create_path ({directory, dirname}); - if (!file_or_dir_exists (dirname)) filter_url_mkdir (dirname); - } - // Write the file's data. - filter_url_file_put_contents (filter_url_create_path ({directory, file}), data); - } - - // Close archive. - res = mtar_close(&tar); - if (res != MTAR_ESUCCESS) return mtar_strerror (res); - - // Done, hallelujah :) - return ""; -} diff --git a/filter/archive.h b/filter/archive.h deleted file mode 100644 index 3c0b3385a..000000000 --- a/filter/archive.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -std::string filter_archive_zip_folder (std::string folder); -std::string filter_archive_zip_folder_shell_internal (std::string folder); -std::string filter_archive_zip_folder_miniz_internal (std::string folder); -std::string filter_archive_unzip (std::string file); -std::string filter_archive_unzip_shell_internal (std::string file); -std::string filter_archive_unzip_miniz_internal (std::string zipfile); -std::string filter_archive_tar_gzip_file (std::string filename); -std::string filter_archive_tar_gzip_folder (std::string folder); -std::string filter_archive_untar_gzip (std::string file); -std::string filter_archive_uncompress (std::string file); -int filter_archive_is_archive (std::string file); -std::string filter_archive_microtar_pack (std::string tarball, std::string directory, std::vector files); -std::string filter_archive_microtar_unpack (std::string tarball, std::string directory); diff --git a/filter/css.cpp b/filter/css.cpp deleted file mode 100644 index 6c6265b0e..000000000 --- a/filter/css.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string Filter_Css::directionUnspecified (int value) -{ - value = value % 10; - if (value == 0) return "checked"; - else return ""; -} - - -string Filter_Css::directionLeftToRight (int value) -{ - value = value % 10; - if (value == 1) return "checked"; - else return ""; -} - - -string Filter_Css::directionRightToLeft (int value) -{ - value = value % 10; - if (value == 2) return "checked"; - else return ""; -} - - -string Filter_Css::ltr () -{ - return "ltr"; -} - - -string Filter_Css::rtl () -{ - return "rtl"; -} - - -int Filter_Css::directionValue (string direction) -{ - if (direction == ltr ()) return 1; - if (direction == rtl ()) return 2; - return 0; -} - - -string Filter_Css::writingModeUnspecified (int value) -{ - value = value / 10; - value = value % 10; - if (value == 0) return "checked"; - else return string(); -} - - -string Filter_Css::writingModeTopBottomLeftRight (int value) -{ - value = value / 10; - value = value % 10; - if (value == 1) return "checked"; - else return string(); -} - - -string Filter_Css::writingModeTopBottomRightLeft (int value) -{ - value = value / 10; - value = value % 10; - if (value == 2) return "checked"; - else return string(); -} - - -string Filter_Css::writingModeBottomTopLeftRight (int value) -{ - value = value / 10; - value = value % 10; - if (value == 3) return "checked"; - else return string(); -} - - -string Filter_Css::writingModeBottomTopRightLeft (int value) -{ - value = (value / 10); - value = value % 10; - if (value == 4) return "checked"; - else return ""; -} - - -string Filter_Css::tb_lr () -{ - return "tb-lr"; -} - - -string Filter_Css::tb_rl () -{ - return "tb-rl"; -} - - -string Filter_Css::bt_lr () -{ - return "bt-lr"; -} - - -string Filter_Css::bt_rl () -{ - return "bt-rl"; -} - - -int Filter_Css::writingModeValue (string mode) -{ - if (mode == tb_lr ()) return 1; - if (mode == tb_rl ()) return 2; - if (mode == bt_lr ()) return 3; - if (mode == bt_rl ()) return 4; - return 0; -} - - -// The purpose of the function is to convert the name of the bible into a string -// that is acceptable as a class identifier in HTML. -// Since a bible can contain any Unicode character, -// just using the bible as the class identifier will not work. -// The function solves that. -string Filter_Css::getClass (string bible) -{ - string classs = md5 (bible); - classs = classs.substr (0, 6); - classs = "custom" + classs; - return classs; -} - - -// This function produces CSS based on input. -// class: The class for the CSS. -// font: The name or URL of the font to use. It may be empty. -// directionvalue: The value for the text direction. -// $lineheigh: Value in percents. -// $letterspacing: Value multiplied by 10, in pixels. -string Filter_Css::get_css (string class_, string font, int directionvalue, int lineheight, int letterspacing) -{ - vector css; - - // If the font has a URL, then it is a web font. - if ((font != filter_url_basename_web (font)) && !font.empty()) { - css.push_back ("@font-face"); - css.push_back ("{"); - css.push_back ("font-family: " + class_ + ";"); - css.push_back ("src: url(" + font + ");"); - css.push_back ("}"); - // Below, properly reference the above web font as the class. - font = class_; - } - - css.push_back ("." + class_); - css.push_back ("{"); - - if (font != "") { - css.push_back ("font-family: " + font + ";"); - } - - int direction = directionvalue % 10; - - if (direction > 0) { - string line = "direction: "; - if (direction == 2) line += rtl (); - else line += ltr (); - line += ";"; - css.push_back (line); - } - - int mode = directionvalue / 10; - mode = mode % 10; - - if (mode > 0) { - string line = "writing-mode: "; - switch (mode) { - case 1: line += tb_lr (); break; - case 2: line += tb_rl (); break; - case 3: line += bt_lr (); break; - case 4: line += bt_rl (); break; - default: line += tb_lr (); break; - } - line += ";"; - css.push_back (line); - } - - if (lineheight != 100) { - string line = "line-height: " + filter::strings::convert_to_string (lineheight) + "%;"; - css.push_back (line); - } - - if (letterspacing != 0) { - float value = static_cast (letterspacing / 10); - string line = "letter-spacing: " + filter::strings::convert_to_string (value) + "px;"; - css.push_back (line); - } - - css.push_back ("}"); - - return filter::strings::implode (css, "\n"); -} - - -void Filter_Css::distinction_set_basic () -{ - return; -} - - -string Filter_Css::distinction_set_light (int itemstyleindex) -{ - if (itemstyleindex == 0) return "light-background"; - if (itemstyleindex == 1) return "light-menu-tabs"; - if (itemstyleindex == 2) return "light-editor"; - if (itemstyleindex == 3) return "light-active-editor"; - if (itemstyleindex == 4) return "light-workspacewrapper"; - return ""; -} - - -string Filter_Css::distinction_set_dark (int itemstyleindex) -{ - if (itemstyleindex == 0) return "dark-background"; - if (itemstyleindex == 1) return "dark-menu-tabs"; - if (itemstyleindex == 2) return "dark-editor"; - if (itemstyleindex == 3) return "dark-active-editor"; - if (itemstyleindex == 4) return "dark-workspacewrapper"; - if (itemstyleindex == 5) return "dark-versebeam"; - return ""; -} - - -string Filter_Css::distinction_set_redblue_light (int itemstyleindex) -{ - string standard_light = distinction_set_light (itemstyleindex); - if (itemstyleindex == 1) { - return standard_light = "redblue-menu-tabs"; - } else { - return standard_light; - } -} - - -string Filter_Css::distinction_set_redblue_dark (int itemstyleindex) -{ - string standard_dark = distinction_set_dark (itemstyleindex); - if (itemstyleindex == 1) { - return standard_dark = "redblue-menu-tabs"; - } else { - return standard_dark; - } -} - - -string Filter_Css::distinction_set_notes (int itemstyleindex) -{ - if (itemstyleindex == 0) return "note-status-new"; - if (itemstyleindex == 1) return "note-status-pending"; - if (itemstyleindex == 2) return "note-status-inprogress"; - if (itemstyleindex == 3) return "note-status-done"; - if (itemstyleindex == 4) return "note-status-reopened"; - if (itemstyleindex == 5) return "note-status-unset"; - return ""; -} - - -string Filter_Css::theme_picker (int indexnumber, int itemstyleindex) -{ - if (indexnumber == 0) distinction_set_basic (); - if (indexnumber == 1) return distinction_set_light (itemstyleindex); - if (indexnumber == 2) return distinction_set_dark (itemstyleindex); - if (indexnumber == 3) return distinction_set_redblue_light (itemstyleindex); - if (indexnumber == 4) return distinction_set_redblue_dark (itemstyleindex); - return ""; -} - - -string filter_css_grey_background () -{ - return R"(style="background-color: #CCCCCC")"; -} - diff --git a/filter/css.h b/filter/css.h deleted file mode 100644 index c0fef811f..000000000 --- a/filter/css.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Filter_Css -{ -public: - static std::string directionUnspecified (int value); - static std::string directionLeftToRight (int value); - static std::string directionRightToLeft (int value); - static std::string ltr (); - static std::string rtl (); - static int directionValue (std::string direction); - static std::string writingModeUnspecified (int value); - static std::string writingModeTopBottomLeftRight (int value); - static std::string writingModeTopBottomRightLeft (int value); - static std::string writingModeBottomTopLeftRight (int value); - static std::string writingModeBottomTopRightLeft (int value); - static std::string tb_lr (); - static std::string tb_rl (); - static std::string bt_lr (); - static std::string bt_rl (); - static int writingModeValue (std::string mode); - static std::string getClass (std::string bible); - static std::string get_css (std::string class_, std::string font, int directionvalue, int lineheight = 100, int letterspacing = 0); - static void distinction_set_basic (); - static std::string distinction_set_light (int itemstyleindex); - static std::string distinction_set_dark (int itemstyleindex); - static std::string distinction_set_redblue_light (int itemstyleindex); - static std::string distinction_set_redblue_dark (int itemstyleindex); - static std::string distinction_set_notes (int itemstyleindex); - static std::string theme_picker (int themestyleindex, int itemstyleindex); -}; - -std::string filter_css_grey_background (); diff --git a/filter/date.cpp b/filter/date.cpp deleted file mode 100644 index 8016edae4..000000000 --- a/filter/date.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -using namespace std; - - -namespace filter::date { - - -// Gets the second within the minute from the seconds since the Unix epoch. -int numerical_second (int seconds) -{ - time_t tt = seconds; - tm utc_tm = *gmtime(&tt); - int second = utc_tm.tm_sec; - return second; -} - - -// Gets the minute within the hour from the seconds since the Unix epoch. -int numerical_minute (int seconds) -{ - time_t tt = seconds; - tm utc_tm = *gmtime(&tt); - int minute = utc_tm.tm_min; - return minute; -} - - -// Gets the hour within the day from the seconds since the Unix epoch. -int numerical_hour (int seconds) -{ - time_t tt = seconds; - tm utc_tm = *gmtime(&tt); - int hour = utc_tm.tm_hour; - return hour; -} - - -// The numerical day of the month from 1 to 31. -int numerical_month_day (int seconds) -{ - time_t tt = seconds; - tm utc_tm = *gmtime(&tt); - int day = utc_tm.tm_mday; - return day; -} - - -// The numerical day of the week: 0 (for Sunday) through 6 (for Saturday) -int numerical_week_day (int seconds) -{ - time_t tt = seconds; - tm utc_tm = *gmtime(&tt); - int day = utc_tm.tm_wday; - return day; -} - - -// A C++ equivalent for PHP's date ("n") function. -// Numeric representation of a month: 1 through 12. -int numerical_month (int seconds) -{ - time_t tt = seconds; - tm utc_tm = *gmtime(&tt); - int month = utc_tm.tm_mon + 1; - return month; -} - - -// A C++ equivalent for PHP's date ("Y") function. -// A full numeric representation of a year, 4 digits: 2014. -int numerical_year (int seconds) -{ - time_t tt = seconds; - tm utc_tm = *gmtime(&tt); - // Get years since 1900, and correct to get years since birth of Christ. - int year = utc_tm.tm_year + 1900; - return year; -} - - -// This function gives the number of microseconds within the current second. -int numerical_microseconds () -{ - auto now = chrono::system_clock::now (); - auto duration = now.time_since_epoch (); - auto microseconds = chrono::duration_cast(duration).count(); - int usecs = static_cast(microseconds % 1000000); - return usecs; -} - - -// This function returns the seconds since the Unix epoch, which is 1 January 1970 UTC. -int seconds_since_epoch () -{ - auto now = chrono::system_clock::now (); - auto duration = now.time_since_epoch (); - int seconds = static_cast(chrono::duration_cast(duration).count()); - return seconds; -} - - -// Returns the seconds since the Unix epoch for $year and $month and $day. -int seconds_since_epoch (int year, int month, int day) -{ - int seconds = 0; - bool done = false; - bool hit = false; - do { - seconds += 86400; - int myyear = numerical_year (seconds); - int mymonth = numerical_month (seconds); - int myday = numerical_month_day (seconds); - if ((year == myyear) && (month == mymonth)) hit = true; - done = ((year == myyear) && (month == mymonth) && (day == myday)); - if (hit) if (month != mymonth) done = true; - } while (!done); - return seconds; -} - - -// This function takes the "seconds" parameter, -// corrects it according to the local timezone, -// and returns it. -int local_seconds (int seconds) -{ - int offset = Database_Config_General::getTimezone (); - seconds += (offset * 3600); - return seconds; -} - - -bool is_first_business_day_of_month (int monthday, int weekday) -{ - if (monthday == 1) { - if (weekday == 1) return true; - if (weekday == 2) return true; - if (weekday == 3) return true; - if (weekday == 4) return true; - if (weekday == 5) return true; - } - if (weekday == 1) { - if (monthday == 2) return true; - if (monthday == 3) return true; - } - return false; -} - - -int get_last_business_day_of_month (int year, int month) -{ - int myyear = year; - int mymonth = month; - get_next_month (mymonth, myyear); - int seconds = seconds_since_epoch (myyear, mymonth, 1); - int iterations = 0; - do { - seconds -= 86400; - int weekday = numerical_week_day (seconds); - if ((weekday == 1) || (weekday == 2) || (weekday == 3) || (weekday == 4) || (weekday == 5)) { - return numerical_month_day (seconds); - } - iterations++; - } while (iterations < 10); - return 28; -} - - -bool is_business_day (int year, int month, int day) -{ - int seconds = seconds_since_epoch (year, month, day); - int weekday = numerical_week_day (seconds); - if ((weekday == 1) || (weekday == 2) || (weekday == 3) || (weekday == 4) || (weekday == 5)) { - return true; - } - return false; -} - - -void get_previous_month (int & month, int & year) -{ - month--; - if (month <= 0) { - month = 12; - year--; - } -} - - -void get_next_month (int & month, int & year) -{ - month++; - if (month > 12) { - month = 1; - year++; - } -} - - -string day_rfc822 (int day) -{ - if (day == 0) return "Sun"; - if (day == 1) return "Mon"; - if (day == 2) return "Tue"; - if (day == 3) return "Wed"; - if (day == 4) return "Thu"; - if (day == 5) return "Fri"; - if (day == 6) return "Sat"; - return ""; -} - - -string month_rfc822 (int month) -{ - if (month == 1) return "Jan"; - if (month == 2) return "Feb"; - if (month == 3) return "Mar"; - if (month == 4) return "Apr"; - if (month == 5) return "May"; - if (month == 6) return "Jun"; - if (month == 7) return "Jul"; - if (month == 8) return "Aug"; - if (month == 9) return "Sep"; - if (month == 10) return "Oct"; - if (month == 11) return "Nov"; - if (month == 12) return "Dec"; - return ""; -} - - -// Converts the number of $seconds since the Unix epoch -// to date and time values according to RFC 822, -// e.g.: Wed, 02 Oct 2002 15:00:00 +0200. -string rfc822 (int seconds) -{ - string rfc822; - // The feed validator at https://validator.w3.org/feed/ says: - // Wed, 18 Feb 2017 12:26:39 +0100 - // This feed does not validate: Incorrect day of week: Wed (2 occurrences). - // Yet, 18 February 2017 is on a Wednesday. - // It continues to say that: - // If it turns out that computing the correct day of week is impractical using the software you have available, then RFC 822 permits omitting both the day of the week and the subsequent comma from the value. - // So to work around the error in the validator, the day of the week is left out. - // int weekday = numerical_week_day (seconds); - // rfc822.append (day_rfc822 (weekday)); - // rfc822.append (", "); - string monthday = filter::strings::convert_to_string (numerical_month_day (seconds)); - rfc822.append (filter::strings::fill (monthday, 2, '0')); - rfc822.append (" "); - int month = numerical_month (seconds); - rfc822.append (month_rfc822 (month)); - rfc822.append (" "); - int year = numerical_year (seconds); - rfc822.append (filter::strings::convert_to_string (year)); - rfc822.append (" "); - string hour = filter::strings::convert_to_string (numerical_hour (seconds)); - rfc822.append (filter::strings::fill (hour, 2, '0')); - rfc822.append (":"); - string minute = filter::strings::convert_to_string (numerical_minute (seconds)); - rfc822.append (filter::strings::fill (minute, 2, '0')); - rfc822.append (":"); - string second = filter::strings::convert_to_string (numerical_second (seconds)); - rfc822.append (filter::strings::fill (second, 2, '0')); - rfc822.append (" "); - int timezone = Database_Config_General::getTimezone (); - if (timezone >= 0) rfc822.append ("+"); - else rfc822.append ("-"); - if (timezone < 0) timezone = 0 - timezone; - rfc822.append (filter::strings::fill (filter::strings::convert_to_string (timezone), 2, '0')); - rfc822.append ("00"); - return rfc822; -} - - -// Calculates the number of microseconds elapsed since $start. -// It returns the elapsed number of microseconds. -long elapsed_microseconds (long start) -{ - auto now = chrono::system_clock::now (); - auto duration = now.time_since_epoch (); - auto microseconds = chrono::duration_cast(duration).count(); - long elapsed = microseconds - start; - return elapsed; -} - - -string localized_date_format () -{ - time_t tt; - time (&tt); - tm * localtm = localtime (&tt); - char buffer[20]; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-y2k" - strftime(buffer, sizeof(buffer), "%x", localtm); -#pragma GCC diagnostic pop - return string (buffer); -} - - -string date_format_to_text (date_format format) -{ - switch (format) { - case dd_mm_yyyy: return "dd/mm/yyyy"; - case mm_dd_yyyy: return "mm/dd/yyyy"; - case yyyy_mn_dd: return "yyyy-mm-dd"; - default: return string(); - } - return string(); -} - - -string localized_date_format (Webserver_Request& webserver_request) -{ - int time = seconds_since_epoch (); - - string day = filter::strings::convert_to_string (numerical_month_day (time)); - string month = filter::strings::convert_to_string (numerical_month (time)); - string year = filter::strings::convert_to_string (numerical_year (time)); - - date_format df = static_cast(webserver_request.database_config_user()->getNotesDateFormat()); - - switch (df) { - case dd_mm_yyyy: - { - return day + "/" + month + "/" + year; - } - case mm_dd_yyyy: - { - return month + "/" + day + "/" + year; - } - case yyyy_mn_dd: - default: - { - return year + "-" + month + "-" + day; - } - } - - return string(); -} - - -} - diff --git a/filter/date.h b/filter/date.h deleted file mode 100644 index c03f6ef41..000000000 --- a/filter/date.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -namespace filter::date { - -int numerical_second (int seconds); -int numerical_minute (int seconds); -int numerical_hour (int seconds); -int numerical_month_day (int seconds); -int numerical_week_day (int seconds); -int numerical_month (int seconds); -int numerical_year (int seconds); -int numerical_microseconds (); -int seconds_since_epoch (); -int seconds_since_epoch (int year, int month, int day); -int local_seconds (int seconds); -bool is_first_business_day_of_month (int monthday, int weekday); -int get_last_business_day_of_month (int year, int month); -bool is_business_day (int year, int month, int day); -void get_previous_month (int & month, int & year); -void get_next_month (int & month, int & year); -std::string day_rfc822 (int day); -std::string month_rfc822 (int month); -std::string rfc822 (int seconds); -long elapsed_microseconds (long start); -std::string localized_date_format (); - -enum date_format { - dd_mm_yyyy = 0, - mm_dd_yyyy = 1, - yyyy_mn_dd = 2 -}; -std::string date_format_to_text (date_format format); -std::string localized_date_format (Webserver_Request& webserver_request); - -} diff --git a/filter/diff.cpp b/filter/diff.cpp deleted file mode 100644 index bd4590346..000000000 --- a/filter/diff.cpp +++ /dev/null @@ -1,418 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#include -#pragma GCC diagnostic pop -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -using dtl::Diff; - - -static mutex filter_diff_mutex; - - -// This filter returns the diff of two input strings. -// $oldstring: The old string for input. -// $newstring: The new string for input. -// The function returns the differences marked. -// If the containers for $removals and $additions are given, -// they will be filled with the appropriate text fragments. -string filter_diff_diff (string oldstring, string newstring, - vector * removals, - vector * additions) -{ - // Save the new lines. - string newline = " newline_newline_newline "; - oldstring = filter::strings::replace ("\n", newline, oldstring); - newstring = filter::strings::replace ("\n", newline, newstring); - - // Split the input up into words. - // It compares with word granularity. - vector old_sequence = filter::strings::explode (oldstring, ' '); - vector new_sequence = filter::strings::explode (newstring, ' '); - - // See issue https://github.com/bibledit/cloud/issues/419 - // It is unclear at this time whether the code below - // to find the differences between texts, is thread-safe. - // So just to be sure, a mutex is placed around it. - filter_diff_mutex.lock(); - - // Run the diff engine. - Diff diff (old_sequence, new_sequence); - diff.compose(); - - // Get the shortest edit distance. - stringstream result; - diff.printSES (result); - - filter_diff_mutex.unlock(); - - // Add html markup for bold and strikethrough. - vector output = filter::strings::explode (result.str (), '\n'); - for (auto & line : output) { - if (line.empty ()) continue; - char indicator = line.front (); - line.erase (0, 1); - if (indicator == '+') { - if (additions) additions->push_back (line); - line.insert (0, R"( )"); - line.append (" "); - } - if (indicator == '-') { - if (removals) removals->push_back(line); - line.insert (0, R"( )"); - line.append (" "); - } - } - - // Resulting html. - string html = filter::strings::implode (output, " "); - - // Restore the new lines. - html = filter::strings::replace (filter::strings::trim (newline), "\n", html); - - return html; -} - - -// This filter returns the diff of two input vector's. -// $old: The old vector for input. -// $new: The new vector for input. -// -// The function produces information, -// that if applied to the old input, will produce the new input. -// This information consists of positions -// for addition or deletion operators, -// and if an addition, which content to add. -// -// Most UTF-8 characters in common use fit within two bytes when encoded in UTF-16. -// Javascript works with UTF-16. -// Also the Quilljs editor works with UTF-16. -// The positions in the Quill editor are influenced by -// whether the character is represented by 2 bytes in UTF-16, or by 4 bytes. -// A 2-byte UTF-16 character when inserted increases the position by 1. -// A 4-byte UTF-16 character when inserted increases the position by 2. -// When deleting a 4-byte UTF-16 character, the Quill API deletes 2 positions. -// -// The C++ server works with UTF-8. -// So there is a need for some translation in positios between UTF-8 in C++ and UTF-16 in Javascript. -// This function gives the positions as related to UTF-16. -// That means that characters that fit in 2-byte UTF-16 give their positions as 1. -// Those that fit in 4-byte UTF-16 give their positions as 2. -// Each differing character is given a size of 1 or 2 accordingly. -void filter_diff_diff_utf16 (const vector & oldinput, const vector & newinput, - vector & positions, - vector & sizes, - vector & additions, - vector & content, - int & new_line_diff_count) -{ - // Clear anything from the output containers just to be sure. - positions.clear(); - sizes.clear(); - additions.clear(); - content.clear(); - - // Start with zero changes in a new line. - new_line_diff_count = 0; - - // The sequences to compare. - vector old_sequence = oldinput; - vector new_sequence = newinput; - - // Save the new lines. - string newline = "_newline_"; - for (auto & s : old_sequence) { - s = filter::strings::replace ("\n", newline, s); - } - for (auto & s : new_sequence) { - s = filter::strings::replace ("\n", newline, s); - } - - // Run the diff engine. - Diff diff (old_sequence, new_sequence); - diff.compose(); - - // Get the shortest edit distance. - stringstream result; - diff.printSES (result); - - // Convert the new line place holder back to the original new line. - vector differences = filter::strings::explode (result.str (), '\n'); - for (auto & s : differences) { - s = filter::strings::replace (newline, "\n", s); - } - - // Convert the additions and deletions to a change set. - int position = 0; - for (auto & line : differences) { - if (line.empty ()) continue; - char indicator = line.front (); - line.erase (0, 1); - // Get the size of the character in UTF-16, whether 1 or 2. - string utf8 = filter::strings::unicode_string_substr (line, 0, 1); - u16string utf16 = filter::strings::convert_to_u16string (utf8); - size_t size = utf16.length(); - if (indicator == '+') { - // Something to be inserted into the old sequence to get at the new sequence. - positions.push_back(position); - sizes.push_back(static_cast (size)); - additions.push_back(true); - content.push_back(line); - // Something was inserted. - // So increase the position to point to the next offset in the sequence from where to proceed. - position += static_cast(size); - // Check on number of changes in paragraphs. - if (line.substr(0, 1) == "\n") new_line_diff_count++; - } - else if (indicator == '-') { - // Something to be deleted at the given position. - positions.push_back(position); - sizes.push_back(static_cast (size)); - additions.push_back(false); - content.push_back(line); - // Something was deleted. - // So the position will remain to point to the same offset in the sequence from where to proceed. - // Check on number of changes in paragraphs. - if (line.substr(0, 1) == "\n") new_line_diff_count++; - } - else { - // No difference. - // Increase the position of the subsequent edit - // with the amount of 16-bits code points of the current text bit in UTF-16. - position += static_cast(size); - } - } -} - - -// This calculates the similarity between the old and new strings. -// It works at the character level. -// It returns the similarity as a percentage. -// 100% means that the text is completely similar. -// And 0% means that the text is completely different. -// The output ranges from 0 to 100%. -int filter_diff_character_similarity (string oldstring, string newstring) -{ - try { - - // Split the input up into unicode characers. - vector old_sequence; - vector new_sequence; - size_t oldlength = oldstring.size(); - for (size_t i = 0; i < oldlength; i++) { - old_sequence.push_back (oldstring.substr (i, 1)); - } - size_t newlength = newstring.size(); - for (size_t i = 0; i < newlength; i++) { - new_sequence.push_back (newstring.substr (i, 1)); - } - - // See issue https://github.com/bibledit/cloud/issues/419 - // It is unclear at this time whether the code below - // to find the differences between texts, is thread-safe. - // So just to be sure, a mutex is placed around it. - filter_diff_mutex.lock(); - - // Run the diff engine. - Diff diff (old_sequence, new_sequence); - diff.compose(); - - // Get the shortest edit distance. - stringstream result; - diff.printSES (result); - - filter_diff_mutex.unlock(); - - // Calculate the total elements compared, and the total differences found. - int element_count = 0; - int similar_count = 0; - vector output = filter::strings::explode (result.str(), '\n'); - for (auto & line : output) { - if (line.empty ()) continue; - element_count++; - char indicator = line.front (); - if (indicator == ' ') similar_count++; - } - - // Calculate the percentage similarity. - int percentage = static_cast (round (100 * (static_cast(similar_count) / static_cast(element_count)))); - return percentage; - - } catch (...) { - } - // An exception was raised. - // Usually related to invalid UTF-8. - // Act as if there's no similarity at all. - return 0; -} - - -// This calculates the similarity between the old and new strings. -// It works at the word level. -// It returns the similarity as a percentage. -// 100% means that the text is completely similar. -// And 0% means that the text is completely different. -// The output ranges from 0 to 100%. -int filter_diff_word_similarity (string oldstring, string newstring) -{ - // Split the input up into words separated by spaces. - vector old_sequence; - vector new_sequence; - oldstring = filter::strings::replace ("\n", " ", oldstring); - newstring = filter::strings::replace ("\n", " ", newstring); - old_sequence = filter::strings::explode (oldstring, ' '); - new_sequence = filter::strings::explode (newstring, ' '); - - // See issue https://github.com/bibledit/cloud/issues/419 - // It is unclear at this time whether the code below - // to find the differences between texts, is thread-safe. - // So just to be sure, a mutex is placed around it. - filter_diff_mutex.lock(); - - // Run the diff engine. - Diff diff (old_sequence, new_sequence); - diff.compose(); - - // Get the shortest edit distance. - stringstream result; - diff.printSES (result); - - filter_diff_mutex.unlock(); - - // Calculate the total elements compared, and the total differences found. - int element_count = 0; - int similar_count = 0; - vector output = filter::strings::explode (result.str(), '\n'); - for (auto & line : output) { - if (line.empty ()) continue; - element_count++; - char indicator = line.front (); - if (indicator == ' ') similar_count++; - } - - // Calculate the percentage similarity. - int percentage = static_cast (round (100 * (static_cast(similar_count) / static_cast(element_count)))); - return percentage; -} - - -// This filter produces files in USFM, html and text format. -// The text files are to be used for showing the differences between them. -// The files contain all verses that differ. -// $bible: The Bible to go through. -// $directory: The existing directory where to put the files. -// Two files are created: verses_old.usfm and verses_new.usfm. -// The book chapter.verse precede each verse. -void filter_diff_produce_verse_level (string bible, string directory) -{ - Webserver_Request request; - Database_Modifications database_modifications; - string stylesheet = Database_Config_Bible::getExportStylesheet (bible); - - vector old_vs_usfm; - vector new_vs_usfm; - - Filter_Text filter_text_old = Filter_Text (bible); - filter_text_old.html_text_standard = new HtmlText (translate("Bible")); - filter_text_old.text_text = new Text_Text (); - Filter_Text filter_text_new = Filter_Text (bible); - filter_text_new.html_text_standard = new HtmlText (translate("Bible")); - filter_text_new.text_text = new Text_Text (); - - vector books = database_modifications.getTeamDiffBooks (bible); - for (auto book : books) { - string bookname = database::books::get_english_from_id (static_cast(book)); - vector chapters = database_modifications.getTeamDiffChapters (bible, book); - for (auto chapter : chapters) { - // Go through the combined verse numbers in the old and new chapter. - string old_chapter_usfm = database_modifications.getTeamDiff (bible, book, chapter); - string new_chapter_usfm = request.database_bibles()->get_chapter (bible, book, chapter); - vector old_verse_numbers = filter::usfm::get_verse_numbers (old_chapter_usfm); - vector new_verse_numbers = filter::usfm::get_verse_numbers (new_chapter_usfm); - vector verses = old_verse_numbers; - verses.insert (verses.end (), new_verse_numbers.begin (), new_verse_numbers.end ()); - verses = filter::strings::array_unique (verses); - sort (verses.begin(), verses.end()); - for (auto verse : verses) { - string old_verse_text = filter::usfm::get_verse_text (old_chapter_usfm, verse); - string new_verse_text = filter::usfm::get_verse_text (new_chapter_usfm, verse); - if (old_verse_text != new_verse_text) { - string usfmCode = "\\p " + bookname + " " + filter::strings::convert_to_string (chapter) + "." + filter::strings::convert_to_string (verse) + ": " + old_verse_text; - old_vs_usfm.push_back (usfmCode); - filter_text_old.add_usfm_code (usfmCode); - usfmCode = "\\p " + bookname + " " + filter::strings::convert_to_string (chapter) + "." + filter::strings::convert_to_string (verse) + ": " + new_verse_text; - new_vs_usfm.push_back (usfmCode); - filter_text_new.add_usfm_code (usfmCode); - } - } - } - } - - filter_url_file_put_contents (filter_url_create_path ({directory, "verses_old.usfm"}), filter::strings::implode (old_vs_usfm, "\n")); - filter_url_file_put_contents (filter_url_create_path ({directory, "verses_new.usfm"}), filter::strings::implode (new_vs_usfm, "\n")); - filter_text_old.run (stylesheet); - filter_text_new.run (stylesheet); - filter_text_old.html_text_standard->save (filter_url_create_path ({directory, "verses_old.html"})); - filter_text_new.html_text_standard->save (filter_url_create_path ({directory, "verses_new.html"})); - filter_text_old.text_text->save (filter_url_create_path ({directory, "verses_old.txt"})); - filter_text_new.text_text->save (filter_url_create_path ({directory, "verses_new.txt"})); -} - - -/** - * This filter runs a diff. - * $oldfile: The name of the old file for input. - * $newfile: The name of the new file for input. - * $outputfile: The name of the output file - */ -void filter_diff_run_file (string oldfile, string newfile, string outputfile) -{ - string oldstring = filter_url_file_get_contents (oldfile); - string newstring = filter_url_file_get_contents (newfile); - - string differences = filter_diff_diff (oldstring, newstring); - - vector lines = filter::strings::explode (differences, '\n'); - for (auto & line : lines) { - line = "

    " + line + "

    "; - } - differences = filter::strings::implode (lines, "\n"); - - filter_url_file_put_contents (outputfile, differences); -} diff --git a/filter/diff.h b/filter/diff.h deleted file mode 100644 index 6b6e273af..000000000 --- a/filter/diff.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -std::string filter_diff_diff (std::string oldstring, std::string newstring, - std::vector * removals = nullptr, - std::vector * additions = nullptr); -void filter_diff_diff_utf16 (const std::vector & oldinput, - const std::vector & newinput, - std::vector & positions, - std::vector & sizes, - std::vector & additions, - std::vector & content, - int & new_line_diff_count); -int filter_diff_character_similarity (std::string oldstring, std::string newstring); -int filter_diff_word_similarity (std::string oldstring, std::string newstring); -void filter_diff_produce_verse_level (std::string bible, std::string directory); -void filter_diff_run_file (std::string oldfile, std::string newfile, std::string outputfile); diff --git a/filter/git.cpp b/filter/git.cpp deleted file mode 100644 index 417820a06..000000000 --- a/filter/git.cpp +++ /dev/null @@ -1,642 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -#ifdef HAVE_CLOUD - - -// This function returns the directory of the git repository belonging to $object. -string filter_git_directory (string object) -{ - return filter_url_create_root_path ({"git", object}); -} - - -void filter_git_check_error (string data) -{ - vector lines = filter::strings::explode (data, '\n'); - for (auto & line : lines) Database_Logs::log (line); -} - - -// Runs the equivalent of "git init". -bool filter_git_init (string directory, bool bare) -{ - vector parameters = {"init"}; - if (bare) parameters.push_back ("--bare"); - string output, error; - int result = filter_shell_run (directory, "git", parameters, &output, &error); - filter_git_check_error (output); - filter_git_check_error (error); - return (result == 0); -} - - -// Internal function that commits a user-generated change to the git repository. -void filter_git_commit_modification_to_git (string repository, string user, int book, int chapter, - string & oldusfm, string & newusfm) -{ - string bookname = database::books::get_english_from_id (static_cast(book)); - string bookdir = filter_url_create_path ({repository, bookname}); - string chapterdir = filter_url_create_path ({bookdir, filter::strings::convert_to_string (chapter)}); - if (!file_or_dir_exists (chapterdir)) filter_url_mkdir (chapterdir); - string datafile = filter_url_create_path ({chapterdir, "data"}); - string contents = filter_url_file_get_contents (datafile); - if (contents != oldusfm) { - filter_url_file_put_contents (datafile, oldusfm); - string error; - filter_git_add_remove_all (repository, error); - vector messages; - filter_git_commit (repository, "", "System-generated to clearly display user modification in next commit", messages, error); - } - filter_url_file_put_contents (datafile, newusfm); - string error; - filter_git_add_remove_all (repository, error); - vector messages; - filter_git_commit (repository, user, "User modification", messages, error); -} - - -// This filter stores the changes made by users on $bible in $repository. -// This puts commits in the repository, where the author is the user who made the changes. -// This information in the git repository can then be used for statistical or other purposes. -void filter_git_sync_modifications_to_git (string bible, string repository) -{ - // Go through all the users who saved data to this Bible. - vector users = Database_Git::get_users (bible); - for (auto & user : users) { - - bool iteration_initialized = false; - string overall_old_usfm, overall_new_usfm; - int overall_book = 0, overall_chapter = 0; - - // Go through all the rowids for the user and the Bible. - vector rowids = Database_Git::get_rowids (user, bible); - for (auto rowid : rowids) { - - string s; - string oldusfm, newusfm; - int book, chapter; - Database_Git::get_chapter (rowid, s, s, book, chapter, oldusfm, newusfm); - - if (iteration_initialized) { - // Look at the sequences of old and new USFM, and join the matching changes together, - // to make one large change that contains all sequential small changes. - if (oldusfm == overall_new_usfm) { - overall_new_usfm = newusfm; - } else { - filter_git_commit_modification_to_git (repository, user, overall_book, overall_chapter, - overall_old_usfm, overall_new_usfm); - iteration_initialized = false; - } - } - - if (!iteration_initialized) { - // Initialize the large overall book/chapter/USFM from the first change set. - overall_book = book; - overall_chapter = chapter; - overall_old_usfm = oldusfm; - overall_new_usfm = newusfm; - iteration_initialized = true; - } - - // This record has been processed. - Database_Git::erase_rowid (rowid); - - } - - if (iteration_initialized) { - // Commit the final overall modification. - filter_git_commit_modification_to_git (repository, user, overall_book, overall_chapter, - overall_old_usfm, overall_new_usfm); - } - - } -} - - -// This filter takes the Bible data as it is stored in Bibledit's database, -// and puts this information into the layout in books and chapters -// such as is used in Bibledit-Gtk into the $git folder. -// The $git is a git repository, and may contain other data as well. -// The filter focuses on reading the data in the git repository, and only writes to it if necessary, -// This speeds up the filter. -void filter_git_sync_bible_to_git (Webserver_Request& webserver_request, string bible, string repository) -{ - // First stage. - // Read the chapters in the git repository, - // and check if they occur in the database. - // If a chapter is not in the database, remove it from the repository. - vector books = webserver_request.database_bibles()->get_books (bible); - vector bookfiles = filter_url_scandir (repository); - for (auto & bookname : bookfiles) { - string path = filter_url_create_path ({repository, bookname}); - if (filter_url_is_dir (path)) { - int book = static_cast(database::books::get_id_from_english (bookname)); - if (book) { - if (in_array (book, books)) { - // Book exists in the database: Check the chapters. - vector chapters = webserver_request.database_bibles()->get_chapters (bible, book); - vector chapterfiles = filter_url_scandir (filter_url_create_path ({repository, bookname})); - for (auto & chaptername : chapterfiles) { - string chapter_path = filter_url_create_path ({repository, bookname, chaptername}); - if (filter_url_is_dir (chapter_path)) { - if (filter::strings::is_numeric (chaptername)) { - int chapter = filter::strings::convert_to_int (chaptername); - string filename = filter_url_create_path ({repository, bookname, chaptername, "data"}); - if (file_or_dir_exists (filename)) { - if (!in_array (chapter, chapters)) { - // Chapter does not exist in the database. - filter_url_rmdir (filter_url_create_path ({repository, bookname, chaptername})); - } - } - } - } - } - } else { - // Book does not exist in the database: Remove it from $git. - filter_url_rmdir (filter_url_create_path ({repository, bookname})); - } - } - } - } - - // Second stage. - // Read the books / chapters from the database, - // and check if they occur in the repository, and the data matches. - // If necessary, save the chapter to the repository. - books = webserver_request.database_bibles()->get_books (bible); - for (auto & book : books) { - string bookname = database::books::get_english_from_id (static_cast(book)); - string bookdir = filter_url_create_path ({repository, bookname}); - if (!file_or_dir_exists (bookdir)) filter_url_mkdir (bookdir); - vector chapters = webserver_request.database_bibles()->get_chapters (bible, book); - for (auto & chapter : chapters) { - string chapterdir = filter_url_create_path ({bookdir, filter::strings::convert_to_string (chapter)}); - if (!file_or_dir_exists (chapterdir)) filter_url_mkdir (chapterdir); - string datafile = filter_url_create_path ({chapterdir, "data"}); - string contents = filter_url_file_get_contents (datafile); - string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - if (contents != usfm) filter_url_file_put_contents (datafile, usfm); - } - } -} - - -// This filter takes the Bible data as it is stored in the git $repository folder, -// and puts this information into Bibledit's database. -// The $repository is a git repository, and may contain other data as well. -// The filter focuses on reading the data in the git repository and the database, -// and only writes to the database if necessary, -// This speeds up the filter. -void filter_git_sync_git_to_bible (Webserver_Request& webserver_request, string repository, string bible) -{ - // Stage one: - // Read the chapters in the git repository, - // and check that they occur in the database. - // If any does not occur, add the chapter to the database. - // This stage does not check the contents of the chapters. - vector bookfiles = filter_url_scandir (repository); - for (auto & bookname : bookfiles) { - string bookpath = filter_url_create_path ({repository, bookname}); - if (filter_url_is_dir (bookpath)) { - int book = static_cast(database::books::get_id_from_english (bookname)); - if (book) { - // Check the chapters. - vector chapters = webserver_request.database_bibles()->get_chapters (bible, book); - vector chapterfiles = filter_url_scandir (bookpath); - for (auto & chapterfile : chapterfiles) { - string chapterpath = filter_url_create_path ({bookpath, chapterfile}); - if (filter_url_is_dir (chapterpath)) { - if (filter::strings::is_numeric (chapterfile)) { - int chapter = filter::strings::convert_to_int (chapterfile); - string filename = filter_url_create_path ({chapterpath, "data"}); - if (file_or_dir_exists (filename)) { - if (!in_array (chapter, chapters)) { - // Chapter does not exist in the database: Add it. - string usfm = filter_url_file_get_contents (filename); - bible_logic::store_chapter (bible, book, chapter, usfm); - // Log it. - string message = translate("A translator added chapter") + " " + bible + " " + bookname + " " + chapterfile; - Database_Logs::log (message); - } - } - } - } - } - } - } - } - - - // Stage two: - // Read through the chapters in the database, - // and check that they occur in the git folder. - // If necessary, remove a chapter from the database. - // If a chapter matches, check that the contents of the data in the git - // folder and the contents in the database match. - // If necessary, update the data in the database. - vector books = webserver_request.database_bibles()->get_books (bible); - for (auto & book : books) { - string bookname = database::books::get_english_from_id (static_cast(book)); - string bookdir = filter_url_create_path ({repository, bookname}); - if (file_or_dir_exists (bookdir)) { - vector chapters = webserver_request.database_bibles()->get_chapters (bible, book); - for (auto & chapter : chapters) { - string chapterdir = filter_url_create_path ({bookdir, filter::strings::convert_to_string (chapter)}); - if (file_or_dir_exists (chapterdir)) { - string datafile = filter_url_create_path ({chapterdir, "data"}); - string contents = filter_url_file_get_contents (datafile); - string usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - if (contents != usfm) { - bible_logic::store_chapter (bible, book, chapter, contents); - Database_Logs::log (translate("A translator updated chapter") + " " + bible + " " + bookname + " " + filter::strings::convert_to_string (chapter)); - rss_logic_schedule_update ("collaborator", bible, book, chapter, usfm, contents); - } - } else { - bible_logic::delete_chapter (bible, book, chapter); - Database_Logs::log (translate("A translator deleted chapter") + " " + bible + " " + bookname + " " + filter::strings::convert_to_string (chapter)); - } - } - } else { - bible_logic::delete_book (bible, book); - Database_Logs::log (translate("A translator deleted book") + " " + bible + " " + bookname); - } - } -} - - -string filter_git_disabled () -{ - return "Git has been disabled on iOS and Android, and can be enabled on Linux, Windows and macOS"; -} - - -// This filter takes one chapter of the Bible data as it is stored in the $git folder, -// and puts this information into Bibledit's database. -// The $git is a git repository, and may contain other data as well. -void filter_git_sync_git_chapter_to_bible (string repository, string bible, int book, int chapter) -{ - // Filename for the chapter. - string bookname = database::books::get_english_from_id (static_cast(book)); - string filename = filter_url_create_path ({repository, bookname, filter::strings::convert_to_string (chapter), "data"}); - - if (file_or_dir_exists (filename)) { - - // Store chapter in database and log it. - Database_Bibles database_bibles; - string existing_usfm = database_bibles.get_chapter (bible, book, chapter); - string usfm = filter_url_file_get_contents (filename); - bible_logic::log_change (bible, book, chapter, usfm, "collaborator", "Chapter updated from git repository", false); - bible_logic::store_chapter (bible, book, chapter, usfm); - rss_logic_schedule_update ("collaborator", bible, book, chapter, existing_usfm, usfm); - - } else { - - // Delete chapter from database. - bible_logic::delete_chapter (bible, book, chapter); - Database_Logs::log (translate("A collaborator deleted chapter") + " " + bible + " " + bookname + " " + filter::strings::convert_to_string (chapter)); - - } -} - - -// Returns true if the git repository at "url" is online. -bool filter_git_remote_read (string url, string & error) -{ - string output; - int result = filter_shell_run ("", "git", {"ls-remote", url}, &output, &error); - filter_git_check_error (output); - filter_git_check_error (error); - return (result == 0); -} - - -bool filter_git_remote_clone (string url, string path, [[maybe_unused]] int jobid, string & error) -{ - // Clear a possible existing git repository directory. - filter_url_rmdir (path); - - string output; - int result = filter_shell_run ("", "git", {"clone", url, path}, &output, &error); - filter_git_check_error (output); - filter_git_check_error (error); - error.clear (); - return (result == 0); -} - - -bool filter_git_add_remove_all (string repository, string & error) -{ - string output; - int result = filter_shell_run (repository, "git", {"add", "--all", "."}, &output, &error); - filter_git_check_error (output); - filter_git_check_error (error); - return (result == 0); -} - - -// This function runs "git commit" through the shell. -bool filter_git_commit (string repository, string user, string message, - vector & messages, string & error) -{ - user = filter_git_user (user); - string email = filter_git_email (user); - stringstream author; - author << "--author=" << quoted(user + " <" + email + ">"); - string out, err; - int result = filter_shell_run (repository, "git", - {"commit", - author.str(), - "-a", - "-m", - message - }, &out, &err); - out = filter::strings::trim (out); - err = filter::strings::trim (err); - error = err; - filter_git_check_error (error); - messages = filter::strings::explode (out, '\n'); - vector lines = filter::strings::explode (err, '\n'); - messages.insert (messages.end(), lines.begin(), lines.end()); - - // In case of Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean, - // git returns exit code 256. Yet this is not an error. - if (out.find ("nothing to commit") != std::string::npos) result = 0; - - return (result == 0); -} - - -void filter_git_config_set_bool (string repository, string name, bool value) -{ - string svalue = value ? "true" : "false"; - filter_git_config_set_string (repository, name, svalue); -} - - -void filter_git_config_set_int (string repository, string name, int value) -{ - string svalue = filter::strings::convert_to_string (value); - filter_git_config_set_string (repository, name, svalue); -} - - -void filter_git_config_set_string (string repository, string name, string value) -{ - string output, error; - filter_shell_run (repository, "git", {"config", name, value}, &output, &error); -} - - -// This filter takes a $line of the output of the git pull command. -// It tries to interpret it to find a passage that would have been updated. -// If a valid book and chapter are found, it returns them. -Passage filter_git_get_passage (string line) -{ - // Sample lines for git pull: - - // "From https://github.com/joe/test" - // " 443579b..90dcb57 master -> origin/master" - // "Updating 443579b..90dcb57" - // "Fast-forward" - // " Genesis/1/data | 2 +-" - // " 1 file changed, 1 insertion(+), 1 deletion(-)" - // " delete mode 100644 Leviticus/1/data" - // " create mode 100644 Leviticus/2/data" - - // Sample lines for git status: - - // On branch master - // Your branch is up-to-date with 'origin/master'. - - // Changes not staged for commit: - // (use "git add ..." to update what will be committed) - // (use "git checkout -- ..." to discard changes in working directory) - // modified: Genesis/1/data - // no changes added to commit (use "git add" and/or "git commit -a") - - Passage passage; - vector bits = filter::strings::explode (line, '/'); - if (bits.size () == 3) { - size_t pos = bits [0].find (":"); - if (pos != std::string::npos) bits [0].erase (0, pos + 1); - string bookname = filter::strings::trim (bits [0]); - int book = static_cast(database::books::get_id_from_english (bookname)); - if (book) { - if (filter::strings::is_numeric (bits [1])) { - int chapter = filter::strings::convert_to_int (bits [1]); - string data = bits [2]; - if (data.find ("data") != std::string::npos) { - passage.m_book = book; - passage.m_chapter = chapter; - } - } - } - } - return passage; -} - - -// Reports information comparable to "git status". -// Repository: "repository". -// If $porcelain is given, it adds the --porcelain flag. -// All changed files will be returned. -vector filter_git_status (string repository, bool porcelain) -{ - vector paths; - string output, error; - vector parameters = {"status"}; - if (porcelain) parameters.push_back("--porcelain"); - filter_shell_run (repository, "git", parameters, &output, &error); - filter_git_check_error (error); - paths = filter::strings::explode (output, '\n'); - return paths; -} - - -// Runs "git pull" and returns true if it ran fine. -// It puts the messages in container "messages". -bool filter_git_pull (string repository, vector & messages) -{ - string out, err; - int result = filter_shell_run (repository, "git", {"pull"}, &out, &err); - out = filter::strings::trim (out); - err = filter::strings::trim (err); - messages = filter::strings::explode (out, '\n'); - vector lines = filter::strings::explode (err, '\n'); - messages.insert (messages.end(), lines.begin(), lines.end()); - return (result == 0); -} - - -// Runs "git pull" and returns true if it ran fine. -// It puts the push messages in container "messages". -bool filter_git_push (string repository, vector & messages, bool all) -{ - string out, err; - vector parameters = {"push"}; - if (all) parameters.push_back ("--all"); - int result = filter_shell_run (repository, "git", parameters, &out, &err); - out = filter::strings::trim (out); - err = filter::strings::trim (err); - messages = filter::strings::explode (out, '\n'); - vector lines = filter::strings::explode (err, '\n'); - messages.insert (messages.end(), lines.begin(), lines.end()); - return (result == 0); -} - - -// Resolves any conflicts in "repository". -// It fills "paths" with the paths to the files with the resolved merge conflicts. -// It fills "error" with any error that git generates. -// It returns true on success, that is, no errors occurred. -bool filter_git_resolve_conflicts (string repository, vector & paths, string & error) -{ - int result = 0; - paths.clear(); - - // Get the unmerged paths. - // Use the --porcelain parameter for a better API for scripting. - vector unmerged_paths; - vector lines = filter_git_status (repository, true); - for (auto line : lines) { - size_t pos = line.find ("UU "); - if (pos != std::string::npos) { - line.erase (0, 3); - line = filter::strings::trim (line); - unmerged_paths.push_back (line); - } - } - - // Deal with each unmerged path. - for (auto & unmerged_path : unmerged_paths) { - - string common_ancestor; - filter_shell_run (repository, "git", {"show", ":1:" + unmerged_path}, &common_ancestor, &error); - - string head_version; - filter_shell_run (repository, "git", {"show", ":2:" + unmerged_path}, &head_version, &error); - - string merge_head_version; - filter_shell_run (repository, "git", {"show", ":3:" + unmerged_path}, &merge_head_version, &error); - - string mergeBase (common_ancestor); - string userData (head_version); - string serverData (merge_head_version); - - vector conflicts; - string mergedData = filter_merge_run (mergeBase, userData, serverData, true, conflicts); - mergedData = filter::strings::trim (mergedData); - filter_url_file_put_contents (filter_url_create_path ({repository, unmerged_path}), mergedData); - - paths.push_back (unmerged_path); - } - - if (!unmerged_paths.empty ()) { - vector messages; - string error2; - filter_git_commit (repository, "", translate ("Bibledit fixed merge conflicts"), messages, error2); - } - - // Done. - return (result == 0); -} - - -// Configure the $repository: Make certain settings. -void filter_git_config (string repository) -{ - // At times there's a stale index.lock file that prevents any collaboration. - // This is to be removed. - string index_lock = filter_url_create_path ({repository, ".git", "index.lock"}); - if (file_or_dir_exists (index_lock)) { - Database_Logs::log ("Cleaning out index lock " + index_lock); - filter_url_unlink (index_lock); - } - - // On some machines the mail name and address are not set properly; therefore these are set here. - string user = Database_Config_General::getSiteMailName (); - if (user.empty ()) user = "Bibledit"; - filter_git_config_set_string (repository, "user.name", user); - - string mail = Database_Config_General::getSiteMailAddress (); - if (mail.empty ()) mail = "bibledit@bibledit.org"; - filter_git_config_set_string (repository, "user.email", mail); - - // Switch rename detection off. - // This is for the consultation notes, since git has been seen to falsely "detect" renames. - filter_git_config_set_int (repository, "diff.renamelimit", 0); - filter_git_config_set_bool (repository, "diff.renames", false); - - // Current versions of git ask the user to set the default push method. - filter_git_config_set_string (repository, "push.default", "matching"); - - // Newer version of git do not automatically fast-forward, so set that here. - filter_git_config_set_string (repository, "pull.ff", "yes"); - -} - - -// This checks $user, and optionally set it, to be sure it always returns a username. -string filter_git_user (string user) -{ - if (user.empty ()) { - user = Database_Config_General::getSiteMailName (); - } - if (user.empty ()) { - user = "Bibledit Cloud"; - } - return user; -} - - -// This takes the email address that belongs to $user, -// and optionally sets the email address to a valid value, -// and returns that email address. -string filter_git_email (string user) -{ - Database_Users database_users; - string email = database_users.get_email (user); - if (email.empty ()) { - email = Database_Config_General::getSiteMailAddress (); - } - if (email.empty ()) { - email = "bibledit@bibledit.org"; - } - return email; -} - - -#endif diff --git a/filter/git.h b/filter/git.h deleted file mode 100644 index 8654519d1..000000000 --- a/filter/git.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include - -class Webserver_Request; - -#ifdef HAVE_CLOUD -std::string filter_git_directory (std::string object); -bool filter_git_init (std::string directory, bool bare = false); -void filter_git_sync_modifications_to_git (std::string bible, std::string repository); -void filter_git_sync_bible_to_git (Webserver_Request& webserver_request, std::string bible, std::string repository); -void filter_git_sync_git_to_bible (Webserver_Request& webserver_request, std::string repository, std::string bible); -void filter_git_sync_git_chapter_to_bible (std::string repository, std::string bible, int book, int chapter); -bool filter_git_remote_read (std::string url, std::string & error); -bool filter_git_remote_clone (std::string url, std::string path, int jobid, std::string & error); -bool filter_git_add_remove_all (std::string repository, std::string & error); -bool filter_git_commit (std::string repository, std::string user, std::string message, - std::vector & messages, std::string & error); -void filter_git_config_set_bool (std::string repository, std::string name, bool value); -void filter_git_config_set_int (std::string repository, std::string name, int value); -void filter_git_config_set_string (std::string repository, std::string name, std::string value); -Passage filter_git_get_passage (std::string line); -std::vector filter_git_status (std::string repository, bool porcelain = false); -bool filter_git_pull (std::string repository, std::vector & messages); -bool filter_git_push (std::string repository, std::vector & messages, bool all = false); -bool filter_git_resolve_conflicts (std::string repository, std::vector & paths, std::string & error); -void filter_git_config (std::string repository); -std::string filter_git_user (std::string user); -std::string filter_git_email (std::string user); -#endif diff --git a/filter/google.cpp b/filter/google.cpp deleted file mode 100644 index a4b63e73a..000000000 --- a/filter/google.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wuseless-cast" -#include -#pragma GCC diagnostic pop -using namespace std; -using namespace jsonxx; - - -namespace filter::google { - - -tuple get_json_key_value_error () -{ - string path = config::logic::google_translate_json_key_path (); - - if (!file_or_dir_exists (path)) { - return { string(), "Cannot find the JSON key to access Google Translate. Looking for this file: " + path }; - } - - string error; - string value = filter_url_file_get_contents (path); - if (value.empty()) error = "The key at " + path + " is empty"; - - return { value, error }; -} - - -// This runs $ gcloud auth activate-service-account --key-file=key.json. -// It returns whether activation was successful, -// plus the resulting output of the command. -tuple activate_service_account () -{ - stringstream command; - command << "gcloud auth activate-service-account --quiet --key-file="; - command << quoted(config::logic::google_translate_json_key_path ()); - string out_err; - int result = filter_shell_run (command.str(), out_err); - return { (result == 0), out_err }; -} - - -string google_access_token {}; - -// This runs $ gcloud auth application-default print-access-token. -// It returns whether the command was successful, -// plus the resulting output of the command. -tuple print_store_access_token () -{ - // Set the path to the JSON key in the environment for gcloud to use. -#ifdef HAVE_CLOUD - setenv("GOOGLE_APPLICATION_CREDENTIALS", config::logic::google_translate_json_key_path ().c_str(), 1); -#endif - // Print the access token. - string command {"gcloud auth application-default print-access-token"}; - string out_err; - int result = filter_shell_run (command.c_str(), out_err); - // Check on success. - bool success = (result == 0); - // Store the token if it was received, else clear it. - // Trim the token to remove any new line it likely contains. - if (success) google_access_token = filter::strings::trim(out_err); - else google_access_token.clear(); - // Done. - return { success, out_err }; -} - - -// Refreshes the Google access token. -void refresh_access_token () -{ - // Check whether the JSON keys exists, if not, bail out. - if (!file_or_dir_exists(config::logic::google_translate_json_key_path ())) { - return; - } - - // Refresh the token. - auto [ success, token ] = print_store_access_token (); - - Database_Logs::log ("Google access token: " + token); -} - - -// This makes an authenticated call to the Google Translate API. -// Pass the text to be translated. -// Pass the source language code and the target language code. -// It returns whether the call was successful, plus the translated text, plus the error -tuple translate (const string text, const char * source, const char * target) -{ - // From the shell, run these two commands to translate a string. - // $ export GOOGLE_APPLICATION_CREDENTIALS=`pwd`"/googletranslate.json" - // $ curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) --data "{ 'q': 'The quick brown fox jumps over the lazy dog', 'source': 'en', 'target': 'fr', 'format': 'text' }" "https://translation.googleapis.com/language/translate/v2" - - // The URL of the translation REST API. - const string url { "https://translation.googleapis.com/language/translate/v2" }; - - // Create the JSON data to post. - Object translation_data; - translation_data << "q" << text; - translation_data << "source" << string (source); - translation_data << "target" << string (target); - translation_data << "format" << "text"; - string postdata = translation_data.json (); - - string error; - bool burst { false }; - bool check_certificate { false }; - const vector > headers { - { "Content-Type", "application/json" }, - { "Authorization", "Bearer " + google_access_token } - }; - string translation = filter_url_http_post (url, postdata, {}, error, burst, check_certificate, headers); - bool success { error.empty() }; - - // Parse the translation JSON. - // Example: - // { - // "data": { - // "translations": [ - // { - // "translatedText": "Ιησούς ο Χριστός ο Μεσσίας" - // } - // ] - // } - // } - if (error.empty()) { - try { - Object json_object; - json_object.parse (translation); - Object data = json_object.get ("data"); - Array translations = data.get ("translations"); - Object translated = translations.get(0); - translation = translated.get ("translatedText"); - } catch (const exception & exception) { - error = exception.what(); - error.append (" - "); - error.append(translation); - success = false; - translation.clear(); - } - } - - if (!error.empty()) { - Database_Logs::log("Error while translating text: " + error); - } - - // Done. - return { success, translation, error }; -} - - -// This asks the Google Translate API for the list of supported languages. -// It returns a container with a pair of . -// The language name is given in the $target language. -vector > get_languages (const string & target) -{ - - // From the shell, run these two commands to translate a string. - // $ export GOOGLE_APPLICATION_CREDENTIALS=`pwd`"/googletranslate.json" - // $ curl -s -X POST -H "Content-Type: application/json; charset=utf-8" -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) --data "{ 'target': 'en' }" "https://translation.googleapis.com/language/translate/v2/languages" - - // The URL of the translation REST API. - const string url { "https://translation.googleapis.com/language/translate/v2/languages" }; - - // Create the JSON data to post. - Object request_data; - request_data << "target" << target; - string postdata = request_data.json (); - - string error; - bool burst { false }; - bool check_certificate { false }; - const vector > headers { - { "Content-Type", "application/json; charset=utf-8" }, - { "Authorization", "Bearer " + google_access_token } - }; - string result_json = filter_url_http_post (url, postdata, {}, error, burst, check_certificate, headers); - - // Parse the resulting JSON. - // Example: - // { - // "data": { - // "languages": [ - // { - // "language": "zh-CN", - // "name": "Chinese (Simplified)" - // }, - // { - // "language": "he", - // "name": "Hebrew" - // }, - // { - // "language": "zu", - // "name": "Zulu" - // } - // ] - // } - // } - vector > language_codes_names; - if (error.empty()) { - try { - Object json_object; - json_object.parse (result_json); - Object data = json_object.get ("data"); - Array languages = data.get ("languages"); - for (size_t i = 0; i < languages.size(); i++) { - Object language_name = languages.get(static_cast(i)); - string language = language_name.get("language"); - string name = language_name.get("name"); - language_codes_names.push_back({language, name}); - } - } catch (const exception & exception) { - error = exception.what(); - error.append (" - "); - error.append(result_json); - language_codes_names.clear(); - } - } - - if (!error.empty()) { - Database_Logs::log("Error while getting Google Translate supported languages: " + error); - language_codes_names.clear(); - } - - // Done. - return language_codes_names; -} - - -} diff --git a/filter/google.h b/filter/google.h deleted file mode 100644 index cb3741993..000000000 --- a/filter/google.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -namespace filter::google { - -std::tuple get_json_key_value_error (); -std::tuple activate_service_account (); -std::tuple print_store_access_token (); -void refresh_access_token (); -std::tuple translate (const std::string text, const char * source, const char * target); -std::vector > get_languages (const std::string & target); - -} diff --git a/filter/html.cpp b/filter/html.cpp deleted file mode 100644 index 0a42d050f..000000000 --- a/filter/html.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -using namespace std; - - -// There's weird behaviour on Android that prevents clicking links at a certain location. -// See https://github.com/bibledit/cloud/issues/321 -// This function delivers a set of
    to mitigate the problem. -string filter_html_android_brs () -{ - string brs; -#ifdef HAVE_ANDROID - brs = "













    "; -#endif - return brs; -} diff --git a/filter/html.h b/filter/html.h deleted file mode 100644 index 0de1ff11a..000000000 --- a/filter/html.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -std::string filter_html_android_brs (); diff --git a/filter/image.cpp b/filter/image.cpp deleted file mode 100644 index aca23a161..000000000 --- a/filter/image.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include - - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-qual" -#pragma GCC diagnostic ignored "-Wcast-align" -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#ifdef COMPILERGCC -#pragma GCC diagnostic ignored "-Wduplicated-branches" -#endif -#define STB_IMAGE_IMPLEMENTATION -#include "stb/stb_image.h" -#pragma GCC diagnostic pop -using namespace std; - - -void filter_image_get_sizes (string image_path, int & width, int & height) -{ - int bpp; - uint8_t* rgb_image = stbi_load (image_path.c_str(), &width, &height, &bpp, 0); - if (rgb_image) { - stbi_image_free(rgb_image); - } -} diff --git a/filter/image.h b/filter/image.h deleted file mode 100644 index 915c8e226..000000000 --- a/filter/image.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -void filter_image_get_sizes (std::string image_path, int & width, int & height); diff --git a/filter/mail.cpp b/filter/mail.cpp deleted file mode 100644 index 18be09d13..000000000 --- a/filter/mail.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include - - -#ifdef HAVE_CLOUD - - -// http://www.codesink.org/mimetic_mime_library.html - - -// Suppress warnings in the included header. -#pragma GCC diagnostic push -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#pragma clang diagnostic ignored "-Wdeprecated-register" -#pragma clang diagnostic ignored "-Wunused-private-field" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wdocumentation" -#pragma clang diagnostic ignored "-Wconditional-uninitialized" -#pragma clang diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#include -#pragma clang diagnostic pop -#pragma GCC diagnostic pop -using namespace std; -using namespace mimetic; - - -string filter_mail_remove_headers_internal (string contents) -{ - bool empty_line_encountered = false; - vector cleaned; - vector inputlines = filter::strings::explode (contents, '\n'); - for (auto line : inputlines) { - if (line.find ("Content-Type") != std::string::npos) continue; - if (line.find ("Content-Transfer-Encoding") != std::string::npos) continue; - if (empty_line_encountered) cleaned.push_back (line); - if (filter::strings::trim (line).empty ()) empty_line_encountered = true; - } - contents = filter::strings::implode (cleaned, "\n"); - contents = filter::strings::trim (contents); - return contents; -} - - -void filter_mail_dissect_internal (const MimeEntity& me, string& plaintext) -{ - // If the plain text of this email has been found already, - // there's no need to search any further. - if (!plaintext.empty ()) return; - - // Get the header of this part. - const Header& h = me.header(); - - // Look for content type and subtype. - // Fold their case as some messages use upper case. - string type = filter::strings::unicode_string_casefold (h.contentType().type()); - string subtype = filter::strings::unicode_string_casefold (h.contentType().subtype()); - - if (type == "text") { - - if (subtype== "plain") { - // Get the plain text of the message. - stringstream ss; - ss << me; - plaintext = ss.str (); - // Remove headers. - plaintext = filter_mail_remove_headers_internal (plaintext); - } - - if (subtype== "html") { - // Get the html text of the message. - stringstream ss; - ss << me; - string html = ss.str (); - // Remove headers. - html = filter_mail_remove_headers_internal (html); - // Convert the html to plain text. - plaintext = filter::strings::html2text (html); - } - - // Get transfer encoding. - // Fold the case as some email messages use uppercase. - string transfer_encoding = filter::strings::unicode_string_casefold (h.contentTransferEncoding().str ()); - - // Decode quoted-printable text. - if (transfer_encoding == ContentTransferEncoding::quoted_printable) { - istringstream is (plaintext); - ostringstream os; - istreambuf_iterator ibeg (is), iend; - ostreambuf_iterator out (os); - QP::Decoder qp; - decode (ibeg, iend, qp, out); - plaintext = os.str (); - } - - // Decode base64 text. - if (transfer_encoding == ContentTransferEncoding::base64) { - istringstream is (plaintext); - ostringstream os; - istreambuf_iterator ibeg (is), iend; - ostreambuf_iterator out (os); - Base64::Decoder b64; - code (ibeg, iend, b64, out); - plaintext = os.str (); - } - } - - // Iterate over the other parts it may contain and process them. - MimeEntityList::const_iterator mime_body_iterator = me.body().parts().begin(); - MimeEntityList::const_iterator meit = me.body().parts().end(); - for (; mime_body_iterator != meit; ++mime_body_iterator) { - filter_mail_dissect_internal (**mime_body_iterator, plaintext); - } -} - - -// Dissects an email $message. -// It extracts the $from address, the $subject, and the plain text body. -void filter_mail_dissect (string message, string & from, string & subject, string & plaintext) -{ - // Load the email message into the mimetic library. - MimeEntity me; - me.load (message.begin(), message.end(), 0); - - // Get the sender's address. - stringstream fromstream; - fromstream << me.header().from(); - from = fromstream.str (); - - // Get the subject. - stringstream subjectstream; - subjectstream << me.header().subject(); - subject = subjectstream.str (); - - // Get the plain text body. - filter_mail_dissect_internal (me, plaintext); - - // In case it's not a MIME message, the plain/text part will not be there. - // Take the email's entire body instead. - if (plaintext.empty ()) plaintext = me.body (); - - // Clean the text body up. - vector cleaned; - vector inputlines = filter::strings::explode (plaintext, '\n'); - for (auto line : inputlines) { - // Remove whitespace and empty lines. - line = filter::strings::trim (line); - if (line.empty ()) continue; - // If the line starts with ">", it indicates quoted text. Skip it. - if (line.substr (0, 1) == ">") continue; - // Store this line. - cleaned.push_back (line); - } - plaintext = filter::strings::implode (cleaned, "\n"); -} - - -#endif diff --git a/filter/mail.h b/filter/mail.h deleted file mode 100644 index c7ac78580..000000000 --- a/filter/mail.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -#ifdef HAVE_CLOUD -void filter_mail_dissect (std::string message, std::string & from, std::string & subject, std::string & plaintext); -#endif diff --git a/filter/md5.cpp b/filter/md5.cpp deleted file mode 100644 index 714ebeb95..000000000 --- a/filter/md5.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -using namespace std; - - -string md5 (const string str) -{ - unsigned char md5sum[16]; - const unsigned char *input = reinterpret_cast(str.c_str ()); - [[maybe_unused]] int ret = mbedtls_md5_ret (input, str.size (), md5sum); - - // Space for 32 bytes of hexits and one terminating null byte. - char hexits [32+1]; - - memset (hexits, 0, sizeof (hexits)); - for (int i = 0; i < 16; i++) { - // sprintf (&hexits[i*2], "%02x", static_cast(md5sum[i])); - // Function sprintf is marked as deprecated. - // Due to security concerns inherent in the design of sprintf(3), - // it now uses snprintf(3) instead. - snprintf (&hexits[i*2], 3, "%02x", static_cast(md5sum[i])); - } - - // Resulting hexits. - return string (hexits); -} diff --git a/filter/md5.h b/filter/md5.h deleted file mode 100644 index 77a857a07..000000000 --- a/filter/md5.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -std::string md5 (const std::string str); diff --git a/filter/memory.cpp b/filter/memory.cpp deleted file mode 100644 index 254ed7769..000000000 --- a/filter/memory.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#ifdef HAVE_MACH_MACH -#include -#endif -#ifdef HAVE_EXECINFO -#include -#endif -using namespace std; - - -// Returns the memory available as a percentage of the total system memory. -int filter_memory_percentage_available () -{ -#ifdef HAVE_MACH_MACH - // macOS. - struct vm_statistics64 stats; - mach_port_t host = mach_host_self(); - natural_t count = HOST_VM_INFO64_COUNT; - host_statistics64 (host, HOST_VM_INFO64, (host_info64_t)&stats, &count); - uint64_t active = stats.active_count; - uint64_t inactive = stats.inactive_count; - uint64_t wired = stats.wire_count; - uint64_t speculative = stats.speculative_count; - uint64_t free = stats.free_count; - uint64_t total = active + inactive + wired + speculative + free; - return static_cast(inactive + speculative + free) * 100 / static_cast (total); - -#else - - // BSD: - // https://forums.freebsd.org/threads/38754/ - // http://stackoverflow.com/questions/2513505/how-to-get-available-memory-c-g - - // Linux. - string path = "/proc/meminfo"; - if (file_or_dir_exists (path)) { - string meminfo = filter_url_file_get_contents (path); - size_t pos; - int memtotal = 0; - pos = meminfo.find ("MemTotal"); - if (pos != std::string::npos) { - memtotal = filter::strings::convert_to_int (meminfo.substr (pos + 15)); - } - int memfree = 0; - pos = meminfo.find ("MemFree"); - if (pos != std::string::npos) { - memfree = filter::strings::convert_to_int (meminfo.substr (pos + 15)); - } - int cached = 0; - pos = meminfo.find ("Cached"); - if (pos != std::string::npos) { - cached = filter::strings::convert_to_int (meminfo.substr (pos + 15)); - } - return (memfree + cached) * 100 / memtotal; - } -#endif - - // Failed to get available memory: Return something sensible. - return 50; -} - - -// Returns how many bytes of memory the app currently uses. -uint64_t filter_memory_total_usage () -{ -#ifdef HAVE_MACH_MACH - // macOS. - struct task_basic_info t_info; - mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; - task_info (mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count); - // Total usage consists of resident and virtual memory size. - uint64_t resident_memory = t_info.resident_size; - // The resident memory is unrealistically high, so can be left out. - //uint64_t virtual_memory = t_info.virtual_size; - return resident_memory; -#endif - return 0; -} - - -void filter_memory_print_back_trace () -{ -#ifdef HAVE_EXECINFO - // https://stackoverflow.com/questions/3899870/print-call-stack-in-c-or-c - // To add linker flag -rdynamic is essential. - char **strings; - void *array[1024]; - int size = backtrace(array, 1024); - strings = backtrace_symbols(array, size); - for (int i = 0; i < size; i++) - std::cout << strings[i] << std::endl; - puts(""); - free(strings); -#endif -} diff --git a/filter/memory.h b/filter/memory.h deleted file mode 100644 index a3e206b72..000000000 --- a/filter/memory.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -int filter_memory_percentage_available (); -uint64_t filter_memory_total_usage (); -void filter_memory_print_back_trace (); - diff --git a/filter/merge.cpp b/filter/merge.cpp deleted file mode 100644 index 7730fad87..000000000 --- a/filter/merge.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#pragma GCC diagnostic push -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#include -#pragma GCC diagnostic pop -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -#include -#include -using namespace std; -using dtl::Diff3; -using namespace pugi; - - -static mutex filter_merge_mutex; - - -// This uses the dtl:: library for merge in C++. -// At times the library failed to merge. -// It was tried whether the Linux "merge" command was able to successfully merge such cases. -// But also this command failed to merge in such cases. -// The conclusion therefore is that the C++ merge library is equivalent in quality. - - -// merge - three-way merge. -// Merge is useful for combining separate changes to an original. -// The function normally returns the merged text. -// If case of conflicts, it returns an empty container. -vector filter_merge_merge (const vector & base, const vector & user, const vector & server) -{ - // See issue https://github.com/bibledit/cloud/issues/418 - // It is unclear at this time whether the code below - // to find the differences between texts, is thread-safe. - // So just to be sure, a mutex is placed around it. - filter_merge_mutex.lock(); - - vector user_sequence (user); - vector base_sequence (base); - vector server_sequence (server); - - Diff3 > diff3 (user_sequence, base_sequence, server_sequence); - diff3.compose (); - bool merged = diff3.merge (); - filter_merge_mutex.unlock(); - if (!merged) { - return {}; - } - return diff3.getMergedSequence (); -} - - -string filter_merge_lines2words (string data) -{ - data = filter::strings::replace ("\n", " new__line ", data); - data = filter::strings::replace (" ", "\n", data); - return data; -} - - -string filter_merge_words2lines (string data) -{ - data = filter::strings::replace ("\n", " ", data); - data = filter::strings::replace (" new__line ", "\n", data); - return data; -} - - -string filter_merge_lines2graphemes (string data) -{ - data = filter::strings::replace ("\n", " new__line ", data); - string data2; - size_t count = filter::strings::unicode_string_length (data); - for (size_t i = 0; i < count; i++) { - string grapheme = filter::strings::unicode_string_substr (data, i, 1); - data2.append (grapheme); - data2.append ("\n"); - } - return data2; -} - - -string filter_merge_graphemes2lines (string data) -{ - data = filter::strings::replace ("\n", "", data); - data = filter::strings::replace (" new__line ", "\n", data); - return data; -} - - -void filter_merge_detect_conflict (string base, - string change, - string prioritized_change, - string result, - vector & conflicts) -{ - // Clean input. - base = filter::strings::trim (base); - change = filter::strings::trim (change); - prioritized_change = filter::strings::trim (prioritized_change); - result = filter::strings::trim (result); - - bool irregularity = false; - string subject; - - if (!irregularity) { - if (base.empty ()) { - subject = "There was no text to base the merge upon"; - irregularity = true; - } - } - - if (!irregularity) { - if (change.empty ()) { - subject = "There was no changed text to merge with"; - irregularity = true; - } - } - - if (!irregularity) { - if (prioritized_change.empty ()) { - subject = "There was no existing text to merge with"; - irregularity = true; - } - } - - if (!irregularity) { - if (result.empty ()) { - subject = "The merge resulted in empty text"; - irregularity = true; - } - } - - if (!irregularity) { - if ((change != base) && (prioritized_change != change) && (prioritized_change == result)) { - subject = "Failed to merge your changes"; - irregularity = true; - } - } - - if (irregularity) { - Merge_Conflict conflict; - conflict.base = base; - conflict.change = change; - conflict.prioritized_change = prioritized_change; - conflict.result = result; - conflict.subject = subject; - conflicts.push_back (conflict); - } -} - - -// This filter merges files. -// $base: Data for the merge base. -// $change: Data as modified by one user. -// $prioritized_change: Data as modified by a user but prioritized. -// The filter uses a three-way merge algorithm. -// There should be one unchanged segment (either a line or word) between the modifications. -// If necessary it converts the data into a new format with one character per line for more fine-grained merging. -// In case of a conflict, it prioritizes changes from $prioritized_change. -// The filter returns the merged data. -// If $clever, it calls a more clever routine when it fails to merge. -string filter_merge_run (string base, string change, string prioritized_change, - bool clever, - vector & conflicts) -{ - // Trim the input. - base = filter::strings::trim (base); - change = filter::strings::trim (change); - prioritized_change = filter::strings::trim (prioritized_change); - - // Try a standard line-based merge. Should be sufficient for most cases. - vector baselines = filter::strings::explode (base, '\n'); - vector userlines = filter::strings::explode (change, '\n'); - vector serverlines = filter::strings::explode (prioritized_change, '\n'); - vector results = filter_merge_merge (baselines, userlines, serverlines); - if (!results.empty ()) { - string result = filter::strings::implode (results, "\n"); - filter_merge_detect_conflict (base, change, prioritized_change, result, conflicts); - return result; - } - - // Convert the data to one word per line, and try to merge again. - string baseWords = filter_merge_lines2words (base); - string userWords = filter_merge_lines2words (change); - string serverWords = filter_merge_lines2words (prioritized_change); - baselines = filter::strings::explode (baseWords, '\n'); - userlines = filter::strings::explode (userWords, '\n'); - serverlines = filter::strings::explode (serverWords, '\n'); - results = filter_merge_merge (baselines, userlines, serverlines); - if (!results.empty ()) { - string mergedWords = filter::strings::implode (results, "\n"); - string result = filter_merge_words2lines (mergedWords); - filter_merge_detect_conflict (base, change, prioritized_change, result, conflicts); - return result; - } - - // Convert the data so it has one grapheme per line, and try again. - string baseGraphemes = filter_merge_lines2graphemes (base); - string userGraphemes = filter_merge_lines2graphemes (change); - string serverGraphemes = filter_merge_lines2graphemes (prioritized_change); - baselines = filter::strings::explode (baseGraphemes, '\n'); - userlines = filter::strings::explode (userGraphemes, '\n'); - serverlines = filter::strings::explode (serverGraphemes, '\n'); - results = filter_merge_merge (baselines, userlines, serverlines); - if (!results.empty ()) { - string mergedGraphemes = filter::strings::implode (results, "\n"); - string result = filter_merge_graphemes2lines (mergedGraphemes); - filter_merge_detect_conflict (base, change, prioritized_change, result, conflicts); - return result; - } - - if (clever) { - // It failed to merge: Call a more clever routine to do the merge. - string result = filter_merge_run_clever (base, change, prioritized_change, conflicts); - // Check on merge failure. - filter_merge_detect_conflict (base, change, prioritized_change, result, conflicts); - // Done. - return result; - } - - // The data could not be merged no matter how hard it tried. - // Detect it as a conflict. - filter_merge_detect_conflict (base, change, prioritized_change, prioritized_change, conflicts); - // Done; - return prioritized_change; -} - - -// This filter merges USFM data in a clever way. -// $base: Data for the merge base. -// $change: Data as modified by one user. -// $prioritized_change: Data as modified by a user but prioritized. -// The filter uses a three-way merge algorithm. -string filter_merge_run_clever (string base, string change, string prioritized_change, - vector & conflicts) -{ - // Get the verse numbers in the changed text. - vector verses = filter::usfm::get_verse_numbers (change); - - vector results; - - string previous_change; - - // Go through the verses. - for (auto verse : verses) { - - // Gets the texts to merge for this verse. - string base_text = filter::usfm::get_verse_text (base, verse); - string change_text = filter::usfm::get_verse_text (change, verse); - string prioritized_change_text = filter::usfm::get_verse_text (prioritized_change, verse); - - // Check for combined verses. - if (change_text == previous_change) continue; - previous_change = change_text; - - // Check whether any of the three text fragments can be considered to be a verse without content. - size_t empty_length = 3 + filter::strings::convert_to_string (verse).length () + 1; // "\v n " - bool base_empty = base_text.length () <= empty_length; - bool change_empty = change_text.length () <= empty_length; - bool prioritized_change_empty = prioritized_change_text.length () <= empty_length; - - // If the prioritized change is empty, and the other two are not, - // update the priotitized change to match the change. - // Without doing this the merge behaves in an unexpected way: - // It would take the prioritized change instead of the the base/change. - if (prioritized_change_empty) { - if (!base_empty && !change_empty) { - prioritized_change_text = change_text; - } - } - - // Run the merge, but clear the "clever" flags else it may enter an infinite loop. - string result = filter_merge_run (base_text, change_text, prioritized_change_text, false, conflicts); - - // Store it. - results.push_back (result); - } - - // Done. - return filter::strings::implode (results, "\n"); -} - - -void filter_merge_add_book_chapter (vector & conflicts, int book, int chapter) -{ - for (auto & conflict : conflicts) { - conflict.book = book; - conflict.chapter = chapter; - } -} diff --git a/filter/merge.h b/filter/merge.h deleted file mode 100644 index 0b92236a8..000000000 --- a/filter/merge.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include -#include - -std::string filter_merge_run (std::string base, std::string change, std::string prioritized_change, - bool clever, std::vector & conflicts); -std::string filter_merge_run_clever (std::string base, std::string change, std::string prioritized_change, - std::vector & conflicts); -void filter_merge_add_book_chapter (std::vector & conflicts, int book, int chapter); diff --git a/filter/note.cpp b/filter/note.cpp deleted file mode 100644 index 5785dca5d..000000000 --- a/filter/note.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -using namespace std; - - -namespace filter::note { - - -citation::citation () -{ - pointer = 0; -} - -void citation::set_sequence (int numbering, const string & usersequence) -{ - if (numbering == NoteNumbering123) { - this->sequence.clear(); - } - else if (numbering == NoteNumberingAbc) { - this->sequence = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}; - } - else if (numbering == NoteNumberingUser) { - if (!usersequence.empty()) this->sequence = filter::strings::explode (usersequence, ' '); - } - else { - this->sequence = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}; // Fallback sequence. - } - // How the above works: - // The note will be numbered as follows: - // If a sequence is given, then this sequence is followed for the citations. - // If no sequence is given, then the note gets numerical citations. -} - -void citation::set_restart (int setting) -{ - if (setting == NoteRestartNumberingNever) this->restart = "never"; - else if (setting == NoteRestartNumberingEveryBook) this->restart = "book"; - else this->restart = "chapter"; -} - -string citation::get (string citation_in) -{ - // Handle USFM automatic note citation. - if (citation_in == "+") { - // If the sequence is empty, then the note citation starts at 1 and increases each time. - if (sequence.empty()) { - pointer++; - citation_in = to_string (pointer); - } - // The sequence of note callers is not empty. - // So take the note citaton from the sequence, - // and then iterate to the next one. - else { - citation_in = sequence [pointer]; - pointer++; - if (pointer >= sequence.size ()) pointer = 0; - } - } - - // Handle situation in USFM that no note citation is to be displayed. - else if (citation_in == "-") { - citation_in.clear(); - } - - // Done. - return citation_in; -} - -void citation::run_restart (const string & moment) -{ - if (restart == moment) { - pointer = 0; - } -} - -void citations::evaluate_style (const Database_Styles_Item & style) -{ - // Evaluate the style to find out whether to create a note citation for it. - bool create = false; - if (style.type == StyleTypeFootEndNote) { - if (style.subtype == FootEndNoteSubtypeFootnote) create = true; - if (style.subtype == FootEndNoteSubtypeEndnote) create = true; - } - if (style.type == StyleTypeCrossreference) { - if (style.subtype == CrossreferenceSubtypeCrossreference) create = true; - } - if (!create) return; - - // Create a new note citation at this point. - citation citation; - // Handle caller sequence. - citation.set_sequence(style.userint1, style.userstring1); - // Handle note caller restart moment. - citation.set_restart(style.userint2); - // Store the citation for later use. - cache [style.marker] = citation; -} - - -string citations::get (const string & marker, const string & citation) -{ - return cache[marker].get(citation); -} - - -// This resets the note citations data. -// Resetting means that the note citations start to count afresh. -// $moment: what type of reset to apply, e.g. 'chapter' or 'book'. -void citations::restart (const string & moment) -{ - for (auto & notecitation : cache) { - notecitation.second.run_restart (moment); - } -} - - -} diff --git a/filter/note.h b/filter/note.h deleted file mode 100644 index 00fb9ca69..000000000 --- a/filter/note.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -namespace filter::note { - -class citation -{ -public: - citation (); - void set_sequence (int numbering, const std::string & usersequence); - void set_restart (int setting); - std::string get (std::string citation_in); - void run_restart (const std::string & moment); -private: - std::string restart {}; - unsigned int pointer {0}; - std::vector sequence {}; -}; - -class citations -{ -public: - void evaluate_style (const Database_Styles_Item & style); - std::string get (const std::string & marker, const std::string & citation); - void restart (const std::string & moment); -private: - std::map cache {}; -}; - - -} diff --git a/filter/passage.cpp b/filter/passage.cpp deleted file mode 100644 index a5e5caf16..000000000 --- a/filter/passage.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -using namespace std; -using namespace pugi; - - -Passage::Passage () -{ - m_book = 0; - m_chapter = 0; -} - - -Passage::Passage (string bible, int book, int chapter, string verse) -{ - m_bible = bible; - m_book = book; - m_chapter = chapter; - m_verse = verse; -} - - -bool Passage::equal (Passage & passage) -{ - if (m_bible != passage.m_bible) return false; - if (m_book != passage.m_book) return false; - if (m_chapter != passage.m_chapter) return false; - if (m_verse != passage.m_verse) return false; - return true; -} - - -// This method converts the passage of the object into text, like e.g. so: -// "hexadecimal Bible _1_2_3". -// First the hexadecimal Bible comes, then the book identifier, then the chapter number, and finally the verse number. -string Passage::encode () const -{ - string text; - // The encoded passage can be used as an attribute in the HTML DOM. - // Therefore it will be encoded such that any Bible name will be acceptable as an attribute in the DOM. - text.append (filter::strings::bin2hex (m_bible)); - text.append ("_"); - text.append (filter::strings::convert_to_string (m_book)); - text.append ("_"); - text.append (filter::strings::convert_to_string (m_chapter)); - text.append ("_"); - text.append (m_verse); - if (m_verse.empty()) text.append ("0"); - return text; -} - - -// This method converts encoded text into a passage. -// The text is in the format as its complementary function, "encode", produces. -Passage Passage::decode (const string& encoded) -{ - Passage passage; - vector bits = filter::strings::explode (encoded, '_'); - if (!bits.empty ()) { - string verse = bits.back (); - if (!verse.empty ()) passage.m_verse = verse; - bits.pop_back (); - } - if (!bits.empty ()) { - string chapter = bits.back (); - if (!chapter.empty()) passage.m_chapter = filter::strings::convert_to_int (chapter); - bits.pop_back (); - } - if (!bits.empty ()) { - string book = bits.back (); - if (!book.empty()) passage.m_book = filter::strings::convert_to_int (book); - bits.pop_back (); - } - if (!bits.empty ()) { - passage.m_bible = filter::strings::hex2bin (bits.back ()); - bits.pop_back (); - } - return passage; -} - - -string filter_passage_display (int book, int chapter, string verse) -{ - string display; - display.append (translate (database::books::get_english_from_id (static_cast(book)).c_str())); - display.append (" "); - display.append (filter::strings::convert_to_string (chapter)); - if (!verse.empty ()) display.append (":" + verse); - return display; -} - - -// Returns the display string for the $passages as one line. -string filter_passage_display_inline (vector passages) -{ - string display; - for (Passage & passage : passages) { - if (!display.empty()) display.append (" | "); - display.append (filter_passage_display (passage.m_book, passage.m_chapter, passage.m_verse)); - } - return display; -} - - - -// Returns the display string for the $passages as several lines. -string filter_passage_display_multiline (vector passages) -{ - string display; - for (Passage & passage : passages) { - display.append (filter_passage_display (passage.m_book, passage.m_chapter, passage.m_verse)); - display.append ("\n"); - } - return display; -} - - -// This function converts $passage to an integer, so that passages can be compared or stored. -int filter_passage_to_integer (Passage passage) -{ - return 1000000 * passage.m_book + 1000 * passage.m_chapter + filter::strings::convert_to_int (passage.m_verse); -} - - -// This converts the $integer, created above, to a passage. -Passage filter_integer_to_passage (int integer) -{ - int book = static_cast (round (integer / 1000000)); - integer -= book * 1000000; - int chapter = static_cast (round (integer / 1000)); - integer -= chapter * 1000; - string verse = filter::strings::convert_to_string (integer); - return Passage ("", book, chapter, verse); -} - - -// This filter takes $books as a string, -// and looks whether it can be interpreted as a valid book in any way. -// It returns a valid book identifier, -// or the unknown enum in case no book could be interpreted. -book_id filter_passage_interpret_book_v2 (string book) -{ - book = filter::strings::trim (book); - - // Recognise the USFM book abbreviations. - { - book_id identifier = database::books::get_id_from_usfm (book); - if (identifier != book_id::_unknown) return identifier; - } - - // Recognize the BibleWorks book abbreviations. - { - book_id identifier = database::books::get_id_from_bibleworks (book); - if (identifier != book_id::_unknown) return identifier; - } - - // Handle names from BibleWorks when copying the verse list to the clipboard. - // These are not handled elsewhere. - if (book == "Cant") return book_id::_song_of_solomon; - if (book == "Mk") return book_id::_mark; - if (book == "Lk") return book_id::_luke; - if (book == "Jn") return book_id::_john; - if (book == "1 Jn") return book_id::_1_john; - if (book == "2 Jn") return book_id::_2_john; - if (book == "3 Jn") return book_id::_3_john; - - // Recognize names like "I Peter", where the "I" can also be "II" or "III". - // Do the longest ones first. - book = filter::strings::replace ("III ", "3 ", book); - book = filter::strings::replace ("II ", "2 ", book); - book = filter::strings::replace ("I ", "1 ", book); - - // Do case folding, i.e., work with lower case only. - book = filter::strings::unicode_string_casefold (book); - - // Remove any spaces from the book name and try with that too. - string nospacebook = filter::strings::replace (" ", "", book); - - // Store all of the available IDs locally. - vector bookids = database::books::get_ids (); - - // Check on names entered like "Genesis" or "1 Corinthians", the full English name. - // A bug was discovered so that "Judges" was interpreted as "Jude", - // because of the three letters "Jud". - // Solved by checking on full English name first. - // In general, do exact matching first before moving on to similarity matching. - // Compare with the translation to Bibledit's language too. - for (auto identifier : bookids) { - string english = database::books::get_english_from_id(identifier); - if (english.empty()) continue; - if (book == filter::strings::unicode_string_casefold(english)) return identifier; - - if (nospacebook == filter::strings::unicode_string_casefold(english)) return identifier; - - string localized = translate(english); - if (localized.empty()) continue; - - if (book == filter::strings::unicode_string_casefold(localized)) return identifier; - - if (nospacebook == filter::strings::unicode_string_casefold(localized)) return identifier; - } - - // Try the OSIS abbreviations. - for (auto identifier : bookids) { - string osis = database::books::get_osis_from_id(identifier); - if (osis.empty()) continue; - if (book == filter::strings::unicode_string_casefold(osis)) return identifier; - if (nospacebook == filter::strings::unicode_string_casefold(osis)) return identifier; - string localized = translate(osis); - if (localized.empty()) continue; - if (book == filter::strings::unicode_string_casefold(localized)) return identifier; - if (nospacebook == filter::strings::unicode_string_casefold(localized)) return identifier; - } - - // Try the abbreviations of BibleWorks. - for (auto identifier : bookids) { - string bibleworks = database::books::get_bibleworks_from_id(identifier); - if (bibleworks.empty()) continue; - if (book == filter::strings::unicode_string_casefold(bibleworks)) return identifier; - if (nospacebook == filter::strings::unicode_string_casefold(bibleworks)) return identifier; - string localized = translate(bibleworks); - if (localized.empty()) continue; - if (book == filter::strings::unicode_string_casefold(localized)) return identifier; - if (nospacebook == filter::strings::unicode_string_casefold(localized)) return identifier; - } - - // Try the abbreviations of the Online Bible. - for (auto identifier : bookids) { - string onlinebible = database::books::get_onlinebible_from_id(identifier); - if (onlinebible.empty()) continue; - if (book == filter::strings::unicode_string_casefold(onlinebible)) return identifier; - if (nospacebook == filter::strings::unicode_string_casefold(onlinebible)) return identifier; - string localized = translate(onlinebible); - if (localized.empty()) continue; - if (book == filter::strings::unicode_string_casefold(localized)) return identifier; - if (nospacebook == filter::strings::unicode_string_casefold(localized)) return identifier; - } - - // Do a case-insensitive search in the books database for something like the book given. - { - book_id identifier = database::books::get_id_like_text (book); - if (identifier != book_id::_unknown) return identifier; - } - - // Sorry, no book found. - return book_id::_unknown; -} - - -string filter_passage_clean_passage (string text) -{ - // Trim text. - text = filter::strings::trim (text); - // As references could be, e.g.: Genesis 10.2, or Genesis 10:2, - // it needs to convert a the full stop and the colon to a space. - text = filter::strings::replace (".", " ", text); - text = filter::strings::replace (":", " ", text); - // Change double spaces into single ones. - text = filter::strings::collapse_whitespace (text); - // Trim again. - text = filter::strings::trim (text); - // Result. - return text; -} - - -// Takes the passage in $text, and explodes it into book, chapter, verse. -// The book is the numerical identifier, not the string, e.g., -// it would not return "Genesis", but identifier 1. -Passage filter_passage_explode_passage (string text) -{ - text = filter_passage_clean_passage (text); - // Cut the text in its parts. - vector bits = filter::strings::explode (text, ' '); - // Defaults to empty passage. - Passage passage; - // Take the bits. - if (!bits.empty ()) { - string verse = bits.back (); - if (!verse.empty ()) passage.m_verse = verse; - bits.pop_back (); - } - if (!bits.empty ()) { - string chapter = bits.back (); - if (!chapter.empty()) passage.m_chapter = filter::strings::convert_to_int (chapter); - bits.pop_back (); - } - string book = filter::strings::implode (bits, " "); - if (!book.empty()) { - book_id bk = filter_passage_interpret_book_v2 (book); - passage.m_book = static_cast(bk); - } - // Return the result. - return passage; -} - - -// Takes the passage in $rawPassage, and tries to interpret it. -// The following situations can occur: -// - Only book given, e.g. "Genesis". -// - One number given, e.g. "10". -// - Two numbers given, e.g. "1 2". -// - Book and one number given, e.g. "Exodus 10". -// - Book and two numbers given, e.g. "Song of Solomon 2 3". -// It deals with these situations. -// If needed, it bases the interpreted passage on $currentPassage. -Passage filter_passage_interpret_passage (Passage currentPassage, string rawPassage) -{ - rawPassage = filter_passage_clean_passage (rawPassage); - - // Create an array with the bits of the raw input. - vector input = filter::strings::explode (rawPassage, ' '); - - // Go through the array from verse to chapter to book. - // Check how many numerals it has after the book part. - vector numerals; - string book = ""; - vector invertedInput (input.begin(), input.end ()); - reverse (invertedInput.begin (), invertedInput.end()); - for (string & bit : invertedInput) { - int integer = filter::strings::convert_to_int (bit); - if (bit == filter::strings::convert_to_string (integer)) { - numerals.push_back (integer); - input.pop_back (); - } else { - book = filter::strings::implode (input, " "); - break; - } - } - - // Deal with: Only book given, e.g. "Genesis". - if ((book != "") && (numerals.size () == 0)) { - return filter_passage_explode_passage (book + " 1 1"); - } - - // Deal with: One number given, e.g. "10". - else if ((book == "") && (numerals.size () == 1)) { - int bk = currentPassage.m_book; - int chapter = currentPassage.m_chapter; - string verse = filter::strings::convert_to_string (numerals [0]); - Passage passage = filter_passage_explode_passage ("Unknown " + filter::strings::convert_to_string (chapter) + " " + verse); - passage.m_book = bk; - return passage; - } - - // Deal with: Two numbers given, e.g. "1 2". - else if ((book == "") && (numerals.size () == 2)) { - int bk = currentPassage.m_book; - int chapter = numerals [1]; - string verse = filter::strings::convert_to_string (numerals [0]); - Passage passage = filter_passage_explode_passage ("Unknown " + filter::strings::convert_to_string (chapter) + " " + verse); - passage.m_book = bk; - return passage; - } - - // Deal with: Book and one number given, e.g. "Exodus 10". - else if ((book != "") && (numerals.size () == 1)) { - int chapter = numerals [0]; - return filter_passage_explode_passage (book + " " + filter::strings::convert_to_string (chapter) + " 1"); - } - - // Deal with: Book and two numbers given, e.g. "Song of Solomon 2 3". - else if ((book != "") && (numerals.size () == 2)) { - return filter_passage_explode_passage (rawPassage); - } - - // Give up. - return currentPassage; -} - - -// This deals with sequences and ranges of verses, like the following: -// Exod. 37:4-5, 14-15, 27-28 -// It puts each verse on a separate line. -vector filter_passage_handle_sequences_ranges (const string& passage) -{ - // A passage like Exod. 37:4-5, 14-15, 27-28 will be cut at the comma. - // The resulting array contains the following: - // Exod. 37:4-5 - // 14-15 - // 27-28 - // It implies that the first sequence has book and chapter. - vector sequences = filter::strings::explode (passage, ','); - for (string & line : sequences) line = filter::strings::trim (line); - - - // Store output lines. - vector output; - - // Cut the passages at the hyphen. - for (unsigned int offset = 0; offset < sequences.size(); offset++) { - string sequence = sequences [offset]; - vector range = filter::strings::explode (sequence, '-'); - if (range.size () == 1) { - output.push_back (filter::strings::trim (range [0])); - } else { - string start = filter::strings::trim (range [0]); - output.push_back (start); - if (offset == 0) { - // Since the first bit contains book / chapter / verse, - // extract the verse number. - start = string (start.rbegin(), start.rend()); - start = filter::strings::convert_to_string (filter::strings::convert_to_int (start)); - start = string (start.rbegin(), start.rend()); - } - unsigned int end = static_cast (filter::strings::convert_to_int (filter::strings::trim (range [1]))); - for (size_t i = static_cast (filter::strings::convert_to_int (start) + 1); i <= end; i++) { - output.push_back (filter::strings::convert_to_string (i)); - } - } - } - - // Result. - return output; -} - - -string filter_passage_link_for_opening_editor_at (int book, int chapter, string verse) -{ - string display = filter_passage_display (book, chapter, verse); - Passage passage = Passage ("", book, chapter, verse); - string numeric = filter::strings::convert_to_string (filter_passage_to_integer (passage)); - xml_document document; - xml_node a_node = document.append_child ("a"); - a_node.append_attribute("class") = "starteditor"; - a_node.append_attribute("href") = "nothing"; - a_node.append_attribute("passage") = numeric.c_str(); - a_node.text().set(display.c_str()); - xml_node span_node = document.append_child("span"); - span_node.text().set(" "); - stringstream output; - document.print (output, "", format_raw); - string link = output.str (); - return link; -} - - -// A Bible has a standard order for the books, and it can have their books in a custom order. -// This function returns either the standard order, or a custom order in case it is available for the $bible. -vector filter_passage_get_ordered_books (const string& bible) -{ - Database_Bibles database_bibles; - - // The available books from the Bible. - vector projectbooks = database_bibles.get_books (bible); - - // The book order from the settings, if any. - string s_orderedbooks = Database_Config_Bible::getBookOrder (bible); - vector vs_orderedbooks = filter::strings::explode (s_orderedbooks, ' '); - - // Keep books available in the Bible. - vector orderedbooks; - for (string & book : vs_orderedbooks) { - int bk = filter::strings::convert_to_int (book); - if (find (projectbooks.begin(), projectbooks.end(), bk) != projectbooks.end()) { - orderedbooks.push_back (bk); - } - } - - // Books in the Bible but not in the settings: Add them to the end. - for (int book : projectbooks) { - if (find (orderedbooks.begin(), orderedbooks.end(), book) == orderedbooks.end()) { - orderedbooks.push_back (book); - } - } - - return orderedbooks; -} - - diff --git a/filter/passage.h b/filter/passage.h deleted file mode 100644 index 40240b9ff..000000000 --- a/filter/passage.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -// Forward declaration. -enum class book_id; - -class Passage -{ -public: - Passage (); - Passage (std::string bible, int book, int chapter, std::string verse); - std::string m_bible {}; - int m_book {}; - int m_chapter {}; - std::string m_verse {}; - bool equal (Passage & passage); - std::string encode () const; - static Passage decode (const std::string& encoded); -}; - -std::string filter_passage_display (int book, int chapter, std::string verse); -std::string filter_passage_display_inline (std::vector passages); -std::string filter_passage_display_multiline (std::vector passages); -int filter_passage_to_integer (Passage passage); -Passage filter_integer_to_passage (int integer); -book_id filter_passage_interpret_book_v2 (std::string book); -std::string filter_passage_clean_passage (std::string text); -Passage filter_passage_explode_passage (std::string text); -Passage filter_passage_interpret_passage (Passage currentPassage, std::string rawPassage); -std::vector filter_passage_handle_sequences_ranges (const std::string& passage); -std::string filter_passage_link_for_opening_editor_at (int book, int chapter, std::string verse); -std::vector filter_passage_get_ordered_books (const std::string& bible); diff --git a/filter/roles.cpp b/filter/roles.cpp deleted file mode 100644 index 3407e8ef4..000000000 --- a/filter/roles.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -using namespace std; - - -int Filter_Roles::guest () -{ - return 1; -} - - -int Filter_Roles::member () -{ - return 2; -} - - -int Filter_Roles::consultant () -{ - return 3; -} - - -int Filter_Roles::translator () -{ - return 4; -} - - -int Filter_Roles::manager () -{ - return 5; -} - - -int Filter_Roles::admin () -{ - return 6; -} - - -int Filter_Roles::lowest () -{ - return guest (); -} - - -int Filter_Roles::highest () -{ - return admin (); -} - - -string Filter_Roles::english (int role) -{ - if (role == admin ()) return "Administrator"; - if (role == manager ()) return "Manager"; - if (role == translator ()) return "Translator"; - if (role == consultant ())return "Consultant"; - if (role == member ()) return "Member"; - return "Guest"; -} - - -string Filter_Roles::text (int role) -{ - if (role == admin ()) return translate ("Administrator"); - if (role == manager ()) return translate ("Manager"); - if (role == translator ()) return translate ("Translator"); - if (role == consultant ())return translate ("Consultant"); - if (role == member ()) return translate ("Member"); - return translate ("Guest"); -} - - -// This is for access control. -// The "role" is the role required for the user to have access. -bool Filter_Roles::access_control (Webserver_Request& webserver_request, int role) -{ - int level = webserver_request.session_logic ()->currentLevel (); - return level >= role; -} - diff --git a/filter/roles.h b/filter/roles.h deleted file mode 100644 index 481125f35..000000000 --- a/filter/roles.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -class Filter_Roles -{ -public: - static int guest (); - static int member (); - static int consultant (); - static int translator (); - static int manager (); - static int admin (); - static int lowest (); - static int highest (); - static std::string english (int role); - static std::string text (int role); - static bool access_control (Webserver_Request& webserver_request, int role); -private: -}; diff --git a/filter/shell.cpp b/filter/shell.cpp deleted file mode 100644 index be62e05ea..000000000 --- a/filter/shell.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#ifndef HAVE_CLIENT -#include -#endif -#ifdef HAVE_WINDOWS -#include -#endif -#include -using namespace std; - - -// Internal declarations. -string filter_shell_escape_argument (string argument); - - -string filter_shell_escape_argument (string argument) -{ - argument = filter::strings::replace ("'", "\\'", argument); - argument.insert (0, "'"); - argument.append ("'"); - return argument; -} - - -// Runs shell $command in folder $directory, with $parameters. -// If $output and $error are non-nullptr, that is where the output of the shell command goes. -// If they are nullptr, the output of the shell command goes to the Journal. -int filter_shell_run ([[maybe_unused]] string directory, - string command, - [[maybe_unused]] const vector parameters, - [[maybe_unused]] string * output, - [[maybe_unused]] string * error) -{ -#ifdef HAVE_CLIENT - Database_Logs::log ("Did not run on client: " + command); - return 0; -#else - command = filter_shell_escape_argument (command); - if (!directory.empty ()) { - directory = filter_shell_escape_argument (directory); - command.insert (0, "cd " + directory + "; "); - } - for (string parameter : parameters) { - parameter = filter_shell_escape_argument (parameter); - command.append (" " + parameter); - } - string pipe = filter_url_tempfile (); - string standardout = pipe + ".out"; - string standarderr = pipe + ".err"; - command.append (" > " + standardout); - command.append (" 2> " + standarderr); - int result = system (command.c_str()); - string contents = filter_url_file_get_contents (standardout); - if (output) { - output->assign (contents); - } else { - Database_Logs::log (contents); - } - contents = filter_url_file_get_contents (standarderr); - if (error) { - error->assign (contents); - } else { - Database_Logs::log (contents); - } - filter_url_unlink (standardout); - filter_url_unlink (standarderr); - return result; -#endif -} - - -// Runs $command with $parameters. -// It does not run $command through the shell, but executes it straight. -int filter_shell_run (string command, - [[maybe_unused]] const char * parameter, - [[maybe_unused]] string & output) -{ -#ifdef HAVE_CLIENT - Database_Logs::log ("Did not run on client: " + command); - return 0; -#else - // File descriptor for file to write child's stdout to. - string path = filter_url_tempfile () + ".txt"; - int fd = open (path.c_str (), O_WRONLY|O_CREAT, 0666); - - // Create child process as a duplicate of this process. - pid_t pid = fork (); - - if (pid == 0) { - - // This runs in the child. - dup2(fd, 1); - close(fd); - execlp (command.c_str(), parameter, static_cast (0)); - // The above only returns in case of an error. - Database_Logs::log (strerror (errno)); - // Use_exit instead of exit, so there's no flushing. - _exit (1); - //close (fd); - return -1; - } - - // Wait till child is ready. - wait(nullptr); - close(fd); - - // Read the child's output. - output = filter_url_file_get_contents (path); -#endif - - return 0; -} - - -// Runs $command as if it were typed on the command line. -// Does not escape anything in the $command. -// Returns the exit code of the process. -// The output of the process, both stdout and stderr, go into $out_err. -int filter_shell_run (string command, string & out_err) -{ -#ifdef HAVE_IOS - return 0; -#else - string pipe = filter_url_tempfile (); - command.append (" > " + pipe + " 2>&1"); - int result = system (command.c_str()); - out_err = filter_url_file_get_contents (pipe); - return result; -#endif -} - - -// Returns true if $program is present on the system. -bool filter_shell_is_present (string program) -{ - // This crashes on iOS, so skip it. -#ifdef HAVE_IOS - return false; -#else - string command = "which " + program + " > /dev/null 2>&1"; - int exitcode = system (command.c_str ()); - return (exitcode == 0); -#endif -} - - -// Lists the running processes. -vector filter_shell_active_processes () -{ - vector processes; - -#ifdef HAVE_WINDOWS - - HANDLE hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); - if (hProcessSnap != INVALID_HANDLE_VALUE) { - PROCESSENTRY32 pe32; - pe32.dwSize = sizeof (PROCESSENTRY32); - if (Process32First (hProcessSnap, &pe32)) { - processes.push_back (filter::strings::wstring2string (pe32.szExeFile)); - while (Process32Next (hProcessSnap, &pe32)) { - processes.push_back (filter::strings::wstring2string (pe32.szExeFile)); - } - CloseHandle (hProcessSnap); - } - } - -#else - - string output; - filter_shell_run ("ps ax", output); - processes = filter::strings::explode (output, '\n'); - -#endif - - return processes; -} - - -// Runs $command with $p1, $p2, etc... -// If $directory is given, the process changes the working directory to that. -// It does not run $command through the shell, but executes it through vfork, -// which is the fastest possibble way to run a child process. -int filter_shell_vfork ([[maybe_unused]] string & output, - [[maybe_unused]] string directory, - [[maybe_unused]] string command, - [[maybe_unused]] const char * p01, - [[maybe_unused]] const char * p02, - [[maybe_unused]] const char * p03, - [[maybe_unused]] const char * p04, - [[maybe_unused]] const char * p05, - [[maybe_unused]] const char * p06, - [[maybe_unused]] const char * p07, - [[maybe_unused]] const char * p08, - [[maybe_unused]] const char * p09, - [[maybe_unused]] const char * p10, - [[maybe_unused]] const char * p11, - [[maybe_unused]] const char * p12, - [[maybe_unused]] const char * p13) -{ - int status = 0; -#ifdef HAVE_CLIENT - Database_Logs::log ("Did not run on client: " + command); -#else - - // File descriptors for files to write child's stdout and stderr to. - string path = filter_url_tempfile () + ".txt"; - int fd = open (path.c_str (), O_WRONLY|O_CREAT, 0666); - - // It seems that waiting very shortly before calling vfork () - // enables running threads to continue running. - this_thread::sleep_for (chrono::milliseconds (1)); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - pid_t pid = vfork(); -#pragma clang diagnostic pop - if (pid != 0) { - if (pid < 0) { - Database_Logs::log ("Failed to run " + command); - } else { - wait (&status); - } - } else { - - // This runs in the child. - dup2 (fd, 1); - dup2 (fd, 2); - close (fd); - if (!directory.empty ()) { - [[maybe_unused]] int result = chdir (directory.c_str()); - } - execlp (command.c_str(), command.c_str(), p01, p02, p03, p04, p05, p06, p07, p08, p09, p10, p11, p12, p13, static_cast (0)); - // The above only returns in case of an error. - Database_Logs::log (command + ": " + strerror (errno)); - _exit (1); - //close (fd); - return -1; - } - - // Read the child's output. - close (fd); - output = filter_url_file_get_contents (path); - filter_url_unlink (path); - -#endif - - return status; -} diff --git a/filter/shell.h b/filter/shell.h deleted file mode 100644 index f3ee7fd87..000000000 --- a/filter/shell.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -int filter_shell_run (std::string directory, std::string command, const std::vector parameters, - std::string * output, std::string * error); -int filter_shell_run (std::string command, const char * parameter, std::string & output); -int filter_shell_run (std::string command, std::string & out_err); -bool filter_shell_is_present (std::string program); -std::vector filter_shell_active_processes (); -int filter_shell_vfork (std::string & output, std::string directory, std::string command, - const char * p01 = nullptr, - const char * p02 = nullptr, - const char * p03 = nullptr, - const char * p04 = nullptr, - const char * p05 = nullptr, - const char * p06 = nullptr, - const char * p07 = nullptr, - const char * p08 = nullptr, - const char * p09 = nullptr, - const char * p10 = nullptr, - const char * p11 = nullptr, - const char * p12 = nullptr, - const char * p13 = nullptr); diff --git a/filter/string.cpp b/filter/string.cpp deleted file mode 100644 index 9ee5dc7af..000000000 --- a/filter/string.cpp +++ /dev/null @@ -1,2268 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -// Suppress errors in Visual Studio 2019. -// No longer needed since upgrading the UTF8 library? -#define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING 1 -#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING 1 -#pragma GCC diagnostic ignored "-Wunused-macros" - -#include -#pragma GCC diagnostic push -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wswitch-default" -#include -#pragma GCC diagnostic pop -#include -#include -#include -#include -#include -#ifdef HAVE_UTF8PROC -#include -#else -#include -#endif -#include -#ifdef HAVE_WINDOWS -#include -#endif -#ifdef HAVE_ICU -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#pragma clang diagnostic ignored "-Wdocumentation" -#pragma clang diagnostic ignored "-Wsign-conversion" -#include -#include -#include -#include -#include -#pragma clang diagnostic pop -#endif -#ifdef HAVE_CLOUD -#include -#include -#endif -#ifdef HAVE_CLOUD -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdocumentation" -#include -#pragma clang diagnostic pop -#endif -#ifdef HAVE_CLOUD -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -//#include -//#include -#include "tidy/tidy.h" -#include "tidy/tidybuffio.h" -#pragma clang diagnostic pop -#endif -#include -#include - - -namespace filter::strings { - - -// Split a string on a delimiter. -// Return a vector of strings. -std::vector explode (std::string value, char delimiter) -{ - std::vector result; - std::istringstream iss (value); - for (std::string token; getline (iss, token, delimiter); ) - { - result.push_back (std::move (token)); - } - return result; -} - - -// Explodes an input string on multiple delimiters. -std::vector explode (std::string value, std::string delimiters) -{ - std::vector result {}; - while (!value.empty ()) { - size_t pos {value.find_first_of (delimiters)}; - if (pos == std::string::npos) { - result.push_back (value); - value.clear (); - } else { - std::string s {value.substr (0, pos)}; - if (!s.empty()) result.push_back (s); - pos++; - value.erase (0, pos); - } - } - return result; -} - - -// Join a vector of string, with delimiters, into a string. -// Return this string. -std::string implode (std::vector & values, std::string delimiter) -{ - std::string full {}; - for (std::vector::iterator it = values.begin (); it != values.end (); ++it) - { - full += (*it); - if (it != values.end ()-1) full += delimiter; - } - return full; -} - - -// Replaces string contents. -std::string replace (const std::string& search, const std::string& replace, std::string subject, int * count) -{ - size_t offposition {subject.find (search)}; - while (offposition != std::string::npos) { - subject.replace (offposition, search.length (), replace); - if (count) (*count)++; - offposition = subject.find (search, offposition + replace.length ()); - } - return subject; -} - - -// Replaces text that starts with "start" and ends with "end" with "replacement". -// Returns true if replacement was done. -bool replace_between (std::string& line, const std::string& start, const std::string& end, const std::string& replacement) -{ - bool replacements_done {false}; - size_t beginpos {line.find (start)}; - size_t endpos {line.find (end)}; - while ((beginpos != std::string::npos) && (endpos != std::string::npos) && (endpos > beginpos)) { - line.replace (beginpos, endpos - beginpos + end.length (), replacement); - beginpos = line.find (start, beginpos + replacement.length ()); - endpos = line.find (end, beginpos + replacement.length ()); - replacements_done = true; - } - return replacements_done; -} - - -// On some platforms the sizeof (unsigned int) is equal to the sizeof (size_t). -// Then compilation would fail if there were two functions "convert_to_string", -// one taking the unsigned int, and the other taking the size_t. -// Therefore there is now one function doing both. -// This may lead to embiguity errors for the C++ compiler. -// In such case the ambiguity can be removed by changing the type to be passed -// to this function to "size_t", possibly via a static_cast. -std::string convert_to_string (const size_t i) -{ - std::ostringstream r; - r << i; - return r.str(); -} - - -std::string convert_to_string (const int i) -{ - std::ostringstream r; - r << i; - return r.str(); -} - - -std::string convert_to_string (const char * c) -{ - std::string s {c}; - return s; -} - - -std::string convert_to_string (const bool b) -{ - if (b) return "1"; - return "0"; -} - - -std::string convert_to_string (const std::string& s) -{ - return s; -} - - -std::string convert_to_string (const float f) -{ - std::ostringstream r; - r << f; - return r.str(); -} - - -int convert_to_int (const std::string& s) -{ - int i {atoi (s.c_str())}; - return i; -} - - -int convert_to_int (const float f) -{ - int i {static_cast (round(f))}; - return i; -} - - -long long convert_to_long_long (const std::string& s) -{ - long long i {0}; - std::istringstream r (s); - r >> i; - return i; -} - - -float convert_to_float (const std::string& s) -{ - float f {0}; - std::istringstream r (s); - r >> f; - return f; -} - - -bool convert_to_bool (const std::string& s) -{ - if (s.empty()) return false; - if (s == "true") return true; - if (s == "TRUE") return true; - bool b; - std::istringstream (s) >> b; - return b; -} - - -std::string convert_to_true_false (const bool b) -{ - if (b) return "true"; - return "false"; -} - - -std::u16string convert_to_u16string (const std::string& s) -{ - std::wstring_convert , char16_t> utf16conv; - std::u16string utf16 = utf16conv.from_bytes (s); - // utf16.length() - return utf16; -} - - -// A C++ equivalent for PHP's filter::strings::array_unique function. -std::vector array_unique (const std::vector & values) -{ - std::vector result; - std::set unique; - for (unsigned int i = 0; i < values.size (); i++) { - if (unique.find (values[i]) == unique.end ()) { - unique.insert (values[i]); - result.push_back ((values[i])); - } - } - return result; -} - - -// A C++ equivalent for PHP's filter::strings::array_unique function. -std::vector array_unique (const std::vector & values) -{ - std::vector result; - std::set unique; - for (unsigned int i = 0; i < values.size (); i++) { - if (unique.find (values[i]) == unique.end ()) { - unique.insert (values[i]); - result.push_back ((values[i])); - } - } - return result; -} - - -// Returns items in "from" which are not present in "against". -std::vector array_diff (const std::vector & from, const std::vector & against) -{ - std::vector result {}; - std::set against2 (against.begin (), against.end ()); - for (unsigned int i = 0; i < from.size (); i++) { - if (against2.find (from[i]) == against2.end ()) { - result.push_back ((from[i])); - } - } - return result; -} - - -// Returns items in "from" which are not present in "against". -std::vector array_diff (const std::vector & from, const std::vector & against) -{ - std::vector result {}; - std::set against2 (against.begin (), against.end ()); - for (unsigned int i = 0; i < from.size (); i++) { - if (against2.find (from[i]) == against2.end ()) { - result.push_back ((from[i])); - } - } - return result; -} - - -// A C++ equivalent for PHP's filter::strings::trim function. -std::string trim (const std::string& s) -{ - if (s.length () == 0) return s; - // Strip spaces, tabs, new lines, carriage returns. - size_t beg = s.find_first_not_of(" \t\n\r"); - size_t end = s.find_last_not_of(" \t\n\r"); - // No non-spaces - if (beg == std::string::npos) return std::string(); - return std::string (s, beg, end - beg + 1); -} - - -// A C++ equivalent for PHP's filter::strings::ltrim function. -std::string ltrim (const std::string& s) -{ - if (s.length () == 0) return s; - // Strip spaces, tabs, new lines, carriage returns. - size_t pos = s.find_first_not_of(" \t\n\r"); - // No non-spaces - if (pos == std::string::npos) return std::string(); - return s.substr (pos); -} - - -// Right trim string. -std::string rtrim (std::string s) -{ - if (s.length () == 0) return s; - // Strip spaces, tabs, new lines, carriage returns. - size_t pos = s.find_last_not_of(" \t\n\r"); - // No non-spaces - if (pos == std::string::npos) return std::string(); - // Erase it. - s.erase (pos + 1); - // Done. - return s; -} - - -// Fills a string up to "width", with the character "fill" at the left. -std::string fill (const std::string& s, const int width, const char fill) -{ - std::ostringstream str {}; - str << std::setfill (fill) << std::setw (width) << s; - return str.str(); -} - - -// Returns true/false whether s is numeric. -bool is_numeric (const std::string& s) -{ - for (char c : s) { - if (!isdigit (c)) { - return false; - } - } - return true; -} - - -// This takes the five special XML characters and escapes them. -// < : < -// & : & -// > : > -// " : " -// ' : ' -std::string escape_special_xml_characters (std::string s) -{ - s = filter::strings::replace ("&", "&", s); - s = filter::strings::replace (R"(")", """, s); - s = filter::strings::replace ("'", "'", s); - s = filter::strings::replace ("<", "<", s); - s = filter::strings::replace (">", ">", s); - return s; -} - - -// This unescapes the five special XML characters. -std::string unescape_special_xml_characters (std::string s) -{ - s = filter::strings::replace (""", R"(")", s); - s = filter::strings::replace ("&", "&", s); - s = filter::strings::replace ("'", "'", s); - s = filter::strings::replace ("<", "<", s); - s = filter::strings::replace (">", ">", s); - return s; -} - - -// Converts other types of spaces to standard spaces. -std::string any_space_to_standard_space (std::string s) -{ - s = filter::strings::replace (unicode_non_breaking_space_entity (), " ", s); - s = filter::strings::replace (non_breaking_space_u00A0 (), " ", s); - s = filter::strings::replace (en_space_u2002 (), " ", s); - s = filter::strings::replace (figure_space_u2007 (), " ", s); - s = filter::strings::replace (narrow_non_breaking_space_u202F (), " ", s); - return s; -} - - -// Returns a no-break space (NBSP) (x00A0). -std::string non_breaking_space_u00A0 () -{ -#ifdef HAVE_WINDOWS - // On Visual Studio 2015 the C-style code below does not work. - return " "; -#endif - // Use C-style code. - return "\u00A0"; -} - - -// Returns a soft hyphen. -std::string soft_hyphen_u00AD () -{ -#ifdef HAVE_WINDOWS - // On Visual Studio 2015 the C-style code below does not work. - return "­"; -#endif - // Soft hyphen U+00AD. - return "\u00AD"; -} - - -// Returns an "en space", this is a nut, half an em space. -std::string en_space_u2002 () -{ -#ifdef HAVE_WINDOWS - // On Visual Studio 2015 the C-style code below does not work. - return " "; -#endif - // U+2002. - return "\u2002"; -} - - -// A "figure space". -// A space to use in numbers. -// It has the same width as the digits. -// It does not break, it keeps the numbers together. -std::string figure_space_u2007 () -{ -#ifdef HAVE_WINDOWS - // On Visual Studio 2015 the C-style code below does not work. - return " "; -#endif - return "\u2007"; -} - - -// Returns a "narrow no-break space (x202F) -std::string narrow_non_breaking_space_u202F () -{ -#ifdef HAVE_WINDOWS - // On Visual Studio 2015 the C-style code below does not work. - return " "; -#endif - return "\u202F"; -} - - -// Returns the length of string s in unicode points, not in bytes. -size_t unicode_string_length (const std::string& s) -{ - size_t length = static_cast (utf8::distance (s.begin(), s.end())); - return length; -} - - -// Get the substring with unicode point pos(ition) and len(gth). -// If len = 0, the string from start till end is returned. -std::string unicode_string_substr (std::string s, size_t pos, size_t len) -{ - char * input = const_cast(s.c_str()); - char * startiter = input; - size_t length = strlen (input); - char * veryend = input + length + 1; - // Iterate forward pos times. - while (pos > 0) { - if (strlen (startiter)) { - utf8::next (startiter, veryend); - } else { - // End reached: Return empty result. - return std::string(); - } - pos--; - } - // Zero len: Return result till the end of the string. - if (len == 0) { - s.assign (startiter); - return s; - } - - // Iterate forward len times. - char * enditer = startiter; - while (len > 0) { - if (strlen (enditer)) { - utf8::next (enditer, veryend); - } else { - // End reached: Return result. - s.assign (startiter); - return s; - } - len--; - } - // Return substring. - size_t startpos = static_cast (startiter - input); - size_t lenpos = static_cast (enditer - startiter); - s = s.substr (startpos, lenpos); - return s; -} - - -// Equivalent to PHP's mb_strpos function. -size_t unicode_string_strpos (const std::string& haystack, const std::string& needle, const size_t offset) -{ - const int haystack_length = static_cast( filter::strings::unicode_string_length (haystack)); - const int needle_length = static_cast( filter::strings::unicode_string_length (needle)); - for (int pos = static_cast(offset); pos <= haystack_length - needle_length; pos++) { - const std::string substring = filter::strings::unicode_string_substr (haystack, static_cast (pos), static_cast (needle_length)); - if (substring == needle) return static_cast (pos); - } - return std::string::npos; -} - - -// Case-insensitive version of "filter::strings::unicode_string_strpos". -size_t unicode_string_strpos_case_insensitive (std::string haystack, std::string needle, size_t offset) -{ - haystack = filter::strings::unicode_string_casefold (haystack); - needle = filter::strings::unicode_string_casefold (needle); - - const int haystack_length = static_cast( filter::strings::unicode_string_length (haystack)); - const int needle_length = static_cast( filter::strings::unicode_string_length (needle)); - for (int pos = static_cast(offset); pos <= haystack_length - needle_length; pos++) { - const std::string substring = filter::strings::unicode_string_substr (haystack, static_cast (pos), static_cast (needle_length)); - if (substring == needle) return static_cast(pos); - } - return std::string::npos; -} - - -// Converts string to lowercase. -std::string unicode_string_casefold (const std::string& s) -{ - std::string casefolded {}; - // The conversion routine below is slow. - // There was a case that a user tried to put a whole Bible into one chapter. - // As a result, the Cloud choked on converting this chapter to lower case. - // So measurements were done as to the time the routine below takes to convert data. - // Processor 1,2 GHz Intel Core m3 took 1.5 minutes to convert 35 kbytes of data. - // So a limit had to be introduced below, - // that is the input text is larger than this limit, - // the routine won't fold it. - if (s.size () > 35000) { - return s; - } - // Do the case folding. - try { - // The UTF8 processor works with one Unicode point at a time. - size_t string_length = filter::strings::unicode_string_length (s); - for (unsigned int pos = 0; pos < string_length; pos++) { - // Get one UTF-8 character. - const std::string character = filter::strings::unicode_string_substr (s, pos, 1); - // Convert it to a Unicode point. - const utf8proc_uint8_t *str = reinterpret_cast (character.c_str ()); - utf8proc_ssize_t len = static_cast (character.length ()); - utf8proc_int32_t dst; - [[maybe_unused]] utf8proc_ssize_t output = utf8proc_iterate (str, len, &dst); - // Convert the Unicode point to lower case. - utf8proc_int32_t luc = utf8proc_tolower (dst); - // Convert the Unicode point back to a UTF-8 string. - utf8proc_uint8_t buffer [10]; - output = utf8proc_encode_char (luc, buffer); - buffer [output] = 0; - std::stringstream ss {}; - ss << buffer; - // Add the casefolded UTF-8 character to the result. - casefolded.append (ss.str ()); - } - } - catch (...) { } - // Done. - return casefolded; - /* - The code below shows how to do it through the ICU library. - But the ICU library could not be compiled properly for Android. - Therefore it is not used on any platform. - - // UTF-8 string -> UTF-16 UnicodeString - UnicodeString source = UnicodeString::fromUTF8 (StringPiece (s)); - // Case folding. - source.foldCase (); - // UTF-16 UnicodeString -> UTF-8 std::string - string result; - source.toUTF8String (result); - // Ready. - return result; - */ -} - - -std::string unicode_string_uppercase (const std::string& s) -{ - std::string uppercase {}; - try { - // The UTF8 processor works with one Unicode point at a time. - const size_t string_length = filter::strings::unicode_string_length (s); - for (unsigned int pos = 0; pos < string_length; pos++) { - // Get one UTF-8 character. - const std::string character = filter::strings::unicode_string_substr (s, pos, 1); - // Convert it to a Unicode point. - const utf8proc_uint8_t *str = reinterpret_cast (character.c_str ()); - utf8proc_ssize_t len = static_cast (character.length ()); - utf8proc_int32_t dst; - [[maybe_unused]] utf8proc_ssize_t output = utf8proc_iterate (str, len, &dst); - // Convert the Unicode point to lower case. - utf8proc_int32_t luc = utf8proc_toupper (dst); - // Convert the Unicode point back to a UTF-8 string. - utf8proc_uint8_t buffer [10]; - output = utf8proc_encode_char (luc, buffer); - buffer [output] = 0; - std::stringstream ss {}; - ss << buffer; - // Add the casefolded UTF-8 character to the result. - uppercase.append (ss.str ()); - } - } catch (...) { } - // Done. - return uppercase; - /* - How to do the above through the ICU library. - UnicodeString source = UnicodeString::fromUTF8 (StringPiece (s)); - source.toUpper (); - string result; - source.toUTF8String (result); - return result; - */ -} - - -std::string unicode_string_transliterate (const std::string& s) -{ - std::string transliteration {}; - try { - const size_t string_length = filter::strings::unicode_string_length (s); - for (unsigned int pos = 0; pos < string_length; pos++) { - const std::string character {unicode_string_substr (s, pos, 1)}; - const utf8proc_uint8_t *str = reinterpret_cast (character.c_str ()); - utf8proc_ssize_t len = static_cast (character.length ()); - uint8_t *dest; - utf8proc_option_t options = static_cast (UTF8PROC_DECOMPOSE | UTF8PROC_STRIPMARK); - [[maybe_unused]] auto output = utf8proc_map (str, len, &dest, options); - std::stringstream ss {}; - ss << dest; - transliteration.append (ss.str ()); - free (dest); - } - } catch (...) { } - return transliteration; - /* - Code showing how to do the transliteration through the ICU library. - // UTF-8 string -> UTF-16 UnicodeString - UnicodeString source = UnicodeString::fromUTF8 (StringPiece (s)); - - // Transliterate UTF-16 UnicodeString following this rule: - // decompose, remove diacritics, recompose - UErrorCode status = U_ZERO_ERROR; - Transliterator *transliterator = Transliterator::createInstance("NFD; [:M:] Remove; NFC", - UTRANS_FORWARD, - status); - transliterator->transliterate(source); - - // UTF-16 UnicodeString -> UTF-8 std::string - string result; - source.toUTF8String (result); - - // Done. - return result; - */ -} - - -// Returns true if string "s" is valid UTF8 encoded. -bool unicode_string_is_valid (const std::string& s) -{ - return utf8::is_valid (s.begin(), s.end()); -} - - -// Returns whether $s is Unicode punctuation. -bool unicode_string_is_punctuation (std::string s) -{ - try { - if (s.empty ()) return false; - // Be sure to take only one character. - s = filter::strings::unicode_string_substr (s, 0, 1); - // Convert the string to a Unicode point. - const utf8proc_uint8_t *str = reinterpret_cast(s.c_str ()); - const utf8proc_ssize_t len = static_cast (s.length ()); - utf8proc_int32_t codepoint; - [[maybe_unused]] auto output = utf8proc_iterate (str, len, &codepoint); - // Get category. - utf8proc_category_t category = utf8proc_category (codepoint); - if ((category >= UTF8PROC_CATEGORY_PC) && (category <= UTF8PROC_CATEGORY_PO)) return true; - } - catch (...) { } - return false; - /* - The following code shows how to do the above code through the ICU library. - UnicodeString source = UnicodeString::fromUTF8 (StringPiece (s)); - StringCharacterIterator iter (source); - UChar32 character = iter.first32 (); - bool punctuation = u_ispunct (character); - return punctuation; - */ -} - - -// Converts the string $s to a Unicode codepoint. -int unicode_string_convert_to_codepoint (std::string s) -{ - int point = 0; - if (!s.empty ()) { - try { - // Be sure to take only one character. - s = filter::strings::unicode_string_substr (s, 0, 1); - // Convert the string to a Unicode point. - const utf8proc_uint8_t *str = reinterpret_cast(s.c_str ()); - const utf8proc_ssize_t len = static_cast (s.length ()); - utf8proc_int32_t codepoint; - [[maybe_unused]] auto output = utf8proc_iterate (str, len, &codepoint); - point = codepoint; - } - catch (...) { } - } - return point; -} - - -std::string unicode_string_str_replace (const std::string& search, const std::string& replace, std::string subject) -{ - // The needle to look for should not be empty. - if (!search.empty ()) { - // Do the replacing. - const size_t searchlength = filter::strings::unicode_string_length (search); - size_t offposition = filter::strings::unicode_string_strpos (subject, search); - while (offposition != std::string::npos) { - std::string subject_before {}; - // Due to the nature of the substr finder, it needs special handling for search position zero. - if (offposition != 0) subject_before = filter::strings::unicode_string_substr (subject, 0, offposition); - // Continue with the splitting and joining. - const std::string subject_after = filter::strings::unicode_string_substr (subject, offposition + searchlength, subject.length()); - subject = subject_before + replace + subject_after; - // Prepare for next iteration. - offposition = filter::strings::unicode_string_strpos (subject, search, offposition + filter::strings::unicode_string_length (replace)); - } - } - // Ready. - return subject; -} - - -#ifdef HAVE_ICU -std::string icu_string_normalize (const std::string& s, const bool remove_diacritics, const bool casefold) -{ - // Skip any conversions that slow things down if no normalization is to be done. - if (!remove_diacritics && !casefold) return s; - - // UTF-8 std::string -> UTF-16 UnicodeString - icu::UnicodeString source = icu::UnicodeString::fromUTF8 (icu::StringPiece (s)); - - // The order of doing the normalization action may be of influence on the result. - // Right now it seems more logical to remove diacritics first and then doing the case folding. - - // Removal of diacritics. - if (remove_diacritics) { - // Transliterate UTF-16 UnicodeString following this rule: - // decompose, remove diacritics, recompose - UErrorCode status = U_ZERO_ERROR; - icu::Transliterator *accents_converter = icu::Transliterator::createInstance("NFD; [:M:] Remove; NFC", UTRANS_FORWARD, status); - accents_converter->transliterate(source); - } - - // Case folding. - if (casefold) { - source.foldCase (); - } - - // UTF-16 UnicodeString -> UTF-8 std::string - std::string result {}; - source.toUTF8String (result); - - // Ready. - return result; -} -#endif - - -// Some code for when it's necessary to find out if text is alphabetic. -//#include -//#include -//#include -//const std::string& word = static_cast(symbol); -//icu::UnicodeString uword = icu::UnicodeString::fromUTF8(icu::StringPiece(word.data(), word.size())); -// -//std::string signature = "= 3 && ch_1 == 's') { -// if (ch_2 != 's' && ch_2 != 'i' && ch_2 != 'u') -// signature += "-s"; -//} else if (length >= 5 && ! has_dash && ! (has_digit && num_caps > 0)) { -// if (uword.endsWith("ed")) -// signature += "-ed"; -// else if (uword.endsWith("ing")) -// signature += "-ing"; -// else if (uword.endsWith("ion")) -// signature += "-ion"; -// else if (uword.endsWith("er")) -// signature += "-er"; -// else if (uword.endsWith("est")) -// signature += "-est"; -// else if (uword.endsWith("ly")) -// signature += "-ly"; -// else if (uword.endsWith("ity")) -// signature += "-ity"; -// else if (uword.endsWith("y")) -// signature += "-y"; -// else if (uword.endsWith("al")) -// signature += "-al"; -//} - - -// Generate a truly random number between $floor and $ceiling. -int rand (const int floor, const int ceiling) -{ - const int range = ceiling - floor; - const int r = config_globals_int_distribution (config_globals_random_engine) % range + floor; - return r; -} - - -std::string html2text (std::string html) -{ - // Clean the html up. - html = replace ("\n", std::string(), html); - - // The output text. - std::string text {}; - - // Keep going while the html contains the < character. - size_t pos {html.find ("<")}; - while (pos != std::string::npos) { - // Add the text before the <. - text.append (html.substr (0, pos)); - html = html.substr (pos + 1); - // Certain tags start new lines. - const std::string tag1 {filter::strings::unicode_string_casefold (html.substr (0, 1))}; - const std::string tag2 {filter::strings::unicode_string_casefold (html.substr (0, 2))}; - const std::string tag3 {filter::strings::unicode_string_casefold (html.substr (0, 3))}; - if ((tag1 == "p") - || (tag3 == "div") - || (tag2 == "li") - || (tag3 == "/ol") - || (tag3 == "/ul") - || (tag2 == "h1") - || (tag2 == "h2") - || (tag2 == "h3") - || (tag2 == "h4") - || (tag2 == "h5") - || (tag2 == "br") - ) { - text.append ("\n"); - } - // Clear text out till the > character. - pos = html.find (">"); - if (pos != std::string::npos) { - html = html.substr (pos + 1); - } - // Next iteration. - pos = html.find ("<"); - } - // Add any remaining bit of text. - text.append (html); - - // Replace xml entities with their text. - text = filter::strings::unescape_special_xml_characters (text); - - while (text.find ("\n\n") != std::string::npos) { - text = filter::strings::replace ("\n\n", "\n", text); - } - text = filter::strings::trim (text); - return text; -} - - -// Extracts the pure email address from a string. -// input: Foo Bar -// input: foo@bar.nl -// Returns: foo@bar.nl -// If there is no valid email, it returns false. -std::string extract_email (std::string input) -{ - size_t pos = input.find ("<"); - if (pos != std::string::npos) { - input = input.substr (pos + 1); - } - pos = input.find (">"); - if (pos != std::string::npos) { - input = input.substr (0, pos); - } - std::string email {input}; - if (!filter_url_email_is_valid (email)) email.clear(); - return email; -} - - -// Extracts a clean string from the email body given in input. -// It leaves out the bit that was quoted. -// If year and sender are given, it also removes lines that contain both strings. -// This is used to remove lines like: -// On Wed, 2011-03-02 at 08:26 +0100, Bibledit wrote: -std::string extract_body (const std::string& input, std::string year, std::string sender) -{ - const std::vector inputlines {filter::strings::explode (input, '\n')}; - if (inputlines.empty ()) return std::string(); - std::vector body {}; - for (const auto& line : inputlines) { - const std::string trimmed {filter::strings::trim (line)}; - if (trimmed.empty()) continue; - if (trimmed.find (">") == 0) continue; - if ((!year.empty()) && (!sender.empty())) { - if (trimmed.find (year) != std::string::npos) { - if (trimmed.find (sender) != std::string::npos) { - continue; - } - } - } - body.push_back (line); - } - std::string bodystring = filter::strings::implode (body, "\n"); - bodystring = trim (bodystring); - return bodystring; -} - - -// Returns an appropriate value. -std::string get_checkbox_status (const bool enabled) -{ - if (enabled) return "checked"; - return ""; -} - - -std::string get_disabled (const bool disabled) -{ - if (disabled) return "disabled"; - return std::string(); -} - - -std::string get_reload () -{ - return "reload"; -} - - -void quick_swap(std::string& a, std::string & b) -{ - std::string t {a}; - a = b; - b = t; -} - - -void quick_swap(unsigned int &a, unsigned int &b) -{ - unsigned int t {a}; - a = b; - b = t; -} - - -void quick_swap(long unsigned int &a, long unsigned int &b) -{ - long unsigned int t {a}; - a = b; - b = t; -} - - -void quick_swap(int &a, int &b) -{ - int t {a}; - a = b; - b = t; -} - - -void quick_swap(bool & a, bool & b) -{ - bool t {a}; - a = b; - b = t; -} - - -// This function is unusual in the sense that it does not sort one container, -// as the majority of sort functions do, but it accepts two containers. -// It sorts on the first, and reorders the second container at the same time, -// following the reordering done in the first container. -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - unsigned int piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - quick_swap(two[l], two[r]); - } - } - --l; - quick_swap(one[l], one[beg]); - quick_swap(two[l], two[beg]); - quick_sort(one, two, beg, l); - quick_sort(one, two, r, end); - } -} - - -void quick_sort(std::vector& one, std::vector& two, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - std::string piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - quick_swap(two[l], two[r]); - } - } - --l; - quick_swap(one[l], one[beg]); - quick_swap(two[l], two[beg]); - quick_sort(one, two, beg, l); - quick_sort(one, two, r, end); - } -} - - -void quick_sort(std::vector& one, std::vector& two, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - unsigned int piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - quick_swap(two[l], two[r]); - } - } - --l; - quick_swap(one[l], one[beg]); - quick_swap(two[l], two[beg]); - quick_sort(one, two, beg, l); - quick_sort(one, two, r, end); - } -} - - -void quick_sort (std::vector& one, std::vector& two, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - unsigned int piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - bool two_l = two[l]; - bool two_r = two[r]; - quick_swap(two_l, two_r); - two[l] = two_l; - two[r] = two_r; - } - } - --l; - quick_swap(one[l], one[beg]); - bool two_l = two[l]; - bool two_beg = two[beg]; - quick_swap(two_l, two_beg); - two[l] = two_l; - two[beg] = two_beg; - quick_sort(one, two, beg, l); - quick_sort(one, two, r, end); - } -} - - -void quick_sort(std::vector& one, std::vector& two, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - int piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - quick_swap(two[l], two[r]); - } - } - --l; - quick_swap(one[l], one[beg]); - quick_swap(two[l], two[beg]); - filter::strings::quick_sort(one, two, beg, l); - filter::strings::quick_sort(one, two, r, end); - } -} - -void quick_sort(std::vector& one, std::vector& two, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - std::string piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - quick_swap(two[l], two[r]); - } - } - --l; - quick_swap(one[l], one[beg]); - quick_swap(two[l], two[beg]); - quick_sort(one, two, beg, l); - quick_sort(one, two, r, end); - } -} - - -void quick_sort(std::vector& one, std::vector& two, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - std::string piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - bool two_l = two[l]; - bool two_r = two[r]; - quick_swap(two_l, two_r); - two[l] = two_l; - two[r] = two_r; - } - } - --l; - quick_swap(one[l], one[beg]); - bool two_l = two[l]; - bool two_beg = two[beg]; - quick_swap(two_l, two_beg); - two[l] = two_l; - two[beg] = two_beg; - quick_sort(one, two, beg, l); - quick_sort(one, two, r, end); - } -} - - -void quick_sort (std::vector& one, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - std::string piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - } - } - --l; - quick_swap(one[l], one[beg]); - quick_sort(one, beg, l); - quick_sort(one, r, end); - } -} - - -void quick_sort (std::vector& one, std::vector & two, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - long unsigned int piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - quick_swap(two[l], two[r]); - } - } - --l; - quick_swap(one[l], one[beg]); - quick_swap(two[l], two[beg]); - quick_sort(one, two, beg, l); - quick_sort(one, two, r, end); - } -} - - -void quick_sort (std::vector& one, std::vector& two, unsigned int beg, unsigned int end) -{ - if (end > beg + 1) { - int piv = one[beg]; - unsigned int l = beg + 1; - unsigned int r = end; - while (l < r) { - if (one[l] <= piv) { - l++; - } else { - --r; - quick_swap(one[l], one[r]); - quick_swap(two[l], two[r]); - } - } - --l; - quick_swap(one[l], one[beg]); - quick_swap(two[l], two[beg]); - quick_sort(one, two, beg, l); - quick_sort(one, two, r, end); - } -} - - -std::string number_in_string (const std::string& str) -{ - constexpr const char* numbers {"0123456789"}; - // Looks for and returns a positive number in a string. - std::string output {str}; - output.erase (0, output.find_first_of (numbers)); - const size_t end_position = output.find_first_not_of (numbers); - if (end_position != std::string::npos) { - output.erase (end_position, output.length()); - } - return output; -} - - - -// This function marks the array of $words in the string $text. -// It uses the markup for display as html. -std::string markup_words (const std::vector& words, std::string text) -{ - // Array of needles to look for. - // The needles contain the search $words as they occur in the $text - // in upper case or lower case, or any mixed case. - std::vector needles {}; - for (const auto& word : words) { - if (word.empty()) continue; - std::vector new_needles {filter::strings::search_needles (word, text)}; - needles.insert (needles.end(), new_needles.begin(), new_needles.end()); - } - needles = filter::strings::array_unique (needles); - - // All the $needles are converted to $markup, - // which will replace the $needles. - for (const auto& needle : needles) { - const std::string markup = "" + needle + ""; - text = filter::strings::replace (needle, markup, text); - } - - // Result. - return text; -} - - -// This function returns an array of needles to look for. -// The needles contain the $search word as it occurs in the $string -// in upper case or lower case or any mixed case. -std::vector search_needles (const std::string& search, const std::string& text) -{ - std::vector needles {}; - size_t position = filter::strings::unicode_string_strpos_case_insensitive (text, search, 0); - while (position != std::string::npos) { - const std::string needle = unicode_string_substr (text, position, filter::strings::unicode_string_length (search)); - needles.push_back (needle); - position = filter::strings::unicode_string_strpos_case_insensitive (text, search, position + 1); - } - needles = filter::strings::array_unique (needles); - return needles; -} - - -// Returns an integer identifier based on the name of the current user. -int user_identifier (Webserver_Request& webserver_request) -{ - const std::string username = webserver_request.session_logic()->currentUser (); - const std::string hash = md5 (username).substr (0, 5); - const int identifier = std::stoi (hash, nullptr, 36); - return identifier; -} - - -// C++ equivalent for PHP's filter::strings::bin2hex function. -std::string bin2hex (const std::string& bin) -{ - std::string res {}; - const char hex[] = "0123456789abcdef"; - for (const auto sc : bin) - { - const unsigned char c = static_cast(sc); - res += hex[c >> 4]; - res += hex[c & 0xf]; - } - return res; -} - - -// C++ equivalent for PHP's hex2bin function. -std::string hex2bin (const std::string& hex) -{ - std::string out {}; - if (hex.length() % 2 == 0) { - out.reserve (hex.length()/2); - std::string extract; - for (std::string::const_iterator pos = hex.begin(); pos < hex.end(); pos += 2) - { - extract.assign (pos, pos+2); - out.push_back (static_cast (std::stoi (extract, nullptr, 16))); - } - } - return out; -} - - -// Tidies up html. -std::string html_tidy (std::string html) -{ - html = filter::strings::replace ("<", "\n<", html); - return html; -} - - -// Converts elements from the HTML specification to the XML spec. -std::string html2xml (std::string html) -{ - // HTML specification:
    , XML specification:
    . - html = filter::strings::replace ("
    ", "
    ", html); - - // HTML specification:
    , XML specification:
    . - html = filter::strings::replace ("
    ", "
    ", html); - - return html; -} - - -// Converts XML character entities, like e.g. "¶" to normal UTF-8 character, like e.g. "¶". -std::string convert_xml_character_entities_to_characters (std::string data) -{ - bool keep_going = true; - int iterations = 0; - size_t pos1 = static_cast(-1); - do { - iterations++; - pos1 = data.find ("&#x", pos1 + 1); - if (pos1 == std::string::npos) { - keep_going = false; - continue; - } - size_t pos2 = data.find (";", pos1); - if (pos2 == std::string::npos) { - keep_going = false; - continue; - } - std::string entity = data.substr (pos1 + 3, pos2 - pos1 - 3); - data.erase (pos1, pos2 - pos1 + 1); - int codepoint; - std::stringstream ss {}; - ss << std::hex << entity; - ss >> codepoint; - - // The following is not available in GNU libstdc++. - // wstring_convert , char32_t> conv1; - // string u8str = conv1.to_bytes (codepoint); - - int cp = codepoint; - // Adapted from: http://www.zedwood.com/article/cpp-utf8-char-to-codepoint. - char c[5]={ 0x00,0x00,0x00,0x00,0x00 }; - if (cp<=0x7F) { - c[0] = static_cast (cp); - } - else if (cp<=0x7FF) { - c[0] = static_cast((cp>>6)+192); - c[1] = static_cast((cp&63)+128); - } - else if (0xd800<=cp && cp<=0xdfff) {} // Invalid block of utf8. - else if (cp<=0xFFFF) { - c[0] = static_cast((cp>>12)+224); - c[1] = static_cast(((cp>>6)&63)+128); - c[2] = static_cast((cp&63)+128); - } - else if (cp<=0x10FFFF) { - c[0] = static_cast((cp>>18)+240); - c[1] = static_cast(((cp>>12)&63)+128); - c[2] = static_cast(((cp>>6)&63)+128); - c[3] = static_cast((cp&63)+128); - } - std::string u8str = std::string (c); - - data.insert (pos1, u8str); - } while (keep_going & (iterations < 100000)); - return data; -} - - -// Encrypts the $data if the data is unencrypted. -// Decrypts the $data if the data is encrypted. -std::string encrypt_decrypt (std::string key, std::string data) -{ - // Encrypt the key. - key = md5 (key); - // Encrypt the data through the encrypted key. - for (size_t i = 0; i < data.size(); i++) { - data[i] = data[i] ^ key [i % key.length ()]; - } - // Result. - return data; -} - - -// Gets a new random string for sessions, encryption, you name it. -std::string get_new_random_string () -{ - const std::string u = filter::strings::convert_to_string (filter::date::numerical_microseconds ()); - const std::string s = filter::strings::convert_to_string (filter::date::seconds_since_epoch ()); - const std::string r = filter::strings::convert_to_string (config_globals_int_distribution (config_globals_random_engine)); - return md5 (u + s + r); -} - - -std::string unicode_non_breaking_space_entity () -{ - return " "; -} - - -std::string unicode_black_up_pointing_triangle () -{ - return "▲"; -} - - -std::string unicode_black_right_pointing_triangle () -{ - return "▶"; -} - - -std::string unicode_black_down_pointing_triangle () -{ - return "▼"; -} - - -std::string unicode_black_left_pointing_triangle () -{ - return "◀"; -} - - -std::string emoji_black_right_pointing_triangle () -{ - return "▶️"; -} - - -std::string emoji_file_folder () -{ - return "📁"; -} - - -std::string emoji_open_book () -{ - return "📖"; -} - - -std::string emoji_wastebasket () -{ - return "🗑"; -} - - -std::string emoji_smiling_face_with_smiling_eyes () -{ - return "😊"; -} - - -std::string emoji_heavy_plus_sign () -{ - return "➕"; -} - - -// Move the $item $up (towards the beginning), or else down (towards the end). -void array_move_up_down (std::vector& container, const size_t item, const bool up) -{ - if (container.empty ()) return; - if (up) { - if (item > 0) { - if (item < container.size ()) { - const std::string s = container [item - 1]; - container [item - 1] = container [item]; - container [item] = s; - } - } - } else { - if (item < (container.size () - 1)) { - const std::string s = container [item + 1]; - container [item + 1] = container [item]; - container [item] = s; - } - } -} - - -// Move the item in the $container from position $from to position $to. -void array_move_from_to (std::vector& container, size_t from, size_t to) -{ - // Check on validity of where moving from and where moving to. - if (from == to) return; - if (from >= container.size ()) return; - if (to >= container.size ()) return; - - // Put the data into a map where the keys are multiplied by two. - std::map mapped_container {}; - for (unsigned int i = 0; i < container.size(); i++) { - mapped_container [static_cast(i * 2)] = container [i]; - } - - // Direction of moving. - const bool move_up = to > from; - - // Updated keys. - from *= 2; - to *= 2; - - // Remove the item, and insert it by a key that puts it at the desired position. - std::string moving_item = mapped_container [static_cast (from)]; - mapped_container.erase (static_cast (from)); - if (move_up) to++; - else to--; - mapped_container [static_cast (to)] = moving_item; - - // Since the map sorts by key, - // transfer its data back to the original container. - container.clear (); - for (auto & element : mapped_container) { - container.push_back (element.second); - } -} - - -const char * english () -{ - return "English"; -} - - -#ifdef HAVE_WINDOWS -std::wstring string2wstring(const std::string& str) -{ - using convert_typeX = std::codecvt_utf8; - std::wstring_convert converterX; - return converterX.from_bytes(str); -} -#endif - - -#ifdef HAVE_WINDOWS -std::string wstring2string(const std::wstring& wstr) -{ - using convert_typeX = std::codecvt_utf8; - std::wstring_convert converterX; - return converterX.to_bytes(wstr); -} -#endif - - -// Converts any line feed character in $str to carriage return + line feed characters, -// basically adding the appropriate carriage return characters. -std::string lf2crlf (std::string str) -{ - return replace ("\n", "\r\n", str); -} - - -// Converts any carriage return + line feed characters to a line feed character, -// essentially removing any carriage return characters. -std::string crlf2lf (std::string str) -{ - return replace ("\r\n", "\n", str); -} - - -// Gets the ... part of the input $html. -std::string html_get_element (std::string html, std::string element) -{ - size_t pos = html.find ("<" + element); - if (pos != std::string::npos) { - html.erase (0, pos); - pos = html.find (""); - if (pos != std::string::npos) { - html.erase (pos + 7); - } - } - return html; -} - - -/* - string filter_string_tidy_invalid_html_leaking (string html) - { - // Everything in the can be left out: It is not relevant. - filter::strings::replace_between (html, "", "", ""); - - // Every can be left out: They are irrelevant. - int counter = 0; - while (counter < 100) { - counter++; - bool replaced = filter::strings::replace_between (html, "", ""); - if (!replaced) break; - } - - #ifdef HAVE_CLOUD - - // This method works via libxml2 and there are many memory leaks each call to this. - // It cannot be used for production code. - // The leaks are fixable, see the laboratory/tiny code. - - // Create a parser context. - htmlParserCtxtPtr parser = htmlCreatePushParserCtxt (nullptr, nullptr, nullptr, 0, nullptr, XML_CHAR_ENCODING_UTF8); - - // Set relevant options on the parser context. - htmlCtxtUseOptions(parser, HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_NONET); - - // Parse the (X)HTML text. - // char * data : buffer containing part of the web page - // int len : number of bytes in data - // Last argument is 0 if the web page isn't complete, and 1 for the final call. - htmlParseChunk(parser, html.c_str(), static_cast (html.size()), 1); - - // Extract the fixed html - if (parser->myDoc) { - xmlChar *s; - int size; - xmlDocDumpMemory(parser->myDoc, &s, &size); - html = reinterpret_cast (s); - xmlFree(s); - } - - // Free memory. - if (parser) xmlFree (parser); - - #endif - - return html; - } - */ - - -const std::string nonbreaking_inline_tags {"|a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|img|kbd|nobr|s|small|span|strike|strong|sub|sup|tt|"}; -const std::string empty_tags {"|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|"}; -const std::string preserve_whitespace_tags {"|pre|textarea|script|style|"}; -const std::string special_handling_tags {"|html|body|"}; -const std::string no_entity_substitution_tags {"|script|style|"}; -const std::string treat_like_inline_tags {"|p|"}; - - -static std::string substitute_xml_entities_into_text(const std::string& text) -{ - std::string result {text}; - // Replacing & must come first. - result = filter::strings::replace ("&", "&", result); - result = filter::strings::replace ("<", "<", result); - result = filter::strings::replace (">", ">", result); - // Done. - return result; -} - - -static std::string substitute_xml_entities_into_attributes(const char quote, const std::string& text) -{ - std::string result {substitute_xml_entities_into_text (text)}; - if (quote == '"') { - result = filter::strings::replace("\"",""", result); - } - else if (quote == '\'') { - result = filter::strings::replace("'","'", result); - } - return result; -} - - -#ifdef HAVE_CLOUD -static std::string handle_unknown_tag(GumboStringPiece *text) -{ - std::string tagname {}; - if (text->data == NULL) { - return tagname; - } - // work with copy GumboStringPiece to prevent asserts - // if try to read same unknown tag name more than once - GumboStringPiece gsp = *text; - gumbo_tag_from_original_text(&gsp); - tagname = std::string(gsp.data, gsp.length); - return tagname; -} -#endif - - -#ifdef HAVE_CLOUD -static std::string get_tag_name(GumboNode *node) -{ - std::string tagname {}; - // Work around lack of proper name for document node. - if (node->type == GUMBO_NODE_DOCUMENT) { - tagname = "document"; - } else { - tagname = gumbo_normalized_tagname(node->v.element.tag); - } - if (tagname.empty()) { - tagname = handle_unknown_tag(&node->v.element.original_tag); - } - return tagname; -} -#endif - - -#ifdef HAVE_CLOUD -static std::string build_doctype(GumboNode *node) -{ - std::string results {}; - if (node->v.document.has_doctype) { - results.append("v.document.name); - std::string pi(node->v.document.public_identifier); - if ((node->v.document.public_identifier != NULL) && !pi.empty() ) { - results.append(" PUBLIC \""); - results.append(node->v.document.public_identifier); - results.append("\" \""); - results.append(node->v.document.system_identifier); - results.append("\""); - } - results.append(">\n"); - } - return results; -} -#endif - - -#ifdef HAVE_CLOUD -static std::string build_attributes(GumboAttribute * at, bool no_entities) -{ - std::string atts {}; - atts.append (" "); - atts.append (at->name); - - // how do we want to handle attributes with empty values - // or - - if ( (!std::string(at->value).empty()) || - (at->original_value.data[0] == '"') || - (at->original_value.data[0] == '\'') ) { - - // determine original quote character used if it exists - char quote = at->original_value.data[0]; - std::string qs {}; - if (quote == '\'') qs = "'"; - if (quote == '"') qs = "\""; - - atts.append("="); - - atts.append(qs); - - if (no_entities) { - atts.append(at->value); - } else { - atts.append(substitute_xml_entities_into_attributes(quote, std::string(at->value))); - } - - atts.append(qs); - } - return atts; -} -#endif - - -// Forward declaration -#ifdef HAVE_CLOUD -static std::string pretty_print (GumboNode*, int lvl, const std::string& indent_chars); -#endif - - -// Pretty-print children of a node. May be invoked recursively. -#ifdef HAVE_CLOUD -static std::string pretty_print_contents (GumboNode* node, int lvl, const std::string& indent_chars) -{ - std::string contents {}; - std::string tagname {get_tag_name(node)}; - std::string key {"|" + tagname + "|"}; - const bool no_entity_substitution {no_entity_substitution_tags.find(key) != std::string::npos}; - const bool keep_whitespace {preserve_whitespace_tags.find(key) != std::string::npos}; - const bool is_inline {nonbreaking_inline_tags.find(key) != std::string::npos}; - const bool pp_okay {!is_inline && !keep_whitespace}; - - GumboVector* children {&node->v.element.children}; - - for (unsigned int i {0}; i < children->length; ++i) { - GumboNode* child = static_cast (children->data[i]); - - if (child->type == GUMBO_NODE_TEXT) { - - std::string val {}; - - if (no_entity_substitution) { - val = std::string(child->v.text.text); - } else { - val = substitute_xml_entities_into_text(std::string(child->v.text.text)); - } - - if (pp_okay) { - val = filter::strings::rtrim(val); - } - - if (pp_okay && (contents.length() == 0)) { - // Add the required indentation. - char c {indent_chars.at(0)}; - size_t n {indent_chars.length()}; - contents.append (std::string (static_cast(lvl-1)*n,c)); - } - - contents.append (val); - - - } else if ((child->type == GUMBO_NODE_ELEMENT) || (child->type == GUMBO_NODE_TEMPLATE)) { - - std::string val = pretty_print(child, lvl, indent_chars); - - // Remove any indentation if this child is inline and not a first child. - const std::string childname = get_tag_name(child); - const std::string childkey = "|" + childname + "|"; - if ((nonbreaking_inline_tags.find(childkey) != std::string::npos) && (contents.length() > 0)) { - val = filter::strings::ltrim(val); - } - - contents.append(val); - - } else if (child->type == GUMBO_NODE_WHITESPACE) { - - if (keep_whitespace || is_inline) { - contents.append(std::string(child->v.text.text)); - } - - } else if (child->type != GUMBO_NODE_COMMENT) { - - // Does this actually exist: (child->type == GUMBO_NODE_CDATA) - fprintf(stderr, "unknown element of type: %d\n", child->type); - - } - - } - - return contents; -} -#endif - - -// Pretty-print a GumboNode back to html/xhtml. May be invoked recursively -#ifdef HAVE_CLOUD -static std::string pretty_print(GumboNode* node, int lvl, const std::string& indent_chars) -{ - // Special case: The document node. - if (node->type == GUMBO_NODE_DOCUMENT) { - std::string results {build_doctype(node)}; - results.append(pretty_print_contents (node, lvl + 1, indent_chars)); - return results; - } - - std::string close {}; - std::string closeTag {}; - std::string attributes {}; - std::string tagname {get_tag_name(node)}; - std::string key {"|" + tagname + "|"}; - //bool need_special_handling {special_handling.find(key) != std::string::npos}; - const bool is_empty_tag {empty_tags.find(key) != std::string::npos}; - const bool no_entity_substitution {no_entity_substitution_tags.find(key) != std::string::npos}; - const bool keep_whitespace {preserve_whitespace_tags.find(key) != std::string::npos}; - const bool is_inline {nonbreaking_inline_tags.find(key) != std::string::npos}; - const bool inline_like {treat_like_inline_tags.find(key) != std::string::npos}; - const bool pp_okay {!is_inline && !keep_whitespace}; - char c {indent_chars.at(0)}; - size_t n {indent_chars.length()}; - - // Build the attr string. - const GumboVector * attribs {&node->v.element.attributes}; - for (unsigned int i = 0; i < attribs->length; ++i) { - GumboAttribute * gumbo_attribute {static_cast(attribs->data[i])}; - attributes.append (build_attributes (gumbo_attribute, no_entity_substitution)); - } - - // Determine the closing tag type. - if (is_empty_tag) { - close = "/"; - } else { - closeTag = ""; - } - - const std::string indent_space {std::string (static_cast(lvl-1)*n,c)}; - - // Pretty print the contents. - std::string contents {pretty_print_contents(node, lvl+1, indent_chars)}; - - // if (need_special_handling) { - // contents = filter::strings::rtrim(contents); - // } - - char last_char = ' '; - if (!contents.empty()) { - last_char = contents.at (contents.length() - 1); - } - - // Build the results. - std::string results; - if (pp_okay) { - results.append(indent_space); - } - results.append("<"+tagname+attributes+close+">"); - if (pp_okay && !inline_like) { - results.append("\n"); - } - // if (inline_like) { - // contents = filter::strings::ltrim(contents); - // } - results.append(contents); - if (pp_okay && !contents.empty() && (last_char != '\n') && (!inline_like)) { - results.append("\n"); - } - if (pp_okay && !inline_like && !closeTag.empty()) { - results.append(indent_space); - } - results.append(closeTag); - if (pp_okay && !closeTag.empty()) { - results.append("\n"); - } - - return results; -} -#endif - - -std::string fix_invalid_html_gumbo (std::string html) -{ - // Everything in the can be left out: It is not relevant. - filter::strings::replace_between (html, "", "", std::string()); - - // Every can be left out: They are irrelevant. - int counter {0}; - while (counter < 100) { - counter++; - const bool replaced = filter::strings::replace_between (html, "", std::string()); - if (!replaced) break; - } - -#ifdef HAVE_CLOUD - - // https://github.com/google/gumbo-parser - GumboOptions options {kGumboDefaultOptions}; - GumboOutput* output = gumbo_parse_with_options(&options, html.data(), html.length()); - const std::string indent_chars {" "}; - html = pretty_print (output->document, 0, indent_chars); - gumbo_destroy_output (&options, output); - -#endif - - return html; -} - - -std::string fix_invalid_html_tidy (std::string html) -{ -#ifdef HAVE_CLOUD - - // The buffers. - TidyBuffer output {}; - memset (&output, 0, sizeof(TidyBuffer)); - TidyBuffer errbuf {}; - memset (&errbuf, 0, sizeof(TidyBuffer)); - - // Initialize the document. - TidyDoc tdoc = tidyCreate(); - - // Set a few options. - tidyOptSetBool (tdoc, TidyXmlOut, yes); - tidyOptSetBool (tdoc, TidyHideComments, yes); - tidyOptSetBool (tdoc, TidyJoinClasses, yes); - tidyOptSetBool (tdoc, TidyBodyOnly, yes); - - // Capture diagnostics. - int rc = tidySetErrorBuffer (tdoc, &errbuf); - - // Parse the input. - if (rc >= 0) rc = tidyParseString (tdoc, html.c_str()); - - // Tidy it up. - if (rc >= 0) rc = tidyCleanAndRepair (tdoc); - - // Run the diagnostics. - if (rc >= 0) rc = tidyRunDiagnostics (tdoc); - // If error, force output. - if (rc > 1) rc = (tidyOptSetBool (tdoc, TidyForceOutput, yes) ? rc : -1); - - // Pretty print. - if (rc >= 0) rc = tidySaveBuffer (tdoc, &output); - - if (rc >= 0) { - if (rc > 0) { - // std::cerr << "Html tidy diagnostics:" << std::endl; - // std::cerr << errbuf.bp << std::endl; - } - // std::cout << "Html tidy result:" << std::endl; - // std::cout << output.bp << std::endl; - html = std::string (reinterpret_cast(output.bp)); - } - else { - Database_Logs::log("A severe error occurred while tidying html - code " + std::to_string(rc) + " - html: " + html); - } - - // Release memory. - tidyBufFree (&output); - tidyBufFree (&errbuf); - tidyRelease (tdoc); - -#endif - - // Done. - return html; -} - - -std::string collapse_whitespace (std::string s) -{ - int count {}; - int iterator {0}; - do { - count = 0; - s = filter::strings::replace (" ", " ", s, &count); - iterator++; - } while ((count > 0) && iterator < 5); - return s; -} - - -std::string convert_windows1252_to_utf8 (const std::string& input) -{ - // Convert the encoding. - std::string utf8 {}; - utf8::utf16to8(input.begin(), input.end(), back_inserter(utf8)); - - // Handle weird conversions. - utf8 = filter::strings::replace ("￯﾿ᄑ", "'", utf8); - - // Pass it to the caller. - return utf8; - - // It could be done through the iconv library. - // in the way that the iconv binary does it. - // 1, Remove the meta information from the html head. - // 2. iconv -f CP1252 -t UTF-8 ./john-ma-lbw2.htm > john-ma-lbw3.htm - // But libiconv-dev is not available as a Debian package. - // So eventually libiconv was not used. - - // The conversion descriptor for converting WINDOWS-1252 -> UTF-8. - //iconv_t conversion_descriptor = iconv_open ("UTF-8", "CP1252"); - //if (conversion_descriptor == (iconv_t)(-1)) { - // throw std::runtime_error("Cannot open converter from Windows-1252 to UTF-8"); - //} - - // The pointer to the input buffer. - //char* input_pointer = const_cast(input.c_str()); - - // The output buffer. - //constexpr int outbuf_size {10000}; // make it dynamic. - //unsigned char outbuf[outbuf_size]; - //memset(outbuf, 0, outbuf_size); - //char *outptr = (char*) outbuf; - - // The number of bytes left in the input and output buffers. - //size_t input_bytes_left {input.length()}; - //size_t output_bytes_left {outbuf_size}; - - // Repeat converting and handling unconvertible characters. - //while (input_bytes_left > 0) { - // Do the conversion. - //size_t result = iconv(conversion_descriptor, &input_pointer, &input_bytes_left, &outptr, &output_bytes_left); - //if (result == (size_t)(-1)) { - // Handle situation that an invalid multibyte sequence is encountered in the input. - // In this case the input pointer is left pointing to - // the beginning of the invalid multibyte sequence. - //if (errno == EILSEQ) { - // int one = 1; - // iconvctl (conversion_descriptor, ICONV_SET_DISCARD_ILSEQ, &one); - //} else if (errno == EINVAL) { - // int one = 1; - // iconvctl (conversion_descriptor, ICONV_SET_DISCARD_ILSEQ, &one); - //} else if (errno == E2BIG) { - // input_bytes_left = 0; - //} else { - // input_bytes_left = 0; - //} - //} - //} - - // Close the conversion descriptor. - //iconv_close(conversion_descriptor); - - // Assemble the resulting UTF-8 text. - //std::string utf8 {}; - //utf8.assign ((char*)outbuf, outbuf_size - output_bytes_left); - - // Handle weird conversions. - //utf8 = filter::strings::replace ("�", "'", utf8); - - // Pass it to the caller. - //return utf8; -} - - -} // Namespace. diff --git a/filter/string.h b/filter/string.h deleted file mode 100644 index 35b665252..000000000 --- a/filter/string.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class Webserver_Request; - -namespace filter::strings { - -std::vector explode (std::string value, char delimiter); -std::vector explode (std::string value, std::string delimiters); -std::string implode (std::vector & values, std::string delimiter); -std::string replace (const std::string& search, const std::string& replace, std::string subject, int * count = nullptr); -bool replace_between (std::string& line, const std::string& start, const std::string& end, const std::string& replacement); -std::string convert_to_string (const size_t i); -std::string convert_to_string (const int i); -std::string convert_to_string (const char * c); -std::string convert_to_string (const bool b); -std::string convert_to_string (const std::string& s); -std::string convert_to_string (const float f); -int convert_to_int (const std::string& s); -int convert_to_int (const float f); -long long convert_to_long_long (const std::string& s); -float convert_to_float (const std::string& s); -bool convert_to_bool (const std::string& s); -std::string convert_to_true_false (const bool b); -std::u16string convert_to_u16string (const std::string& s); -std::vector array_unique (const std::vector & values); -std::vector array_unique (const std::vector & values); -std::vector array_diff (const std::vector & from, const std::vector & against); -std::vector array_diff (const std::vector & from, const std::vector & against); -std::string trim (const std::string& s); -std::string ltrim (const std::string& s); -std::string rtrim (std::string s); -std::string fill (const std::string& s, const int width, const char fill); -bool is_numeric (const std::string& s); -std::string escape_special_xml_characters (std::string s); -std::string unescape_special_xml_characters (std::string s); -std::string any_space_to_standard_space (std::string s); -std::string non_breaking_space_u00A0 (); -std::string soft_hyphen_u00AD (); -std::string en_space_u2002 (); -std::string figure_space_u2007 (); -std::string narrow_non_breaking_space_u202F (); -size_t unicode_string_length (const std::string& s); -std::string unicode_string_substr (std::string s, size_t pos = 0, size_t len = 0); -size_t unicode_string_strpos (const std::string& haystack, const std::string& needle, const size_t offset = 0); -size_t unicode_string_strpos_case_insensitive (std::string haystack, std::string needle, size_t offset = 0); -std::string unicode_string_casefold (const std::string& s); -std::string unicode_string_uppercase (const std::string& s); -std::string unicode_string_transliterate (const std::string& s); -bool unicode_string_is_valid (const std::string& s); -bool unicode_string_is_punctuation (std::string s); -int unicode_string_convert_to_codepoint (std::string s); -std::string unicode_string_str_replace (const std::string& search, const std::string& replace, std::string subject); -#ifdef HAVE_ICU -std::string icu_string_normalize (const std::string& s, const bool remove_diacritics, const bool casefold); -#endif -int rand (const int floor, const int ceiling); -std::string html2text (std::string html); -std::string extract_email (std::string input); -std::string extract_body (const std::string& input, const std::string year = "", const std::string sender = ""); -std::string get_checkbox_status (const bool enabled); -std::string get_disabled (const bool disabled = true); -std::string get_reload (); -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end); -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end); -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end); -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end); -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end); -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end); -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end); -void quick_sort (std::vector & one, unsigned int beg, unsigned int end); -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end); -void quick_sort (std::vector & one, std::vector & two, unsigned int beg, unsigned int end); -std::string number_in_string (const std::string & str); -std::string markup_words (const std::vector & words, std::string text); -std::vector search_needles (const std::string& search, const std::string& text); -int user_identifier (Webserver_Request& webserver_request); -std::string bin2hex (const std::string& bin); -std::string hex2bin (const std::string& hex); -std::string html_tidy (std::string html); -std::string html2xml (std::string html); -std::string convert_xml_character_entities_to_characters (std::string data); -std::string encrypt_decrypt (std::string key, std::string data); -std::string get_new_random_string (); -std::string unicode_non_breaking_space_entity (); -std::string unicode_black_up_pointing_triangle (); -std::string unicode_black_right_pointing_triangle (); -std::string unicode_black_down_pointing_triangle (); -std::string unicode_black_left_pointing_triangle (); -std::string emoji_black_right_pointing_triangle (); -std::string emoji_file_folder (); -std::string emoji_open_book (); -std::string emoji_wastebasket (); -std::string emoji_smiling_face_with_smiling_eyes (); -std::string emoji_heavy_plus_sign (); -void array_move_up_down (std::vector & container, const size_t item, const bool up); -void array_move_from_to (std::vector & container, size_t from, size_t to); -const char * english (); -#ifdef HAVE_WINDOWS -std::wstring string2wstring (const std::string& str); -std::string wstring2string (const std::wstring& wstr); -#endif -std::string lf2crlf (std::string str); -std::string crlf2lf (std::string str); -std::string html_get_element (std::string html, std::string element); -std::string fix_invalid_html_gumbo (std::string html); -std::string fix_invalid_html_tidy (std::string html); -std::string collapse_whitespace (std::string s); -std::string convert_windows1252_to_utf8 (const std::string& input); - -} diff --git a/filter/string.hpp b/filter/string.hpp deleted file mode 100644 index 6551a8f4a..000000000 --- a/filter/string.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - - -// A C++ equivalent for PHP's function. -template -std::vector array_intersect (std::vector a, std::vector b) -{ - std::vector result; - std::set aset (a.begin(), a.end()); - for (auto & item : b) { - if (aset.find (item) != aset.end()) { - result.push_back (item); - } - } - return result; -} - - -// A C++ equivalent for PHP's function. -template -bool in_array (const T & needle, const std::vector & haystack) -{ - return (find (haystack.begin(), haystack.end(), needle) != haystack.end()); -} - - -// Clip a value to not be less than "lower" and not more than "higher" -template -T clip (const T& n, const T& lower, const T& upper) { - return std::max (lower, std::min (n, upper)); -} - diff --git a/filter/text.cpp b/filter/text.cpp deleted file mode 100644 index a00f313ab..000000000 --- a/filter/text.cpp +++ /dev/null @@ -1,1745 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -namespace filter::text { - -passage_marker_value::passage_marker_value (int book, int chapter, string verse, string marker, string value) -{ - m_book = book; - m_chapter = chapter; - m_verse = verse; - m_marker = marker; - m_value = value; -} - -} - - -// This class filters USFM text, converting it into other formats. - - -Filter_Text::Filter_Text (string bible) -{ - m_bible = bible; - space_type_after_verse = Database_Config_Bible::getOdtSpaceAfterVerse (m_bible); - odt_left_align_verse_in_poetry_styles = Database_Config_Bible::getOdtPoetryVersesLeft (m_bible); -} - - - -Filter_Text::~Filter_Text () -{ - if (odf_text_standard) delete odf_text_standard; - if (odf_text_text_only) delete odf_text_text_only; - if (odf_text_text_and_note_citations) delete odf_text_text_and_note_citations; - if (odf_text_notes) delete odf_text_notes; - if (html_text_standard) delete html_text_standard; - if (html_text_linked) delete html_text_linked; - if (onlinebible_text) delete onlinebible_text; - if (esword_text) delete esword_text; - if (text_text) delete text_text; - if (tbsx_text) delete tbsx_text; -} - - - -// This function adds USFM code to the class. -// $code: USFM code. -void Filter_Text::add_usfm_code (string usfm) -{ - // Check that the USFM is valid UTF-8. - if (!filter::strings::unicode_string_is_valid (usfm)) { - Database_Logs::log (translate ("Exporting invalid UTF-8.") + " " + translate ("Please check.") + " " + usfm); - } - // Clean the USFM. - usfm = filter::strings::trim (usfm); - usfm += "\n"; - // Sort the USFM code out and separate it into markers and text. - vector markers_and_text = filter::usfm::get_markers_and_text (usfm); - // Add the USFM to the object. - m_usfm_markers_and_text.insert (m_usfm_markers_and_text.end(), markers_and_text.begin(), markers_and_text.end()); -} - - - -// This function runs the filter. -// $stylesheet - The stylesheet to use. -void Filter_Text::run (string stylesheet) -{ - // Get the styles. - get_styles (stylesheet); - - // Preprocess. - pre_process_usfm (); - - // Process data. - process_usfm (); - - store_verses_paragraphs (); - - // Clear USFM and styles. - m_usfm_markers_and_text.clear(); - usfm_markers_and_text_ptr = 0; - chapter_usfm_markers_and_text.clear(); - chapter_usfm_markers_and_text_pointer = 0; - styles.clear(); - chapterMarker.clear(); - createdStyles.clear(); -} - - - -// This function return true when there is still unprocessed USFM code available. -bool Filter_Text::unprocessed_usfm_code_available () -{ - return (usfm_markers_and_text_ptr < m_usfm_markers_and_text.size()); -} - - - -// This function stores data in the class: -// The next chapter from the unprocessed USFM code. -void Filter_Text::get_usfm_next_chapter () -{ - // Initialization. - chapter_usfm_markers_and_text.clear(); - chapter_usfm_markers_and_text_pointer = 0; - bool firstLine = true; - - // Obtain the standard marker for the chapter number. - // Deal with the unlikely case that the chapter marker is non-standard. - if (chapterMarker.empty()) { - chapterMarker = "c"; - for (const auto & style : styles) { - if (style.second.type == StyleTypeChapterNumber) { - chapterMarker = style.second.marker; - break; - } - } - } - - // Load the USFM code till the next chapter marker. - while (unprocessed_usfm_code_available ()) { - string item = m_usfm_markers_and_text [usfm_markers_and_text_ptr]; - if (!firstLine) { - if (filter::strings::trim (item) == (R"(\)" + chapterMarker)) { - return; - } - } - chapter_usfm_markers_and_text.push_back (item); - firstLine = false; - usfm_markers_and_text_ptr++; - } -} - - - -// This function gets the styles from the database, -// and stores them in the object for quicker access. -void Filter_Text::get_styles (string stylesheet) -{ - styles.clear(); - // Get the relevant styles information included. - if (odf_text_standard) odf_text_standard->create_page_break_style (); - if (odf_text_text_only) odf_text_text_only->create_page_break_style (); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->create_page_break_style (); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->create_superscript_style (); - Database_Styles database_styles; - vector markers = database_styles.getMarkers (stylesheet); - for (auto marker : markers) { - Database_Styles_Item style = database_styles.getMarkerData (stylesheet, marker); - styles [marker] = style; - if (style.type == StyleTypeFootEndNote) { - if (style.subtype == FootEndNoteSubtypeStandardContent) { - standard_content_marker_foot_end_note = style.marker; - } - } - if (style.type == StyleTypeCrossreference) { - if (style.subtype == CrossreferenceSubtypeStandardContent) { - standard_content_marker_cross_reference = style.marker; - } - } - } -} - - - -// This function does the preprocessing of the USFM code -// extracting a variety of information, creating note citations, etc. -void Filter_Text::pre_process_usfm () -{ - usfm_markers_and_text_ptr = 0; - while (unprocessed_usfm_code_available ()) { - get_usfm_next_chapter (); - for (chapter_usfm_markers_and_text_pointer = 0; chapter_usfm_markers_and_text_pointer < chapter_usfm_markers_and_text.size(); chapter_usfm_markers_and_text_pointer++) { - string currentItem = chapter_usfm_markers_and_text[chapter_usfm_markers_and_text_pointer]; - if (filter::usfm::is_usfm_marker (currentItem)) { - string marker = filter::strings::trim (currentItem); // Change, e.g. '\id ' to '\id'. - marker = marker.substr (1); // Remove the initial backslash, e.g. '\id' becomes 'id'. - if (filter::usfm::is_opening_marker (marker)) { - if (styles.find (marker) != styles.end()) { - Database_Styles_Item style = styles [marker]; - note_citations.evaluate_style(style); - switch (style.type) { - case StyleTypeIdentifier: - switch (style.subtype) { - case IdentifierSubtypeBook: - { - // Get book number. - string usfm_id = filter::usfm::get_book_identifier (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - usfm_id = filter::strings::replace (filter::strings::soft_hyphen_u00AD (), "", usfm_id); // Remove possible soft hyphen. - // Get Bibledit book number. - m_current_book_identifier = static_cast(database::books::get_id_from_usfm (usfm_id)); - // Reset chapter and verse numbers. - m_current_chapter_number = 0; - m_number_of_chapters_per_book[m_current_book_identifier] = 0; - set_to_zero(m_current_verse_number); - // Done. - break; - } - case IdentifierSubtypeRunningHeader: - { - const string runningHeader = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - runningHeaders.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, m_current_verse_number, marker, runningHeader)); - break; - } - case IdentifierSubtypeLongTOC: - { - const string longTOC = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - longTOCs.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, m_current_verse_number, marker, longTOC)); - break; - } - case IdentifierSubtypeShortTOC: - { - const string shortTOC = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - shortTOCs.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, m_current_verse_number, marker, shortTOC)); - break; - } - case IdentifierSubtypeBookAbbrev: - { - const string bookAbbreviation = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - bookAbbreviations.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, m_current_verse_number, marker, bookAbbreviation)); - break; - } - case IdentifierSubtypeChapterLabel: - { - // Store the chapter label for this book and chapter. - const string chapterLabel = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - chapterLabels.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, m_current_verse_number, marker, chapterLabel)); - // If a chapter label is in the book, there's no drop caps output of the chapter number. - book_has_chapter_label [m_current_book_identifier] = true; - // Done. - break; - } - case IdentifierSubtypePublishedChapterMarker: - { - const string publishedChapterMarker = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - publishedChapterMarkers.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, m_current_verse_number, marker, publishedChapterMarker)); - break; - } - case IdentifierSubtypePublishedVerseMarker: - { - // It gets the published verse markup. - // The marker looks like: ... \vp ၁။\vp* ... - // It stores this markup in the object for later reference. - const string publishedVerseMarker = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - publishedVerseMarkers.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, m_current_verse_number, marker, publishedVerseMarker)); - break; - } - default: { - break; - } - } - break; - case StyleTypeChapterNumber: - { - const string number = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - m_current_chapter_number = filter::strings::convert_to_int (number); - m_number_of_chapters_per_book[m_current_book_identifier] = m_current_chapter_number; - set_to_zero(m_current_verse_number); - break; - } - case StyleTypeVerseNumber: - { - const string fragment = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - const int number = filter::strings::convert_to_int (fragment); - m_current_verse_number = filter::strings::convert_to_string (number); - break; - } - case StyleTypeFootEndNote: - { - switch (style.subtype) - { - case FootEndNoteSubtypeFootnote: - case FootEndNoteSubtypeEndnote: - case FootEndNoteSubtypeStandardContent: - case FootEndNoteSubtypeContent: - case FootEndNoteSubtypeContentWithEndmarker: - case FootEndNoteSubtypeParagraph: - default: { - break; - } - } - break; - } - case StyleTypeCrossreference: - { - switch (style.subtype) - { - case CrossreferenceSubtypeCrossreference: - case CrossreferenceSubtypeStandardContent: - case CrossreferenceSubtypeContent: - case CrossreferenceSubtypeContentWithEndmarker: - default: { - break; - } - } - break; - } - default: { - break; - } - } - } - } - } - } - } -} - - - -// This function does the processing of the USFM code, -// formatting the document and extracting other useful information. -void Filter_Text::process_usfm () -{ - // Go through the USFM code. - int processed_books_count {0}; - usfm_markers_and_text_ptr = 0; - while (unprocessed_usfm_code_available ()) { - get_usfm_next_chapter (); - for (chapter_usfm_markers_and_text_pointer = 0; chapter_usfm_markers_and_text_pointer < chapter_usfm_markers_and_text.size(); chapter_usfm_markers_and_text_pointer++) { - const string current_item = chapter_usfm_markers_and_text [chapter_usfm_markers_and_text_pointer]; - if (filter::usfm::is_usfm_marker (current_item)) - { - // Indicator describing the marker. - const bool is_opening_marker = filter::usfm::is_opening_marker (current_item); - const bool is_embedded_marker = filter::usfm::is_embedded_marker (current_item); - // Clean up the marker, so we remain with the basic version, e.g. 'id'. - const string marker = filter::usfm::get_marker (current_item); - // Strip word-level attributes. - if (is_opening_marker) filter::usfm::remove_word_level_attributes (marker, chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - if (styles.find (marker) != styles.end()) - { - // Deal with known style. - const Database_Styles_Item& style = styles.at(marker); - switch (style.type) - { - case StyleTypeIdentifier: - { - if (odf_text_standard) odf_text_standard->close_text_style (false, false); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->close_text_style (false, false); - switch (style.subtype) - { - case IdentifierSubtypeBook: - { - // Get book number. - string usfm_id = filter::usfm::get_book_identifier (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - usfm_id = filter::strings::replace (filter::strings::soft_hyphen_u00AD (), "", usfm_id); // Remove possible soft hyphen. - m_current_book_identifier = static_cast(database::books::get_id_from_usfm (usfm_id)); - // Reset chapter and verse numbers. - m_current_chapter_number = 0; - set_to_zero(m_current_verse_number); - // Throw away whatever follows the \id, e.g. 'GEN xxx xxx'. - filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - // Whether to insert a new page before the book. But never before the first book. - if (style.userbool1) { - if (processed_books_count) { - if (odf_text_standard) odf_text_standard->new_page_break (); - if (odf_text_text_only) odf_text_text_only->new_page_break (); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->new_page_break (); - if (html_text_standard) html_text_standard->new_page_break (); - if (html_text_linked) html_text_linked->new_page_break (); - } - } - processed_books_count++; - // Reset notes. - note_citations.restart("book"); - // Online Bible. - if (onlinebible_text) onlinebible_text->storeData (); - // eSword. - if (esword_text) esword_text->newBook (m_current_book_identifier); - // The hidden header in the text normally displays in the running header. - // It does this only when it's the first header on the page. - // The book starts here. - // So create a correct hidden header for displaying in the running header. - string runningHeader = database::books::get_english_from_id (static_cast(m_current_book_identifier)); - for (auto item : runningHeaders) { - if (item.m_book == m_current_book_identifier) { - runningHeader = item.m_value; - } - } - if (odf_text_standard) odf_text_standard->new_heading1 (runningHeader, true); - if (odf_text_text_only) odf_text_text_only->new_heading1 (runningHeader, true); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->new_heading1 (runningHeader, true); - if (odf_text_notes) odf_text_notes->new_heading1 (runningHeader, false); - // The TBSX book identifier is identical to the USFM book identifier. - if (tbsx_text) tbsx_text->set_book_id(usfm_id); - // Done. - break; - } - case IdentifierSubtypeEncoding: - { - addToInfo (R"(Text encoding: \)" + marker, true); - break; - } - case IdentifierSubtypeComment: - { - addToInfo (R"(Comment: \)" + marker, true); - break; - } - case IdentifierSubtypeRunningHeader: - { - // This information was processed during the preprocessing stage. - string runningHeader = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - // Ideally this information should be inserted in the headers of the standard text document. - // UserBool2RunningHeaderLeft: - // UserBool3RunningHeaderRight: - if (tbsx_text) tbsx_text->set_book_name(runningHeader); - break; - } - case IdentifierSubtypeLongTOC: - { - // This information already went into the Info document. Remove it from the USFM stream. - filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - break; - } - case IdentifierSubtypeShortTOC: - { - // This information already went into the Info document. Remove it from the USFM stream. - filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - break; - } - case IdentifierSubtypeBookAbbrev: - { - // This information already went into the Info document. Remove it from the USFM stream. - filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - break; - } - case IdentifierSubtypeChapterLabel: - { - // This information is already in the object. Remove it from the USFM stream. - filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - break; - } - case IdentifierSubtypePublishedChapterMarker: - { - // This information is already in the object. - // Remove it from the USFM stream. - filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - break; - } - case IdentifierSubtypeCommentWithEndmarker: - { - if (is_opening_marker) { - addToInfo (R"(Comment: \)" + marker, true); - } - break; - } - case IdentifierSubtypePublishedVerseMarker: - { - if (is_opening_marker) { - // This information is already in the object. - // Remove it from the USFM stream at the opening marker. - filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - } else { - // USFM allows the closing marker \vp* to be followed by a space. - // But this space should not be converted to text output. - // https://github.com/bibledit/cloud/issues/311 - // It is going to be removed here. - const size_t pointer = chapter_usfm_markers_and_text_pointer + 1; - if (pointer < chapter_usfm_markers_and_text.size()) { - string text = chapter_usfm_markers_and_text[pointer]; - text = filter::strings::ltrim (text); - chapter_usfm_markers_and_text[pointer] = text; - } - } - break; - } - default: - { - addToFallout (R"(Unknown markup: \)" + marker, true); - break; - } - } - break; - } - case StyleTypeNotUsedComment: - { - addToFallout (R"(Unknown markup: \)" + marker, true); - break; - } - case StyleTypeNotUsedRunningHeader: - { - addToFallout (R"(Unknown markup: \)" + marker, true); - break; - } - case StyleTypeStartsParagraph: - { - if (odf_text_standard) odf_text_standard->close_text_style (false, false); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->close_text_style (false, false); - switch (style.subtype) - { - case ParagraphSubtypeMainTitle: - case ParagraphSubtypeSubTitle: - case ParagraphSubtypeSectionHeading: - { - new_paragraph (style, true); - heading_started = true; - text_started = false; - break; - } - case ParagraphSubtypeNormalParagraph: - default: - { - new_paragraph (style, false); - heading_started = false; - text_started = true; - if (headings_text_per_verse_active) { - // If a new paragraph starts within an existing verse, - // add a space to the text already in that verse. - int iverse = filter::strings::convert_to_int (m_current_verse_number); - if (m_verses_text.count (iverse) && !m_verses_text [iverse].empty ()) { - m_verses_text [iverse].append (" "); - } - // Record the style that started this new paragraph. - paragraph_starting_markers.push_back (style.marker); - // Store previous paragraph, if any, and start recording the new one. - store_verses_paragraphs (); - } - break; - } - } - break; - } - case StyleTypeInlineText: - { - // Support for a normal and an embedded character style. - if (is_opening_marker) { - if (odf_text_standard) odf_text_standard->open_text_style (style, false, is_embedded_marker); - if (odf_text_text_only) odf_text_text_only->open_text_style (style, false, is_embedded_marker); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->open_text_style (style, false, is_embedded_marker); - if (html_text_standard) html_text_standard->open_text_style (style, false, is_embedded_marker); - if (html_text_linked) html_text_linked->open_text_style (style, false, is_embedded_marker); - } else { - if (odf_text_standard) odf_text_standard->close_text_style (false, is_embedded_marker); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, is_embedded_marker); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, is_embedded_marker); - if (html_text_standard) html_text_standard->close_text_style (false, is_embedded_marker); - if (html_text_linked) html_text_linked->close_text_style (false, is_embedded_marker); - } - break; - } - case StyleTypeChapterNumber: - { - if (odf_text_standard) odf_text_standard->close_text_style (false, false); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->close_text_style (false, false); - - if (onlinebible_text) onlinebible_text->storeData (); - - // Get the chapter number. - string usfm_c_fragment = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - int chapter_number = filter::strings::convert_to_int (usfm_c_fragment); - - // Update this object. - m_current_chapter_number = chapter_number; - set_to_zero(m_current_verse_number); - - // If there is a published chapter character, the chapter number takes that value. - for (const auto& published_chapter_marker : publishedChapterMarkers) { - if (published_chapter_marker.m_book == m_current_book_identifier) { - if (published_chapter_marker.m_chapter == m_current_chapter_number) { - usfm_c_fragment = published_chapter_marker.m_value; - chapter_number = filter::strings::convert_to_int (usfm_c_fragment); - } - } - } - - // Enter text for the running headers. - string running_header = database::books::get_english_from_id (static_cast(m_current_book_identifier)); - for (auto item : runningHeaders) { - if (item.m_book == m_current_book_identifier) { - running_header = item.m_value; - } - } - running_header += (" " + usfm_c_fragment); - if (odf_text_standard) odf_text_standard->new_heading1 (running_header, true); - if (odf_text_text_only) odf_text_text_only->new_heading1 (running_header, true); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->new_heading1 (running_header, true); - if (odf_text_notes) odf_text_notes->new_heading1 (running_header, false); - - // This is the phase of outputting the chapter number in the text body. - // It always outputs the chapter number to the clear text export. - if (text_text) { - text_text->paragraph (usfm_c_fragment); - } - // The chapter number is only output when there is more than one chapter in a book. - // if (m_number_of_chapters_per_book [m_current_book_identifier] > 1) - // This was disabled because of a bug where exporting to web did not output the chapter number - // for the first chapter. See https://github.com/bibledit/cloud/issues/905 for more info. - { - // Putting the chapter number at the first verse is determined by the style of the \c marker. - // But if a chapter label (\cl) is found in the current book, that disables the above. - const bool cl_found = book_has_chapter_label[m_current_book_identifier]; - if (style.userbool1 && !cl_found) { - // Output the chapter number at the first verse, not here. - // Store it for later processing. - m_output_chapter_text_at_first_verse = usfm_c_fragment; - } else { - // Output the chapter in a new paragraph. - // If the chapter label \cl is entered once before chapter 1 (\c 1) - // it represents the text for "chapter" to be used throughout the current book. - // If \cl is used after each individual chapter marker, it represents the particular text - // to be used for the display of the current chapter heading - // (usually done if numbers are being presented as words, not numerals). - string labelEntireBook {}; - string labelCurrentChapter {}; - for (auto pchapterLabel : chapterLabels) { - if (pchapterLabel.m_book == m_current_book_identifier) { - if (pchapterLabel.m_chapter == 0) { - labelEntireBook = pchapterLabel.m_value; - } - if (pchapterLabel.m_chapter == m_current_chapter_number) { - labelCurrentChapter = pchapterLabel.m_value; - } - } - } - if (!labelEntireBook.empty()) { - usfm_c_fragment = labelEntireBook + " " + usfm_c_fragment; - } - if (!labelCurrentChapter.empty()) { - usfm_c_fragment = labelCurrentChapter; - } - // The chapter number shows in a new paragraph. - // Keep it together with the next paragraph. - new_paragraph (style, true); - if (odf_text_standard) odf_text_standard->add_text (usfm_c_fragment); - if (odf_text_text_only) odf_text_text_only->add_text (usfm_c_fragment); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->add_text (usfm_c_fragment); - if (html_text_standard) html_text_standard->add_text (usfm_c_fragment); - if (html_text_linked) html_text_linked->add_text (usfm_c_fragment); - } - } - - // Output chapter number for other formats. - if (esword_text) esword_text->newChapter (m_current_chapter_number); - if (tbsx_text) tbsx_text->set_chapter(m_current_chapter_number); - - // Open a paragraph for the notes. - // It takes the style of the footnote content marker, usually 'ft'. - // This is done specifically for the version that has the notes only. - ensureNoteParagraphStyle (standard_content_marker_foot_end_note, styles[standard_content_marker_foot_end_note]); - if (odf_text_notes) odf_text_notes->new_paragraph (standard_content_marker_foot_end_note); - // UserBool2ChapterInLeftRunningHeader -> no headings implemented yet. - // UserBool3ChapterInRightRunningHeader -> no headings implemented yet. - - // Reset. - note_citations.restart("chapter"); - - // Done. - break; - } - case StyleTypeVerseNumber: - { - if (odf_text_standard) odf_text_standard->close_text_style (false, false); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->close_text_style (false, false); - if (onlinebible_text) onlinebible_text->storeData (); - // Handle a situation that a verse number starts a new paragraph. - if (style.userbool1) { - if (odf_text_standard) { - if (!odf_text_standard->m_current_paragraph_content.empty()) { - odf_text_standard->new_paragraph (odf_text_standard->m_current_paragraph_style); - } - } - if (odf_text_text_only) { - if (!odf_text_text_only->m_current_paragraph_content.empty()) { - odf_text_text_only->new_paragraph (odf_text_text_only->m_current_paragraph_style); - } - } - if (odf_text_text_and_note_citations) { - if (!odf_text_text_and_note_citations->m_current_paragraph_content.empty()) { - odf_text_text_and_note_citations->new_paragraph (odf_text_text_and_note_citations->m_current_paragraph_style); - } - } - if (html_text_standard) { - if (!html_text_standard->current_paragraph_content.empty()) { - html_text_standard->new_paragraph (html_text_standard->current_paragraph_style); - } - } - if (html_text_linked) { - if (!html_text_linked->current_paragraph_content.empty()) { - html_text_linked->new_paragraph (html_text_linked->current_paragraph_style); - } - } - if (text_text) { - text_text->paragraph (); - } - } - // Deal with the case of a pending chapter number. - if (!m_output_chapter_text_at_first_verse.empty()) { - if (!Database_Config_Bible::getExportChapterDropCapsFrames (m_bible)) { - int dropCapsLength = static_cast( filter::strings::unicode_string_length (m_output_chapter_text_at_first_verse)); - applyDropCapsToCurrentParagraph (dropCapsLength); - if (odf_text_standard) odf_text_standard->add_text (m_output_chapter_text_at_first_verse); - if (odf_text_text_only) odf_text_text_only->add_text (m_output_chapter_text_at_first_verse); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->add_text (m_output_chapter_text_at_first_verse); - } else { - putChapterNumberInFrame (m_output_chapter_text_at_first_verse); - } - Database_Styles_Item styleItem = Database_Styles_Item (); - styleItem.marker = "dropcaps"; - if (html_text_standard) html_text_standard->open_text_style (styleItem, false, false); - if (html_text_standard) html_text_standard->add_text (m_output_chapter_text_at_first_verse); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->open_text_style (styleItem, false, false); - if (html_text_linked) html_text_linked->add_text (m_output_chapter_text_at_first_verse); - if (html_text_linked) html_text_linked->close_text_style (false, false); - } - // Temporarily retrieve the text that follows the \v verse marker. - string text_following_v_marker = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - // Extract the verse number, and store it in the object. - string v_number = filter::usfm::peek_verse_number (text_following_v_marker); - m_current_verse_number = v_number; - // In case there was a published verse marker, use that markup for publishing. - string v_vp_number = v_number; - for (auto publishedVerseMarker : publishedVerseMarkers) { - if (publishedVerseMarker.m_book == m_current_book_identifier) { - if (publishedVerseMarker.m_chapter == m_current_chapter_number) { - if (publishedVerseMarker.m_verse == m_current_verse_number) { - v_vp_number = publishedVerseMarker.m_value; - } - } - } - } - // Output the verse number. But only if no chapter number was put here. - if (m_output_chapter_text_at_first_verse.empty ()) { - // If the current paragraph has text already, then insert a space. - if (odf_text_standard) { - if (!odf_text_standard->m_current_paragraph_content.empty()) { - odf_text_standard->add_text (" "); - } - } - if (odf_text_text_only) { - if (!odf_text_text_only->m_current_paragraph_content.empty()) { - odf_text_text_only->add_text (" "); - } - } - if (odf_text_text_and_note_citations) { - if (!odf_text_text_and_note_citations->m_current_paragraph_content.empty()) { - odf_text_text_and_note_citations->add_text (" "); - } - } - if (html_text_standard) { - if (!html_text_standard->current_paragraph_content.empty()) { - html_text_standard->add_text (" "); - } - } - if (html_text_linked) { - if (!html_text_linked->current_paragraph_content.empty()) { - html_text_linked->add_text (" "); - } - } - if (odf_text_standard) odf_text_standard->open_text_style (style, false, false); - if (odf_text_text_only) odf_text_text_only->open_text_style (style, false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->open_text_style (style, false, false); - if (html_text_standard) html_text_standard->open_text_style (style, false, false); - if (html_text_linked) html_text_linked->open_text_style (style, false, false); - if (odf_text_standard) odf_text_standard->add_text (v_vp_number); - if (odf_text_text_only) odf_text_text_only->add_text (v_vp_number); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->add_text (v_vp_number); - if (html_text_standard) html_text_standard->add_text (v_vp_number); - if (html_text_linked) html_text_linked->add_text (v_vp_number); - if (odf_text_standard) odf_text_standard->close_text_style (false, false); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->close_text_style (false, false); - } - // Plain text output. - if (text_text) { - if (!text_text->line ().empty()) { - text_text->addtext (" "); - } - text_text->addtext (v_vp_number); - // Plain text output always has a space following the verse. - // Important for outputting the first verse. - text_text->addtext (" "); - } - // If there was any text following the \v marker, remove the verse number, - // put the remainder back into the object, and update the pointer. - if (!text_following_v_marker.empty()) { - size_t pos = text_following_v_marker.find (v_number); - if (pos != std::string::npos) { - text_following_v_marker = text_following_v_marker.substr (pos + v_number.length ()); - } - // If a verse number was put, do this: - // Remove any whitespace from the start of the following text. - text_following_v_marker = filter::strings::ltrim (text_following_v_marker); - chapter_usfm_markers_and_text [chapter_usfm_markers_and_text_pointer] = text_following_v_marker; - chapter_usfm_markers_and_text_pointer--; - // If a verse number was put, do this too: - // Output the type of space that the user has set. - // This could be a fixed-width space, or a non-breaking space, - // or a combination of the two. - // This space type improves the appearance of the verse plus text. - // In case the verse numbers in poetry are to be left aligned, - // then output a tab to OpenDocument instead of the space. - // Exception: - // If a chapter number was put, do not output any white space. - if (m_output_chapter_text_at_first_verse.empty()) { - if (odf_text_standard) { - bool tab = odt_left_align_verse_in_poetry_styles && filter::usfm::is_standard_q_poetry (odf_text_standard->m_current_paragraph_style); - if (tab) odf_text_standard->add_tab(); - else odf_text_standard->add_text (space_type_after_verse); - } - if (odf_text_text_only) { - bool tab = odt_left_align_verse_in_poetry_styles && filter::usfm::is_standard_q_poetry (odf_text_text_only->m_current_paragraph_style); - if (tab) odf_text_text_only->add_tab(); - else odf_text_text_only->add_text (space_type_after_verse); - } - if (odf_text_text_and_note_citations) { - bool tab = odt_left_align_verse_in_poetry_styles && filter::usfm::is_standard_q_poetry (odf_text_text_and_note_citations->m_current_paragraph_style); - if (tab) odf_text_text_and_note_citations->add_tab(); - else odf_text_text_and_note_citations->add_text (space_type_after_verse); - } - if (html_text_standard) html_text_standard->add_text (space_type_after_verse); - if (html_text_linked) html_text_linked->add_text (space_type_after_verse); - } - } - // Unset the chapter variable, whether it was used or not. - // This makes it ready for subsequent use. - m_output_chapter_text_at_first_verse.clear(); - // Other export formats. - if (onlinebible_text) onlinebible_text->newVerse (m_current_book_identifier, m_current_chapter_number, filter::strings::convert_to_int (m_current_verse_number)); - if (esword_text) esword_text->newVerse (filter::strings::convert_to_int (m_current_verse_number)); - if (tbsx_text) { - tbsx_text->open_verse(filter::strings::convert_to_int (m_current_verse_number)); - tbsx_text->add_text(" "); - } - // Done. - break; - } - case StyleTypeFootEndNote: - { - processNote (); - break; - } - case StyleTypeCrossreference: - { - processNote (); - break; - } - case StyleTypePeripheral: - { - if (odf_text_standard) odf_text_standard->close_text_style (false, false); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->close_text_style (false, false); - switch (style.subtype) - { - case PeripheralSubtypePublication: - case PeripheralSubtypeTableOfContents: - case PeripheralSubtypePreface: - case PeripheralSubtypeIntroduction: - case PeripheralSubtypeGlossary: - case PeripheralSubtypeConcordance: - case PeripheralSubtypeIndex: - case PeripheralSubtypeMapIndex: - case PeripheralSubtypeCover: - case PeripheralSubtypeSpine: - { - addToFallout (R"(Unknown pheripheral marker \)" + marker, false); - break; - } - case PeripheralSubtypeGeneral: - { - addToInfo(R"(Pheripheral markup: \)" + marker, true); - // To start peripheral material o a new page. - // https://ubsicap.github.io/usfm/peripherals/index.html - if (odf_text_standard) odf_text_standard->new_page_break (); - if (odf_text_text_only) odf_text_text_only->new_page_break (); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->new_page_break (); - if (html_text_standard) html_text_standard->new_page_break (); - if (html_text_linked) html_text_linked->new_page_break (); - // Done. - break; - } - default: break; - } - break; - } - case StyleTypePicture: - { - if (is_opening_marker) { - // Set a flag that the parser is going to be within figure markup and save the style. - is_within_figure_markup = true; - figure_marker = marker; - // Create the style for the figure because it is used within the ODT generator. - create_paragraph_style (style, false); - // At the start of the \fig marker, close all text styles that might be open. - if (odf_text_standard) odf_text_standard->close_text_style (false, false); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->close_text_style (false, false); - } else { - // Closing the \fig* markup. - // Clear the flag since the parser is no longer within figure markup. - is_within_figure_markup = false; - } - break; - } - case StyleTypePageBreak: - { - if (odf_text_standard) odf_text_standard->close_text_style (false, false); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->close_text_style (false, false); - if (odf_text_standard) odf_text_standard->new_page_break (); - if (odf_text_text_only) odf_text_text_only->new_page_break (); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->new_page_break (); - if (html_text_standard) html_text_standard->new_page_break (); - if (html_text_linked) html_text_linked->new_page_break (); - if (text_text) text_text->paragraph (); - break; - } - case StyleTypeTableElement: - { - if (odf_text_standard) odf_text_standard->close_text_style (false, false); - if (odf_text_text_only) odf_text_text_only->close_text_style (false, false); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (false, false); - if (html_text_linked) html_text_linked->close_text_style (false, false); - switch (style.subtype) - { - case TableElementSubtypeRow: - { - addToFallout ("Table elements not implemented", false); - break; - } - case TableElementSubtypeHeading: - case TableElementSubtypeCell: - { - new_paragraph (style, false); - break; - } - default: - { - break; - } - } - // UserInt1TableColumnNumber: - break; - } - case StyleTypeWordlistElement: - { - switch (style.subtype) - { - case WorListElementSubtypeWordlistGlossaryDictionary: - { - if (is_opening_marker) { - addToWordList (wordListGlossaryDictionary); - } - break; - } - case WorListElementSubtypeHebrewWordlistEntry: - { - if (is_opening_marker) { - addToWordList (hebrewWordList); - } - break; - } - case WorListElementSubtypeGreekWordlistEntry: - { - if (is_opening_marker) { - addToWordList (greekWordList); - } - break; - } - case WorListElementSubtypeSubjectIndexEntry: - { - if (is_opening_marker) { - addToWordList (subjectIndex); - } - break; - } - default: - { - if (is_opening_marker) { - addToFallout (R"(Unknown word list marker \)" + marker, false); - } - break; - } - } - // UserString1WordListEntryAddition: - break; - } - default: - { - // This marker is not yet implemented. - // Add it to the fallout, plus any text that follows the marker. - addToFallout (R"(Marker not yet implemented \)" + marker + ", possible formatting error:", true); - break; - } - } - } else { - // Here is an unknown marker. - // Add it to the fallout, plus any text that follows the marker. - addToFallout (R"(Unknown marker \)" + marker + ", formatting error:", true); - } - } else { - // Here is no marker, just text. - - // Treat this content as figure directions. - if (is_within_figure_markup) { - // Extract the bits for this image / picture / figure. - string caption, alt, src, size, loc, copy, ref; - filter::usfm::extract_fig (current_item, caption, alt, src, size, loc, copy, ref); - // Store the name of this image in the object, ready to be copied into place if needed. - image_sources.push_back(src); - // Add the image to the various output formats. - if (odf_text_standard) odf_text_standard->add_image(figure_marker, alt, src, caption); - if (odf_text_text_only) odf_text_text_only->add_image(figure_marker, alt, src, caption); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->add_image(figure_marker, alt, src, caption); - if (html_text_standard) html_text_standard->add_image(figure_marker, alt, src, caption); - if (html_text_linked) html_text_linked->add_image(figure_marker, alt, src, caption); - } - - // Treat this content as text. - else { - // Handle situation that verses in poetry are to be left aligned. - // In such a case, if the OpenDocument paragraph is still empty, - // output a tab before any text. - if (odf_text_standard) - if (odt_left_align_verse_in_poetry_styles) - if (filter::usfm::is_standard_q_poetry (odf_text_standard->m_current_paragraph_style)) - if (odf_text_standard->m_current_paragraph_content.empty()) - odf_text_standard->add_tab(); - if (odf_text_text_only) - if (odt_left_align_verse_in_poetry_styles) - if (filter::usfm::is_standard_q_poetry (odf_text_text_only->m_current_paragraph_style)) - if (odf_text_text_only->m_current_paragraph_content.empty()) - odf_text_text_only->add_tab(); - if (odf_text_text_and_note_citations) - if (odt_left_align_verse_in_poetry_styles) - if (filter::usfm::is_standard_q_poetry (odf_text_text_and_note_citations->m_current_paragraph_style)) - if (odf_text_text_and_note_citations->m_current_paragraph_content.empty()) - odf_text_text_and_note_citations->add_tab(); - // Output text as normal. - if (odf_text_standard) odf_text_standard->add_text (current_item); - if (odf_text_text_only) odf_text_text_only->add_text (current_item); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->add_text (current_item); - if (html_text_standard) html_text_standard->add_text (current_item); - if (html_text_linked) html_text_linked->add_text (current_item); - if (onlinebible_text) onlinebible_text->add_text (current_item); - if (esword_text) esword_text->add_text (current_item); - if (text_text) text_text->addtext (current_item); - if (tbsx_text) tbsx_text->add_text(current_item); - if (headings_text_per_verse_active && heading_started) { - int iverse = filter::strings::convert_to_int (m_current_verse_number); - verses_headings [iverse].append (current_item); - } - if (headings_text_per_verse_active && text_started) { - int iverse = filter::strings::convert_to_int (m_current_verse_number); - if (m_verses_text.count (iverse) && !m_verses_text [iverse].empty ()) { - m_verses_text [iverse].append (current_item); - actual_verses_paragraph [iverse].append (current_item); - } else { - // The verse text straight after the \v starts with certain space type. - // Replace it with a normal space. - string item = filter::strings::replace (space_type_after_verse, " ", current_item); - m_verses_text [iverse] = filter::strings::ltrim (item); - actual_verses_paragraph [iverse] = filter::strings::ltrim (item); - } - } - if (note_open_now) { - notes_plain_text_buffer.append (current_item); - } - } - } - } - } -} - - - -// This function does the processing of the USFM code for one note, -// formatting the document and extracting information. -void Filter_Text::processNote () -{ - for ( ; chapter_usfm_markers_and_text_pointer < chapter_usfm_markers_and_text.size(); chapter_usfm_markers_and_text_pointer++) - { - string currentItem = chapter_usfm_markers_and_text[chapter_usfm_markers_and_text_pointer]; - if (filter::usfm::is_usfm_marker (currentItem)) - { - // Flags about the nature of the marker. - bool is_opening_marker = filter::usfm::is_opening_marker (currentItem); - bool isEmbeddedMarker = filter::usfm::is_embedded_marker (currentItem); - // Clean up the marker, so we remain with the basic version, e.g. 'f'. - string marker = filter::usfm::get_marker (currentItem); - if (styles.find (marker) != styles.end()) - { - Database_Styles_Item style = styles[marker]; - switch (style.type) - { - case StyleTypeVerseNumber: - { - // Verse found. The note should have stopped here. Incorrect note markup. - addToFallout ("The note did not close at the end of the verse. The text is not correct.", false); - goto noteDone; - } - case StyleTypeFootEndNote: - { - switch (style.subtype) - { - case FootEndNoteSubtypeFootnote: - { - if (is_opening_marker) { - ensureNoteParagraphStyle (marker, styles [standard_content_marker_foot_end_note]); - string citation = getNoteCitation (style); - if (odf_text_standard) odf_text_standard->add_note (citation, marker); - // Note citation in superscript in the document with text and note citations. - if (odf_text_text_and_note_citations) { - vector current_text_styles = odf_text_text_and_note_citations->m_current_text_style; - odf_text_text_and_note_citations->m_current_text_style = {"superscript"}; - odf_text_text_and_note_citations->add_text (citation); - odf_text_text_and_note_citations->m_current_text_style = current_text_styles; - } - // Add space if the paragraph has text already. - if (odf_text_notes) { - if (odf_text_notes->m_current_paragraph_content != "") { - odf_text_notes->add_text (" "); - } - } - // Add the note citation. And a no-break space after it. - if (odf_text_notes) odf_text_notes->add_text (citation + filter::strings::non_breaking_space_u00A0()); - // Open note in the web pages. - if (html_text_standard) html_text_standard->add_note (citation, standard_content_marker_foot_end_note); - if (html_text_linked) html_text_linked->add_note (citation, standard_content_marker_foot_end_note); - // Online Bible. Footnotes do not seem to behave as they ought in the Online Bible compiler. Just leave them out. - //if ($this->onlinebible_text) $this->onlinebible_text->addNote (); - if (text_text) text_text->note (); - // Handle opening notes in plain text. - notes_plain_text_handler (); - // Set flag. - note_open_now = true; - } else { - goto noteDone; - } - break; - } - case FootEndNoteSubtypeEndnote: - { - if (is_opening_marker) { - ensureNoteParagraphStyle (marker, styles[standard_content_marker_foot_end_note]); - string citation = getNoteCitation (style); - if (odf_text_standard) odf_text_standard->add_note (citation, marker, true); - // Note citation in superscript in the document with text and note citations. - if (odf_text_text_and_note_citations) { - vector current_text_styles = odf_text_text_and_note_citations->m_current_text_style; - odf_text_text_and_note_citations->m_current_text_style = {"superscript"}; - odf_text_text_and_note_citations->add_text (citation); - odf_text_text_and_note_citations->m_current_text_style = current_text_styles; - } - // Open note in the web page. - if (html_text_standard) html_text_standard->add_note (citation, standard_content_marker_foot_end_note, true); - if (html_text_linked) html_text_linked->add_note (citation, standard_content_marker_foot_end_note, true); - // Online Bible: Leave note out. - //if ($this->onlinebible_text) $this->onlinebible_text->addNote (); - if (text_text) text_text->note (); - // Handle opening notes in plain text. - notes_plain_text_handler (); - // Set flag. - note_open_now = true; - } else { - goto noteDone; - } - break; - } - case FootEndNoteSubtypeStandardContent: - { - // The style of the standard content is already used in the note's body. - // If means that the text style should be cleared - // in order to return to the correct style for the paragraph. - if (odf_text_standard) odf_text_standard->close_text_style (true, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (true, false); - if (html_text_linked) html_text_linked->close_text_style (true, false); - break; - } - case FootEndNoteSubtypeContent: - case FootEndNoteSubtypeContentWithEndmarker: - { - if (is_opening_marker) { - if (odf_text_standard) odf_text_standard->open_text_style (style, true, isEmbeddedMarker); - if (odf_text_notes) odf_text_notes->open_text_style (style, false, isEmbeddedMarker); - if (html_text_standard) html_text_standard->open_text_style (style, true, isEmbeddedMarker); - if (html_text_linked) html_text_linked->open_text_style (style, true, isEmbeddedMarker); - } else { - if (odf_text_standard) odf_text_standard->close_text_style (true, isEmbeddedMarker); - if (odf_text_notes) odf_text_notes->close_text_style (false, isEmbeddedMarker); - if (html_text_standard) html_text_standard->close_text_style (true, isEmbeddedMarker); - if (html_text_linked) html_text_linked->close_text_style (true, isEmbeddedMarker); - } - break; - } - case FootEndNoteSubtypeParagraph: - { - // The style of this is not yet implemented. - if (odf_text_standard) odf_text_standard->close_text_style (true, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (true, false); - if (html_text_linked) html_text_linked->close_text_style (true, false); - if (text_text) text_text->note (); - break; - } - default: - { - break; - } - } - // UserBool1NoteAppliesToApocrypha: For xref too? - break; - } - case StyleTypeCrossreference: - { - switch (style.subtype) - { - case CrossreferenceSubtypeCrossreference: - { - if (is_opening_marker) { - ensureNoteParagraphStyle (marker, styles[standard_content_marker_cross_reference]); - string citation = getNoteCitation (style); - if (odf_text_standard) odf_text_standard->add_note (citation, marker); - // Note citation in superscript in the document with text and note citations. - if (odf_text_text_and_note_citations) { - vector current_text_styles = odf_text_text_and_note_citations->m_current_text_style; - odf_text_text_and_note_citations->m_current_text_style = {"superscript"}; - odf_text_text_and_note_citations->add_text (citation); - odf_text_text_and_note_citations->m_current_text_style = current_text_styles; - } - // Add a space if the paragraph has text already. - if (odf_text_notes) { - if (odf_text_notes->m_current_paragraph_content != "") { - odf_text_notes->add_text (" "); - } - } - // Add the note citation. And a no-break space (NBSP) after it. - if (odf_text_notes) odf_text_notes->add_text (citation + filter::strings::non_breaking_space_u00A0()); - // Open note in the web page. - ensureNoteParagraphStyle (standard_content_marker_cross_reference, styles[standard_content_marker_cross_reference]); - if (html_text_standard) html_text_standard->add_note (citation, standard_content_marker_cross_reference); - if (html_text_linked) html_text_linked->add_note (citation, standard_content_marker_cross_reference); - // Online Bible: Skip notes. - //if ($this->onlinebible_text) $this->onlinebible_text->addNote (); - if (text_text) text_text->note (); - // Handle opening notes in plain text. - notes_plain_text_handler (); - // Set flag. - note_open_now = true; - } else { - goto noteDone; - } - break; - } - case CrossreferenceSubtypeStandardContent: - { - // The style of the standard content is already used in the note's body. - // If means that the text style should be cleared - // in order to return to the correct style for the paragraph. - if (odf_text_standard) odf_text_standard->close_text_style (true, false); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_text_style (true, false); - if (html_text_linked) html_text_linked->close_text_style (true, false); - break; - } - case CrossreferenceSubtypeContent: - case CrossreferenceSubtypeContentWithEndmarker: - { - if (is_opening_marker) { - if (odf_text_standard) odf_text_standard->open_text_style (style, true, isEmbeddedMarker); - if (odf_text_notes) odf_text_notes->open_text_style (style, false, isEmbeddedMarker); - if (html_text_standard) html_text_standard->open_text_style (style, true, isEmbeddedMarker); - if (html_text_linked) html_text_linked->open_text_style (style, true, isEmbeddedMarker); - } else { - if (odf_text_standard) odf_text_standard->close_text_style (true, isEmbeddedMarker); - if (odf_text_notes) odf_text_notes->close_text_style (false, isEmbeddedMarker); - if (html_text_standard) html_text_standard->close_text_style (true, isEmbeddedMarker); - if (html_text_linked) html_text_linked->close_text_style (true, isEmbeddedMarker); - } - break; - } - default: - { - break; - } - } - break; - } - default: - { - addToFallout (R"(Marker not suitable in note context \)" + marker, false); - break; - } - } - } else { - // Here is an unknown marker. Add the marker to fallout, plus any text that follows. - addToFallout (R"(Unknown marker \)" + marker, true); - } - } else { - // Here is no marker. Treat it as text. - if (odf_text_standard) odf_text_standard->add_note_text (currentItem); - if (odf_text_notes) odf_text_notes->add_text (currentItem); - if (html_text_standard) html_text_standard->add_note_text (currentItem); - if (html_text_linked) html_text_linked->add_note_text (currentItem); - if (text_text) text_text->addnotetext (currentItem); - if (note_open_now) { - notes_plain_text_buffer.append (currentItem); - } - } - } - - noteDone: - - // "Close" the current note, so that any following note text, if malformed, - // will be added to a new note, not to the last one created. - if (odf_text_standard) odf_text_standard->close_current_note (); - if (odf_text_notes) odf_text_notes->close_text_style (false, false); - if (html_text_standard) html_text_standard->close_current_note (); - if (html_text_linked) html_text_linked->close_current_note (); - //if ($this->onlinebible_text) $this->onlinebible_text->close_current_note (); - if (!notes_plain_text_buffer.empty ()) { - notes_plain_text.push_back (pair (m_current_verse_number, notes_plain_text_buffer)); - } - note_open_now = false; - notes_plain_text_buffer.clear (); -} - - - -// This creates and saves the information document. -// It contains formatting information, collected from the USFM code. -// $path: Path to the document. -void Filter_Text::produceInfoDocument (string path) -{ - HtmlText information (translate("Information")); - - // Number of chapters per book. - information.new_heading1 (translate("Number of chapters per book")); - for (const auto& element : m_number_of_chapters_per_book) { - const string line = database::books::get_english_from_id (static_cast(element.first)) + " => " + filter::strings::convert_to_string (element.second); - information.new_paragraph (); - information.add_text (line); - } - - // Running headers. - information.new_heading1 (translate("Running headers")); - for (auto item : runningHeaders) { - const string line = database::books::get_english_from_id (static_cast(item.m_book)) + " (USFM " + item.m_marker + ") => " + item.m_value; - information.new_paragraph (); - information.add_text (line); - } - - // Table of Contents entries. - information.new_heading1 (translate("Long table of contents entries")); - for (auto item : longTOCs) { - const string line = database::books::get_english_from_id (static_cast(item.m_book)) + " (USFM " + item.m_marker + ") => " + item.m_value; - information.new_paragraph (); - information.add_text (line); - } - information.new_heading1 (translate("Short table of contents entries")); - for (auto item : shortTOCs) { - const string line = database::books::get_english_from_id (static_cast(item.m_book)) + " (USFM " + item.m_marker + ") => " + item.m_value; - information.new_paragraph (); - information.add_text (line); - } - - // Book abbreviations. - information.new_heading1 (translate("Book abbreviations")); - for (auto item : bookAbbreviations) { - const string line = database::books::get_english_from_id (static_cast(item.m_book)) + " (USFM " + item.m_marker + ") => " + item.m_value; - information.new_paragraph (); - information.add_text (line); - } - - // Chapter specials. - information.new_heading1 (translate("Publishing chapter labels")); - for (auto item : chapterLabels) { - const string line = database::books::get_english_from_id (static_cast(item.m_book)) + " (USFM " + item.m_marker + ") => " + item.m_value; - information.new_paragraph (); - information.add_text (line); - } - information.new_heading1 (translate("Publishing alternate chapter numbers")); - for (auto item : publishedChapterMarkers) { - const string line = database::books::get_english_from_id (static_cast(item.m_book)) + " (USFM " + item.m_marker + ") => " + item.m_value; - information.new_paragraph (); - information.add_text (line); - } - - // Word lists. - information.new_heading1 (translate("Word list, glossary, dictionary entries")); - for (const auto& item : wordListGlossaryDictionary) { - information.new_paragraph (); - information.add_text (item); - } - information.new_heading1 (translate("Hebrew word list entries")); - for (const auto& item : hebrewWordList) { - information.new_paragraph (); - information.add_text (item); - } - information.new_heading1 (translate("Greek word list entries")); - for (const auto& item : greekWordList) { - information.new_paragraph (); - information.add_text (item); - } - information.new_heading1 (translate("Subject index entries")); - for (const auto& item : subjectIndex) { - information.new_paragraph (); - information.add_text (item); - } - - // Other info. - information.new_heading1 (translate("Other information")); - for (const auto& item : info) { - information.new_paragraph (); - information.add_text (item); - } - - information.save (path); -} - - - -// This function produces the text of the current passage, e.g.: Genesis 1:1. -// Returns: The passage text -string Filter_Text::getCurrentPassageText () -{ - return filter_passage_display (m_current_book_identifier, m_current_chapter_number, m_current_verse_number); -} - - - -// This function adds a string to the Info array, prefixed by the current passage. -// $text: String to add to the Info array. -// $next: If true, it also adds the text following the marker to the info, -// and removes this text from the USFM input stream. -void Filter_Text::addToInfo (string text, bool next) -{ - text = getCurrentPassageText() + " " + text; - if (next) { - text.append (" " + filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer)); - } - info.push_back (text); -} - - - -// This function adds a string to the Fallout array, prefixed by the current passage. -// $text: String to add to the Fallout array. -// $next: If true, it also adds the text following the marker to the fallout, -// and removes this text from the USFM input stream. -void Filter_Text::addToFallout (string text, bool next) -{ - text = getCurrentPassageText () + " " + text; - if (next) { - text.append (" " + filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer)); - } - fallout.push_back (text); -} - - - -// This function adds something to a word list array, prefixed by the current passage. -// $list: which list to add the text to. -// The word is extracted from the input USFM. The Usfm pointer points to the current marker, -// and the text following that marker is added to the word list array. -void Filter_Text::addToWordList (vector & list) -{ - string text = filter::usfm::peek_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer); - text.append (" ("); - text.append (getCurrentPassageText ()); - text.append (")"); - list.push_back (text); -} - - - -// This produces and saves the Fallout document. -// $path: Path to the document. -void Filter_Text::produceFalloutDocument (string path) -{ - HtmlText html_text (translate("Fallout")); - html_text.new_heading1 (translate("Fallout")); - for (string line : fallout) { - html_text.new_paragraph (); - html_text.add_text (line); - } - html_text.save (path); -} - - -// This function ensures that a certain paragraph style is in the OpenDocument. -// $style: The style to use. -// $keepWithNext: Whether to keep this paragraph with the next one. -void Filter_Text::create_paragraph_style (const Database_Styles_Item & style, bool keepWithNext) -{ - string marker = style.marker; - if (find (createdStyles.begin(), createdStyles.end(), marker) == createdStyles.end()) { - string fontname = Database_Config_Bible::getExportFont (m_bible); - float fontsize = style.fontsize; - int italic = style.italic; - int bold = style.bold; - int underline = style.underline; - int smallcaps = style.smallcaps; - int alignment = style.justification; - float spacebefore = style.spacebefore; - float spaceafter = style.spaceafter; - float leftmargin = style.leftmargin; - float rightmargin = style.rightmargin; - float firstlineindent = style.firstlineindent; - // Columns are not implemented at present. Reason: - // Copying and pasting sections with columns between documents in LibreOffice failed to work. - // int spancolumns = style.spancolumns; - int dropcaps = 0; - if (odf_text_standard) odf_text_standard->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps); - if (odf_text_text_only) odf_text_text_only->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps); - createdStyles.push_back (marker); - } -} - - -// This function ensures that a certain paragraph style is in the OpenDocument, -// and then opens a paragraph with that style. -// $style: The style to use. -// $keepWithNext: Whether to keep this paragraph with the next one. -void Filter_Text::new_paragraph (const Database_Styles_Item & style, bool keepWithNext) -{ - create_paragraph_style(style, keepWithNext); - string marker = style.marker; - if (odf_text_standard) odf_text_standard->new_paragraph (marker); - if (odf_text_text_only) odf_text_text_only->new_paragraph (marker); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->new_paragraph (marker); - if (html_text_standard) html_text_standard->new_paragraph (marker); - if (html_text_linked) html_text_linked->new_paragraph (marker); - if (text_text) text_text->paragraph (); -} - - - -// This applies the drop caps setting to the current paragraph style. -// This is for the chapter number to appear in drop caps in the OpenDocument. -// $dropCapsLength: Number of characters to put in drop caps. -void Filter_Text::applyDropCapsToCurrentParagraph (int dropCapsLength) -{ - // To name a style according to the number of characters to put in drop caps, - // e.g. a style name like p_c1 or p_c2 or p_c3. - if (odf_text_standard) { - string combined_style = odf_text_standard->m_current_paragraph_style + "_" + chapterMarker + filter::strings::convert_to_string (dropCapsLength); - if (find (createdStyles.begin(), createdStyles.end(), combined_style) == createdStyles.end()) { - Database_Styles_Item style = styles[odf_text_standard->m_current_paragraph_style]; - string fontname = Database_Config_Bible::getExportFont (m_bible); - float fontsize = style.fontsize; - int italic = style.italic; - int bold = style.bold; - int underline = style.underline; - int smallcaps = style.smallcaps; - int alignment = style.justification; - float spacebefore = style.spacebefore; - float spaceafter = style.spaceafter; - float leftmargin = style.leftmargin; - float rightmargin = style.rightmargin; - float firstlineindent = 0; // First line that contains the chapter number in drop caps is not indented. - //int spancolumns = style.spancolumns; - bool keepWithNext = false; - if (odf_text_standard) odf_text_standard->create_paragraph_style (combined_style, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropCapsLength); - if (odf_text_text_only) odf_text_text_only->create_paragraph_style (combined_style, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropCapsLength); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->create_paragraph_style (combined_style, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropCapsLength); - createdStyles.push_back (combined_style); - } - if (odf_text_standard) odf_text_standard->update_current_paragraph_style (combined_style); - if (odf_text_text_only) odf_text_text_only->update_current_paragraph_style (combined_style); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->update_current_paragraph_style (combined_style); - } -} - - - -// This puts the chapter number in a frame in the current paragraph. -// This is to put the chapter number in a frame so it looks like drop caps in the OpenDocument. -// $chapterText: The text of the chapter indicator to put. -void Filter_Text::putChapterNumberInFrame (string chapterText) -{ - Database_Styles_Item style = styles[chapterMarker]; - if (odf_text_standard) odf_text_standard->place_text_in_frame (chapterText, this->chapterMarker, style.fontsize, style.italic, style.bold); - if (odf_text_text_only) odf_text_text_only->place_text_in_frame (chapterText, this->chapterMarker, style.fontsize, style.italic, style.bold); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->place_text_in_frame (chapterText, this->chapterMarker, style.fontsize, style.italic, style.bold); -} - - - -// This gets the note citation. -// The first time that a xref is encountered, this function would return, e.g. 'a'. -// The second time, it would return 'b'. Then 'c', 'd', 'e', and so on, up to 'z'. -// Then it would restart with 'a'. And so on. -// The note citation is the character that is put in superscript in the main body of Bible text. -// $style: array with values for the note opening marker. -// Returns: The character for the note citation. -string Filter_Text::getNoteCitation (const Database_Styles_Item & style) -{ - bool end_of_text_reached = (chapter_usfm_markers_and_text_pointer + 1) >= chapter_usfm_markers_and_text.size (); - if (end_of_text_reached) return string(); - - // Extract the raw note citation from the USFM. This could be, e.g. '+'. - string nextText = chapter_usfm_markers_and_text [chapter_usfm_markers_and_text_pointer + 1]; - string citation = nextText.substr (0, 1); - nextText = filter::strings::ltrim (nextText.substr (1)); - chapter_usfm_markers_and_text [chapter_usfm_markers_and_text_pointer + 1] = nextText; - citation = filter::strings::trim (citation); - - // Get the rendered note citation. - citation = note_citations.get(style.marker, citation); - return citation; -} - - - -// This function ensures that a certain paragraph style for a note is present in the OpenDocument. -// $marker: Which note, e.g. 'f' or 'x' or 'fe'. -// $style: The style to use. -void Filter_Text::ensureNoteParagraphStyle (string marker, const Database_Styles_Item & style) -{ - if (find (createdStyles.begin(), createdStyles.end(), marker) == createdStyles.end()) { - string fontname = Database_Config_Bible::getExportFont (m_bible); - float fontsize = style.fontsize; - int italic = style.italic; - int bold = style.bold; - int underline = style.underline; - int smallcaps = style.smallcaps; - int alignment = style.justification; - float spacebefore = style.spacebefore; - float spaceafter = style.spaceafter; - float leftmargin = style.leftmargin; - float rightmargin = style.rightmargin; - float firstlineindent = style.firstlineindent; - //bool spancolumns = false; - bool keepWithNext = false; - int dropcaps = 0; - if (odf_text_standard) odf_text_standard->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps); - if (odf_text_text_only) odf_text_text_only->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps); - if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps); - if (odf_text_notes) odf_text_notes->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, 0, 0, 0, 0, 0, keepWithNext, dropcaps); - createdStyles.push_back (marker); - } -} - - -// This function initializes the array that holds verse numbers and the text of the headings, -// and the array that holds verse numbers and the plain text of the Bible. -// The object will only use the array when it has been initialized. -// The resulting arrays use the verse numbers as keys. Therefore it only works reliably within one chapter. -void Filter_Text::initializeHeadingsAndTextPerVerse (bool start_text_now) -{ - headings_text_per_verse_active = true; - // Normally collecting the plain text starts only after the first normal paragraph marker. - // But this can be force to start immediately - if (start_text_now) text_started = true; -} - - -map Filter_Text::getVersesText () -{ - // Trim white space at start and end of each line. - for (auto& element : m_verses_text) { - element.second = filter::strings::trim (element.second); - } - // Return the result. - return m_verses_text; -} - - -void Filter_Text::store_verses_paragraphs () -{ - if (!actual_verses_paragraph.empty ()) { - verses_paragraphs.push_back (actual_verses_paragraph); - actual_verses_paragraph.clear (); - } -} - - -void Filter_Text::notes_plain_text_handler () -{ - int offset {0}; - const int iverse = filter::strings::convert_to_int (m_current_verse_number); - if (m_verses_text.count (iverse)) { - offset = static_cast(m_verses_text [iverse].size ()); - } - verses_text_note_positions[iverse].push_back (offset); -} - - -void Filter_Text::set_to_zero (string& value) -{ - value = "0"; -} diff --git a/filter/text.h b/filter/text.h deleted file mode 100644 index bf7d62344..000000000 --- a/filter/text.h +++ /dev/null @@ -1,237 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace filter::text { - -class passage_marker_value -{ -public: - passage_marker_value (int book, int chapter, std::string verse, std::string marker, std::string value); - int m_book {0}; - int m_chapter {0}; - std::string m_verse {}; - std::string m_marker {}; - std::string m_value {}; -}; - -} - - -class Filter_Text -{ -public: - Filter_Text (std::string bible); - ~Filter_Text (); - Filter_Text(const Filter_Text&) = delete; - Filter_Text operator=(const Filter_Text&) = delete; - -private: - std::string m_bible {}; - -public: - void add_usfm_code (std::string usfm); -private: - // Container holding USFM, alternating between markup and text. - std::vector m_usfm_markers_and_text {}; - unsigned int usfm_markers_and_text_ptr {0}; - bool unprocessed_usfm_code_available (); - void get_usfm_next_chapter (); - -public: - void run (std::string stylesheet); -private: - // Container holding a chapter of USFM code, alternating between USFM and text. - std::vector chapter_usfm_markers_and_text {}; - unsigned int chapter_usfm_markers_and_text_pointer {0}; - -public: - void get_styles (std::string stylesheet); -private: - // A map of marker -> object with style information. - std::map styles {}; - // Usually this is: c - std::string chapterMarker {}; - // Array holding styles created in Odf_Text class. - std::vector createdStyles {}; - -public: - void pre_process_usfm (); -private: - // Book identifier, e.g. 1, 2, 3, and so on. - int m_current_book_identifier {0}; - // Chapter number, e.g. 1, 2, 3, etc. - int m_current_chapter_number {0}; - // Verse number, e.g. "0", "1", "2", and so on. - std::string m_current_verse_number {}; - std::string getCurrentPassageText (); - // Map of (book, chapter number). - std::map m_number_of_chapters_per_book {}; - void process_usfm (); - void processNote (); - // Opening a new paragraph. - void create_paragraph_style (const Database_Styles_Item & style, bool keepWithNext); - void new_paragraph (const Database_Styles_Item & style, bool keepWithNext); - void applyDropCapsToCurrentParagraph (int dropCapsLength); - void putChapterNumberInFrame (std::string chapterText); - std::string getNoteCitation (const Database_Styles_Item & style); - void ensureNoteParagraphStyle (std::string marker, const Database_Styles_Item & style); - -public: - // Container with objects (book, chapter, verse, marker, header value). - std::vector runningHeaders {}; - // Container with objects (book, chapter, verse, marker, TOC value). - std::vector longTOCs {}; - // Container with objects (book, chapter, verse, marker, TOC value). - std::vector shortTOCs {}; - // Container with objects (book, chapter, verse, marker, abbreviation value). - std::vector bookAbbreviations {}; - -public: - // Vector with objects (book, chapter, verse, marker, label value). - std::vector chapterLabels {}; - // Vector with object (book, chapter, verse, marker, marker value). - std::vector publishedChapterMarkers {}; - // Vector with object (book, chapter, verse, marker, marker value). - std::vector publishedVerseMarkers {}; -private: - // std::string holding the chapter number or text to output at the first verse. - std::string m_output_chapter_text_at_first_verse {}; - -public: - // Object for creating OpenDocument with text in standard form. - odf_text * odf_text_standard {nullptr}; - // Object for creating OpenDocument with text only. - odf_text * odf_text_text_only {nullptr}; - // Object for creating OpenDocument with text and note citations. - odf_text * odf_text_text_and_note_citations {nullptr}; - // Object for creating OpenDocument with the notes only. - odf_text * odf_text_notes {nullptr}; - -public: - void produceInfoDocument (std::string path); - void produceFalloutDocument (std::string path); - std::vector info {}; - std::vector fallout {}; -private: - void addToInfo (std::string text, bool next = false); - void addToFallout (std::string text, bool next = false); - void addToWordList (std::vector & list); - std::vector wordListGlossaryDictionary {}; - std::vector hebrewWordList {}; - std::vector greekWordList {}; - std::vector subjectIndex {}; - -private: - // Information for the citations for the notes. - filter::note::citations note_citations {}; - - std::string standard_content_marker_foot_end_note {}; - std::string standard_content_marker_cross_reference {}; - -public: - // Object for creating standard web documents. - HtmlText * html_text_standard {nullptr}; - // Object for creating interlinked web documents. - HtmlText * html_text_linked {nullptr}; - -public: - // Object for creating the input file for the Online Bible compiler. - OnlineBible_Text * onlinebible_text {nullptr}; - -public: - // Object for creating the Bible module for eSword. - Esword_Text * esword_text {nullptr}; - -public: - // Object for exporting to plain text. - Text_Text * text_text { nullptr }; - -public: - // Object for exporting to TBS online bible format. - Tbsx_Text * tbsx_text { nullptr }; - -public: - void initializeHeadingsAndTextPerVerse (bool start_text_now); - std::map getVersesText (); - // Vector with objects to hold verse numbers and the text of the headings. - std::map verses_headings {}; - // Markers that started the above paragraph start positions. - std::vector paragraph_starting_markers {}; - // Complete paragraphs keyed to verse numbers. - std::vector > verses_paragraphs {}; -private: - // Flags for headings per verse processor. - bool headings_text_per_verse_active { false }; - bool heading_started { false }; - // Holds verse numbers and the plain text in that verse, without anything extra. - std::map m_verses_text {}; - // Flag for text per verse processor. - bool text_started {false}; - void store_verses_paragraphs (); - std::map actual_verses_paragraph {}; - -private: - std::string space_type_after_verse {}; // The type of space to follow a verse number. - std::map book_has_chapter_label {}; // Whether \cl was found in the book. - -public: - // The notes plain text. - std::vector > notes_plain_text {}; - // Holds the positions of the notes in the plain text, keyed to the verse numbers. - std::map > verses_text_note_positions {}; -private: - // Flag to keep track of open note. - bool note_open_now { false }; - // The joined fragments. - std::string notes_plain_text_buffer {}; - // Handler. - void notes_plain_text_handler (); - -public: - // The images that have been encountered to use. - std::vector image_sources {}; -private: - // Flag for whether the processor is now within figure markup. - bool is_within_figure_markup { false }; - std::string figure_marker {}; - -public: -private: - // Flag for whether to left-align certain poetry styles - // in exports to OpenDocument format. - bool odt_left_align_verse_in_poetry_styles { false }; - -public: -private: - void set_to_zero (std::string& value); -}; diff --git a/filter/url.cpp b/filter/url.cpp deleted file mode 100644 index d3670cb89..000000000 --- a/filter/url.cpp +++ /dev/null @@ -1,2173 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" -#include -#pragma GCC diagnostic pop -#include -#include -#include -#include -#ifdef HAVE_CLOUD -#include -#endif -#pragma GCC diagnostic push -#pragma clang diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wswitch-enum" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop -#ifdef HAVE_WINDOWS -#include -#include -#endif -using namespace std; - - -// Internal function declarations. -vector filter_url_scandir_internal (string folder); -string filter_url_dirname_internal (string url, const char * separator); -string filter_url_basename_internal (string url, const char * separator); -size_t filter_url_curl_write_function (void *ptr, size_t size, size_t count, void *stream); -void filter_url_curl_debug_dump (const char *text, FILE *stream, unsigned char *ptr, size_t size); -#ifdef HAVE_CLOUD -int filter_url_curl_trace (CURL *handle, curl_infotype type, char *data, size_t size, void *userp); -#endif - - -// SSL/TLS globals. -mbedtls_entropy_context filter_url_mbed_tls_entropy; -mbedtls_ctr_drbg_context filter_url_mbed_tls_ctr_drbg; -mbedtls_x509_crt filter_url_mbed_tls_cacert; - - -vector filter_url_scandir_internal (string folder) -{ - vector files; - -#ifdef HAVE_WINDOWS - - if (!folder.empty()) { - if (folder[folder.size() - 1] == '\\') { - folder = folder.substr(0, folder.size() - 1); - } - folder.append("\\*"); - wstring wfolder = filter::strings::string2wstring(folder); - WIN32_FIND_DATA fdata; - HANDLE hFind = FindFirstFileW(wfolder.c_str(), &fdata); - if (hFind != INVALID_HANDLE_VALUE) { - do { - wstring wfilename(fdata.cFileName); - string name = filter::strings::wstring2string (wfilename); - if (name.substr(0, 1) != ".") { - files.push_back(name); - } - } while (FindNextFileW(hFind, &fdata) != 0); - } - FindClose(hFind); - } - -#else - - DIR * dir = opendir (folder.c_str()); - if (dir) { - dirent * direntry; - while ((direntry = readdir (dir)) != nullptr) { - string name = direntry->d_name; - // Exclude short-hand directory names. - if (name == ".") continue; - if (name == "..") continue; - // Exclude developer temporal files. - if (name == ".deps") continue; - if (name == ".dirstamp") continue; - // Exclude macOS files. - if (name == ".DS_Store") continue; - // Store the name. - files.push_back (name); - } - closedir (dir); - } - sort (files.begin(), files.end()); - -#endif - - // Remove . and .. - files = filter::strings::array_diff (files, {".", ".."}); - - return files; -} - - -// Gets the base URL of current Bibledit installation. -string get_base_url (Webserver_Request& webserver_request) -{ - string scheme; - string port; - if (webserver_request.secure || config_globals_enforce_https_browser) { - scheme = "https"; - port = config::logic::https_network_port (); - } else { - scheme = "http"; - port = config::logic::http_network_port (); - } - string url = scheme + "://" + webserver_request.host + ":" + port + "/"; - return url; -} - - -// This function redirects the browser to "path". -// "path" is an absolute value. -void redirect_browser (Webserver_Request& webserver_request, string path) -{ - // A location header should contain an absolute url, like http://localhost/some/path. - // See 14.30 in the specification https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html. - - // The absolute location contains the user-facing URL, when the administrator entered it. - // This is needed in case of a proxy server, - // where Bibledit may not be able to obtain the user-facing URL of the website. - string location = config::logic::site_url (webserver_request); - - // If the request was secure, or supposed to be secure, - // ensure the location contains https rather than plain http, - // plus the correct secure port. - if (webserver_request.secure || config_globals_enforce_https_browser) { - location = filter::strings::replace ("http:", "https:", location); - string plainport = config::logic::http_network_port (); - string secureport = config::logic::https_network_port (); - location = filter::strings::replace (":" + plainport, ":" + secureport, location); - } - - location.append (path); - - // If the page contains the topbar suppressing query, - // the same query will be appended on the URL of the redirected page. - if (webserver_request.query.count ("topbar") || webserver_request.post.count ("topbar")) { - string new_location = filter_url_build_http_query (location, "topbar", "0"); - location.clear (); - location.append (new_location); - } - - webserver_request.header = "Location: " + location; - webserver_request.response_code = 302; -} - - -// C++ replacement for the dirname function, see http://linux.die.net/man/3/dirname. -// The BSD dirname is not thread-safe, see the implementation notes on $ man 3 dirname. -string filter_url_dirname_internal (string url, const char * separator) -{ - if (!url.empty ()) { - if (url.find_last_of (separator) == url.length () - 1) { - // Remove trailing slash. - url = url.substr (0, url.length () - 1); - } - size_t pos = url.find_last_of (separator); - if (pos != std::string::npos) url = url.substr (0, pos); - else url = string(); - } - if (url.empty ()) url = "."; - return url; -} - - -// Dirname routine for the operating system. -// It uses the defined slash as the separator. -string filter_url_dirname (string url) -{ - return filter_url_dirname_internal (url, DIRECTORY_SEPARATOR); -} - - -// Dirname routine for the filesystem. -// It uses the automatically defined separator as the directory separator. -// As of February 2022 the std::filesystem does not yet work on Android. -//string filter_url_dirname (string url) -//{ -// // Remove possible trailing path slash. -// if (!url.empty ()) { -// const char separator = filesystem::path::preferred_separator; -// if (url.find_last_of (separator) == url.length () - 1) { -// url = url.substr (0, url.length () - 1); -// } -// } -// // Standard library call for getting parent path. -// url = filesystem::path(url).parent_path().string(); -// // The . is important in a few cases rather than an empty string. -// if (url.empty ()) url = "."; -// // Done. -// return url; -//} - - -// Dirname routine for the web. -// It uses the forward slash as the separator. -string filter_url_dirname_web (string url) -{ - const char * separator = "/"; - if (!url.empty ()) { - // Remove trailing slash. - if (url.find_last_of (separator) == url.length () - 1) { - url = url.substr (0, url.length () - 1); - } - // Get dirname or empty string. - size_t pos = url.find_last_of (separator); - if (pos != std::string::npos) url = url.substr (0, pos); - else url.clear(); - } - // Done. - return url; -} - - -// C++ replacement for the basename function, see http://linux.die.net/man/3/basename. -// The BSD basename is not thread-safe, see the warnings in $ man 3 basename. -string filter_url_basename_internal (string url, const char * separator) -{ - if (!url.empty ()) { - if (url.find_last_of (separator) == url.length () - 1) { - // Remove trailing slash. - url = url.substr (0, url.length () - 1); - } - size_t pos = url.find_last_of (separator); - if (pos != std::string::npos) url = url.substr (pos + 1); - } - return url; -} - - -// Basename routine for the operating system. -// It uses the defined slash as the separator. -string filter_url_basename (string url) -{ - return filter_url_basename_internal (url, DIRECTORY_SEPARATOR); -} - - -// Basename routine for the filesystem. -// It uses the automatically defined separator as the directory separator. -// As of February 2022 the std::filesystem does not yet work on Android. -//string filter_url_basename (string url) -//{ -// // Remove possible trailing path slash. -// if (!url.empty ()) { -// const char separator = filesystem::path::preferred_separator; -// if (url.find_last_of (separator) == url.length () - 1) { -// url = url.substr (0, url.length () - 1); -// } -// } -// // Standard library call for getting base name path. -// url = filesystem::path(url).filename().string(); -// // Done. -// return url; -//} - - -// Basename routine for the web. -// It uses the forward slash as the separator. -string filter_url_basename_web (string url) -{ - if (!url.empty ()) { - // Remove trailing slash. - const char * separator = "/"; - if (url.find_last_of (separator) == url.length () - 1) { - url = url.substr (0, url.length () - 1); - } - // Keep last element: the base name. - size_t pos = url.find_last_of (separator); - if (pos != std::string::npos) url = url.substr (pos + 1); - } - // Done. - return url; -} - - -void filter_url_unlink (string filename) -{ -#ifdef HAVE_WINDOWS - wstring wfilename = filter::strings::string2wstring (filename); - _wunlink (wfilename.c_str ()); -#else - unlink (filename.c_str ()); -#endif -} - - -// As of February 2022 the std::filesystem does not yet work on Android. -//void filter_url_unlink (string filename) -//{ -// try { -// filesystem::path path (filename); -// filesystem::remove (path); -// } catch (...) { } -//} - - -void filter_url_rename (const string& oldfilename, const string& newfilename) -{ -#ifdef HAVE_WINDOWS - wstring woldfilename = filter::strings::string2wstring (oldfilename); - wstring wnewfilename = filter::strings::string2wstring (newfilename); - _wrename (woldfilename.c_str (), wnewfilename.c_str ()); -#else - rename (oldfilename.c_str (), newfilename.c_str ()); -#endif -} - - -// As of February 2022 the std::filesystem does not yet work on Android. -//void filter_url_rename (const string& oldfilename, const string& newfilename) -//{ -// try { -// filesystem::path oldpath (oldfilename); -// filesystem::path newpath (newfilename); -// filesystem::rename(oldpath, newpath); -// } catch (...) { } -//} - - -// Creates a file path out of the components. -string filter_url_create_path (const vector& parts) -{ - // Empty path. - string path; - for (size_t i = 0; i < parts.size(); i++) { - // Initially append the first part without directory separator. - if (i == 0) path += parts[i]; - else { - // Other parts: Append the directory separator and then the part. - path += DIRECTORY_SEPARATOR; - path += parts[i]; - } - } - // Done. - return path; -} - - -// Creates a file path out of the parts. -// As of February 2022 the std::filesystem does not yet work on Android. -//string filter_url_create_path (const vector& parts) -//{ -// // Empty path. -// filesystem::path path; -// for (size_t i = 0; i < parts.size(); i++) { -// if (i == 0) path += parts[i]; // Append the part without directory separator. -// else path /= parts[i]; // Append the directory separator and then the part. -// } -// // Done. -// return path.string(); -//} - - -// Creates a file path out of the variable list of components, -// relative to the server's document root. -string filter_url_create_root_path (const vector& parts) -{ - // Construct path from the document root. - string path (config_globals_document_root); - // Add the bits. - for (size_t i = 0; i < parts.size(); i++) { - string part = parts[i]; - // At times a path is created from a URL. - // The URL likely starts with a slash, like this: /css/mouse.css - // When creating a path out of that, the path will become this: /css/mouse.css - // Such a path does not exist. - // The path that is wanted is something like this: - // /home/foo/bar/bibledit/css/mouse.css - // So remove that starting slash. - if (!part.empty()) if (part[0] == '/') part = part.erase(0, 1); - // Add the part, with a preceding path separator. - path += DIRECTORY_SEPARATOR; - path += part; - } - // Done. - return path; -} - - -// Creates a file path out of the variable list of components, -// relative to the server's document root. -// As of February 2022 the std::filesystem does not yet work on Android. -//string filter_url_create_root_path (const vector& parts) -//{ -// // Construct path from the document root. -// filesystem::path path (config_globals_document_root); -// // Add the bits. -// for (size_t i = 0; i < parts.size(); i++) { -// string part = parts[i]; -// // At times a path is created from a URL. -// // The URL likely starts with a slash, like this: /css/mouse.css -// // When creating a path out of that, the path will become this: /css/mouse.css -// // Such a path does not exist. -// // The path that is wanted is something like this: -// // /home/foo/bar/bibledit/css/mouse.css -// // So remove that starting slash. -// if (!part.empty()) if (part[0] == '/') part = part.erase(0, 1); -// // Add the part, with a preceding path separator. -// path /= part; -// } -// // Done. -// return path.string(); -//} - - -// Gets the file / url extension, e.g. /home/joe/file.txt returns "txt". -string filter_url_get_extension (string url) -{ - string extension; - size_t pos = url.find_last_of ("."); - if (pos != std::string::npos) { - extension = url.substr (pos + 1); - } - return extension; -} - - -// Gets the file / url extension, e.g. /home/joe/file.txt returns "txt". -// As of February 2022 the std::filesystem does not yet work on Android. -//string filter_url_get_extension (string url) -//{ -// std::filesystem::path path (url); -// string extension; -// if (path.has_extension()) { -// // Get the extension with the dot, e.g. ".txt". -// extension = path.extension().string(); -// // Wanted is the extension without the dot, e.g. "txt". -// extension.erase (0, 1); -// } -// return extension; -//} - - -// Returns true if the file at $url exists. -bool file_or_dir_exists (string url) -{ -#ifdef HAVE_WINDOWS - // Function '_wstat' works with wide characters. - wstring wurl = filter::strings::string2wstring(url); - struct _stat buffer; - int result = _wstat (wurl.c_str (), &buffer); - return (result == 0); -#else - // The 'stat' function works as expected on Linux. - struct stat buffer; - return (stat (url.c_str(), &buffer) == 0); -#endif -} - - -// Returns true if the file or directory at $url exists. -// As of February 2022 the std::filesystem does not yet work on Android. -//bool file_or_dir_exists (string url) -//{ -// filesystem::path path (url); -// bool exists = filesystem::exists (path); -// return exists; -//} - - -// Makes a directory. -// Creates parents where needed. -void filter_url_mkdir (string directory) -{ - int status; -#ifdef HAVE_WINDOWS - wstring wdirectory = filter::strings::string2wstring(directory); - status = _wmkdir (wdirectory.c_str()); -#else - status = mkdir (directory.c_str(), 0777); -#endif - if (status != 0) { - vector paths; - paths.push_back (directory); - directory = filter_url_dirname (directory); - while (directory.length () > 2) { - paths.push_back (directory); - directory = filter_url_dirname (directory); - } - reverse (paths.begin (), paths.end ()); - for (unsigned int i = 0; i < paths.size (); i++) { -#ifdef HAVE_WINDOWS - wstring wpathsi = filter::strings::string2wstring(paths[i]); - _wmkdir (wpathsi.c_str ()); -#else - mkdir (paths[i].c_str (), 0777); -#endif - } - } -} - - -// Makes a directory. -// Creates parents where needed. -// As of February 2022 the std::filesystem does not yet work on Android. -//void filter_url_mkdir (string directory) -//{ -// try { -// std::filesystem::path path (directory); -// std::filesystem::create_directories(path); -// } catch (...) { } -//} - - -// Removes directory recursively. -void filter_url_rmdir (string directory) -{ - vector files = filter_url_scandir_internal (directory); - for (auto path : files) { - path = filter_url_create_path ({directory, path}); - if (filter_url_is_dir(path)) { - filter_url_rmdir(path); - } -#ifdef HAVE_WINDOWS - // Remove directory. - wstring wpath = filter::strings::string2wstring(path); - _wrmdir(wpath.c_str()); - // Remove file. - filter_url_unlink(path); -#else - // On Linux remove the directory or the file. - remove(path.c_str()); -#endif - } -#ifdef HAVE_WINDOWS - wstring wdirectory = filter::strings::string2wstring(directory); - _wrmdir(wdirectory.c_str()); - filter_url_unlink(directory); -#else - remove(directory.c_str()); -#endif -} - - -// Removes directory recursively. -// As of February 2022 the std::filesystem does not yet work on Android. -//void filter_url_rmdir (string directory) -//{ -// try { -// filesystem::path path (directory); -// filesystem::remove_all(path); -// } catch (...) { } -//} - - -// Returns true is $path points to a directory. -bool filter_url_is_dir (string path) -{ -#ifdef HAVE_WINDOWS - // Function '_wstat', on Windows, works with wide characters. - wstring wpath = filter::strings::string2wstring (path); - struct _stat sb; - _wstat (wpath.c_str (), &sb); -#else - struct stat sb; - stat (path.c_str (), &sb); -#endif - return (sb.st_mode & S_IFMT) == S_IFDIR; -} - - -// Returns true is $path points to a directory. -// As of February 2022 the std::filesystem does not yet work on Android. -//bool filter_url_is_dir (string path) -//{ -// bool is_dir = false; -// try { -// filesystem::path p (path); -// is_dir = filesystem::is_directory(p); -// } catch (...) { } -// return is_dir; -//} - - -bool filter_url_get_write_permission (string path) -{ -#ifdef HAVE_WINDOWS - wstring wpath = filter::strings::string2wstring (path); - int result = _waccess (wpath.c_str (), 06); -#else - int result = access (path.c_str(), W_OK); -#endif - return (result == 0); -} - - -void filter_url_set_write_permission (string path) -{ -#ifdef HAVE_WINDOWS - wstring wpath = filter::strings::string2wstring (path); - _wchmod (wpath.c_str (), _S_IREAD | _S_IWRITE); -#else - chmod (path.c_str (), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH); -#endif -} - - -// As of February 2022 the std::filesystem does not yet work on Android. -//void filter_url_set_write_permission (string path) -//{ -// filesystem::path p (path); -// filesystem::permissions(p, filesystem::perms::owner_all | filesystem::perms::group_all | filesystem::perms::others_all); -//} - - -// Get and returns the contents of $filename. -string filter_url_file_get_contents(string filename) -{ - if (!file_or_dir_exists (filename)) return string(); - try { -#ifdef HAVE_WINDOWS - wstring wfilename = filter::strings::string2wstring(filename); - ifstream ifs(wfilename.c_str(), ios::in | ios::binary | ios::ate); -#else - ifstream ifs(filename.c_str(), ios::in | ios::binary | ios::ate); -#endif - streamoff filesize = ifs.tellg(); - if (filesize == 0) return string(); - ifs.seekg(0, ios::beg); - vector bytes(static_cast (filesize)); - ifs.read(&bytes[0], static_cast (filesize)); - return string(&bytes[0], static_cast (filesize)); - } - catch (...) { - return string(); - } -} - - -// Puts the $contents into $filename. -void filter_url_file_put_contents (string filename, string contents) -{ - try { - ofstream file; -#ifdef HAVE_WINDOWS - wstring wfilename = filter::strings::string2wstring(filename); - file.open(wfilename, ios::binary | ios::trunc); -#else - file.open(filename, ios::binary | ios::trunc); -#endif - file << contents; - file.close (); - } catch (...) { - } -} - - -// C++ rough equivalent for PHP's file_put_contents. -// Appends the data if the file exists. -void filter_url_file_put_contents_append (string filename, string contents) -{ - try { - ofstream file; -#ifdef HAVE_WINDOWS - wstring wfilename = filter::strings::string2wstring (filename); - file.open (wfilename, ios::binary | ios::app); -#else - file.open (filename, ios::binary | ios::app); -#endif - file << contents; - file.close (); - } catch (...) { - } -} - - -// Copies the contents of file named "input" to file named "output". -// It is assumed that the folder where "output" will reside exists. -bool filter_url_file_cp (string input, string output) -{ - try { -#ifdef HAVE_WINDOWS - ifstream source (filter::strings::string2wstring (input), ios::binary); - ofstream dest (filter::strings::string2wstring (output), ios::binary | ios::trunc); -#else - ifstream source (input, ios::binary); - ofstream dest (output, ios::binary | ios::trunc); -#endif - dest << source.rdbuf(); - source.close(); - dest.close(); - } catch (...) { - return false; - } - return true; -} - - -// Copies the entire directory $input to a directory named $output. -// It will recursively copy the inner directories also. -void filter_url_dir_cp (const string & input, const string & output) -{ - // Create the output directory. - filter_url_mkdir (output); - // Check on all files in the input directory. - vector files = filter_url_scandir (input); - for (auto & file : files) { - string input_path = filter_url_create_path ({input, file}); - string output_path = filter_url_create_path ({output, file}); - if (filter_url_is_dir (input_path)) { - // Create output directory. - filter_url_mkdir (output_path); - // Handle the new input directory. - filter_url_dir_cp (input_path, output_path); - } else { - // Copy input file to output. - filter_url_file_cp (input_path, output_path); - } - } -} - - -// A C++ equivalent for PHP's filesize function. -int filter_url_filesize (string filename) -{ -#ifdef HAVE_WINDOWS - wstring wfilename = filter::strings::string2wstring (filename); - struct _stat buf; - int rc = _wstat (wfilename.c_str (), &buf); -#else - struct stat buf; - int rc = stat (filename.c_str (), &buf); -#endif - return rc == 0 ? static_cast (buf.st_size) : 0; -} - - -// Returns the size of the file at $filename. -// As of February 2022 the std::filesystem does not yet work on Android. -//int filter_url_filesize (string filename) -//{ -// uintmax_t filesize = 0; -// try { -// filesystem::path p (filename); -// filesize = filesystem::file_size(p); -// } catch (...) { } -// return static_cast(filesize); -//} - - -// Scans the directory for files it contains. -vector filter_url_scandir (string folder) -{ - vector files = filter_url_scandir_internal (folder); - files = filter::strings::array_diff (files, {"gitflag"}); - return files; -} - - -// Scans the directory for files it contains. -// As of February 2022 the std::filesystem does not yet work on Android. -//vector filter_url_scandir (string folder) -//{ -// vector files; -// try { -// filesystem::path dir_path (folder); -// for (auto const & directory_entry : filesystem::directory_iterator {dir_path}) -// { -// // The full path. -// filesystem::path entry_path = directory_entry.path(); -// // Get the path as relative to the directory. -// filesystem::path relative_path = filesystem::relative(entry_path, dir_path); -// // Get the name of the relative path. -// string name = relative_path.string(); -// // Exclude developer temporal files. -// if (name == ".deps") continue; -// if (name == ".dirstamp") continue; -// // Exclude macOS files. -// if (name == ".DS_Store") continue; -// // Exclude non-interesting files. -// if (name == "gitflag") continue; -// // Store the name. -// files.push_back (name); -// } -// } catch (...) { } -// sort (files.begin(), files.end()); -// return files; -//} - - -// Recursively scans a directory for directories and files. -void filter_url_recursive_scandir (string folder, vector & paths) -{ - vector files = filter_url_scandir (folder); - for (auto & file : files) { - string path = filter_url_create_path ({folder, file}); - paths.push_back (path); - if (filter_url_is_dir (path)) { - filter_url_recursive_scandir (path, paths); - } - } -} - - -// Gets the file modification time. -int filter_url_file_modification_time (string filename) -{ -#ifdef HAVE_WINDOWS - wstring wfilename = filter::strings::string2wstring (filename); - struct _stat attributes; - _wstat (wfilename.c_str (), &attributes); -#else - struct stat attributes; - stat (filename.c_str (), &attributes); -#endif - return (int) attributes.st_mtime; -} - - -// A C++ near equivalent for PHP's urldecode function. -string filter_url_urldecode (string url) -{ - url = UriDecode (url); - replace (url.begin (), url.end (), '+', ' '); - return url; -} - - -// A C++ near equivalent for PHP's urlencode function. -string filter_url_urlencode (string url) -{ - url = UriEncode (url); - return url; -} - - -// Returns the name of the temp directory. -const char * filter_url_temp_dir () -{ - return "tmp"; -} - - -// Returns the name of a temporary file. -string filter_url_tempfile (const char * directory) -{ - string filename = filter::strings::convert_to_string (filter::date::seconds_since_epoch ()) + filter::strings::convert_to_string (filter::date::numerical_microseconds ()) + filter::strings::convert_to_string (filter::strings::rand (10000000, 99999999)); - if (directory) { - filename = filter_url_create_path ({directory, filename}); - } else { - filename = filter_url_create_root_path ({filter_url_temp_dir (), filename}); - } - return filename; -} - - -// C++ equivalent for PHP's escapeshellarg function. -string filter_url_escape_shell_argument (string argument) -{ - argument = filter::strings::replace ("'", "\\'", argument); - argument.insert (0, "'"); - argument.append ("'"); - return argument; -} - - -// The function accepts a $path. -// The function may add a numerical suffix -// to ensure that the $path does not yet exist in the filesystem. -string filter_url_unique_path (string path) -{ - if (!file_or_dir_exists (path)) return path; - for (size_t i = 1; i < 100; i++) { - string uniquepath = path + "." + filter::strings::convert_to_string (i); - if (!file_or_dir_exists (uniquepath)) return uniquepath; - } - return path + "." + filter::strings::convert_to_string (filter::strings::rand (100, 1000)); -} - - -// Returns true if the email address is valid. -bool filter_url_email_is_valid (string email) -{ - const string valid_set ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-"); - // The @ character should appear only once. - vector atbits = filter::strings::explode (email, '@'); - if (atbits.size() != 2) return false; - // The characters on the left of @ should be from the valid set. - string left = atbits [0]; - for (unsigned int i = 0; i < left.size(); i++) { - char c = left [i]; - if (valid_set.find (c) == std::string::npos) return false; - } - // The characters on the right of @ should be from the valid set. - string right = atbits [1]; - for (unsigned int i = 0; i < right.size(); i++) { - char c = right [i]; - if (valid_set.find (c) == std::string::npos) return false; - } - // The character . should appear at least once to the right of @. - vector dotbits = filter::strings::explode (right, '.'); - if (dotbits.size () < 2) return false; - // The email address is valid. - return true; -} - - -string filter_url_build_http_query (string url, const string& parameter, const string& value) -{ - size_t pos = url.find ("?"); - if (pos == std::string::npos) url.append ("?"); - else url.append ("&"); - url.append (parameter); - url.append ("="); - url.append (value); - return url; -} - - -size_t filter_url_curl_write_function (void *ptr, size_t size, size_t count, void *stream) -{ - static_cast(stream)->append (static_cast(ptr), 0, size * count); - return size * count; -} - - -// Sends a http GET request to the $url. -// It returns the response from the server. -// It writes any error to $error. -string filter_url_http_get (string url, string& error, [[maybe_unused]] bool check_certificate) -{ - string response; -#ifdef HAVE_CLIENT - response = filter_url_http_request_mbed (url, error, {}, "", check_certificate); -#else - CURL *curl = curl_easy_init (); - if (curl) { - curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, filter_url_curl_write_function); - curl_easy_setopt (curl, CURLOPT_WRITEDATA, &response); - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - //curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); - // Because a Bibledit client should work even over very bad networks, - // pass some timeout options to curl so it properly deals with such networks. - filter_url_curl_set_timeout (curl); - CURLcode res = curl_easy_perform (curl); - if (res == CURLE_OK) { - error.clear (); - long http_code = 0; - curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); - if (http_code != 200) { - response.append ("http code " + filter::strings::convert_to_string (static_cast(http_code))); - } - } else { - response.clear (); - error = curl_easy_strerror (res); - } - curl_easy_cleanup (curl); - } -#endif - return response; -} - - -// The debug function for libcurl, it dumps the data as specified. -void filter_url_curl_debug_dump (const char *text, FILE *stream, unsigned char *ptr, size_t size) -{ - size_t i; - size_t c; - unsigned int width = 0x10; - - fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n", text, static_cast (size), static_cast (size)); - - for (i = 0; i < size; i += width) { - fprintf(stream, "%4.4lx: ", static_cast (i)); - - // Show hex to the left. - for (c = 0; c < width; c++) { - if (i + c < size) fprintf (stream, "%02x ", ptr[i + c]); - else fputs(" ", stream); - } - - // Show data on the right. - for (c = 0; (c < width) && (i + c < size); c++) { - unsigned char x = (ptr[i + c] >= 0x20 && ptr[i + c] < 0x80) ? ptr[i + c] : '.'; - fputc (x, stream); - } - - // Newline. - fputc ('\n', stream); - } -} - - -// The trace function for libcurl. -#ifdef HAVE_CLOUD -int filter_url_curl_trace (CURL *handle, curl_infotype type, char *data, size_t size, void *userp) -{ - const char *text { nullptr }; - - // Prevent compiler warnings. - (void)handle; - (void)userp; - - switch (type) { - case CURLINFO_TEXT: - fprintf(stderr, "== Info: %s", data); - return 0; - case CURLINFO_HEADER_OUT: - text = "=> Send header"; - break; - case CURLINFO_DATA_OUT: - text = "=> Send data"; - break; - case CURLINFO_SSL_DATA_OUT: - text = "=> Send SSL data"; - break; - case CURLINFO_HEADER_IN: - text = "<= Recv header"; - break; - case CURLINFO_DATA_IN: - text = "<= Recv data"; - break; - case CURLINFO_SSL_DATA_IN: - text = "<= Recv SSL data"; - break; - case CURLINFO_END: - default: - return 0; - } - - filter_url_curl_debug_dump(text, stderr, reinterpret_cast (data), size); - return 0; -} -#endif - - -// Sends a http POST request to $url. -// burst: Set connection timing for burst mode, where the response comes after a relatively long silence. -// It posts the $post_data as-t. -// It appends the $values to the post data. -// It returns the response from the server. -// It writes any error to $error. -string filter_url_http_post (const string & url, [[maybe_unused]] string post_data, const map & post_values, string& error, [[maybe_unused]] bool burst, [[maybe_unused]] bool check_certificate, [[maybe_unused]] const vector > & headers) -{ - string response; -#ifdef HAVE_CLIENT - response = filter_url_http_request_mbed (url, error, post_values, "", check_certificate); -#else - // Get a curl handle. - CURL *curl = curl_easy_init (); - if (curl) { - // First set the URL that is about to receive the POST. - // This can be http or https. - curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); - // Generate the post data, add it to the plain post data. - for (auto & element : post_values) { - if (!post_data.empty ()) post_data.append ("&"); - post_data.append (element.first); - post_data.append ("="); - post_data.append (filter_url_urlencode (element.second)); - } - // Specify the POST data to curl, e.g.: "name=foo&project=bar" - curl_easy_setopt (curl, CURLOPT_POSTFIELDS, post_data.c_str()); - // Callback for the server response. - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, filter_url_curl_write_function); - curl_easy_setopt (curl, CURLOPT_WRITEDATA, &response); - // Further options. - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - // Enable the trace function. - // curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, filter_url_curl_trace); - // The DEBUGFUNCTION has no effect until we enable VERBOSE. - // curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); - // Timeouts for very bad networks, see the GET routine above for an explanation. - filter_url_curl_set_timeout (curl, burst); - // Whether to check the secure certificate. - // If the configuration of the site is not right, the certificate cannot be verified. - // That would result in resources not being fetched anymore. - if (!check_certificate) curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - // Optional extra headers. - curl_slist *list {nullptr}; - for (auto header : headers) { - string line = header.first + ": " + header.second; - list = curl_slist_append (list, line.c_str ()); - } - if (list) { - curl_easy_setopt (curl, CURLOPT_HTTPHEADER, list); - } - // Perform the request. - CURLcode res = curl_easy_perform (curl); - // Result check. - if (res == CURLE_OK) { - error.clear (); - long http_code = 0; - curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); - if (http_code != 200) { - error.append ("Server response " + filter_url_http_response_code_text (static_cast(http_code))); - } - } else { - error = curl_easy_strerror (res); - } - // Always cleanup. - if (list) curl_slist_free_all (list); - curl_easy_cleanup (curl); - } -#endif - return response; -} - - -// Sends a http POST request to $url as from a
    with enctype="multipart/form-data". -// It posts the $values. -// It uploads $filename. -// It returns the response from the server. -// It writes any error to $error. -string filter_url_http_upload ([[maybe_unused]] string url, - [[maybe_unused]] map values, - [[maybe_unused]] string filename, - string& error) -{ - string response; - -#ifdef HAVE_CLIENT - error = "Not implemented in client configuration"; -#else - - // Coded while looking at http://curl.haxx.se/libcurl/c/postit2.html. - curl_httppost * formpost {nullptr}; - curl_httppost * lastptr {nullptr}; - - // Fill in the text fields to submit. - for (auto & element : values) { - curl_formadd (&formpost, &lastptr, - CURLFORM_COPYNAME, element.first.c_str (), - CURLFORM_COPYCONTENTS, element.second.c_str(), - CURLFORM_END); - } - - // Fill in the file upload field to submit. - curl_formadd(&formpost, &lastptr, - CURLFORM_COPYNAME, "uploadedZipFile", - CURLFORM_FILE, filename.c_str(), - CURLFORM_END); - - // Get a curl handle. - CURL *curl = curl_easy_init (); - if (curl) { - // First set the URL that is about to receive the POST. - curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); - // Specify the POST data to curl. - curl_easy_setopt (curl, CURLOPT_HTTPPOST, formpost); - // Callback for the server response. - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, filter_url_curl_write_function); - curl_easy_setopt (curl, CURLOPT_WRITEDATA, &response); - // Further options. - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - // curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); - // Timeouts for very bad networks, see the GET routine above for an explanation. - filter_url_curl_set_timeout (curl, false); - // Perform the request. - CURLcode res = curl_easy_perform (curl); - // Result check. - if (res == CURLE_OK) { - error.clear (); - long http_code = 0; - curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); - if (http_code != 200) { - error.append ("Server response " + filter_url_http_response_code_text (static_cast(http_code))); - } - } else { - error = curl_easy_strerror (res); - } - // Always cleanup cURL. - curl_easy_cleanup (curl); - // Then cleanup the formpost chain. - curl_formfree (formpost); - } -#endif - - return response; -} - - -string filter_url_http_response_code_text (int code) -{ - string text = filter::strings::convert_to_string (code); - text.append (" "); - switch (code) { - case 100: text += "Continue"; break; - case 101: text += "Switching Protocols"; break; - case 200: text += "OK"; break; - case 201: text += "Created"; break; - case 202: text += "Accepted"; break; - case 203: text += "Non-Authoritative Information"; break; - case 204: text += "No Content"; break; - case 205: text += "Reset Content"; break; - case 206: text += "Partial Content"; break; - case 300: text += "Multiple Choices"; break; - case 301: text += "Moved Permanently"; break; - case 302: text += "Found"; break; - case 303: text += "See Other"; break; - case 304: text += "Not Modified"; break; - case 305: text += "Use Proxy"; break; - case 307: text += "Temporary Redirect"; break; - case 308: text += "Permanent Redirect"; break; - case 400: text += "Bad Request"; break; - case 401: text += "Unauthorized"; break; - case 402: text += "Payment Required"; break; - case 403: text += "Forbidden"; break; - case 404: text += "Not Found"; break; - case 405: text += "Method Not Allowed"; break; - case 406: text += "Not Acceptable"; break; - case 407: text += "Proxy Authentication Required"; break; - case 408: text += "Request Timeout"; break; - case 409: text += "Conflict"; break; - case 410: text += "Gone"; break; - case 411: text += "Length Required"; break; - case 412: text += "Precondition Failed"; break; - case 413: text += "Request Entity Too Large"; break; - case 414: text += "Request-URI Too Long"; break; - case 415: text += "Unsupported Media Type"; break; - case 416: text += "Requested Range Not Satisfiable"; break; - case 417: text += "Expectation Failed"; break; - case 426: text += "Upgrade Required"; break; - case 428: text += "Precondition Required"; break; - case 429: text += "Too Many Requests"; break; - case 431: text += "Request Header Fields Too Large"; break; - case 500: text += "Internal Server Error"; break; - case 501: text += "Not Implemented"; break; - case 502: text += "Bad Gateway"; break; - case 503: text += "Service Unavailable"; break; - case 504: text += "Gateway Timeout"; break; - case 505: text += "HTTP Version Not Supported"; break; - case 511: text += "Network Authentication Required"; break; - default: text += "Error"; break; - } - return text; -} - - -// Downloads the file at $url, and stores it at $filename. -void filter_url_download_file (string url, string filename, string& error, - [[maybe_unused]] bool check_certificate) -{ -#ifdef HAVE_CLIENT - filter_url_http_request_mbed (url, error, {}, filename, check_certificate); -#else - CURL *curl = curl_easy_init (); - if (curl) { - curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); - FILE* file = fopen (filename.c_str(), "w"); - curl_easy_setopt (curl, CURLOPT_WRITEDATA, file); - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - // curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); - filter_url_curl_set_timeout (curl); - CURLcode res = curl_easy_perform (curl); - if (res == CURLE_OK) { - error.clear (); - long http_code = 0; - curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); - if (http_code != 200) { - error.append ("http code " + filter::strings::convert_to_string (static_cast(http_code))); - } - } else { - error = curl_easy_strerror (res); - } - curl_easy_cleanup (curl); - fclose (file); - } -#endif -} - - -/* - * The function returns the filename for a html file for a Bible. - * $path - The path where to store the files. - * $book - The book identifier. - * $chapter - The chapter number. - */ -string filter_url_html_file_name_bible (string path, int book, int chapter) -{ - string filename; - - // If a path is given, prefix it. - if (path != "") { - filename = path + "/"; - } - - // No book ID given: Return the name for the index file for the Bible. - if (book == 0) { - filename += "index.html"; - return filename; - } - - // Add the name for the book. No spaces. - filename += filter::strings::fill (filter::strings::convert_to_string (book), 2, '0'); - string sbook = database::books::get_english_from_id (static_cast(book)); - sbook = filter::strings::replace (" ", "", sbook); - filename += '-' + sbook; - - // Chapter given: Provide name for the chaper. - if (chapter >= 0) { - filename += '-' + filter::strings::fill (filter::strings::convert_to_string (chapter), 3, '0'); - } - - filename += ".html"; - - return filename; -} - - -// Callback function for logging cURL debug information. -#ifdef HAVE_CLIENT -#else -int filter_url_curl_debug_callback (void *curl_handle, int curl_info_type, char *data, size_t size, void *userptr) -{ - if (curl_handle && userptr) {}; - bool log = true; - curl_infotype type = static_cast(curl_info_type); - if (type == CURLINFO_SSL_DATA_OUT) log = false; - if (type == CURLINFO_SSL_DATA_OUT) log = false; - if (log) { - string message (data, size); - Database_Logs::log (message); - } - return 0; -} -#endif - - -// Sets timeouts for cURL operations. -// burst: When true, the server gives a burst response, that is, all data arrives at once after a delay. -// When false, the data is supposed to be downloaded gradually. -// Without these timeouts, the Bibledit client will hang on stalled sync operations. -#ifdef HAVE_CLIENT -#else -void filter_url_curl_set_timeout (void *curl_handle, bool burst) -{ - CURL * handle = curl_handle; - - // There is a timeout on establishing a connection. - curl_easy_setopt (handle, CURLOPT_CONNECTTIMEOUT, 10); - - // There is a also a transfer timeout for normal speeds. - curl_easy_setopt (handle, CURLOPT_TIMEOUT, 600); - - // There is also a shorter transfer timeout for low speeds, - // because low speeds indicate a stalled connection. - // But when the server needs to do a lot of processing and then sends then response at once, - // the low speed timeouts should be disabled, - // else it times out before the response has come. - if (!burst) { - curl_easy_setopt (handle, CURLOPT_LOW_SPEED_LIMIT, 100); - curl_easy_setopt (handle, CURLOPT_LOW_SPEED_TIME, 10); - } - - // Timing out may use signals, which is not what we want. - curl_easy_setopt (handle, CURLOPT_NOSIGNAL, 1L); -} -#endif - - - -// When the client POSTs + sign to the server, -// the + sign is replaced with a space in the process. -// Therefore first convert the + to a TAG before sending it off. -string filter_url_plus_to_tag (string data) -{ - return filter::strings::replace ("+", "PLUSSIGN", data); -} - - -// When POSTing a + sign via jQuery to the server, -// the + sign is replaced with a space in the process. -// Javascript first converts the + to a TAG before sending it off. -// This function reverts the TAG to the original + sign. -string filter_url_tag_to_plus (string data) -{ - return filter::strings::replace ("PLUSSIGN", "+", data); -} - - -// This filter removes the username and password components from the $url. -string filter_url_remove_username_password (string url) -{ - string slashes = "//"; - size_t pos = url.find (slashes); - - // Consider the following URL for github: - // https://username:password@github.com/username/repository.git - if (filter::strings::replace_between (url, slashes, ":", "")) { - if (pos != std::string::npos) url.insert (pos, slashes); - } - if (filter::strings::replace_between (url, slashes, "@", "")) { - if (pos != std::string::npos) url.insert (pos, slashes); - } - - return url; -} - - -// A very simple function that sends a HTTP GET or POST request and reads the response. -// It handles plain and secure http. -// $url: The URL including host / port / path. -// $error: To store any error messages. -// $post: Value pairs for a POST request. -// $filename: The filename to save the data to. -// $check_certificate: Whether to check the server certificate in case of secure http. -string filter_url_http_request_mbed (string url, string& error, const map & post, const string& filename, bool check_certificate) -{ - // The "http" scheme is used to locate network resources via the HTTP protocol. - // $url = "http(s):" "//" host [ ":" port ] [ abs_path [ "?" query ]] - - - // Whether this is a secure http request. - bool secure = url.find ("https:") != std::string::npos; - - - // Remove the scheme: http(s). - size_t pos = url.find ("://"); - if (pos != std::string::npos) { - url.erase (0, pos + 3); - } - - - // Extract the host. - pos = url.find (":"); - if (pos == std::string::npos) pos = url.find ("/"); - if (pos == std::string::npos) pos = url.length () + 1; - string hostname = url.substr (0, pos); - url.erase (0, hostname.length ()); - - - // Default port numbers for plain or secure http. - int port = 80; - if (secure) port = 443; - // Extract the port number if any. - pos = url.find (":"); - if (pos != std::string::npos) { - url.erase (0, 1); - size_t pos2 = url.find ("/"); - if (pos2 == std::string::npos) pos2 = url.length () + 1; - string p = url.substr (0, pos2); - port = filter::strings::convert_to_int (p); - url.erase (0, p.length ()); - } - - - // Empty URL results in a slash. - if (url.empty ()) url = "/"; - - - // The absolute path plus optional query remain after extracting the preceding stuff. - - - bool connection_healthy = true; - - - // SSL/TLS configuration and context. - // The configuration is local, because options may not be the same for every website. - // On Windows, threading has been disabled in the mbedTLS library. - // On the server, this will lead to undefined crashes which are hard to find. - // On a client, since the TLS context is not shared, there won't be any crashes. - mbedtls_ssl_context ssl; - mbedtls_ssl_config conf; - if (secure) { - mbedtls_ssl_init (&ssl); - mbedtls_ssl_config_init (&conf); - } - - - // Resolve the host. - addrinfo hints; - addrinfo * address_results {nullptr}; - bool address_info_resolved {false}; - if (!secure) { - memset (&hints, 0, sizeof (addrinfo)); - // Allow IPv4 and IPv6. - hints.ai_family = AF_UNSPEC; - // TCP/IP socket. - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = 0; - // Select protocol that matches with the socket type. - hints.ai_protocol = 0; - // The 'service' is actually the port number. - string service = filter::strings::convert_to_string (port); - // Get a list of address structures. There can be several of them. - int res = getaddrinfo (hostname.c_str(), service.c_str (), &hints, &address_results); - if (res != 0) { - error = "Internet connection failure: " + hostname + ": "; -#ifdef HAVE_WINDOWS - wchar_t * err = gai_strerrorW (res); - error.append (filter::strings::wstring2string (err)); -#else - error.append (gai_strerror (res)); -#endif - connection_healthy = false; - } else { - address_info_resolved = true; - } - } - - - // Secure connection setup. - mbedtls_net_context fd; - if (secure) { - - // Secure socket setup. - if (connection_healthy) { - mbedtls_net_init (&fd); - } - - // SSL/TLS connection configuration. - if (connection_healthy) { - int ret = mbedtls_ssl_config_defaults (&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); - if (ret != 0) { - filter_url_display_mbed_tls_error (ret, &error, false); - connection_healthy = false; - } - mbedtls_ssl_conf_authmode (&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); - mbedtls_ssl_conf_ca_chain (&conf, &filter_url_mbed_tls_cacert, nullptr); - mbedtls_ssl_conf_rng (&conf, mbedtls_ctr_drbg_random, &filter_url_mbed_tls_ctr_drbg); - ret = mbedtls_ssl_setup (&ssl, &conf); - if (ret != 0) { - filter_url_display_mbed_tls_error (ret, &error, false); - connection_healthy = false; - } - // The hostname it connects to, and verifies the certificate for. - ret = mbedtls_ssl_set_hostname (&ssl, hostname.c_str ()); - if (ret != 0) { - filter_url_display_mbed_tls_error (ret, &error, false); - connection_healthy = false; - } - mbedtls_ssl_set_bio (&ssl, &fd, mbedtls_net_send, mbedtls_net_recv, nullptr); - } - - // Secure connect to host. - if (connection_healthy) { - // It used to pass the "server_port" to the connect routine: - // const char * server_port = filter::strings::convert_to_string (port).c_str (); - // But MSVC optimized this variable away before it could be passed to that routine. - // The code was updated to work around that. - int ret = mbedtls_net_connect (&fd, hostname.c_str(), filter::strings::convert_to_string (port).c_str (), MBEDTLS_NET_PROTO_TCP); - if (ret != 0) { - filter_url_display_mbed_tls_error (ret, &error, false); - connection_healthy = false; - } - } - } - - - // Plain connection setup. - int sock = 0; - if (!secure) { - - // Iterate over the list of address structures. - vector errors; - addrinfo * rp {nullptr}; - if (connection_healthy) { - for (rp = address_results; rp != nullptr; rp = rp->ai_next) { - // Try to get a socket for this address structure. - sock = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol); - // If it fails, try the next one. - if (sock < 0) { - string err = "Creating socket: "; - err.append (strerror (errno)); - errors.push_back (err); - continue; - } - // Try to connect. - int res = connect (sock, rp->ai_addr, rp->ai_addrlen); - // Test and record error. - if (res < 0) { - string err = hostname + ":" + filter::strings::convert_to_string (port) + ": "; - err.append (strerror (errno)); - errors.push_back (err); - } - // If success: Done. - if (res != -1) break; - // Failure: Socket should be closed. - if (sock) { -#ifdef HAVE_WINDOWS - closesocket (sock); -#else - close (sock); -#endif - } - sock = 0; - } - } - - // Check whether no address succeeded. - if (connection_healthy) { - if (rp == nullptr) { - error = filter::strings::implode (errors, " | "); - connection_healthy = false; - } - } - - // No longer needed: Only to be freed when the address was resolved. - if (address_info_resolved) freeaddrinfo (address_results); - } - - - // A Bibledit client should work even over very bad networks, - // so set a timeout on the network connection. - if (connection_healthy) { - // Socket, whether plain or secure http. - int comm_sock = sock; - if (secure) comm_sock = fd.fd; - // Make the timeout not too short, so it can support very slow networks. -#ifdef HAVE_WINDOWS - // Windows: Timeout value is a DWORD in milliseconds, address passed to setsockopt() is const char * - const char * tv = "600000"; -#else - // Linux: Timeout value is a struct timeval, address passed to setsockopt() is const void * - timeval tv; - tv.tv_sec = 600; - tv.tv_usec = 0; -#endif - // Check on the result of setting the socket options. - // If it cannot be set, record it in the journal, - // but still proceed with the connection, because this is not fatal. - int ret; -#ifdef HAVE_WINDOWS - ret = setsockopt (comm_sock, SOL_SOCKET, SO_RCVTIMEO, tv, sizeof (tv)); -#else - ret = setsockopt (comm_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(timeval)); -#endif - if (ret != 0) Database_Logs::log (strerror (errno)); -#ifdef HAVE_WINDOWS - ret = setsockopt (comm_sock, SOL_SOCKET, SO_SNDTIMEO, tv, sizeof (tv)); -#else - ret = setsockopt (comm_sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(timeval)); -#endif - if (ret != 0) Database_Logs::log (strerror (errno)); - } - - - // SSL/TLS handshake. - if (secure) { - int ret; - while (connection_healthy && ((ret = mbedtls_ssl_handshake (&ssl)) != 0)) { - if (ret == MBEDTLS_ERR_SSL_WANT_READ) continue; - if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) continue; - filter_url_display_mbed_tls_error (ret, &error, false); - connection_healthy = false; - } - } - - - // Optionally verify the server certificate. - if (connection_healthy && secure && check_certificate) { - uint32_t flags = mbedtls_ssl_get_verify_result (&ssl); - if (flags != 0) { - char vrfy_buf [512]; - mbedtls_x509_crt_verify_info (vrfy_buf, sizeof (vrfy_buf), " ! ", flags); - error = vrfy_buf; - connection_healthy = false; - } - } - - - // Assemble the data to POST, if any. - string postdata; - for (auto & element : post) { - if (!postdata.empty ()) postdata.append ("&"); - postdata.append (element.first); - postdata.append ("="); - postdata.append (filter_url_urlencode (element.second)); - } - - - // Send the request. - if (connection_healthy) { - string request = "GET"; - if (!post.empty ()) request = "POST"; - request.append (" "); - request.append (url); - request.append (" "); - request.append ("HTTP/1.1"); - request.append ("\r\n"); - request.append ("Host: "); - request.append (hostname); - request.append ("\r\n"); - // Close connection, else it's harder to locate the end of the response. - request.append ("Connection: close"); - request.append ("\r\n"); - if (!post.empty ()) { - request.append ("Content-Type: application/x-www-form-urlencoded"); - request.append ("\r\n"); - request.append ("Content-Length: " + filter::strings::convert_to_string (postdata.length())); - request.append ("\r\n"); - } - request.append ("\r\n"); - request.append (postdata); - if (secure) { - - // Write the secure http request to the server. - const char * output = request.c_str(); - const unsigned char * buf = reinterpret_cast(output); - // The C function strlen () fails on null characters in the request, so take string::size() - size_t len = request.size (); - while (connection_healthy && (len > 0)) { - // Function - // int ret = mbedtls_ssl_write (&ssl, buf, len) - // will do partial writes in some cases. - // If the return value is non-negative but less than length, - // the function must be called again with updated arguments: - // buf + ret, len - ret - // until it returns a value equal to the last 'len' argument. - int ret = mbedtls_ssl_write (&ssl, buf, len); - if (ret > 0) { - buf += ret; - len -= static_cast(ret); - } else { - // When it returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, - // it must be called later with the *same* arguments, - // until it returns a positive value. - if (ret == MBEDTLS_ERR_SSL_WANT_READ) continue; - if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) continue; - filter_url_display_mbed_tls_error (ret, &error, false); - connection_healthy = false; - } - } - - } else { - - // Send plain http. - if (send (sock, request.c_str(), request.length(), 0) != static_cast(request.length ())) { - error = "Sending request: "; - error.append (strerror (errno)); - connection_healthy = false; - } - - } - } - - - // Read the response headers and body. - string headers; - string response; - if (connection_healthy) { - - bool reading = true; - bool reading_body = false; - char prev = 0; - char cur; - FILE * file = nullptr; - if (!filename.empty ()) { -#ifdef HAVE_WINDOWS - wstring wfilename = filter::strings::string2wstring (filename); - file = _wfopen (wfilename.c_str (), L"w"); -#else - file = fopen (filename.c_str (), "w"); -#endif - } - - do { - int ret = 0; - if (secure) { - unsigned char buffer [1]; - memset (&buffer, 0, 1); - ret = mbedtls_ssl_read (&ssl, buffer, 1); - cur = static_cast(buffer [0]); - } else { -#ifdef HAVE_WINDOWS - ret = (int)recv(sock, &cur, 1, 0); -#else - ret = static_cast(read(sock, &cur, 1)); -#endif - } - if (ret > 0) { - if (reading_body) { - if (file) { - fwrite (&cur, 1, 1, file); - } - else response += cur; - } else { - if (cur == '\r') continue; - headers += cur; - if ((cur == '\n') && (prev == '\n')) reading_body = true; - prev = cur; - } - } else if (!secure && (ret < 0)) { - error = "Receiving: "; - error.append (strerror (errno)); - connection_healthy = false; - } else if (secure && (ret == MBEDTLS_ERR_SSL_WANT_READ)) { - } else if (secure && (ret == MBEDTLS_ERR_SSL_WANT_WRITE)) { - } else if (secure && (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)) { - } else if (secure && (ret < 0)) { - filter_url_display_mbed_tls_error (ret, &error, false); - connection_healthy = false; - } else { - // Probably EOF. - reading = false; - } - } while (reading && connection_healthy); - - if (file) fclose (file); - } - - - if (secure) { - mbedtls_ssl_close_notify (&ssl); - mbedtls_net_free (&fd); - mbedtls_ssl_free (&ssl); - mbedtls_ssl_config_free (&conf); - } else { - // Only close the socket if it was open. - // It used to close (0) in error, - // and on Android and iOS, when this was done a couple of times, it would crash the app. - if (sock > 0) { -#ifdef HAVE_WINDOWS - closesocket(sock); -#else - close (sock); -#endif - } - } - - - // Check the response headers. - vector lines = filter::strings::explode (headers, '\n'); - for (auto & line : lines) { - if (line.empty ()) continue; - if (line.find ("HTTP") != std::string::npos) { - size_t pos2 = line.find (" "); - if (pos2 != std::string::npos) { - line.erase (0, pos2 + 1); - int response_code = filter::strings::convert_to_int (line); - if (response_code != 200) { - error = "Response code: " + line; - return string(); - } - } else { - error = "Invalid response: " + line; - return string(); - } - } - } - - - // Done. - if (!connection_healthy) response.clear (); - return response; -} - - -// Initialize the SSL/TLS system once. -void filter_url_ssl_tls_initialize () -{ - int ret = 0; - // Random number generator. - mbedtls_ctr_drbg_init (&filter_url_mbed_tls_ctr_drbg); - mbedtls_entropy_init (&filter_url_mbed_tls_entropy); - const char *pers = "Client"; - ret = mbedtls_ctr_drbg_seed (&filter_url_mbed_tls_ctr_drbg, mbedtls_entropy_func, &filter_url_mbed_tls_entropy, reinterpret_cast (pers), strlen (pers)); - filter_url_display_mbed_tls_error (ret, nullptr, false); - // Wait until the trusted root certificates exist. - // This is necessary as there's cases that the data is still being installed at this point. - string path = filter_url_create_root_path ({"filter", "cas.crt"}); - while (!file_or_dir_exists (path)) this_thread::sleep_for (chrono::milliseconds (100)); - // Read the trusted root certificates. - ret = mbedtls_x509_crt_parse_file (&filter_url_mbed_tls_cacert, path.c_str ()); - filter_url_display_mbed_tls_error (ret, nullptr, false); -} - - -// Finalize the SSL/TLS system once. -void filter_url_ssl_tls_finalize () -{ - mbedtls_ctr_drbg_free (&filter_url_mbed_tls_ctr_drbg); - mbedtls_entropy_free (&filter_url_mbed_tls_entropy); - mbedtls_x509_crt_free (&filter_url_mbed_tls_cacert); -} - - -// This logs the $ret (return) value, converted to readable text, to the journal. -// If $error is given, it is stored there instead. -// It $server is true, it suppresses additional error codes. -void filter_url_display_mbed_tls_error (int & ret, string * error, bool server) -{ - // Local copy of the return value, and clear the original return value. - int local_return = ret; - ret = 0; - - // Everything OK - if (local_return == 0) return; - - // The server suppresses a couple of error messages caused by rogue clients or spiders. - // The reason for suppressing them is to prevent them from flooding the Journal. - if (server) { - // SSL - Processing of the ClientHello handshake message failed (-30976) - if (local_return == MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) return; - // SSL - The connection indicated an EOF (-29312) - if (local_return == MBEDTLS_ERR_SSL_CONN_EOF) return; - // NET - Reading information from the socket failed (-76) - if (local_return == MBEDTLS_ERR_NET_RECV_FAILED) return; - // NET - Connection was reset by peer (-80) - if (local_return == MBEDTLS_ERR_NET_CONN_RESET) return; - } - - // There's an error: Display it. - char error_buf [100]; - mbedtls_strerror (local_return, error_buf, 100); - string msg = error_buf; - msg.append (" ("); - msg.append (filter::strings::convert_to_string (local_return)); - msg.append (")"); - if (error) { - error->assign (msg); - } else { - Database_Logs::log (msg); - } -} - - -// This takes $url, removes any scheme (http / https) it has, -// then sets the correct scheme based on $secure, -// and returns the URL, e.g. as http://localhost or https://localhost. -string filter_url_set_scheme (string url, bool secure) -{ - // Remove whitespace. - url = filter::strings::trim (url); - // Remove amy existing scheme: http(s) or whatever. - size_t pos = url.find ("://"); - if (pos != std::string::npos) { - url.erase (0, pos + 3); - } - // Produce the correct scheme. - string scheme = "http"; - if (secure) scheme.append ("s"); - scheme.append ("://"); - // Insert the scheme. - url = scheme + url; - // Done. - return url; -} - - -// Replace invalid characters in Windows filenames with valid abbreviations. -string filter_url_clean_filename (string name) -{ - name = filter::strings::replace ("\\", "b2", name); - name = filter::strings::replace ("/", "sl", name); - name = filter::strings::replace (":", "co", name); - name = filter::strings::replace ("*", "as", name); - name = filter::strings::replace ("?", "qu", name); - name = filter::strings::replace ("\"", "ba", name); - name = filter::strings::replace ("<", "sm", name); - name = filter::strings::replace (">", "la", name); - name = filter::strings::replace ("|", "ve", name); - return name; -} - - -// Replace invalid characters in Windows filenames with valid abbreviations. -// In contrast with the above function, the $name in this function can be "uncleaned" again. -// The next function does the "unclean" operation, to get the original $name back. -string filter_url_filename_clean (string name) -{ - name = filter::strings::replace ("\\", "___b2___", name); - name = filter::strings::replace ("/", "___sl___", name); - name = filter::strings::replace (":", "___co___", name); - name = filter::strings::replace ("*", "___as___", name); - name = filter::strings::replace ("?", "___qu___", name); - name = filter::strings::replace ("\"", "___ba___", name); - name = filter::strings::replace ("<", "___sm___", name); - name = filter::strings::replace (">", "___la___", name); - name = filter::strings::replace ("|", "___ve___", name); - return name; -} - - -// Take $name, and undo the "clean" function in the above. -string filter_url_filename_unclean (string name) -{ - name = filter::strings::replace ("___b2___", "\\", name); - name = filter::strings::replace ("___sl___", "/", name); - name = filter::strings::replace ("___co___", ":", name); - name = filter::strings::replace ("___as___", "*", name); - name = filter::strings::replace ("___qu___", "?", name); - name = filter::strings::replace ("___ba___", "\"", name); - name = filter::strings::replace ("___sm___", "<", name); - name = filter::strings::replace ("___la___", ">", name); - name = filter::strings::replace ("___ve___", "|", name); - return name; -} - - -// Changes a Unix directory separator to a Windows one. -// Works on Windows only. -string filter_url_update_directory_separator_if_windows (string filename) -{ -#ifdef HAVE_WINDOWS - filename = filter::strings::replace ("/", DIRECTORY_SEPARATOR, filename); -#endif - return filename; -} - - -// Returns true if it is possible to connect to port $port on $hostname. -bool filter_url_port_can_connect (string hostname, int port) -{ - // Resolve the host. - addrinfo hints; - addrinfo * address_results {nullptr}; - bool address_info_resolved {false}; - memset (&hints, 0, sizeof (addrinfo)); - // Allow IPv4 and IPv6. - hints.ai_family = AF_UNSPEC; - // TCP/IP socket. - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = 0; - // Select protocol that matches with the socket type. - hints.ai_protocol = 0; - // The 'service' is actually the port number. - string service = filter::strings::convert_to_string (port); - // Get a list of address structures. There can be several of them. - int res = getaddrinfo (hostname.c_str(), service.c_str (), &hints, &address_results); - if (res != 0) return false; - // Result of the text. - bool connected {false}; - // Iterate over the list of address structures. - vector errors {}; - addrinfo * rp {nullptr}; - for (rp = address_results; rp != nullptr; rp = rp->ai_next) { - // Try to get a socket for this address structure. - int sock = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol); - // If it fails, try the next one. - if (sock < 0) continue; - // Try to connect. - int res2 = connect (sock, rp->ai_addr, rp->ai_addrlen); - // If connected, set the flag. - if (res2 != -1) connected = true; - // Socket should be closed. - if (sock) { - #ifdef HAVE_WINDOWS - closesocket (sock); - #else - close (sock); - #endif - } - // If connected: Done. - if (connected) break; - } - // No longer needed: Only to be freed when the address was resolved. - if (address_info_resolved) freeaddrinfo (address_results); - // Done. - return connected; -} - - -bool filter_url_is_image (string extension) -{ - if (extension == "png") return true; - - if (extension == "gif") return true; - - if (extension == "jpg") return true; - - if (extension == "svg") return true; - - // Default: It is not an image. - return false; -} - - -// Source: -// https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types -// See also: -// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types -string filter_url_get_mime_type (string extension) -{ - static map mime_types = { - {"jar", "application/java-archive"}, - {"js", "application/javascript"}, - {"json", "application/json"}, - {"pdf", "application/pdf"}, - {"odt", "application/vnd.oasis.opendocument.text"}, - {"xml", "application/xml"}, - {"zip", "application/zip"}, - {"otf", "font/otf"}, - {"ttf", "application/font-sfnt"}, - {"woff", "application/font-woff"}, - {"bmp", "image/bmp"}, // Windows OS/2 Bitmap Graphics - {"gif", "image/gif"}, // Graphics Interchange Format - {"jpe", "image/jpeg"}, // JPEG images - {"jpg", "image/jpeg"}, // JPEG images - {"jpeg", "image/jpeg"}, // JPEG images - {"png", "image/png"}, // Portable Network Graphics - {"svgz", "image/svg+xml"}, - {"svg", "image/svg+xml"}, // Scalable Vector Graphics - {"tif", "image/tiff"}, // Tagged Image File Format - {"tiff", "image/tiff"}, // Tagged Image File Format - {"ico", "image/vnd.microsoft.icon"}, // Icon format - {"css", "text/css"}, - {"csv", "text/csv"}, - {"htm", "text/html"}, - {"html", "text/html"}, - {"txt", "text/plain"}, - {"usfm", "text/plain"}, - {"webp", "image/webp"}, // WEBP image - }; - return mime_types [extension]; -} - - -// Read the URL, and split it up in three parts: The scheme, the host, and the port. -// For example: "https://bibledit.org:8080" will be split up into this: -// - https -// - bibledit.org -// - 8080 -// If any of these three parts is not found, then the part is left empty, or the port remains 0. -void filter_url_get_scheme_host_port (string url, string & scheme, string & host, int & port) -{ - // Clear the values that are going to be detected. - scheme.clear(); - host.clear(); - port = 0; - - // Extract the scheme: http(s). - size_t pos = url.find ("://"); - if (pos != std::string::npos) { - scheme = url.substr(0, pos); - url.erase (0, pos + 3); - } - - // Extract the host. - pos = url.find (":"); - if (pos == std::string::npos) pos = url.find ("/"); - if (pos == std::string::npos) pos = url.length () + 1; - host = url.substr (0, pos); - url.erase (0, host.length ()); - - // Extract the port number if any. - pos = url.find (":"); - if (pos != std::string::npos) { - url.erase (0, 1); - size_t pos2 = url.find ("/"); - if (pos2 == std::string::npos) pos2 = url.length () + 1; - string p = url.substr (0, pos2); - port = filter::strings::convert_to_int (p); - url.erase (0, p.length ()); - } -} diff --git a/filter/url.h b/filter/url.h deleted file mode 100644 index 75adc1256..000000000 --- a/filter/url.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string get_base_url (Webserver_Request& webserver_request); -void redirect_browser (Webserver_Request& webserver_request, std::string url); -std::string filter_url_dirname (std::string url); -std::string filter_url_dirname_web (std::string url); -std::string filter_url_basename (std::string url); -std::string filter_url_basename_web (std::string url); -void filter_url_unlink (std::string filename); -void filter_url_rename (const std::string& oldfilename, const std::string& newfilename); -std::string filter_url_create_path (const std::vector& parts); -std::string filter_url_create_root_path (const std::vector& parts); -std::string filter_url_get_extension (std::string url); -bool file_or_dir_exists (std::string url); -void filter_url_mkdir (std::string directory); -void filter_url_rmdir (std::string directory); -bool filter_url_is_dir (std::string path); -bool filter_url_get_write_permission (std::string path); -void filter_url_set_write_permission (std::string path); -std::string filter_url_file_get_contents (std::string filename); -void filter_url_file_put_contents (std::string filename, std::string contents); -void filter_url_file_put_contents_append (std::string filename, std::string contents); -bool filter_url_file_cp (std::string input, std::string output); -void filter_url_dir_cp (const std::string & input, const std::string & output); -int filter_url_filesize (std::string filename); -std::vector filter_url_scandir (std::string folder); -void filter_url_recursive_scandir (std::string folder, std::vector & paths); -int filter_url_file_modification_time (std::string filename); -std::string filter_url_urldecode (std::string url); -std::string filter_url_urlencode (std::string url); -const char * filter_url_temp_dir (); -std::string filter_url_tempfile (const char * directory = nullptr); -std::string filter_url_escape_shell_argument (std::string argument); -std::string filter_url_unique_path (std::string path); -bool filter_url_email_is_valid (std::string email); -std::string filter_url_build_http_query (std::string url, const std::string& parameter, const std::string& value); -std::string filter_url_http_get (std::string url, std::string& error, bool check_certificate); -std::string filter_url_http_post (const std::string & url, std::string post_data, const std::map & post_values, std::string& error, bool burst, bool check_certificate, const std::vector > & headers); -std::string filter_url_http_upload (std::string url, std::map values, std::string filename, std::string& error); -std::string filter_url_http_response_code_text (int code); -void filter_url_download_file (std::string url, std::string filename, std::string& error, bool check_certificate); -std::string filter_url_html_file_name_bible (std::string path = "", int book = 0, int chapter = -1); -int filter_url_curl_debug_callback (void *curl_handle, int curl_info_type, char *data, size_t size, void *userptr); -void filter_url_curl_set_timeout (void *curl_handle, bool burst = false); -std::string filter_url_plus_to_tag (std::string data); -std::string filter_url_tag_to_plus (std::string data); -std::string filter_url_remove_username_password (std::string url); -std::string filter_url_http_request_mbed (std::string url, std::string& error, const std::map & post, const std::string& filename, bool check_certificate); -void filter_url_ssl_tls_initialize (); -void filter_url_ssl_tls_finalize (); -void filter_url_display_mbed_tls_error (int & ret, std::string * error, bool server); -std::string filter_url_set_scheme (std::string url, bool secure); -std::string filter_url_clean_filename (std::string name); -std::string filter_url_filename_clean (std::string name); -std::string filter_url_filename_unclean (std::string name); -std::string filter_url_update_directory_separator_if_windows (std::string filename); -bool filter_url_port_can_connect (std::string hostname, int port); -bool filter_url_is_image (std::string extension); -std::string filter_url_get_mime_type (std::string extension); -void filter_url_get_scheme_host_port (std::string url, std::string & scheme, std::string & host, int & port); - diff --git a/filter/usfm.cpp b/filter/usfm.cpp deleted file mode 100644 index 4572ff669..000000000 --- a/filter/usfm.cpp +++ /dev/null @@ -1,1054 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -using namespace std; -using namespace pugi; - - -namespace filter::usfm { - - -BookChapterData::BookChapterData (int book, int chapter, string data) -{ - m_book = book; - m_chapter = chapter; - m_data = data; -} - - -// Returns the string $usfm as one long string. -// $usfm may contain new lines, but the resulting long string won't. -string one_string (string usfm) -{ - string long_string = ""; - vector usfm_lines = filter::strings::explode (usfm, '\n'); - for (string & line : usfm_lines) { - line = filter::strings::trim (line); - // Skip empty line. - if (line != "") { - // The line will be appended to the output line. - // If it does not start with a backslash (\), a space is inserted first. - size_t pos = line.find ("\\"); - if (pos != 0) { - if (long_string != "") long_string += " "; - } - long_string += line; - } - } - return long_string; -} - - -// Returns the string $code as an array alternating between marker and text. -// Example, input is: \id GEN -// \c 10 -// ... -// Output would be: array ("\id ", "GEN", "\c ", "10", ...) -// If $code does not start with a marker, this becomes visible in the output too. -vector get_markers_and_text (string code) -{ - vector markers_and_text; - code = filter::strings::replace ("\n\\", "\\", code); // New line followed by backslash: leave new line out. - code = filter::strings::replace ("\n", " ", code); // New line only: change to space, according to the USFM specification. - // No removal of double spaces, because it would remove an opening marker (which already has its own space), followed by a space. - code = filter::strings::trim (code); - while (!code.empty ()) { - size_t pos = code.find ("\\"); - if (pos == 0) { - // Marker found. - // The marker ends - // - after the first space, or - // - after the first asterisk (*), or - // - at the first backslash (\), or - // - at the end of the string, - // whichever comes first. - vector positions; - pos = code.find (" "); - if (pos != std::string::npos) positions.push_back (pos + 1); - pos = code.find ("*"); - if (pos != std::string::npos) positions.push_back (pos + 1); - pos = code.find ("\\", 1); - if (pos != std::string::npos) positions.push_back (pos); - positions.push_back (code.length()); - sort (positions.begin (), positions.end()); - pos = positions[0]; - string marker = code.substr (0, pos); - markers_and_text.push_back (marker); - code = code.substr (pos); - } else { - // Text found. It ends at the next backslash or at the end of the string. - pos = code.find ("\\"); - if (pos == std::string::npos) pos = code.length(); - string text = code.substr (0, pos); - markers_and_text.push_back (text); - code = code.substr (pos); - } - } - return markers_and_text; -} - - -// Gets the marker from $usfm if it is there, else returns an empty string. -// Examples: -// "\id" -> "id" -// "\id " -> "id" -// "\add*" -> "add" -// "\+add*" -> "add" -string get_marker (string usfm) -{ - if (usfm.empty ()) return usfm; - size_t pos = usfm.find ("\\"); - if (pos == 0) { - // Marker found. - // Erase backslash. - usfm = usfm.substr (1); - // Optionally erase the + embedded marker. - pos = usfm.find ("+"); - if (pos == 0) usfm = usfm.substr (1); - // The marker ends - // - at the first space, or - // - at the first asterisk (*), or - // - at the first backslash (\), or - // - at the end of the string, - // whichever comes first. - vector positions; - pos = usfm.find (" "); - if (pos != std::string::npos) positions.push_back (pos); - pos = usfm.find ("*"); - if (pos != std::string::npos) positions.push_back (pos); - pos = usfm.find ("\\"); - if (pos != std::string::npos) positions.push_back (pos); - positions.push_back (usfm.length()); - sort (positions.begin(), positions.end()); - pos = positions[0]; - string marker = usfm.substr (0, pos); - return marker; - } - // Text found. No marker. - return ""; -} - - -// This imports USFM $input. -// It takes raw $input, -// and returns a vector with objects with book_number, chapter_number, chapter_data. -vector usfm_import (string input, string stylesheet) -{ - vector result; - - book_id bookid {0}; - int chapter_number {0}; - string chapter_data {}; - - input = one_string (input); - vector markers_and_text = get_markers_and_text (input); - bool retrieve_book_number_on_next_iteration = false; - bool retrieve_chapter_number_on_next_iteration = false; - - for (string marker_or_text : markers_and_text) { - if (retrieve_book_number_on_next_iteration) { - bookid = database::books::get_id_from_usfm (marker_or_text.substr (0, 3)); - chapter_number = 0; - retrieve_book_number_on_next_iteration = false; - } - if (retrieve_chapter_number_on_next_iteration) { - retrieve_chapter_number_on_next_iteration = false; - chapter_number = filter::strings::convert_to_int (marker_or_text); - } - string marker = get_marker (marker_or_text); - if (!marker.empty()) { - // USFM marker found. - bool opener = is_opening_marker (marker_or_text); - bool store_chapter_data = false; - if (marker == "id") { - retrieve_book_number_on_next_iteration = true; - store_chapter_data = true; - } - if (marker == "c") { - retrieve_chapter_number_on_next_iteration = true; - store_chapter_data = true; - } - if (store_chapter_data) { - chapter_data = filter::strings::trim (chapter_data); - if (!chapter_data.empty()) result.push_back ( { static_cast(bookid), chapter_number, chapter_data } ); - chapter_number = 0; - chapter_data = ""; - store_chapter_data = false; - } - Database_Styles database_styles; - Database_Styles_Item marker_data = database_styles.getMarkerData (stylesheet, marker); - int type = marker_data.type; - int subtype = marker_data.subtype; - // Only opening markers can start on a new line. - // Closing markers never do. - if (opener) { - if (styles_logic_starts_new_line_in_usfm (type, subtype)) { - chapter_data.append ("\n"); - } - } - } - chapter_data += marker_or_text; - } - chapter_data = filter::strings::trim (chapter_data); - if (!chapter_data.empty()) result.push_back (BookChapterData (static_cast(bookid), chapter_number, chapter_data)); - return result; -} - - -// Returns an array with the verse numbers found in $usfm. -// It handles a single verse, a range of verses, or a sequence of verses. -// It locates separate whole verse numbers. -// Examples: -// 10 -// 10-12b -// 10,11a -// 10,12 -vector get_verse_numbers (string usfm) -{ - vector verse_numbers = { 0 }; - vector markers_and_text = get_markers_and_text (usfm); - bool extract_verse = false; - for (string marker_or_text : markers_and_text) { - if (extract_verse) { - string verse = peek_verse_number (marker_or_text); - // Range of verses. - if (handle_verse_range (verse, verse_numbers)); - // Sequence of verses. - else if (handle_verse_sequence (verse, verse_numbers)); - // Single verse. - else verse_numbers.push_back (filter::strings::convert_to_int (verse)); - extract_verse = false; - } - if (marker_or_text.substr (0, 2) == marker_v ()) extract_verse = true; - string va_or_vp = marker_or_text.substr (0, 3); - if (va_or_vp == marker_va ()) extract_verse = false; - if (va_or_vp == marker_vp ()) extract_verse = false; - } - return verse_numbers; -} - - -// Returns the chapter numbers found in $usfm. -vector get_chapter_numbers (string usfm) -{ - vector chapter_numbers = { 0 }; - vector markers_and_text = get_markers_and_text (usfm); - bool extract_chapter = false; - for (string marker_or_text : markers_and_text) { - if (extract_chapter) { - string chapter = peek_verse_number (marker_or_text); - chapter_numbers.push_back (filter::strings::convert_to_int (chapter)); - extract_chapter = false; - } - if (marker_or_text.substr (0, 2) == "\\c") { - extract_chapter = true; - } - } - return chapter_numbers; -} - - -// Returns the verse numbers in the string of $usfm code at line number $line_number. -vector linenumber_to_versenumber (string usfm, unsigned int line_number) -{ - vector verse_number = {0}; // Initial verse number. - vector lines = filter::strings::explode (usfm, '\n'); - for (unsigned int i = 0; i < lines.size(); i++) { - if (i <= line_number) { - vector verse_numbers = get_verse_numbers (lines[i]); - if (verse_numbers.size() >= 2) { - verse_number = filter::strings::array_diff (verse_numbers, {0}); - } - } - } - return verse_number; -} - - -// Returns the verse numbers in the string of $usfm code at offset $offset. -// Offset is calculated with filter::strings::unicode_string_length to support UTF-8. -vector offset_to_versenumber (string usfm, unsigned int offset) -{ - size_t totalOffset = 0; - vector lines = filter::strings::explode (usfm, '\n'); - for (unsigned i = 0; i < lines.size(); i++) { - size_t length = filter::strings::unicode_string_length (lines [i]); - totalOffset += length; - if (totalOffset >= offset) { - return linenumber_to_versenumber (usfm, i); - } - // Add 1 for new line. - totalOffset += 1; - } - return {0}; -} - - - -// Returns the offset within the $usfm code where $verse number starts. -int versenumber_to_offset (string usfm, int verse) -{ - // Verse number 0 starts at offset 0. - if (verse == 0) return 0; - int totalOffset = 0; - vector lines = filter::strings::explode (usfm, '\n'); - for (string line : lines) { - vector verses = get_verse_numbers (line); - for (auto & v : verses) { - if (v == verse) return totalOffset; - } - totalOffset += static_cast( filter::strings::unicode_string_length (line)); - // Add 1 for new line. - totalOffset += 1; - } - return static_cast( filter::strings::unicode_string_length (usfm)); -} - - -// Returns the verse text given a $verse_number and $usfm code. -// Handles combined verses. -string get_verse_text (string usfm, int verse_number) -{ - vector result; - bool hit = (verse_number == 0); - - vector lines = filter::strings::explode (usfm, '\n'); - for (string line : lines) { - vector verses = get_verse_numbers (line); - if (verse_number == 0) { - if (verses.size () != 1) hit = false; - if (hit) result.push_back (line); - } else { - if (in_array (verse_number, verses)) { - // Desired verse found. - hit = true; - } else if (verses.size () == 1) { - // No verse found: No change in situation. - } else { - // Outside desired verse. - hit = false; - } - if (hit) result.push_back (line); - } - } - - // Return the verse text. - string verseText = filter::strings::implode (result, "\n"); - return verseText; -} - - -// Gets the USFM for the $verse number for a Quill-based verse editor. -// This means that preceding empty paragraphs will be included also. -// And that empty paragraphs at the end will be omitted. -string get_verse_text_quill (string usfm, int verse) -{ - // Get the raw USFM for the verse, that is, the bit between the \v... markers. - string raw_verse_usfm = get_verse_text (usfm, verse); - - // Bail out if empty. - if (raw_verse_usfm.empty ()) { - return raw_verse_usfm; - } - - // Omit new paragraphs at the end. - // In this context it is taken as opening USFM markers without content. - string verse_usfm (raw_verse_usfm); - vector markers_and_text = get_markers_and_text (verse_usfm); - while (true) { - if (markers_and_text.empty ()) break; - string code = markers_and_text.back (); - markers_and_text.pop_back (); - if (!is_usfm_marker (code)) break; - if (!is_opening_marker (code)) break; - verse_usfm.erase (verse_usfm.size () - code.size ()); - verse_usfm = filter::strings::trim (verse_usfm); - if (verse_usfm.empty ()) break; - } - - // Bail out if empty USFM for the verse. - if (verse_usfm.empty ()) { - return verse_usfm; - } - - // Get the raw USFM for the previous verse for verses greater than 0, in the same way. - // Any empty paragraphs at the end of the previous verse USFM, - // add them to the current verse's USFM. - if (verse) { - string previous_verse_usfm = get_verse_text (usfm, verse - 1); - // For combined verses: The raw USFM fragments should differ to make sense. - if (previous_verse_usfm != raw_verse_usfm) { - if (!previous_verse_usfm.empty ()) { - markers_and_text = get_markers_and_text (previous_verse_usfm); - while (true) { - if (markers_and_text.empty ()) break; - string code = markers_and_text.back (); - markers_and_text.pop_back (); - if (!is_usfm_marker (code)) break; - if (!is_opening_marker (code)) break; - verse_usfm.insert (0, code + "\n"); - } - } - } - } - - // Done. - return verse_usfm; -} - - -// Gets the chapter text given a book of $usfm code, and the $chapter_number. -string get_chapter_text (string usfm, int chapter_number) -{ - // Empty input: Ready. - if (usfm.empty ()) return usfm; - - // Remove the part of the USFM that precedes the chapter fragment. - if (chapter_number) { - // Normal chapter marker (new line after the number). - bool found = false; - string marker = get_opening_usfm ("c", false) + filter::strings::convert_to_string (chapter_number) + "\n"; - size_t pos = usfm.find (marker); - // Was the chapter found? - if (pos != std::string::npos) { - found = true; - usfm.erase (0, pos); - } - // Unusual chapter marker (space after the number). - marker = get_opening_usfm ("c", false) + filter::strings::convert_to_string (chapter_number) + " "; - pos = usfm.find (marker); - if (pos != std::string::npos) { - found = true; - usfm.erase (0, pos); - } - // Another observed unusual situation: A non-breaking space after the chapter number. - marker = get_opening_usfm ("c", false) + filter::strings::convert_to_string (chapter_number) + filter::strings::non_breaking_space_u00A0 (); - pos = usfm.find (marker); - if (pos != std::string::npos) { - found = true; - usfm.erase (0, pos); - } - - // Starting chapter markup not found: Non-existing chapter. - if (!found) return ""; - } - - // Look for any next chapter marker. - size_t pos = usfm.find (get_opening_usfm ("c", false), 1); - if (pos != std::string::npos) { - usfm.erase (pos); - } - - // Clean up. - usfm = filter::strings::trim (usfm); - - // Done. - return usfm; -} - - -// Returns the USFM text for a range of verses for the input $usfm code. -// It handles combined verses. -// It ensures that the $exclude_usfm does not make it to the output of the function. -// In case of $quill, it uses a routine optimized for a Quill-based editor. -// This means that empty paragraphs at the end of the extracted USFM fragment are not included. -string get_verse_range_text (string usfm, int verse_from, int verse_to, const string& exclude_usfm, bool quill) -{ - vector bits; - string previous_usfm; - for (int vs = verse_from; vs <= verse_to; vs++) { - string verse_usfm; - if (quill) verse_usfm = get_verse_text_quill (usfm, vs); - else verse_usfm = get_verse_text (usfm, vs); - // Do not include repeating USFM in the case of combined verse numbers in the input USFM code. - if (verse_usfm == previous_usfm) continue; - if (!verse_usfm.empty () && !previous_usfm.empty ()) { - if (verse_usfm.find (previous_usfm) != std::string::npos) continue; - if (previous_usfm.find (verse_usfm) != std::string::npos) continue; - } - previous_usfm = verse_usfm; - // In case of combined verses, the excluded USFM should not be included in the result. - if (verse_usfm == exclude_usfm) continue; - if (!verse_usfm.empty () && !exclude_usfm.empty ()) { - if (verse_usfm.find (exclude_usfm) != std::string::npos) continue; - if (exclude_usfm.find (verse_usfm) != std::string::npos) continue; - } - bits.push_back (verse_usfm); - } - usfm = filter::strings::implode (bits, "\n"); - return usfm; -} - - -// Returns true if the $code contains a USFM marker. -bool is_usfm_marker (string code) -{ - if (code.length () < 2) return false; - if (code.substr (0, 1) == "\\") return true; - return false; -} - - -// Returns true if the marker in $usfm is an opening marker. -// Else it returns false. -bool is_opening_marker (string usfm) -{ - return usfm.find ("*") == std::string::npos; -} - - -// Returns true if the marker in $usfm is an embedded marker. -// Else it returns false. -bool is_embedded_marker (string usfm) -{ - return usfm.find ( "+") != std::string::npos; -} - - -// Returns the USFM book identifier. -// $usfm: array of strings alternating between USFM code and subsequent text. -// $pointer: if increased by one, it should point to the \id in $usfm. -string get_book_identifier (const vector & usfm, unsigned int pointer) -{ - string identifier = "XXX"; // Fallback value. - if (++pointer < usfm.size ()) { - identifier = usfm[pointer].substr (0, 3); - } - return identifier; -} - - -// Returns the text that follows a USFM marker. -// $usfm: array of strings alternating between USFM code and subsequent text. -// $pointer: should point to the marker in $usfm. It gets increased by one. -string get_text_following_marker (const vector & usfm, unsigned int & pointer) -{ - string text = ""; // Fallback value. - ++pointer; - if (pointer < usfm.size()) { - text = usfm [pointer]; - } - return text; -} - - -// Returns the text that follows a USFM marker. -// $usfm: array of strings alternating between USFM code and subsequent text. -// $pointer: should point to the marker in $usfm. Pointer is left as it is. -string peek_text_following_marker (const vector & usfm, unsigned int pointer) -{ - return get_text_following_marker (usfm, pointer); -} - - -// Returns the verse number in the $usfm code. -string peek_verse_number (string usfm) -{ - // Make it robust, even handling cases like \v 1-2“Moi - No space after verse number. - string verseNumber = ""; - size_t usfmStringLength = usfm.length (); - unsigned int i = 0; - for (i = 0; i < usfmStringLength; i++) { - string character = usfm.substr (i, 1); - if (character == "0") continue; - if (character == "1") continue; - if (character == "2") continue; - if (character == "3") continue; - if (character == "4") continue; - if (character == "5") continue; - if (character == "6") continue; - if (character == "7") continue; - if (character == "8") continue; - if (character == "9") continue; - if (character == ",") continue; - if (character == "-") continue; - if (character == "a") continue; - if (character == "b") continue; - break; - } - verseNumber = usfm.substr (0, i); - verseNumber = filter::strings::trim (verseNumber); - return verseNumber; -} - - -// Takes a marker in the form of text only, like "id" or "add", -// and converts it into opening USFM, like "\id " or "\add ". -// Supports the embedded markup "+". -string get_opening_usfm (string text, bool embedded) -{ - string embed = embedded ? "+" : ""; - return "\\" + embed + text + " "; -} - - -// Takes a marker in the form of text only, like "add", -// and converts it into closing USFM, like "\add*". -// Supports the embedded markup "+". -string get_closing_usfm (string text, bool embedded) -{ - string embed = embedded ? "+" : ""; - return "\\" + embed + text + "*"; -} - - -// This function compares the $newtext with the $oldtext. -// It returns an empty string if the difference is below the limit set for the Bible. -// It returns a short message specifying the difference if it exceeds that limit. -// It fills $explanation with a longer message in case saving is not safe. -string save_is_safe (Webserver_Request& webserver_request, - string oldtext, string newtext, bool chapter, string & explanation) -{ - // Two texts are equal: safe. - if (newtext == oldtext) return string(); - - const char * explanation1 = "The text was not saved for safety reasons."; - const char * explanation2 = "Make fewer changes at a time and wait till the editor has saved the text. Or relax the restriction in the editing settings. See menu Settings - Preferences."; - - // Allowed percentage difference. - int allowed_percentage = 0; - if (chapter) - allowed_percentage = webserver_request.database_config_user ()->getEditingAllowedDifferenceChapter (); - else - allowed_percentage = webserver_request.database_config_user ()->getEditingAllowedDifferenceVerse (); - - // When the verse editor has an empty verse, it should allow for 100% change. - // Same for the chapter editor, if it has empty verses, allow for a 100% change. - // This is useful for filling in empty verses. - if (chapter) { - if (oldtext.length () < 50) allowed_percentage = 100; - } else { - if (oldtext.length () < 10) allowed_percentage = 100; - } - - // When the new text is longer than the old text, it means the user is typing extra text in the verse. - // Allow that in all cases. - if (newtext.length() > oldtext.length()) allowed_percentage = 100; - - // The length of the new text should not differ more than a set percentage from the old text. - float existingLength = static_cast (oldtext.length()); - float newLength = static_cast (newtext.length ()); - int percentage = static_cast (100 * (newLength - existingLength) / existingLength); - percentage = abs (percentage); - if (percentage > 100) percentage = 100; - if (percentage > allowed_percentage) { - explanation.append (explanation1); - explanation.append (" "); - explanation.append ("The length differs " + filter::strings::convert_to_string (percentage) + "% from the existing text."); - explanation.append (" "); - explanation.append (explanation2); - Database_Logs::log (explanation + "\n" + newtext); - return translate ("Text length differs too much"); - } - - // The new text should be at least a set percentage similar to the old text. - if (chapter) { - // For larger texts, work at the word level, for much better performance. - // The time it takes to calculate the difference was measured: - // character level: 327421 microseconds. - // word level: 489 microseconds. - // Doing it at the word level is more than 650 times faster. - percentage = filter_diff_word_similarity (oldtext, newtext); - } else { - // For shorter texts, work at the character level, for better accuracy. - percentage = filter_diff_character_similarity (oldtext, newtext); - } - if (percentage < (100 - allowed_percentage)) { - explanation.append (explanation1); - explanation.append (" "); - explanation.append ("The new text is " + filter::strings::convert_to_string (percentage) + "% similar to the existing text."); - explanation.append (" "); - explanation.append (explanation2); - Database_Logs::log (explanation + "\n" + newtext); - return translate ("Text content differs too much"); - } - - // Safety checks have passed. - return ""; -} - - -// Function to safely store a chapter. -// It saves the chapter if the new USFM does not differ too much from the existing USFM. -// On success it returns an empty string. -// On failure it returns the reason of the failure. -// This function proves useful in cases that the text in the Bible editor gets corrupted -// due to human error. -// It also is useful in cases where the session is deleted from the server, -// where the text in the editors would get corrupted. -// It also is useful in view of an unstable connection between browser and server, to prevent data corruption. -string safely_store_chapter (Webserver_Request& webserver_request, - string bible, int book, int chapter, string usfm, string & explanation) -{ - // Existing chapter contents. - string existing = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - // Bail out if the existing chapter equals the USFM to be saved. - if (usfm == existing) return ""; - - // Safety check. - string message = save_is_safe (webserver_request, existing, usfm, true, explanation); - if (!message.empty ()) return message; - - // Record the change in the journal. - string user = webserver_request.session_logic ()->currentUser (); - bible_logic::log_change (bible, book, chapter, usfm, user, translate ("Saving chapter"), false); - - // Safety checks have passed: Save chapter. - bible_logic::store_chapter (bible, book, chapter, usfm); - return ""; -} - - -// Function to safely store a verse. -// It saves the verse if the new USFM does not differ too much from the existing USFM. -// On success it returns an empty message. -// On failure it returns a message that specifies the reason why it could not be saved. -// This function proves useful in cases that the text in the Bible editor gets corrupted due to human error. -// It also is useful in cases where the session is deleted from the server, - // where the text in the editors would get corrupted. -// It also is useful in view of an unstable connection between browser and server, to prevent data corruption. -// It handles combined verses. -string safely_store_verse (Webserver_Request& webserver_request, - string bible, int book, int chapter, int verse, string usfm, - string & explanation, bool quill) -{ - usfm = filter::strings::trim (usfm); - - // Check that the USFM to be saved is for the correct verse. - vector save_verses = get_verse_numbers (usfm); - if ((verse != 0) && !save_verses.empty ()) { - save_verses.erase (save_verses.begin()); - } - if (save_verses.empty ()) { - explanation = "The USFM contains no verse information"; - Database_Logs::log (explanation + ": " + usfm); - return translate ("Missing verse number"); - } - if (!in_array (verse, save_verses)) { - vector vss; - for (auto vs : save_verses) vss.push_back (filter::strings::convert_to_string (vs)); - explanation = "The USFM contains verse(s) " + filter::strings::implode (vss, " ") + " while it wants to save to verse " + filter::strings::convert_to_string (verse); - Database_Logs::log (explanation + ": " + usfm); - return translate ("Verse mismatch"); - } - - // Get the existing chapter USFM. - string chapter_usfm = webserver_request.database_bibles()->get_chapter (bible, book, chapter); - - // Get the existing USFM fragment for the verse to save. - string existing_verse_usfm; - if (quill) existing_verse_usfm = get_verse_text_quill (chapter_usfm, verse); - else existing_verse_usfm = get_verse_text (chapter_usfm, verse); - existing_verse_usfm = filter::strings::trim (existing_verse_usfm); - - // Check that there is a match between the existing verse numbers and the verse numbers to save. - vector existing_verses = get_verse_numbers (existing_verse_usfm); - save_verses = get_verse_numbers (usfm); - bool verses_match = true; - if (save_verses.size () == existing_verses.size ()) { - for (unsigned int i = 0; i < save_verses.size (); i++) { - if (save_verses [i] != existing_verses [i]) - verses_match = false; - } - } else { - verses_match = false; - } - if (!verses_match) { - vector existing, save; - for (auto vs : existing_verses) existing.push_back (filter::strings::convert_to_string (vs)); - for (auto vs : save_verses) save.push_back (filter::strings::convert_to_string (vs)); - explanation = "The USFM contains verse(s) " + filter::strings::implode (save, " ") + " which would overwrite a fragment that contains verse(s) " + filter::strings::implode (existing, " "); - Database_Logs::log (explanation + ": " + usfm); - return translate ("Cannot overwrite another verse"); - } - - // Bail out if the new USFM is the same as the existing. - if (usfm == existing_verse_usfm) { - return ""; - } - - // Check maximum difference between new and existing USFM. - string message = save_is_safe (webserver_request, existing_verse_usfm, usfm, false, explanation); - if (!message.empty ()) return message; - - // Store the new verse USFM in the existing chapter USFM. - size_t pos = chapter_usfm.find (existing_verse_usfm); - size_t length = existing_verse_usfm.length (); - if (pos == std::string::npos) { - explanation = "Cannot find the exact location in the chapter where to save this USFM fragment"; - Database_Logs::log (explanation + ": " + usfm); - return translate ("Doesn't know where to save"); - } - chapter_usfm.erase (pos, length); - chapter_usfm.insert (pos, usfm); - - // Record the change in the journal. - string user = webserver_request.session_logic ()->currentUser (); - bible_logic::log_change (bible, book, chapter, chapter_usfm, user, translate ("Saving verse"), false); - - // Safety checks have passed: Save chapter. - bible_logic::store_chapter (bible, book, chapter, chapter_usfm); - - // Done: OK. - return ""; -} - - -// Returns whether $usfm contains one or more empty verses. -bool contains_empty_verses (string usfm) -{ - usfm = filter::strings::replace ("\n", "", usfm); - if (usfm.empty ()) return false; - for (int i = 0; i <= 9; i++) { - usfm = filter::strings::replace (filter::strings::convert_to_string (i), "", usfm); - } - if (usfm.empty ()) return false; - usfm = filter::strings::replace (" ", "", usfm); - if (usfm.empty ()) return false; - size_t pos = usfm.find ("\\v\\v"); - if (pos != std::string::npos) return true; - pos = usfm.find ("\\v \\v"); - if (pos != std::string::npos) return true; - pos = usfm.find_last_of (marker_v ()); - if (pos == usfm.length () - 1) return true; - return false; -} - - -// This looks at the $fragment, whether it's a range of verses. -// If so, it puts the all of the verses in $verses, and returns true. -bool handle_verse_range (string verse, vector & verses) -{ - if (verse.find ("-") != std::string::npos) { - size_t position; - position = verse.find ("-"); - string start_range, end_range; - start_range = verse.substr (0, position); - verse.erase (0, ++position); - end_range = verse; - int start_verse_i = filter::strings::convert_to_int(filter::strings::number_in_string(start_range)); - int end_verse_i = filter::strings::convert_to_int(filter::strings::number_in_string(end_range)); - for (int i = start_verse_i; i <= end_verse_i; i++) { - if (i == start_verse_i) - verses.push_back (filter::strings::convert_to_int (start_range)); - else if (i == end_verse_i) - verses.push_back (filter::strings::convert_to_int (end_range)); - else - verses.push_back (i); - } - return true; - } - return false; -} - - -// This looks at the $fragment, whether it's a sequence of verses. -// If so, it puts the all of the verses in $verses, and returns true. -bool handle_verse_sequence (string verse, vector & verses) -{ - if (verse.find (",") != std::string::npos) { - int iterations = 0; - do { - // In case of an unusual range formation, do not hang. - iterations++; - if (iterations > 50) { - break; - } - size_t position = verse.find (","); - string vs; - if (position == std::string::npos) { - vs = verse; - verse.clear (); - } else { - vs = verse.substr (0, position); - verse.erase(0, ++position); - } - verses.push_back (filter::strings::convert_to_int (vs)); - } while (!verse.empty()); - return true; - } - return false; -} - - -const char * marker_v () -{ - return R"(\v)"; -} - - -const char * marker_va () -{ - return R"(\va)"; -} - - -const char * marker_vp () -{ - return R"(\vp)"; -} - - -// Find and remove the word-level attributes. -// https://ubsicap.github.io/usfm/attributes/index.html -// Example: \+w Lord|strong="H3068"\+w* -// It will dispose of e.g. this: |strong="H3068" -// It handles the default attribute: \w gracious|grace\w* -void remove_word_level_attributes (const string & marker, - vector & container, unsigned int & pointer) -{ - // USFM 3.0 has four markers providing attributes. - // https://ubsicap.github.io/usfm/attributes/index.html. - // Deal with those only, and don't deal with any others. - // Note that the \fig markup is handled elsewhere in this class. - if ((marker != "w") && (marker != "rb") && (marker != "xt")) return; - - // Check the text following this markup whether it contains word-level attributes. - string possible_markup = filter::usfm::peek_text_following_marker (container, pointer); - - // If the markup is too short to contain the required characters, then bail out. - if (possible_markup.length() < 4) return; - - // Look for the vertical bar. If it's not there, bail out. - size_t bar_position = possible_markup.find("|"); - if (bar_position == std::string::npos) return; - - // Remove the fragment and store the remainder back into the object. - possible_markup.erase(bar_position); - container [pointer + 1] = possible_markup; -} - - -// This extracts the attributs for the "fig" markup. -// It supports USFM 3.x. -// https://ubsicap.github.io/usfm/characters/index.html#fig-fig -// That means it is backwards compatible with USFM 1/2: -// \fig DESC|FILE|SIZE|LOC|COPY|CAP|REF\fig* -string extract_fig (string usfm, string & caption, string & alt, string& src, string& size, string& loc, string& copy, string& ref) -{ - // The resulting USFM where the \fig markup has been removed from. - string usfm_out; - - // The string passed in the $usfm variable may contain the \fig..\fig* markup. - // Or it may omit those. - // Handle both cases: Get the USFM fragment within the \fig...\fig* markup. - string marker = "fig"; - - // If the opener is there, it means the \fig markup could be there. - string opener = get_opening_usfm (marker); - size_t pos1 = usfm.find (opener); - if (pos1 != std::string::npos) { - usfm_out.append(usfm.substr(0, pos1)); - usfm.erase (0, pos1 + opener.length()); - // Erase the \fig* closing markup. - string closer = get_closing_usfm(marker); - size_t pos2 = usfm.find(closer); - if (pos2 != std::string::npos) { - usfm_out.append(usfm.substr(pos2 + closer.length())); - usfm.erase(pos2); - } - } else { - usfm_out.assign(usfm); - } - - // Split the bit of USFM between the \fig...\fig* markup on the vertical bar. - vector bits = filter::strings::explode(usfm, '|'); - - // Clear the variables that will contain the extracted information. - caption.clear(); - alt.clear(); - src.clear(); - size.clear(); - loc.clear(); - copy.clear(); - ref.clear(); - - // Handle a situation that there are 7 bits of information. - // That is the situation as used in USFM 1/2.x - // \fig DESC|FILE|SIZE|LOC|COPY|CAP|REF\fig* - if (bits.size() == 7) { - alt = bits[0]; - src = bits[1]; - size = bits[2]; - loc = bits[3]; - copy = bits[4]; - caption = bits[5]; - ref = bits[6]; - } - - // Handle the situation that there are two bits of information. - // This is when there is one vertical bar. - // This is the situation of USFM 3.x. - // https://ubsicap.github.io/usfm/characters/index.html#fig-fig - if (bits.size() == 2) { - caption = bits[0]; - string xml = ""; - xml_document document; - document.load_string (xml.c_str(), parse_ws_pcdata_single); - xml_node node = document.first_child (); - alt = node.attribute ("alt").value (); - src = node.attribute ("src").value (); - size = node.attribute ("size").value (); - loc = node.attribute ("loc").value (); - copy = node.attribute ("copy").value (); - ref = node.attribute ("ref").value (); - } - - // The resulting USFM with the figure markup removed. - return usfm_out; -} - - -// Returns true if the marker is a standard "q." marker. -bool is_standard_q_poetry (const string & marker) -{ - if (marker == "q") return true; - if (marker == "q1") return true; - if (marker == "q2") return true; - if (marker == "q3") return true; - return false; -} - - -} // End of namespace. diff --git a/filter/usfm.h b/filter/usfm.h deleted file mode 100644 index 7dfb89013..000000000 --- a/filter/usfm.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -namespace filter::usfm { - -class BookChapterData -{ -public: - BookChapterData (int book, int chapter, std::string data); - int m_book { 0 }; - int m_chapter { 0 }; - std::string m_data {}; -}; - -std::string one_string (std::string usfm); -std::vector get_markers_and_text (std::string code); -std::string get_marker (std::string usfm); -std::vector usfm_import (std::string input, std::string stylesheet); -std::vector get_verse_numbers (std::string usfm); -std::vector get_chapter_numbers (std::string usfm); -std::vector linenumber_to_versenumber (std::string usfm, unsigned int line_number); -std::vector offset_to_versenumber (std::string usfm, unsigned int offset); -int versenumber_to_offset (std::string usfm, int verse); -std::string get_verse_text (std::string usfm, int verse); -std::string get_verse_text_quill (std::string usfm, int verse_number); -std::string get_chapter_text (std::string usfm, int chapter_number); -std::string get_verse_range_text (std::string usfm, int verse_from, int verse_to, const std::string& exclude_usfm, bool quill); -bool is_usfm_marker (std::string code); -bool is_opening_marker (std::string usfm); -bool is_embedded_marker (std::string usfm); -std::string get_book_identifier (const std::vector & usfm, unsigned int pointer); -std::string get_text_following_marker (const std::vector & usfm, unsigned int & pointer); -std::string peek_text_following_marker (const std::vector & usfm, unsigned int pointer); -std::string peek_verse_number (std::string usfm); -std::string get_opening_usfm (std::string text, bool embedded = false); -std::string get_closing_usfm (std::string text, bool embedded = false); -std::string save_is_safe (Webserver_Request& webserver_request, - std::string oldtext, std::string newtext, bool chapter, std::string & explanation); -std::string safely_store_chapter (Webserver_Request& webserver_request, - std::string bible, int book, int chapter, std::string usfm, std::string & explanation); -std::string safely_store_verse (Webserver_Request& webserver_request, - std::string bible, int book, int chapter, int verse, std::string usfm, - std::string & explanation, bool quill); -bool contains_empty_verses (std::string usfm); -bool handle_verse_range (std::string verse, std::vector & verses); -bool handle_verse_sequence (std::string verse, std::vector & verses); -const char * marker_v (); -const char * marker_va (); -const char * marker_vp (); -void remove_word_level_attributes (const std::string & marker, - std::vector & container, unsigned int & pointer); -std::string extract_fig (std::string usfm, std::string & caption, std::string & alt, std::string& src, std::string& size, std::string& loc, std::string& copy, std::string& ref); -bool is_standard_q_poetry (const std::string & marker); - -} - diff --git a/filter/webview.cpp b/filter/webview.cpp deleted file mode 100644 index d0608711d..000000000 --- a/filter/webview.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -using namespace std; - - -void filter_webview_log_user_agent (string user_agent) -{ - // Whether the information has been logged. - static bool filter_webview_logged = false; - - // Log the browser's user agent once. - if (!filter_webview_logged) { - Database_Logs::log (user_agent); - filter_webview_logged = true; - } -} diff --git a/filter/webview.h b/filter/webview.h deleted file mode 100644 index 143d75f28..000000000 --- a/filter/webview.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -void filter_webview_log_user_agent (std::string user_agent); diff --git a/flate/flate.cpp b/flate/flate.cpp deleted file mode 100644 index 1ae973217..000000000 --- a/flate/flate.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Sets a variable (key and value) for the html template. -void Flate::set_variable (string key, string value) -{ - variables [key] = value; -} - - -// Enable a zone in the html template. -void Flate::enable_zone (string zone) -{ - zones [zone] = true; -} - - -// Add $value-s for one iteration to iterator $key. -void Flate::add_iteration (string key, map value) -{ - // The $key is the name for the iteration, - // where to add $value, which is a map of keys and values. - iterations[key].push_back (value); -} - - -// Renders the html template. -string Flate::render (string html) -{ - string rendering; - try { - if (file_or_dir_exists (html)) { - rendering = filter_url_file_get_contents (html); - process_iterations (rendering); - process_zones (rendering); - process_variables (rendering); - process_translate (rendering); - } - } catch (...) { - Database_Logs::log ("Failure to process template " + html); - } - // Remove empty lines. - vector lines = filter::strings::explode (rendering, '\n'); - rendering.clear (); - for (auto & line : lines) { - line = filter::strings::trim (line); - if (line.empty ()) continue; - rendering.append (line); - rendering.append ("\n"); - } - // Done. - return rendering; -} - - -void Flate::process_iterations (string & rendering) -{ - // Limit iteration count. - int iteration_count = 0; - // Start processing iterations by locating the first one. - string beginiteration ("", position); - string iteration_start_line = rendering.substr (position, pos - position + 3); - // Remove the opening tag for the current iteration. - rendering.erase (position, iteration_start_line.length ()); - // Name for the current iteration. - string name = iteration_start_line.substr (21, iteration_start_line.length () - 21 - 4); - // Assemble the ending line for the current iteration. - string iterationendline = ""; - // Locate the ending position. - size_t iterationendposition = rendering.find (iterationendline); - // Process if it exists. - if (iterationendposition != std::string::npos) { - // Take the ending line out. - rendering.erase (iterationendposition, iterationendline.length ()); - // Get and remove the inner contents of this iteration. - string iterating_fragment = rendering.substr (position, iterationendposition - position); - rendering.erase (position, iterationendposition - position); - // The fragment to insert after ready iterating. - string iterated_fragment; - // Go through the container for the name of the current iteration. - vector < map > named_iterations = iterations [name]; - for (auto & named_iteration : named_iterations) { - // Process one iteration. - string fragment (iterating_fragment); - for (auto & element : named_iteration) { - fragment = filter::strings::replace ("##" + element.first + "##", element.second, fragment); - } - // Add the processed fragment. - iterated_fragment.append ("\n"); - iterated_fragment.append (fragment); - iterated_fragment.append ("\n"); - } - // Insert it into the rendering. - rendering.insert (position, iterated_fragment); - } - // Next iteration. - position = rendering.find (beginiteration); - } -} - - -void Flate::process_zones (string& rendering) -{ - // Limit zone iterations. - int zone_iteration_count = 0; - // Start processing zones by locating the first one. - string beginzone ("", position); - string zonestartline = rendering.substr (position, pos - position + 3); - // Remove the opening tag for the current zone. - rendering.erase (position, zonestartline.length ()); - // Name for the current zone. - string name = zonestartline.substr (16, zonestartline.length () - 16 - 4); - // Assemble the ending line for the current zone. - string zoneendline = ""; - // Locate the ending position. - size_t zoneendposition = rendering.find (zoneendline); - // Process if it exists. - if (zoneendposition != std::string::npos) { - // Take the ending line out. - rendering.erase (zoneendposition, zoneendline.length ()); - // If the zone has not been enabled, remove all its contents within. - if (zones.count (name) == 0) { - rendering.erase (position, zoneendposition - position); - } - } - // Next zone. - position = rendering.find (beginzone); - } -} - - -void Flate::process_variables (string& rendering) -{ - // Limit variable iterations. - int variable_iteration_count = 0; - // Start processing variables by locating the first one. - size_t position = rendering.find ("##"); - // Iterate through the contents till all variables have been dealt with. - while ((position != std::string::npos) && (variable_iteration_count < 1000)) { - variable_iteration_count++; - bool correct = true; - // Check that this is a correct position: It should not have hashes nearby. - if (correct) if (position > 0) if (rendering.substr (position - 1, 1) == "#") { - correct = false; - } - if (correct) if (position < rendering.size ()) if (rendering.substr (position + 2, 1) == "#") { - correct = false; - } - // Position where the variable ends. - size_t pos = rendering.find ("##", position + 1); - if (pos == std::string::npos) pos = position + 4; - // Name for the variable zone. - string name = rendering.substr (position + 2, pos - position - 2); - // No new line in the variable name. - if (correct) if (name.find ("\n") != std::string::npos) correct = false; - if (correct) { - // Take the variable out. - rendering.erase (position, name.length () + 4); - // Insert the replacement. - rendering.insert (position, variables [name]); - } - // Next zone. - position = rendering.find ("##", position + 1); - } -} - - -void Flate::process_translate (string& rendering) -{ - // Clean up the "translate" (gettext) calls. - rendering = filter::strings::replace ("translate (", "translate(", rendering); - // Gettext markup. - string gettextopen = R"(translate(")"; - string gettextclose = R"("))"; - // Limit gettext iterations. - int iteration_counter { 0 }; - // Start processing variables by locating the first one. - size_t position = rendering.find (gettextopen); - // Iterate through the contents till all gettext calls have been dealt with. - while ((position != std::string::npos) && (iteration_counter < 1000)) { - iteration_counter++; - // Remove the gettext opener. - rendering.erase (position, gettextopen.length()); - // Position where the gettext call ends. - size_t pos = rendering.find (gettextclose, position); - if (pos != std::string::npos) { - // Take the gettext closer out. - rendering.erase (pos, gettextclose.length()); - // The English string. - string english = rendering.substr (position, pos - position); - // Take the English out. - rendering.erase (position, pos - position); - // Insert the localization. - rendering.insert (position, translate (english)); - } - // Next gettext call. - position = rendering.find (gettextopen); - } -} diff --git a/flate/flate.h b/flate/flate.h deleted file mode 100644 index 6030e72c5..000000000 --- a/flate/flate.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Flate -{ -public: - void set_variable (std::string key, std::string value); - void enable_zone (std::string zone); - std::string render (std::string html); - void add_iteration (std::string key, std::map value); - std::map > > iterations {}; -private: - std::map variables {}; - std::map zones {}; - void process_iterations (std::string & rendering); - void process_zones (std::string& rendering); - void process_variables (std::string& rendering); - void process_translate (std::string& rendering); -}; diff --git a/fonts/logic.cpp b/fonts/logic.cpp deleted file mode 100644 index 26070dcfd..000000000 --- a/fonts/logic.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include - - -namespace fonts::logic { - - -static std::string folder () -{ - return filter_url_create_root_path ({"fonts"}); -} - - -std::vector get_fonts () -{ - const std::vector files = filter_url_scandir (folder()); - std::vector fonts; - for (const auto& file : files) { - const std::string suffix = filter_url_get_extension (file); - if (suffix == "txt") continue; - if (suffix == "html") continue; - if (suffix == "h") continue; - if (suffix == "cpp") continue; - if (suffix == "o") continue; - fonts.push_back (file); - } - return fonts; -} - - -bool font_exists (const std::string& font) -{ - const std::string path = filter_url_create_path ({folder (), font}); - return file_or_dir_exists (path); -} - - -std::string get_font_path (const std::string& font) -{ - // Case of no font. - if (font.empty()) return font; - - // Case when the font exists within Bibledit. - if (font_exists (font)) { - return filter_url_create_path ({"../fonts", font}); - } - - // Case when the font is available from the browser independent of Bibledit. - if (filter_url_basename (font) == font) { - return font; - } - - // Font is on external location. - return font; -} - - -void erase (const std::string& font) -{ - const std::string path = filter_url_create_path ({folder (), font}); - filter_url_unlink (path); -} - - -// When a font is set for a Bible in Bibledit Cloud, this becomes the default font for the clients. -// Ahd when the client sets its own font, this font will be taken instead. -std::string get_text_font (const std::string& bible) -{ - std::string font = Database_Config_Bible::getTextFont (bible); -#ifdef HAVE_CLIENT - const std::string client_font = Database_Config_Bible::getTextFontClient (bible); - if (!client_font.empty ()) { - font = client_font; - } -#endif - return font; -} - - -// Returns true if the $font path has a font suffix. -bool is_font (const std::string& suffix) -{ - return (suffix == "ttf") - || (suffix == "otf") - || (suffix == "otf") - || (suffix == "woff"); -} - - -} // namespace diff --git a/fonts/logic.h b/fonts/logic.h deleted file mode 100644 index 22c5370af..000000000 --- a/fonts/logic.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -namespace fonts::logic { - -std::vector get_fonts (); -bool font_exists (const std::string& font); -std::string get_font_path (const std::string& font); -void erase (const std::string& font); -std::string get_text_font (const std::string& bible); -bool is_font (const std::string& suffix); - -} // namespace diff --git a/help/index.cpp b/help/index.cpp deleted file mode 100644 index 38f0e0c3a..000000000 --- a/help/index.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -std::string help_index_html (const std::string& url) -{ - std::string path (url); - size_t pos = url.find ("/"); - if (pos != std::string::npos) - path.erase (0, ++pos); - path.append (".html"); - path = filter_url_create_root_path ({"help", path}); - return path; -} - - -bool help_index_url (const std::string& url) -{ - size_t pos = url.find ("help/"); - if (pos != 0) return false; - return file_or_dir_exists (help_index_html (url)); -} - - -bool help_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::guest ()); -} - - -std::string help_index (Webserver_Request& webserver_request, const std::string& url) -{ - std::string page {}; - - Assets_Header header = Assets_Header (translate("Help"), webserver_request); - page = header.run (); - - Assets_View view {}; - - view.set_variable ("version", config::logic::version ()); - - view.set_variable ("external", assets_external_logic_link_addon ()); - - view.set_variable ("config", filter_url_create_root_path ({config::logic::config_folder ()})); - - std::string filename (url); - size_t pos = url.find ("/"); - if (pos != std::string::npos) - filename.erase (0, ++pos); - - page += view.render ("help", filename); - - page += assets_page::footer (); - - return page; -} diff --git a/help/index.h b/help/index.h deleted file mode 100644 index 676c7fbed..000000000 --- a/help/index.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string help_index_html (const std::string& url); -bool help_index_url (const std::string& url); -bool help_index_acl (Webserver_Request& webserver_request); -std::string help_index (Webserver_Request& webserver_request, const std::string& url); diff --git a/html/header.cpp b/html/header.cpp deleted file mode 100644 index a6a2e3496..000000000 --- a/html/header.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -using namespace std; -using namespace pugi; - - -// Class for creating a html Bible header with breadcrumbs and search box. - - -Html_Header::Html_Header (HtmlText& html_text): -m_html_text (html_text) -{ } - - -void Html_Header::search_back_link (string url, string text) -{ - m_search_back_link_url = url; - m_search_back_link_text = text; -} - - -void Html_Header::create (const vector > & breadcrumbs) -{ - xml_node table_element = m_html_text.new_table (); - xml_node table_row_element = m_html_text.new_table_row (table_element); - xml_node table_data_element = m_html_text.new_table_data (table_row_element); - for (auto breadcrumb : breadcrumbs) { - m_html_text.add_link (table_data_element, breadcrumb.second, "", breadcrumb.first, "", ' ' + breadcrumb.first + ' '); - } - table_data_element = m_html_text.new_table_data (table_row_element, true); - xml_node formElement = table_data_element.append_child ("form"); - formElement.append_attribute ("action") = "/webbb/search"; - formElement.append_attribute ("method") = "GET"; - formElement.append_attribute ("name") = "search"; - formElement.append_attribute ("id") = "search"; - xml_node inputElement = formElement.append_child ("input"); - inputElement.append_attribute ("name") = "q"; - inputElement.append_attribute ("type") = "text"; - inputElement.append_attribute ("placeholder") = translate ("Search the Bible").c_str(); - inputElement = formElement.append_child ("input"); - inputElement.append_attribute ("type") = "image"; - inputElement.append_attribute ("name") = "search"; - inputElement.append_attribute ("src") = "lens.png"; - inputElement = formElement.append_child ("input"); - inputElement.append_attribute ("type") = "hidden"; - inputElement.append_attribute ("name") = "url"; - inputElement.append_attribute ("value") = m_search_back_link_url.c_str (); - inputElement = formElement.append_child ("input"); - inputElement.append_attribute ("type") = "hidden"; - inputElement.append_attribute ("name") = "text"; - inputElement.append_attribute ("value") = m_search_back_link_text.c_str (); -} - diff --git a/html/header.h b/html/header.h deleted file mode 100644 index e12dbf1bc..000000000 --- a/html/header.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include - -class HtmlText; - -class Html_Header -{ -public: - Html_Header (HtmlText& html_text); - Html_Header(const Html_Header&) = delete; - Html_Header operator=(const Html_Header&) = delete; - void search_back_link (std::string url, std::string text); - void create (const std::vector > & breadcrumbs); -private: - HtmlText& m_html_text; - std::string m_search_back_link_url {}; - std::string m_search_back_link_text {}; -}; diff --git a/html/text.cpp b/html/text.cpp deleted file mode 100644 index ae3d2d427..000000000 --- a/html/text.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include - - -// Class for creating Html text documents. - - -HtmlText::HtmlText (const std::string& title) -{ - current_paragraph_style.clear(); - current_paragraph_content.clear(); - note_count = 0; - - // - xml_node root_node = document.append_child ("html"); - - // - head_node = root_node.append_child ("head"); - - xml_node title_node = head_node.append_child ("title"); - title_node.text ().set (title.c_str()); - - // - xml_node meta_node = head_node.append_child ("meta"); - meta_node.append_attribute ("http-equiv") = "content-type"; - meta_node.append_attribute ("content") = "text/html; charset=UTF-8"; - - // - // This tag helps to make the page mobile-friendly. - // See https://www.google.com/webmasters/tools/mobile-friendly/ - meta_node = head_node.append_child ("meta"); - meta_node.append_attribute ("name") = "viewport"; - meta_node.append_attribute ("content") = "width=device-width, initial-scale=1.0"; - - // - xml_node link_node = head_node.append_child ("link"); - link_node.append_attribute ("rel") = "stylesheet"; - link_node.append_attribute ("type") = "text/css"; - link_node.append_attribute ("href") = "stylesheet.css"; - - // - body_node = root_node.append_child ("body"); - - // Optional for notes:
    - notes_div_node = body_node.append_child ("div"); -} - - -void HtmlText::new_paragraph (const std::string& style) -{ - // First close a previous paragraph, if there's any open. - if (current_p_node_open) { - // Deal with a blank line. - // If the paragraph is empty, add a
    to it. - if (current_paragraph_content.empty()) { - current_p_node.append_child("br"); - } - } - // Secondly open the paragraph. - current_p_node = body_node.append_child ("p"); - if (!style.empty()) { - std::string clss = style; - if (!custom_class.empty()) { - clss += " " + custom_class; - } - current_p_node.append_attribute ("class") = clss.c_str(); - } - current_p_node_open = true; - current_paragraph_style = style; - current_paragraph_content.clear(); -} - - -// This function adds text to the current paragraph. -// $text: The text to add. -void HtmlText::add_text (const std::string& text) -{ - if (!text.empty()) { - if (!current_p_node_open) new_paragraph (); - xml_node span = current_p_node.append_child ("span"); - span.text().set (text.c_str()); - if (!current_text_style.empty ()) { - // Take character style(s) as specified in the object. - span.append_attribute ("class") = filter::strings::implode (current_text_style, " ").c_str(); - } - current_paragraph_content += text; - } -} - - -// This creates a

    heading with contents. -// $text: Contents. -void HtmlText::new_heading1 (const std::string& text) -{ - new_named_heading ("h1", text); -} - - -// This applies a page break. -void HtmlText::new_page_break () -{ - // The style is already in the css. - new_paragraph ("break"); - // Always clear the flag for the open paragraph, - // because we don't want subsequent text to be added to this page break, - // since it would be nearly invisible, and thus text would seem to be lost. - current_p_node_open = false; - current_paragraph_style.clear(); - current_paragraph_content.clear(); -} - - -// This opens a text style. -// $style: the array containing the style variables. -// $note: boolean: Whether this refers to notes. -// $embed: boolean: Whether to embed the new text style in an existing text style. -// true: add the new style to the existing style. -// false: close any existing text style, and open the new style. -void HtmlText::open_text_style (const Database_Styles_Item& style, const bool note, const bool embed) -{ - std::string marker = style.marker; - if (note) { - if (!embed) current_note_text_style.clear(); - current_note_text_style.push_back (marker); - } else { - if (!embed) current_text_style.clear(); - current_text_style.push_back (marker); - } -} - - -// This closes any open text style. -// $note: boolean: Whether this refers to notes. -// $embed: boolean: Whether to embed the new text style in an existing text style. -// true: add the new style to the existing style. -// false: close any existing text style, and open the new style. -void HtmlText::close_text_style (const bool note, const bool embed) -{ - if (note) { - if (!current_note_text_style.empty()) current_note_text_style.pop_back (); - if (!embed) current_note_text_style.clear(); - } else { - if (!current_text_style.empty()) current_text_style.pop_back (); - if (!embed) current_text_style.clear (); - } -} - - -// This function adds a note to the current paragraph. -// $citation: The text of the note citation. -// $style: Style name for the paragraph in the note body. -// $endnote: Whether this is a footnote and cross reference (false), or an endnote (true). -void HtmlText::add_note (const std::string& citation, const std::string& style, [[maybe_unused]] const bool endnote) -{ - // Ensure that a paragraph is open, so that the note can be added to it. - if (!current_p_node_open) new_paragraph (); - - note_count++; - - // Add the link with all relevant data for the note citation. - std::string reference = "#note" + filter::strings::convert_to_string (note_count); - std::string identifier = "citation" + filter::strings::convert_to_string (note_count); - add_link (current_p_node, reference, identifier, "", "superscript", citation, add_popup_notes); - - // Open a paragraph element for the note body. - note_p_node = notes_div_node.append_child ("p"); - note_p_node.append_attribute ("class") = style.c_str(); - note_p_node_open = true; - - close_text_style (true, false); - - // Add the link with all relevant data for the note body. - reference = "#citation" + filter::strings::convert_to_string (note_count); - identifier = "note" + filter::strings::convert_to_string (note_count); - add_link (note_p_node, reference, identifier, "", "", citation); - - // Add a space. - add_note_text (" "); -} - - -// This function adds text to the current footnote. -// $text: The text to add. -void HtmlText::add_note_text (const std::string& text) -{ - if (text.empty()) return; - if (!note_p_node_open) add_note ("?", ""); - xml_node span_node = note_p_node.append_child ("span"); - span_node.text().set (text.c_str()); - if (!current_note_text_style.empty ()) { - // Take character style as specified in this object. - span_node.append_attribute ("class") = filter::strings::implode (current_note_text_style, " ").c_str(); - } - if (popup_node) { - xml_node span_node_2 = popup_node.append_child ("span"); - span_node_2.text().set (text.c_str()); - } -} - - -// This function closes the current footnote. -void HtmlText::close_current_note () -{ - close_text_style (true, false); - note_p_node_open = false; -} - - -// This adds a link. -// $domNode: The DOM node where to add the link to. -// $reference: The link's href, e.g. where it links to. -// $identifier: The link's identifier. Others can link to it. -// $title: The link's title, to make it accessible, e.g. for screenreaders. -// $style: The link text's style. -// $text: The link's text. -void HtmlText::add_link (xml_node node, - const std::string& reference, const std::string& identifier, - const std::string& title, const std::string& style, const std::string& text, - const bool add_popup) -{ - xml_node a_node = node.append_child ("a"); - a_node.append_attribute ("href") = reference.c_str(); - a_node.append_attribute ("id") = identifier.c_str(); - if (!title.empty ()) a_node.append_attribute ("title") = title.c_str(); - if (!style.empty()) a_node.append_attribute ("class") = style.c_str(); - xml_node pcdata = a_node.append_child (node_pcdata); - pcdata.set_value(text.c_str()); - // Whether to add a popup span in a note. - if (add_popup) { - popup_node = a_node.append_child("span"); - popup_node.append_attribute("class") = "popup"; - } -} - - -// This gets and then returns the html text -std::string HtmlText::get_html () -{ - // Move any notes into place: At the end of the body. - // Or remove empty notes container. - if (note_count > 0) { - body_node.append_move (notes_div_node); - } else { - body_node.remove_child (notes_div_node); - } - note_count = 0; - - // Get the html. - std::stringstream output {}; - document.print (output, "", format_raw); - std::string html = output.str (); - - // Add html5 doctype. - html.insert (0, "\n"); - - return html; -} - - -// Returns the html text within the tags, that is, without the stuff. -std::string HtmlText::get_inner_html () -{ - std::string page = get_html (); - size_t pos = page.find (""); - if (pos != std::string::npos) { - page = page.substr (pos + 6); - pos = page.find (""); - if (pos != std::string::npos) { - page = page.substr (0, pos); - } - } - return page; -} - - -// This saves the web page to file -// $name: the name of the file to save to. -void HtmlText::save (std::string name) -{ - const std::string html = get_html (); - filter_url_file_put_contents (name, html); -} - - -// This adds a new table to the html DOM. -// Returns: The new $tableElement -xml_node HtmlText::new_table () -{ - // Adding subsequent text should create a new paragraph. - current_p_node_open = false; - current_paragraph_style.clear(); - current_paragraph_content.clear(); - // Append the table. - xml_node table_element = body_node.append_child ("table"); - table_element.append_attribute ("width") = "100%"; - return table_element; -} - - -// This adds a new row to an existing $table_element. -// Returns: The new $table_row_element. -xml_node HtmlText::new_table_row (xml_node table_element) -{ - xml_node table_row_element = table_element.append_child ("tr"); - return table_row_element; -} - - -// This adds a new data cell to an existing $table_row_element. -// Returns: The new $table_data_element. -xml_node HtmlText::new_table_data (xml_node table_row_element, const bool align_right) -{ - xml_node table_data_element = table_row_element.append_child ("td"); - if (align_right) table_data_element.append_attribute ("align") = "right"; - return table_data_element; -} - - -// This creates a heading with styled content. -// $style: A style name. -// $text: Content. -void HtmlText::new_named_heading (const std::string& style, const std::string& text) -{ - xml_node text_h_dom_element = body_node.append_child (style.c_str()); - text_h_dom_element.text ().set (text.c_str()); - // Make paragraph null, so that adding subsequent text creates a new paragraph. - current_p_node_open = false; - current_paragraph_style.clear (); - current_paragraph_content.clear (); -} - - -// Whether to add pop-up notes as well. -void HtmlText::have_popup_notes () -{ - add_popup_notes = true; -} - - -// Add an image to the html. -void HtmlText::add_image (const std::string& style, - const std::string& alt, - const std::string& src, - const std::string& caption) -{ - xml_node img_node = body_node.append_child ("img"); - img_node.append_attribute("alt") = alt.c_str(); - img_node.append_attribute("src") = src.c_str(); - img_node.append_attribute ("width") = "100%"; - // Add the caption if it is given. - if (!caption.empty()) { - new_paragraph(style); - add_text(caption); - } - // Close the paragraph so that adding subsequent text creates a new paragraph. - current_p_node_open = false; - current_paragraph_style.clear (); - current_paragraph_content.clear (); -} diff --git a/html/text.h b/html/text.h deleted file mode 100644 index f0c488c61..000000000 --- a/html/text.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop - -using namespace pugi; - -class HtmlText -{ -public: - HtmlText (const std::string& title); - void new_paragraph (const std::string& style = std::string()); - void add_text (const std::string& text); - std::string get_html (); - std::string get_inner_html (); - void new_heading1 (const std::string& text); - void new_page_break (); - void open_text_style (const Database_Styles_Item& style, const bool note, const bool embed); - void close_text_style (const bool note, const bool embed); - void add_note (const std::string& citation, const std::string& style, const bool endnote = false); - void add_note_text (const std::string& text); - void close_current_note (); - void add_link (xml_node node, - const std::string& reference, const std::string& identifier, - const std::string& title, const std::string& style, const std::string& text, - const bool add_popup = false); - xml_node new_table (); - xml_node new_table_row (xml_node table_element); - xml_node new_table_data (xml_node table_row_element, const bool align_right = false); - void save (std::string name); - xml_node current_p_node {}; // The current p element. - std::string current_paragraph_style {}; - std::string current_paragraph_content {}; - std::vector current_text_style {}; - // This class to be added to each paragraph. The class to be defined in the stylesheet.css. - std::string custom_class {}; - void have_popup_notes (); - void add_image (const std::string& style, - const std::string& alt, - const std::string& src, - const std::string& caption); -private: - xml_document document {}; - xml_node head_node {}; - xml_node body_node {}; - xml_node notes_div_node {}; - bool current_p_node_open {false}; - int note_count {0}; - xml_node note_p_node {}; // The p element of the current footnote, if any. - bool note_p_node_open {false}; - std::vector current_note_text_style {}; - void new_named_heading (const std::string& style, const std::string& text); - bool add_popup_notes {false}; - xml_node popup_node {}; -}; diff --git a/i18n/i18n.cpp b/i18n/i18n.cpp deleted file mode 100644 index 20091029e..000000000 --- a/i18n/i18n.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -#include "database/stylesdata.h" -#include "database/books.h" -#include "database/booksdata.h" - - -string file_get_contents (string filename) -{ - ifstream ifs(filename.c_str(), ios::in | ios::binary | ios::ate); - streamoff filesize = ifs.tellg(); - if (filesize == 0) return ""; - ifs.seekg(0, ios::beg); - vector bytes((int)filesize); - ifs.read(&bytes[0], (int)filesize); - return string(&bytes[0], (int)filesize); -} - - -void file_put_contents (string filename, string contents) -{ - ofstream file; - file.open(filename, ios::binary | ios::trunc); - file << contents; - file.close (); -} - - -vector explode (string value, char delimiter) -{ - vector result; - istringstream iss (value); - for (string token; getline (iss, token, delimiter); ) - { - result.push_back (move (token)); - } - return result; -} - - -string implode (vector & values, string delimiter) -{ - string full; - for (vector::iterator it = values.begin (); it != values.end (); ++it) - { - full += (*it); - if (it != values.end ()-1) full += delimiter; - } - return full; -} - - -string str_replace (string search, string replace, string subject) -{ - size_t offposition = subject.find (search); - while (offposition != std::string::npos) { - subject.replace (offposition, search.length (), replace); - offposition = subject.find (search, offposition + replace.length ()); - } - return subject; -} - - -int main () -{ - // Read all html files to process. - string contents = file_get_contents ("i18n.html"); - vector files = explode (contents, '\n'); - std::cout << "Processing " << files.size () << " html files" << std::endl; - - // Store the translatable strings. - vector translatables; - - // Go over all html files. - for (auto file : files) { - - // Read the html. - contents = file_get_contents (file); - - // Clean up the "translate" (gettext) calls. - contents = str_replace ("translate (", "translate(", contents); - - // Gettext markup. - string gettextopen = R"(translate(")"; - string gettextclose = R"("))"; - - // Limit gettext iterations. - int iterations = 0; - - // Start processing variables by locating the first one. - size_t position = contents.find (gettextopen); - - // Iterate through the contents till all gettext calls have been dealt with. - while ((position != std::string::npos) && (iterations < 1000)) { - iterations++; - - // Remove the gettext opener. - contents.erase (position, gettextopen.length()); - - // Position where the gettext call ends. - size_t pos = contents.find (gettextclose, position); - if (pos != std::string::npos) { - - // Take the gettext closer out. - contents.erase (pos, gettextclose.length()); - - // The English string. - string english = contents.substr (position, pos - position); - - // If the English string is empty, don't store it. - if (english.empty()) continue; - - // Wrap it in calls recognizable as gettext calls, and store it. - english.insert (0, "translate(\""); - english.append ("\")"); - translatables.push_back (english); - } - - // Next gettext call. - position = contents.find (gettextopen); - } - } - - // Go over all USFM styles to internationalize them. - unsigned int styles_data_count = sizeof (styles_table) / sizeof (*styles_table); - for (unsigned int i = 0; i < styles_data_count; i++) { - string english = styles_table[i].name; - if (!english.empty()) { - english.insert (0, "translate(\""); - english.append ("\")"); - translatables.push_back (english); - } - english = styles_table[i].info; - if (!english.empty()) { - english.insert (0, "translate(\""); - english.append ("\")"); - translatables.push_back (english); - } - } - - // Go over all Bible books to internationalize them. - unsigned int books_data_count = sizeof (books_table) / sizeof (*books_table); - for (unsigned int i = 0; i < books_data_count; i++) { - string english = books_table[i].english; - if (!english.empty()) { - english.insert (0, "translate(\""); - english.append ("\")"); - translatables.push_back (english); - } - string osis = books_table[i].osis; - if (!osis.empty()) { - osis.insert (0, "translate(\""); - osis.append ("\")"); - translatables.push_back (osis); - } - string bibleworks = books_table[i].bibleworks; - if (!bibleworks.empty ()) { - bibleworks.insert (0, "translate(\""); - bibleworks.append ("\")"); - translatables.push_back (bibleworks); - } - } - - // Store translatable strings. - contents = implode (translatables, "\n"); - file_put_contents ("translatables.cpp", contents); - - return 0; -} diff --git a/i18n/logic.cpp b/i18n/logic.cpp deleted file mode 100644 index 279d61ae7..000000000 --- a/i18n/logic.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -using namespace std; - - -void i18n_logic_augment_via_google_translate () -{ - std::cout << "Not implemented yet" << std::endl; - - return; - - // The following assumes that Google Translate has been set up already. - // Run $ gcloud auth application-default print-access-token. - auto [ google_translate_ok, google_translate_output ] = filter::google::print_store_access_token (); - std::cout << "Store Google Translate access token: " << (google_translate_ok?"Ok":"Fail") << std::endl; - std::cout << google_translate_output << std::endl; - if (!google_translate_ok) return; - - // Get the available localizations in the "locale" folder. - map localizations = locale_logic_localizations (); - for (auto & element : localizations) { - // The language abbreviation and name, like e.g. "nl" for Dutch. - string language_abbrev = element.first; - if (language_abbrev.empty ()) continue; - string language_name = element.second; - - // The path to the .po file that contains the translatable strings. - string po_path = filter_url_create_root_path ({"locale", language_abbrev + ".po"}); - - // Read the current .po file. - std::cout << "Reading current " << language_name << " definitions from " << po_path << std::endl; - unordered_map current_msgid_msgstr_map = locale_logic_read_msgid_msgstr (po_path); - - // Find the number of defined strings, and how many have been translated already. - int translated_messages {0}; - for (const auto & message : current_msgid_msgstr_map) { - if (!message.second.empty ()) translated_messages++; - } - std::cout << "Translated definitions " << translated_messages << " out of total " << current_msgid_msgstr_map.size() << std::endl; - - // The suffix for the Google translate generated content. - string google_suffix {"_po_google.txt"}; - - // Load the content of the translations generated by Google for this language. - string google_translate_txt_path = filter_url_create_root_path ({"locale", language_abbrev + google_suffix}); - unordered_map google_msgid_msgstr_map = locale_logic_read_msgid_msgstr (google_translate_txt_path); - - // Find the ones in the google file and insert them into the real .po file - - // Container for updated .po file contents. - stringstream updated_po_contents {}; - - // Iterate over the current messages and assemble translations. - for (auto & message : current_msgid_msgstr_map) { - const string & msgid = element.first; - string & msgstr = element.second; - - // In case of the en_GB.po file, - // copy the msgid to the msgstr, instead of requesting that from Google Translate. - if (language_abbrev == "en_GB") { - msgstr = msgid; - } - - // Request the missing translation via Google Translate. - else { - - } - - // Add the translation to the updated po file. - updated_po_contents << R"(msgid ")" << msgid << R"(")" << std::endl; - updated_po_contents << R"(msgstr ")" << msgstr << R"(")" << std::endl; - } - - // Write the updated .po file to the desktop. - string home_folder {getenv ("HOME")}; - string desktop_po_path = filter_url_create_path ({home_folder, "Desktop", language_abbrev + ".po"}); - filter_url_file_put_contents (desktop_po_path, updated_po_contents.str()); - - // Add the headers to the above. - - // Write the update google .po file to the desktop. - } - - // Give information about what to do at the end, - // like to copy wich files back to where, and to check them first. -} diff --git a/i18n/logic.h b/i18n/logic.h deleted file mode 100644 index 7f24357ba..000000000 --- a/i18n/logic.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -void i18n_logic_augment_via_google_translate (); diff --git a/images/fetch.cpp b/images/fetch.cpp deleted file mode 100644 index 18efb6468..000000000 --- a/images/fetch.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -string images_fetch_url () -{ - return "images/fetch"; -} - - -bool images_fetch_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ()); -} - - -string images_fetch (Webserver_Request& webserver_request) -{ - // Image name. - string image = webserver_request.query ["image"]; - - // Set the HTTP GET parameter to the image name, - // so the server will return the appropriate Mime type for this image. - webserver_request.get = image; - - // Return the raw image data for sending off to the browser. - Database_BibleImages database_bibleimages; - return database_bibleimages.get (image); -} diff --git a/images/fetch.h b/images/fetch.h deleted file mode 100644 index 013a04a26..000000000 --- a/images/fetch.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string images_fetch_url (); -bool images_fetch_acl (Webserver_Request& webserver_request); -std::string images_fetch (Webserver_Request& webserver_request); diff --git a/images/index.cpp b/images/index.cpp deleted file mode 100644 index 11042afb7..000000000 --- a/images/index.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string images_index_url () -{ - return "images/index"; -} - - -bool images_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -string images_index (Webserver_Request& webserver_request) -{ - Database_BibleImages database_bibleimages; - - - string page; - Assets_Header header = Assets_Header (translate("Bible images"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (images_index_url (), menu_logic_images_index_text ()); - page = header.run (); - Assets_View view; - string error, success; - - - // File upload. - if (webserver_request.post.count ("upload")) { - string folder = filter_url_tempfile (); - filter_url_mkdir (folder); - string file = filter_url_create_path ({folder, webserver_request.post ["filename"]}); - string data = webserver_request.post ["data"]; - if (!data.empty ()) { - filter_url_file_put_contents (file, data); - bool background_import = filter_archive_is_archive (file); - string extension = filter_url_get_extension (file); - extension = filter::strings::unicode_string_casefold (extension); - if (background_import) { - tasks_logic_queue (IMPORTBIBLEIMAGES, { file }); - success = translate("The file was uploaded and is being processed."); - view.set_variable ("journal", journal_logic_see_journal_for_progress ()); - } else { - // Store image. - database_bibleimages.store (file); - } - } else { - error = translate ("Nothing was uploaded"); - } - } - - - // Delete image. - string remove = webserver_request.query ["delete"]; - if (!remove.empty()) { - string confirm = webserver_request.query ["confirm"]; - if (confirm.empty()) { - Dialog_Yes dialog_yes = Dialog_Yes ("index", translate("Would you like to delete this image?")); - dialog_yes.add_query ("delete", remove); - page += dialog_yes.run (); - return page; - } if (confirm == "yes") { - database_bibleimages.erase (remove); - success = translate("The image was deleted."); - } - } - - - vector images = database_bibleimages.get(); - for (auto image : images) { - view.add_iteration ("images", { - pair ("image", image), - } ); - } - - view.set_variable ("success", success); - view.set_variable ("error", error); - page += view.render ("images", "index"); - page += assets_page::footer (); - return page; -} diff --git a/images/index.h b/images/index.h deleted file mode 100644 index 602e74a26..000000000 --- a/images/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string images_index_url (); -bool images_index_acl (Webserver_Request& webserver_request); -std::string images_index (Webserver_Request& webserver_request); diff --git a/images/logic.cpp b/images/logic.cpp deleted file mode 100644 index 714a00486..000000000 --- a/images/logic.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void images_logic_import_images (string path) -{ - Database_BibleImages database_bibleimages; - - Database_Logs::log ("Importing: " + filter_url_basename (path)); - - // To begin with, add the path of the zip file to the main file to the list of paths to be processed. - vector paths = {path}; - - while (!paths.empty ()) { - - // Take the first path and remove it from the container. - path = paths[0]; - paths.erase (paths.begin()); - string basename = filter_url_basename (path); - string extension = filter_url_get_extension (path); - extension = filter::strings::unicode_string_casefold (extension); - - // Store images. - if (filter_url_is_image (extension)) { - if (basename.size() > 1) { - if (basename[0] != '.') { - database_bibleimages.store (path); - Database_Logs::log ("Storing image " + basename); - } - } - } - - // Uncompress archives. - else if (filter_archive_is_archive (path)) { - Database_Logs::log ("Unpacking archive " + basename); - string folder = filter_archive_uncompress (path); - filter_url_recursive_scandir (folder, paths); - } - - } - - Database_Logs::log ("Ready importing Bible images"); -} diff --git a/images/logic.h b/images/logic.h deleted file mode 100644 index d576c9b8f..000000000 --- a/images/logic.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void images_logic_import_images (std::string path); diff --git a/images/view.cpp b/images/view.cpp deleted file mode 100644 index 4039f3783..000000000 --- a/images/view.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string images_view_url () -{ - return "images/view"; -} - - -bool images_view_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -string images_view (Webserver_Request& webserver_request) -{ - string page; - Assets_Header header = Assets_Header (translate("Bible image"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (images_view_url (), menu_logic_images_index_text ()); - page = header.run (); - Assets_View view; - string error, success; - - string image = webserver_request.query ["image"]; - - view.set_variable ("image", image); - view.set_variable ("success", success); - view.set_variable ("error", error); - page += view.render ("images", "view"); - page += assets_page::footer (); - return page; -} diff --git a/images/view.h b/images/view.h deleted file mode 100644 index f596cf247..000000000 --- a/images/view.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string images_view_url (); -bool images_view_acl (Webserver_Request& webserver_request); -std::string images_view (Webserver_Request& webserver_request); diff --git a/index/index.cpp b/index/index.cpp deleted file mode 100644 index 71d137490..000000000 --- a/index/index.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -const char * index_index_url () -{ - return "index/index"; -} - - -bool index_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::guest ()); -} - - -std::string index_index (Webserver_Request& webserver_request) -{ - filter_webview_log_user_agent (webserver_request.user_agent); - - Assets_Header header = Assets_Header (translate ("Bibledit"), webserver_request); - - // Basic or advanced mode setting. - const std::string mode = webserver_request.query ["mode"]; - if (!mode.empty ()) { - const bool basic = (mode == "basic"); - webserver_request.database_config_user ()->setBasicInterfaceMode (basic); - menu_logic_tabbed_mode_save_json (webserver_request); - } - - // Upon app start, initialize the JSON for tabbed mode. - // It should be done during the setup phase. - // But in this case the setup phase does not provide user information. - // Here on this page, the user information is available. - static bool tabbed_json_initialized = false; - if (!tabbed_json_initialized) { - if (menu_logic_can_do_tabbed_mode ()) { - menu_logic_tabbed_mode_save_json (webserver_request); - } - tabbed_json_initialized = true; - } - - // Normally a page does not show the expanded main menu. - // This is to save space on the screen. - // But the home page of Bibledit shows the extended main menu. - if (webserver_request.query.count ("item") == 0) { - webserver_request.query ["item"] = "main"; - } - - std::string page = header.run (); - - Assets_View view {}; - - view.set_variable ("warning", bible_logic::unsent_unreceived_data_warning ()); - - page += view.render ("index", "index"); - page += assets_page::footer (); - return page; -} diff --git a/index/index.h b/index/index.h deleted file mode 100644 index 7abed60b5..000000000 --- a/index/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -const char * index_index_url (); -bool index_index_acl (Webserver_Request& webserver_request); -std::string index_index (Webserver_Request& webserver_request); diff --git a/index/listing.cpp b/index/listing.cpp deleted file mode 100644 index 8d8b05cda..000000000 --- a/index/listing.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -using namespace std; -using namespace pugi; - - -bool index_listing_match (string url) -{ - if (url.length () >= 9) if (url.substr (0, 9) == "revisions") return true; - if (url.length () >= 7) if (url.substr (0, 7) == "exports") return true; - return false; -} - - -string index_listing_url (string url) -{ - if (index_listing_match (url)) return url; - return "\\"; -} - - -bool index_listing_acl (Webserver_Request& webserver_request, string url) -{ - // Bible exports are public. - if (url.find ("exports") == 0) { - return Filter_Roles::access_control (webserver_request, Filter_Roles::guest ()); - } - // Any other files are for people with at least a member role. - return Filter_Roles::access_control (webserver_request, Filter_Roles::member ()); -} - - -string index_listing (Webserver_Request& webserver_request, string url) -{ - string page; - page = assets_page::header (translate ("Bibledit"), webserver_request); - // No breadcrumbs because the user can arrive here from more than one place. - Assets_View view; - url = filter_url_urldecode (url); - url = filter_url_create_path ({string(), url}); - url = filter::strings::replace (R"(\)", "/", url); - view.set_variable ("url", url); - string parent = filter_url_dirname_web (url); - if (parent.length () > 1) { - view.enable_zone ("parent"); - view.set_variable ("parent", parent); - } - string directory = filter_url_create_root_path ({url}); - if (!file_or_dir_exists (directory) || filter_url_is_dir (directory)) { - // The document that contains the listing. - xml_document listing_document; - string listing; - // Check the files in this folder. - vector files = filter_url_scandir (directory); - // Handle empty folder. - if (files.empty()) { - xml_node span_node = listing_document.append_child("span"); - span_node.text().set(translate ("No files in this folder").c_str()); - } - // Handle file / folder listing. - else { - xml_node table_node = listing_document.append_child("table"); - for (auto & file : files) { - // Open a new row. - xml_node tr_node = table_node.append_child("tr"); - // Add the link to the file in the first column. - xml_node td_node = tr_node.append_child("td"); - xml_node a_node = td_node.append_child("a"); - string href = filter_url_create_path ({url, file}); - a_node.append_attribute("href") = href.c_str(); - a_node.text().set(file.c_str()); - // Implement force download for USFM files. - // https://github.com/bibledit/cloud/issues/771 - string suffix = filter_url_get_extension (file); - if (suffix == "usfm") { - a_node.append_attribute("download") = file.c_str(); - } - // Optionally add the file size. - string path = filter_url_create_path ({directory, file}); - if (!filter_url_is_dir (path)) { - td_node = tr_node.append_child("td"); - td_node.text().set(filter::strings::convert_to_string (filter_url_filesize (path)).c_str()); - } - } - } - stringstream ss; - listing_document.print (ss, "", format_raw); - view.set_variable ("listing", ss.str()); - } else { - string filename = filter_url_create_root_path ({url}); - return filter_url_file_get_contents (filename); - } - page += view.render ("index", "listing"); - page += assets_page::footer (); - return page; -} diff --git a/index/listing.h b/index/listing.h deleted file mode 100644 index b97872160..000000000 --- a/index/listing.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string index_listing_url (std::string url); -bool index_listing_acl (Webserver_Request& webserver_request, std::string url); -std::string index_listing (Webserver_Request& webserver_request, std::string url); diff --git a/ipc/focus.cpp b/ipc/focus.cpp deleted file mode 100644 index 971da01e3..000000000 --- a/ipc/focus.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -using namespace std; - - -// Sets the focus. -void Ipc_Focus::set (Webserver_Request& webserver_request, int book, int chapter, int verse) -{ - bool set = false; - if (book != getBook (webserver_request)) set = true; - if (chapter != getChapter (webserver_request)) set = true; - if (verse != getVerse (webserver_request)) set = true; - if (set) { - webserver_request.database_config_user()->setFocusedBook (book); - webserver_request.database_config_user()->setFocusedChapter (chapter); - webserver_request.database_config_user()->setFocusedVerse (verse); - } -} - - -// Gets the focused book. -int Ipc_Focus::getBook (Webserver_Request& webserver_request) -{ - int book = webserver_request.database_config_user()->getFocusedBook (); - return book; -} - - -// Gets the focused chapter. -int Ipc_Focus::getChapter (Webserver_Request& webserver_request) -{ - int chapter = webserver_request.database_config_user()->getFocusedChapter (); - return chapter; -} - - -// Gets the focused verse. -int Ipc_Focus::getVerse (Webserver_Request& webserver_request) -{ - int verse = webserver_request.database_config_user()->getFocusedVerse (); - return verse; -} diff --git a/ipc/focus.h b/ipc/focus.h deleted file mode 100644 index 7561b10ce..000000000 --- a/ipc/focus.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -class Ipc_Focus -{ -public: - static void set (Webserver_Request& webserver_request, int book, int chapter, int verse); - static int getBook (Webserver_Request& webserver_request); - static int getChapter (Webserver_Request& webserver_request); - static int getVerse (Webserver_Request& webserver_request); -private: -}; diff --git a/ipc/notes.cpp b/ipc/notes.cpp deleted file mode 100644 index ecde3dab2..000000000 --- a/ipc/notes.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -using namespace std; - - -// Deals with the consultation notes stuff. - - -void Ipc_Notes::open (Webserver_Request& webserver_request, int identifier) -{ - string user = webserver_request.session_logic()->currentUser (); - webserver_request.database_ipc()->storeMessage (user, "", "opennote", filter::strings::convert_to_string (identifier)); -} - - -int Ipc_Notes::get (Webserver_Request& webserver_request) -{ - Database_Ipc_Message data = webserver_request.database_ipc()->getNote (); - return filter::strings::convert_to_int (data.message); -} - - -void Ipc_Notes::erase (Webserver_Request& webserver_request) -{ - Database_Ipc_Message data = webserver_request.database_ipc()->getNote (); - int counter = 0; - while (data.id && (counter < 100)) { - int id = data.id; - webserver_request.database_ipc()->deleteMessage (id); - counter++; - } -} - - -// If $set is true, it sets the alive status of the notes editor. -// If $set is false, it returns the alive status. -bool Ipc_Notes::alive (Webserver_Request& webserver_request, bool set, bool alive) -{ - string user = webserver_request.session_logic()->currentUser (); - if (set) { - webserver_request.database_ipc()->storeMessage (user, "", "notesalive", filter::strings::convert_to_string (alive)); - } else { - return webserver_request.database_ipc()->getNotesAlive (); - } - return false; -} diff --git a/ipc/notes.h b/ipc/notes.h deleted file mode 100644 index b81442751..000000000 --- a/ipc/notes.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -class Ipc_Notes -{ -public: - static void open (Webserver_Request& webserver_request, int identifier); - static int get (Webserver_Request& webserver_request); - static void erase (Webserver_Request& webserver_request); - static bool alive (Webserver_Request& webserver_request, bool set, bool alive = false); -private: -}; diff --git a/jobs/index.cpp b/jobs/index.cpp deleted file mode 100644 index a9d0da9d0..000000000 --- a/jobs/index.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string jobs_index_url () -{ - return "jobs/index"; -} - - -bool jobs_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ()); -} - - -string jobs_index (Webserver_Request& webserver_request) -{ - string page; - - Assets_Header header = Assets_Header (translate ("Job"), webserver_request); - - Assets_View view; - - const int id = filter::strings::convert_to_int (webserver_request.query ["id"]); - - // Get information about this job. - Database_Jobs database_jobs = Database_Jobs (); - const bool exists = database_jobs.id_exists (id); - const int level = database_jobs.get_level (id); - const string start = database_jobs.get_start (id); - const string percentage = database_jobs.get_percentage (id); - const string progress = database_jobs.get_progress (id); - const string result = database_jobs.get_result (id); - - // Access control for the user. - const int userlevel = webserver_request.session_logic()->currentLevel (); - - string contents; - if (!exists) { - // Check on existence of the job. - contents = translate("This job does not exist."); - } else if (level > userlevel) { - // Check user access to the job. - contents = translate("This job is not available to you."); - } else if (!result.empty ()) { - contents = result; - } else if (!start.empty () | !progress.empty () | !percentage.empty ()) { - contents = start; - if (!percentage.empty ()) { - view.enable_zone ("percentage"); - view.set_variable ("percentage", percentage); - } - if (!progress.empty ()) { - view.enable_zone ("progress"); - view.set_variable ("progress", progress); - } - } else { - contents = translate("The job is scheduled to start shortly."); - } - view.set_variable ("contents", contents); - - // If the result is still pending, refresh the page shortly. - if (result.empty ()) { - header.refresh (1); - } - - header.set_editor_stylesheet (); - - page += header.run (); - - page += view.render ("jobs", "index"); - - page += assets_page::footer (); - - return page; -} diff --git a/jobs/index.h b/jobs/index.h deleted file mode 100644 index 325c528b4..000000000 --- a/jobs/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string jobs_index_url (); -bool jobs_index_acl (Webserver_Request& webserver_request); -std::string jobs_index (Webserver_Request& webserver_request); diff --git a/journal/index.cpp b/journal/index.cpp deleted file mode 100644 index 8e0f5e76c..000000000 --- a/journal/index.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -const char * journal_index_url () -{ - return "journal/index"; -} - - -bool journal_index_acl ([[maybe_unused]]Webserver_Request& webserver_request) -{ - // In Client mode, anyone can view the journal. -#ifdef HAVE_CLIENT - return true; -#endif - // In the Cloud, the role of Consultant or higher can view the journal. -#ifdef HAVE_CLOUD - if (Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ())) { - return true; - } -#endif - // No access. - return false; -} - - -string render_journal_entry (string filename, [[maybe_unused]] int userlevel) -{ - // Sample filename: "146495380700927147". - // The first 10 characters are the number of seconds past the Unix epoch, - // followed by the number of microseconds within the current second. - - // Get the contents of the file. - string path = filter_url_create_path ({Database_Logs::folder (), filename}); - string entry = filter_url_file_get_contents (path); - - // Deal with the user-level of the entry. - [[maybe_unused]] int entryLevel = filter::strings::convert_to_int (entry); - // Cloud: Only render journal entries of a sufficiently high level. - // Client: Render journal entries of any level. -#ifndef HAVE_CLIENT - if (entryLevel > userlevel) return string(); -#endif - // Remove the user's level. - entry.erase (0, 2); - - // Split entry into lines. - vector lines = filter::strings::explode (entry, '\n'); - if (!lines.empty ()) entry = lines [0]; - - // Sanitize HTML. - entry = filter::strings::escape_special_xml_characters (entry); - - bool limit = entry.size () > 150; - if (limit) { - entry.erase (150); - entry.append ("..."); - } - - // Extract the seconds since the Unix epoch from the filename. - int seconds = filter::strings::convert_to_int (filename.substr (0, 10)); - // Localized date and time stamp. - string timestamp = locale_logic_date_time (seconds); - - string a_open, a_close; - if (limit || lines.size () > 1) { - a_open = R"()"; - a_close = ""; - } - - // Done. - return "

    " + timestamp + " | " + a_open + entry + a_close + "

    \n"; -} - - -// Deal with AJAX call for a possible new journal entry. -string journal_index_ajax_next (Webserver_Request& webserver_request, string filename) -{ - int userLevel = webserver_request.session_logic()->currentLevel (); - string result = Database_Logs::next (filename); - if (!result.empty()) { - result = render_journal_entry (result, userLevel); - result.insert (0, filename + "\n"); - } - return result; -} - - -string journal_index (Webserver_Request& webserver_request) -{ - int userLevel = webserver_request.session_logic()->currentLevel (); - - - string filename = webserver_request.query ["filename"]; - if (!filename.empty ()) { - return journal_index_ajax_next (webserver_request, filename); - } - - - string expansion = webserver_request.query ["expansion"]; - if (!expansion.empty ()) { - // Get file path. - expansion = filter_url_basename_web (expansion); - string path = filter_url_create_path ({Database_Logs::folder (), expansion}); - // Get contents of the record. - expansion = filter_url_file_get_contents (path); - // Remove the user's level. - expansion.erase (0, 2); - // The only formatting currently allowed in the journal is new lines. - // The rest is sanitized. - // To do this properly, the order is important: - // 1. Clean it up. - expansion = filter::strings::escape_special_xml_characters (expansion); - // 2. Convert \n to
    - expansion = filter::strings::replace ("\n", "
    ", expansion); - // Done. - return expansion; - } - - - Assets_Header header = Assets_Header (translate ("Journal"), webserver_request); - header.add_bread_crumb (menu_logic_tools_menu (), menu_logic_tools_text ()); - string page = header.run (); - - - Assets_View view; - - - if (webserver_request.query.count ("clear")) { - Database_Logs::clear (); - // If the logbook has been cleared on a mobile device, and the screen goes off, - // and then the user activates the screen on the mobile device, - // the logbook will then again be cleared, because that was the last opened URL. - // Redirecting the browser to a clean URL fixes this behaviour. - redirect_browser (webserver_request, journal_index_url ()); - return ""; - } - - - string lastfilename; - vector records = Database_Logs::get (lastfilename); - - - string lines; - for (string record : records) { - string rendering = render_journal_entry (record, userLevel); - if (!rendering.empty ()) { - lines.append (rendering); - } - } - view.set_variable ("lines", lines); - - - // Pass the filename of the most recent entry to javascript - // for use by the AJAX calls for getting subsequent journal entries. - // It should be passed as a String object in JavaScript. - // Because when it were passed as an Int, JavaScript would round the value off. - // And rounding it off often led to double journal entries. - stringstream script; - script << "var filename = " << quoted(lastfilename) << ";"; - view.set_variable ("script", script.str()); - - - page += view.render ("journal", "index"); - - page += assets_page::footer (); - - return page; -} - diff --git a/journal/index.h b/journal/index.h deleted file mode 100644 index b362ab5a3..000000000 --- a/journal/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -const char * journal_index_url (); -bool journal_index_acl (Webserver_Request& webserver_request); -std::string journal_index (Webserver_Request& webserver_request); diff --git a/journal/logic.cpp b/journal/logic.cpp deleted file mode 100644 index 9db22b1e8..000000000 --- a/journal/logic.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -#include -#include -#include -using namespace std; -using namespace pugi; - - -// This returns true if the $entry can be filtered out from the Journal. -bool journal_logic_filter_entry (const string& entry) -{ - if (entry.find (sendreceive_notes_sendreceive_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_notes_up_to_date_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_bibles_sendreceive_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_bibles_up_to_date_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_settings_sendreceive_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_settings_up_to_date_text ()) != std::string::npos) return true; - if (entry.find (Paratext_Logic::synchronizeStartText ()) != std::string::npos) return true; - if (entry.find (Paratext_Logic::synchronizeReadyText ()) != std::string::npos) return true; - if (entry.find (sendreceive_changes_sendreceive_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_changes_up_to_date_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_files_sendreceive_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_files_up_to_date_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_sendreceive_sendreceive_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_sendreceive_send_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_sendreceive_sendreceive_ready_text ()) != std::string::npos) return true; - if (entry.find (sendreceive_sendreceive_send_ready_text ()) != std::string::npos) return true; - return false; -} - - -string journal_logic_filtered_message () -{ - return translate ("Has been sending and receiving during the past hour"); -} - - -string journal_logic_see_journal_for_progress () -{ - xml_document document; - xml_node a_node = document.append_child ("a"); - string href = "../"; - href.append (journal_index_url ()); - a_node.append_attribute ("href") = href.c_str (); - a_node.text () = translate ("See the Journal for progress.").c_str(); - stringstream output; - document.print (output, "", format_default); - return output.str (); -} - - diff --git a/journal/logic.h b/journal/logic.h deleted file mode 100644 index f283dd8ac..000000000 --- a/journal/logic.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -bool journal_logic_filter_entry (const std::string& entry); -std::string journal_logic_filtered_message (); -std::string journal_logic_see_journal_for_progress (); diff --git a/jsonxx/jsonxx.cpp b/jsonxx/jsonxx.cpp deleted file mode 100644 index 8387dd153..000000000 --- a/jsonxx/jsonxx.cpp +++ /dev/null @@ -1,1186 +0,0 @@ -/* -Copyright (c) 2010 Hong Jiang - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -*/ -// -*- mode: c++; c-basic-offset: 4; -*- - -// Author: Hong Jiang -// Contributors: -// Sean Middleditch -// rlyeh - -#pragma clang diagnostic ignored "-Wstring-conversion" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wswitch-enum" -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma GCC diagnostic ignored "-Wuseless-cast" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#include "jsonxx.h" - -#include -#include -#include -#include -#include -#include -#include - -// Snippet that creates an assertion function that works both in DEBUG & RELEASE mode. -// JSONXX_ASSERT(...) macro will redirect to this. assert() macro is kept untouched. -#if defined(NDEBUG) || defined(_NDEBUG) -# define JSONXX_REENABLE_NDEBUG -# undef NDEBUG -# undef _NDEBUG -#endif -#include -#include -void jsonxx::assertion (const char *file, int line, const char *expression, bool result) -{ - if (!result) { -// fprintf( stderr, "[JSONXX] expression '%s' failed at %s:%d -> ", expression, file, line ); -// assert( 0 ); - (void) file; - (void) line; - throw std::runtime_error (expression); - } -} -#if defined(JSONXX_REENABLE_NDEBUG) -# define NDEBUG -# define _NDEBUG -#endif -#include - -namespace jsonxx { - -//static_assert( sizeof(unsigned long long) < sizeof(long double), "'long double' cannot hold 64bit values in this compiler :("); - -bool match(const char* pattern, std::istream& input); -bool parse_array(std::istream& input, Array& array); -bool parse_bool(std::istream& input, Boolean& value); -bool parse_comment(std::istream &input); -bool parse_null(std::istream& input); -bool parse_number(std::istream& input, Number& value); -bool parse_object(std::istream& input, Object& object); -bool parse_string(std::istream& input, String& value); -bool parse_identifier(std::istream& input, String& value); -bool parse_value(std::istream& input, Value& value); - -// Try to consume characters from the input stream and match the -// pattern string. -bool match(const char* pattern, std::istream& input) { - input >> std::ws; - const char* cur(pattern); - char ch(0); - while(input && !input.eof() && *cur != 0) { - input.get(ch); - if (ch != *cur) { - input.putback(ch); - if( parse_comment(input) ) - continue; - while (cur > pattern) { - cur--; - input.putback(*cur); - } - return false; - } else { - cur++; - } - } - return *cur == 0; -} - -bool parse_string(std::istream& input, String& value) { - char ch = '\0', delimiter = '"'; - if (!match("\"", input)) { - if (Parser == Strict) { - return false; - } - delimiter = '\''; - if (input.peek() != delimiter) { - return false; - } - input.get(ch); - } - while(!input.eof() && input.good()) { - input.get(ch); - if (ch == delimiter) { - break; - } - if (ch == '\\') { - input.get(ch); - switch(ch) { - case '\\': - case '/': - value.push_back(ch); - break; - case 'b': - value.push_back('\b'); - break; - case 'f': - value.push_back('\f'); - break; - case 'n': - value.push_back('\n'); - break; - case 'r': - value.push_back('\r'); - break; - case 't': - value.push_back('\t'); - break; - case 'u': { - int i; - std::stringstream ss; - for( i = 0; (!input.eof() && input.good()) && i < 4; ++i ) { - input.get(ch); - ss << std::hex << ch; - } - if( input.good() && (ss >> i) ) - value.push_back(i); - } - break; - default: - if (ch != delimiter) { - value.push_back('\\'); - value.push_back(ch); - } else value.push_back(ch); - break; - } - } else { - value.push_back(ch); - } - } - if (input && ch == delimiter) { - return true; - } else { - return false; - } -} - -bool parse_identifier(std::istream& input, String& value) { - input >> std::ws; - - char ch = '\0', delimiter = ':'; - bool first = true; - - while(!input.eof() && input.good()) { - input.get(ch); - - if (ch == delimiter) { - input.unget(); - break; - } - - if(first) { - if ((ch != '_' && ch != '$') && - (ch < 'a' || ch > 'z') && - (ch < 'A' || ch > 'Z')) { - return false; - } - first = false; - } - if(ch == '_' || ch == '$' || - (ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9')) { - value.push_back(ch); - } - else if(ch == '\t' || ch == ' ') { - input >> std::ws; - } - } - if (input && ch == delimiter) { - return true; - } else { - return false; - } -} - -bool parse_number(std::istream& input, Number& value) { - input >> std::ws; - std::streampos rollback = input.tellg(); - input >> value; - if (input.fail()) { - input.clear(); - input.seekg(rollback); - return false; - } - return true; -} - -bool parse_bool(std::istream& input, Boolean& value) { - if (match("true", input)) { - value = true; - return true; - } - if (match("false", input)) { - value = false; - return true; - } - return false; -} - -bool parse_null(std::istream& input) { - if (match("null", input)) { - return true; - } - if (Parser == Strict) { - return false; - } - return (input.peek()==','); -} - -bool parse_array(std::istream& input, Array& array) { - return array.parse(input); -} - -bool parse_object(std::istream& input, Object& object) { - return object.parse(input); -} - -bool parse_comment(std::istream &input) { - if( Parser == Permissive ) - if( !input.eof() && input.peek() == '/' ) - { - char ch0(0); - input.get(ch0); - - if( !input.eof() ) - { - char ch1(0); - input.get(ch1); - - if( ch0 == '/' && ch1 == '/' ) - { - // trim chars till \r or \n - for( char ch(0); !input.eof() && (input.peek() != '\r' && input.peek() != '\n'); ) - input.get(ch); - - // consume spaces, tabs, \r or \n, in case no eof is found - if( !input.eof() ) - input >> std::ws; - return true; - } - - input.unget(); - input.clear(); - } - - input.unget(); - input.clear(); - } - - return false; -} - -bool parse_value(std::istream& input, Value& value) { - return value.parse(input); -} - - -Object::Object() : value_map_() {} - -Object::~Object() { - reset(); -} - -bool Object::parse(std::istream& input, Object& object) { - object.reset(); - - if (!match("{", input)) { - return false; - } - if (match("}", input)) { - return true; - } - - do { - std::string key; - if(UnquotedKeys == Enabled) { - // This code will never be executed - // because of the default setting for unquoted keys. - // To disable the warning, the code will be disabled just now. - //if (!parse_identifier(input, key)) { - // if (Parser == Permissive) { - // if (input.peek() == '}') - // break; - // } - // return false; - //} - } - else { - if (!parse_string(input, key)) { - if (Parser == Permissive) { - if (input.peek() == '}') - break; - } - return false; - } - } - if (!match(":", input)) { - return false; - } - Value* v = new Value(); - if (!parse_value(input, *v)) { - delete v; - break; - } - object.value_map_[key] = v; - } while (match(",", input)); - - - if (!match("}", input)) { - return false; - } - - return true; -} - -Value::Value() : type_(INVALID_) {} - -void Value::reset() { - if (type_ == STRING_) { - delete string_value_; - string_value_ = 0; - } - else if (type_ == OBJECT_) { - delete object_value_; - object_value_ = 0; - } - else if (type_ == ARRAY_) { - delete array_value_; - array_value_ = 0; - } -} - -bool Value::parse(std::istream& input, Value& value) { - value.reset(); - - std::string string_value; - if (parse_string(input, string_value)) { - value.string_value_ = new std::string(); - value.string_value_->swap(string_value); - value.type_ = STRING_; - return true; - } - if (parse_number(input, value.number_value_)) { - value.type_ = NUMBER_; - return true; - } - - if (parse_bool(input, value.bool_value_)) { - value.type_ = BOOL_; - return true; - } - if (parse_null(input)) { - value.type_ = NULL_; - return true; - } - if (input.peek() == '[') { - value.array_value_ = new Array(); - if (parse_array(input, *value.array_value_)) { - value.type_ = ARRAY_; - return true; - } - delete value.array_value_; - } - value.object_value_ = new Object(); - if (parse_object(input, *value.object_value_)) { - value.type_ = OBJECT_; - return true; - } - delete value.object_value_; - return false; -} - -Array::Array() : values_() {} - -Array::~Array() { - reset(); -} - -bool Array::parse(std::istream& input, Array& array) { - array.reset(); - - if (!match("[", input)) { - return false; - } - if (match("]", input)) { - return true; - } - - do { - Value* v = new Value(); - if (!parse_value(input, *v)) { - delete v; - break; - } - array.values_.push_back(v); - } while (match(",", input)); - - if (!match("]", input)) { - return false; - } - return true; -} - -static std::ostream& stream_string(std::ostream& stream, - const std::string& string) { - stream << '"'; - for (std::string::const_iterator i = string.begin(), - e = string.end(); i != e; ++i) { - switch (*i) { - case '"': - stream << "\\\""; - break; - case '\\': - stream << "\\\\"; - break; - case '/': - stream << "\\/"; - break; - case '\b': - stream << "\\b"; - break; - case '\f': - stream << "\\f"; - break; - case '\n': - stream << "\\n"; - break; - case '\r': - stream << "\\r"; - break; - case '\t': - stream << "\\t"; - break; - default: - if (*i < 32) { - stream << "\\u" << std::hex << std::setw(4) << - std::setfill('0') << static_cast(*i) << std::dec << - std::setw(0); - } else { - stream << *i; - } - } - } - stream << '"'; - return stream; -} - -} // namespace jsonxx - -std::ostream& operator<<(std::ostream& stream, const jsonxx::Value& v) { - using namespace jsonxx; - if (v.is()) { - return stream << v.get(); - } else if (v.is()) { - return stream_string(stream, v.get()); - } else if (v.is()) { - if (v.get()) { - return stream << "true"; - } else { - return stream << "false"; - } - } else if (v.is()) { - return stream << "null"; - } else if (v.is()) { - return stream << v.get(); - } else if (v.is()){ - return stream << v.get(); - } - // Shouldn't reach here. - return stream; -} - -std::ostream& operator<<(std::ostream& stream, const jsonxx::Array& v) { - stream << "["; - jsonxx::Array::container::const_iterator - it = v.values().begin(), - end = v.values().end(); - while (it != end) { - stream << *(*it); - ++it; - if (it != end) { - stream << ", "; - } - } - return stream << "]"; -} - -std::ostream& operator<<(std::ostream& stream, const jsonxx::Object& v) { - stream << "{"; - jsonxx::Object::container::const_iterator - it = v.kv_map().begin(), - end = v.kv_map().end(); - while (it != end) { - jsonxx::stream_string(stream, it->first); - stream << ": " << *(it->second); - ++it; - if (it != end) { - stream << ", "; - } - } - return stream << "}"; -} - - -namespace jsonxx { -namespace { - -typedef unsigned char byte; - -//template -std::string escape_string( const std::string &input, const bool quote = false ) { - static std::string map[256], *once = 0; - if( !once ) { - // base - for( int i = 0; i < 256; ++i ) { - map[ i ] = std::string() + char(i); - } - // non-printable - for( int i = 0; i < 32; ++i ) { - std::stringstream str; - str << "\\u" << std::hex << std::setw(4) << std::setfill('0') << i; - map[ i ] = str.str(); - } - // exceptions - map[ byte('"') ] = "\\\""; - map[ byte('\\') ] = "\\\\"; - map[ byte('/') ] = "\\/"; - map[ byte('\b') ] = "\\b"; - map[ byte('\f') ] = "\\f"; - map[ byte('\n') ] = "\\n"; - map[ byte('\r') ] = "\\r"; - map[ byte('\t') ] = "\\t"; - - once = map; - } - std::string output; - output.reserve( input.size() * 2 + 2 ); // worst scenario - if( quote ) output += '"'; - for( std::string::const_iterator it = input.begin(), end = input.end(); it != end; ++it ) - output += map[ byte(*it) ]; - if( quote ) output += '"'; - return output; -} - - -namespace json { - - std::string remove_last_comma( const std::string &_input ) { - std::string input( _input ); - size_t size = input.size(); - if( size > 2 ) - if( input[ size - 2 ] == ',' ) - input[ size - 2 ] = ' '; - return input; - } - - std::string tag( unsigned format, unsigned depth, const std::string &name, const jsonxx::Value &t) { - std::stringstream ss; - const std::string tab(depth, '\t'); - - if( !name.empty() ) - ss << tab << '\"' << escape_string( name ) << '\"' << ':' << ' '; - else - ss << tab; - - switch( t.type_ ) - { - default: - case jsonxx::Value::NULL_: - ss << "null"; - return ss.str() + ",\n"; - - case jsonxx::Value::BOOL_: - ss << ( t.bool_value_ ? "true" : "false" ); - return ss.str() + ",\n"; - - case jsonxx::Value::ARRAY_: - ss << "[\n"; - for(Array::container::const_iterator it = t.array_value_->values().begin(), - end = t.array_value_->values().end(); it != end; ++it ) - ss << tag( format, depth+1, std::string(), **it ); - return remove_last_comma( ss.str() ) + tab + "]" ",\n"; - - case jsonxx::Value::STRING_: - ss << '\"' << escape_string( *t.string_value_ ) << '\"'; - return ss.str() + ",\n"; - - case jsonxx::Value::OBJECT_: - ss << "{\n"; - for(Object::container::const_iterator it=t.object_value_->kv_map().begin(), - end = t.object_value_->kv_map().end(); it != end ; ++it) - ss << tag( format, depth+1, it->first, *it->second ); - return remove_last_comma( ss.str() ) + tab + "}" ",\n"; - - case jsonxx::Value::NUMBER_: - // max precision - ss << std::setprecision(std::numeric_limits::digits10 + 1); - ss << t.number_value_; - return ss.str() + ",\n"; - } - } -} // namespace jsonxx::anon::json - -namespace xml { - -std::string escape_attrib( const std::string &input ) { - static std::string map[256], *once = 0; - if( !once ) { - for( int i = 0; i < 256; ++i ) - map[ i ] = "_"; - for( int i = int('a'); i <= int('z'); ++i ) - map[ i ] = std::string() + char(i); - for( int i = int('A'); i <= int('Z'); ++i ) - map[ i ] = std::string() + char(i); - for( int i = int('0'); i <= int('9'); ++i ) - map[ i ] = std::string() + char(i); - once = map; - } - std::string output; - output.reserve( input.size() ); // worst scenario - for( std::string::const_iterator it = input.begin(), end = input.end(); it != end; ++it ) - output += map[ byte(*it) ]; - return output; -} - -std::string escape_tag( const std::string &input, unsigned format ) { - static std::string map[256], *once = 0; - if( !once ) { - for( int i = 0; i < 256; ++i ) - map[ i ] = std::string() + char(i); - map[ byte('<') ] = "<"; - map[ byte('>') ] = ">"; - - switch( format ) - { - default: - break; - - case jsonxx::JXML: - case jsonxx::JXMLex: - case jsonxx::JSONx: - case jsonxx::TaggedXML: - map[ byte('&') ] = "&"; - break; - } - - once = map; - } - std::string output; - output.reserve( input.size() * 5 ); // worst scenario - for( std::string::const_iterator it = input.begin(), end = input.end(); it != end; ++it ) - output += map[ byte(*it) ]; - return output; -} - -std::string open_tag( unsigned format, char type, const std::string &name, const std::string &attr = std::string(), const std::string &text = std::string() ) { - std::string tagname; - switch( format ) - { - default: - return std::string(); - - case jsonxx::JXML: - if( name.empty() ) - tagname = std::string("j son=\"") + type + '\"'; - else - tagname = std::string("j son=\"") + type + ':' + escape_string(name) + '\"'; - break; - - case jsonxx::JXMLex: - if( name.empty() ) - tagname = std::string("j son=\"") + type + '\"'; - else - tagname = std::string("j son=\"") + type + ':' + escape_string(name) + "\" " + escape_attrib(name) + "=\"" + escape_string(text) + "\""; - break; - - case jsonxx::JSONx: - if( !name.empty() ) - tagname = std::string(" name=\"") + escape_string(name) + "\""; - switch( type ) { - default: - case '0': tagname = "json:null" + tagname; break; - case 'b': tagname = "json:boolean" + tagname; break; - case 'a': tagname = "json:array" + tagname; break; - case 's': tagname = "json:string" + tagname; break; - case 'o': tagname = "json:object" + tagname; break; - case 'n': tagname = "json:number" + tagname; break; - } - break; - - case jsonxx::TaggedXML: // @TheMadButcher - if( !name.empty() ) - tagname = escape_attrib(name); - else - tagname = "JsonItem"; - switch( type ) { - default: - case '0': tagname += " type=\"json:null\""; break; - case 'b': tagname += " type=\"json:boolean\""; break; - case 'a': tagname += " type=\"json:array\""; break; - case 's': tagname += " type=\"json:string\""; break; - case 'o': tagname += " type=\"json:object\""; break; - case 'n': tagname += " type=\"json:number\""; break; - } - - if( !name.empty() ) - tagname += std::string(" name=\"") + escape_string(name) + "\""; - - break; - } - - return std::string("<") + tagname + attr + ">"; -} - -std::string close_tag( unsigned format, char type, const std::string &name ) { - switch( format ) - { - default: - return std::string(); - - case jsonxx::JXML: - case jsonxx::JXMLex: - return ""; - - case jsonxx::JSONx: - switch( type ) { - default: - case '0': return ""; - case 'b': return ""; - case 'a': return ""; - case 'o': return ""; - case 's': return ""; - case 'n': return ""; - } - break; - - case jsonxx::TaggedXML: // @TheMadButcher - if( !name.empty() ) - return ""; - else - return ""; - } -} - -std::string tag( unsigned format, unsigned depth, const std::string &name, const jsonxx::Value &t, const std::string &attr = std::string() ) { - std::stringstream ss; - const std::string tab(depth, '\t'); - - switch( t.type_ ) - { - default: - case jsonxx::Value::NULL_: - return tab + open_tag( format, '0', name, " /" ) + '\n'; - - case jsonxx::Value::BOOL_: - ss << ( t.bool_value_ ? "true" : "false" ); - return tab + open_tag( format, 'b', name, std::string(), format == jsonxx::JXMLex ? ss.str() : std::string() ) - + ss.str() - + close_tag( format, 'b', name ) + '\n'; - - case jsonxx::Value::ARRAY_: - for(Array::container::const_iterator it = t.array_value_->values().begin(), - end = t.array_value_->values().end(); it != end; ++it ) - ss << tag( format, depth+1, std::string(), **it ); - return tab + open_tag( format, 'a', name, attr ) + '\n' - + ss.str() - + tab + close_tag( format, 'a', name ) + '\n'; - - case jsonxx::Value::STRING_: - ss << escape_tag( *t.string_value_, format ); - return tab + open_tag( format, 's', name, std::string(), format == jsonxx::JXMLex ? ss.str() : std::string() ) - + ss.str() - + close_tag( format, 's', name ) + '\n'; - - case jsonxx::Value::OBJECT_: - for(Object::container::const_iterator it=t.object_value_->kv_map().begin(), - end = t.object_value_->kv_map().end(); it != end ; ++it) - ss << tag( format, depth+1, it->first, *it->second ); - return tab + open_tag( format, 'o', name, attr ) + '\n' - + ss.str() - + tab + close_tag( format, 'o', name ) + '\n'; - - case jsonxx::Value::NUMBER_: - // max precision - ss << std::setprecision(std::numeric_limits::digits10 + 1); - ss << t.number_value_; - return tab + open_tag( format, 'n', name, std::string(), format == jsonxx::JXMLex ? ss.str() : std::string() ) - + ss.str() - + close_tag( format, 'n', name ) + '\n'; - } -} - -// order here matches jsonxx::Format enum -const char *defheader[] = { - "", - - "" - JSONXX_XML_TAG "\n", - - "" - JSONXX_XML_TAG "\n", - - "" - JSONXX_XML_TAG "\n", - - "" - JSONXX_XML_TAG "\n" -}; - -// order here matches jsonxx::Format enum -const char *defrootattrib[] = { - "", - - " xsi:schemaLocation=\"http://www.datapower.com/schemas/json jsonx.xsd\"" - " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" - " xmlns:json=\"http://www.ibm.com/xmlns/prod/2009/jsonx\"", - - "", - - "", - - "" -}; - -} // namespace jsonxx::anon::xml - -} // namespace jsonxx::anon - -std::string Object::json() const { - using namespace json; - - jsonxx::Value v; - v.object_value_ = const_cast(this); - v.type_ = jsonxx::Value::OBJECT_; - - std::string result = tag( jsonxx::JSON, 0, std::string(), v ); - - v.object_value_ = 0; - return remove_last_comma( result ); -} - -std::string Object::xml( unsigned format, const std::string &header, const std::string &attrib ) const { - using namespace xml; - JSONXX_ASSERT( format == jsonxx::JSONx || format == jsonxx::JXML || format == jsonxx::JXMLex || format == jsonxx::TaggedXML ); - - jsonxx::Value v; - v.object_value_ = const_cast(this); - v.type_ = jsonxx::Value::OBJECT_; - - std::string result = tag( format, 0, std::string(), v, attrib.empty() ? std::string(defrootattrib[format]) : attrib ); - - v.object_value_ = 0; - return ( header.empty() ? std::string(defheader[format]) : header ) + result; -} - -std::string Array::json() const { - using namespace json; - - jsonxx::Value v; - v.array_value_ = const_cast(this); - v.type_ = jsonxx::Value::ARRAY_; - - std::string result = tag( jsonxx::JSON, 0, std::string(), v ); - - v.array_value_ = 0; - return remove_last_comma( result ); -} - -std::string Array::xml( unsigned format, const std::string &header, const std::string &attrib ) const { - using namespace xml; - JSONXX_ASSERT( format == jsonxx::JSONx || format == jsonxx::JXML || format == jsonxx::JXMLex || format == jsonxx::TaggedXML ); - - jsonxx::Value v; - v.array_value_ = const_cast(this); - v.type_ = jsonxx::Value::ARRAY_; - - std::string result = tag( format, 0, std::string(), v, attrib.empty() ? std::string(defrootattrib[format]) : attrib ); - - v.array_value_ = 0; - return ( header.empty() ? std::string(defheader[format]) : header ) + result; -} - -bool validate( std::istream &input ) { - - // trim non-printable chars - for( char ch(0); !input.eof() && input.peek() <= 32; ) - input.get(ch); - - // validate json - if( input.peek() == '{' ) - { - jsonxx::Object o; - if( parse_object( input, o ) ) - return true; - } - else - if( input.peek() == '[' ) - { - jsonxx::Array a; - if( parse_array( input, a ) ) - return true; - } - - // bad json input - return false; -} - -bool validate( const std::string &input ) { - std::istringstream is( input ); - return jsonxx::validate( is ); -} - -std::string reformat( std::istream &input ) { - - // trim non-printable chars - for( char ch(0); !input.eof() && input.peek() <= 32; ) - input.get(ch); - - // validate json - if( input.peek() == '{' ) - { - jsonxx::Object o; - if( parse_object( input, o ) ) - return o.json(); - } - else - if( input.peek() == '[' ) - { - jsonxx::Array a; - if( parse_array( input, a ) ) - return a.json(); - } - - // bad json input - return std::string(); -} - -std::string reformat( const std::string &input ) { - std::istringstream is( input ); - return jsonxx::reformat( is ); -} - -std::string xml( std::istream &input, unsigned format ) { - using namespace xml; - JSONXX_ASSERT( format == jsonxx::JSONx || format == jsonxx::JXML || format == jsonxx::JXMLex || format == jsonxx::TaggedXML ); - - // trim non-printable chars - for( char ch(0); !input.eof() && input.peek() <= 32; ) - input.get(ch); - - // validate json, then transform - if( input.peek() == '{' ) - { - jsonxx::Object o; - if( parse_object( input, o ) ) - return o.xml(format); - } - else - if( input.peek() == '[' ) - { - jsonxx::Array a; - if( parse_array( input, a ) ) - return a.xml(format); - } - - // bad json, return empty xml - return defheader[format]; -} - -std::string xml( const std::string &input, unsigned format ) { - std::istringstream is( input ); - return jsonxx::xml( is, format ); -} - - -Object::Object(const Object &other) { - import(other); -} -Object::Object(const std::string &key, const Value &value) { - import(key,value); -} -void Object::import( const Object &other ) { - odd.clear(); - if (this != &other) { - // default - container::const_iterator - it = other.value_map_.begin(), - end = other.value_map_.end(); - for (/**/ ; it != end ; ++it) { - container::iterator found = value_map_.find(it->first); - if( found != value_map_.end() ) { - delete found->second; - } - value_map_[ it->first ] = new Value( *it->second ); - } - } else { - // recursion is supported here - import( Object(*this) ); - } -} -void Object::import( const std::string &key, const Value &value ) { - odd.clear(); - container::iterator found = value_map_.find(key); - if( found != value_map_.end() ) { - delete found->second; - } - value_map_[ key ] = new Value( value ); -} -Object &Object::operator=(const Object &other) { - odd.clear(); - if (this != &other) { - reset(); - import(other); - } - return *this; -} -Object &Object::operator<<(const Value &value) { - if (odd.empty()) { - odd = value.get(); - } else { - import( Object(odd, value) ); - odd.clear(); - } - return *this; -} -Object &Object::operator<<(const Object &value) { - import( std::string(odd),value); - odd.clear(); - return *this; -} -size_t Object::size() const { - return value_map_.size(); -} -bool Object::empty() const { - return value_map_.size() == 0; -} -const std::map &Object::kv_map() const { - return value_map_; -} -std::string Object::write( unsigned format ) const { - return format == JSON ? json() : xml(format); -} -void Object::reset() { - container::iterator i; - for (i = value_map_.begin(); i != value_map_.end(); ++i) { - delete i->second; - } - value_map_.clear(); -} -bool Object::parse(std::istream &input) { - return parse(input,*this); -} -bool Object::parse(const std::string &input) { - std::istringstream is( input ); - return parse(is,*this); -} - - -Array::Array(const Array &other) { - import(other); -} -Array::Array(const Value &value) { - import(value); -} -void Array::import(const Array &other) { - if (this != &other) { - // default - container::const_iterator - it = other.values_.begin(), - end = other.values_.end(); - for (/**/ ; it != end; ++it) { - values_.push_back( new Value(**it) ); - } - } else { - // recursion is supported here - import( Array(*this) ); - } -} -void Array::import(const Value &value) { - values_.push_back( new Value(value) ); -} -size_t Array::size() const { - return values_.size(); -} -bool Array::empty() const { - return values_.size() == 0; -} -void Array::reset() { - for (container::iterator i = values_.begin(); i != values_.end(); ++i) { - delete *i; - } - values_.clear(); -} -bool Array::parse(std::istream &input) { - return parse(input,*this); -} -bool Array::parse(const std::string &input) { - std::istringstream is(input); - return parse(is,*this); -} -Array &Array::operator<<(const Array &other) { - import(other); - return *this; -} -Array &Array::operator<<(const Value &value) { - import(value); - return *this; -} -Array &Array::operator=(const Array &other) { - if( this != &other ) { - reset(); - import(other); - } - return *this; -} -Array &Array::operator=(const Value &value) { - reset(); - import(value); - return *this; -} - -Value::Value(const Value &other) : type_(INVALID_) { - import( other ); -} -bool Value::empty() const { - if( type_ == INVALID_ ) return true; - if( type_ == STRING_ && string_value_ == 0 ) return true; - if( type_ == ARRAY_ && array_value_ == 0 ) return true; - if( type_ == OBJECT_ && object_value_ == 0 ) return true; - return false; -} -bool Value::parse(std::istream &input) { - return parse(input,*this); -} -bool Value::parse(const std::string &input) { - std::istringstream is( input ); - return parse(is,*this); -} - -} // namespace jsonxx diff --git a/jsonxx/jsonxx.h b/jsonxx/jsonxx.h deleted file mode 100644 index 5d7f25fa4..000000000 --- a/jsonxx/jsonxx.h +++ /dev/null @@ -1,525 +0,0 @@ -/* -Copyright (c) 2010 Hong Jiang - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -*/ -// -*- mode: c++; c-basic-offset: 4; -*- - -// Author: Hong Jiang -// Contributors: -// Sean Middleditch -// rlyeh - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -// jsonxx versioning: major.minor-extra where -// major = { number } -// minor = { number } -// extra = { 'a':alpha, 'b':beta, 'rc': release candidate, 'r': release, 's':stable } -#define JSONXX_MAJOR "0" -#define JSONXX_MINOR "22" -#define JSONXX_EXTRA "a" -#define JSONXX_VERSION JSONXX_MAJOR "." JSONXX_MINOR "-" JSONXX_EXTRA -#define JSONXX_XML_TAG "" - -#if __cplusplus > 199711L -#define JSONXX_COMPILER_HAS_CXX11 1 -#elif defined(_MSC_VER) && _MSC_VER > 1700 -#define JSONXX_COMPILER_HAS_CXX11 1 -#else -#define JSONXX_COMPILER_HAS_CXX11 0 -#endif - -#define JSONXX_ASSERT(...) do { if( jsonxx::Assertions ) \ - jsonxx::assertion(__FILE__,__LINE__,#__VA_ARGS__,bool(__VA_ARGS__)); } while(0) - -namespace jsonxx { - -// Settings -enum Settings { - // constants - Enabled = true, - Disabled = false, - Permissive = true, - Strict = false, - // values - Parser = Permissive, // permissive or strict parsing - UnquotedKeys = Disabled, // support of unquoted keys - Assertions = Enabled // enabled or disabled assertions (these asserts work both in DEBUG and RELEASE builds) -}; - -// Constants for .write() and .xml() methods -enum Format { - JSON = 0, // JSON output - JSONx = 1, // XML output, JSONx format. see http://goo.gl/I3cxs - JXML = 2, // XML output, JXML format. see https://github.com/r-lyeh/JXML - JXMLex = 3, // XML output, JXMLex format. see https://github.com/r-lyeh/JXMLex - TaggedXML = 4 // XML output, tagged XML format. see https://github.com/hjiang/jsonxx/issues/12 -}; - -// Types -typedef long double Number; -typedef bool Boolean; -typedef std::string String; -struct Null {}; -class Value; -class Object; -class Array; - -// Identity meta-function -template -struct identity { - typedef T type; -}; - -// Tools -bool validate( const std::string &input ); -bool validate( std::istream &input ); -std::string reformat( const std::string &input ); -std::string reformat( std::istream &input ); -std::string xml( const std::string &input, unsigned format = JSONx ); -std::string xml( std::istream &input, unsigned format = JSONx ); - -// Detail -void assertion( const char *file, int line, const char *expression, bool result ); - -// A JSON Object -class Object { - public: - Object(); - ~Object(); - - template - bool has(const std::string& key) const; - - // Always call has<>() first. If the key doesn't exist, consider - // the behavior undefined. - template - T& get(const std::string& key); - template - const T& get(const std::string& key) const; - - template - const T& get(const std::string& key, const typename identity::type& default_value) const; - - size_t size() const; - bool empty() const; - - const std::map& kv_map() const; - std::string json() const; - std::string xml( unsigned format = JSONx, const std::string &header = std::string(), const std::string &attrib = std::string() ) const; - std::string write( unsigned format ) const; - - void reset(); - bool parse(std::istream &input); - bool parse(const std::string &input); - typedef std::map container; - void import( const Object &other ); - void import( const std::string &key, const Value &value ); - Object &operator<<(const Value &value); - Object &operator<<(const Object &value); - Object &operator=(const Object &value); - Object(const Object &other); - Object(const std::string &key, const Value &value); - template - Object(const char (&key)[N], const Value &value) { - import(key,value); - } - template - Object &operator<<(const T &value); - - protected: - static bool parse(std::istream& input, Object& object); - container value_map_; - std::string odd; -}; - -class Array { - public: - Array(); - ~Array(); - - size_t size() const; - bool empty() const; - - template - bool has(unsigned int i) const; - - template - T& get(unsigned int i); - template - const T& get(unsigned int i) const; - - template - const T& get(unsigned int i, const typename identity::type& default_value) const; - - const std::vector& values() const { - return values_; - } - std::string json() const; - std::string xml( unsigned format = JSONx, const std::string &header = std::string(), const std::string &attrib = std::string() ) const; - - std::string write( unsigned format ) const { return format == JSON ? json() : xml(format); } - void reset(); - bool parse(std::istream &input); - bool parse(const std::string &input); - typedef std::vector container; - void import(const Array &other); - void import(const Value &value); - Array &operator<<(const Array &other); - Array &operator<<(const Value &value); - Array &operator=(const Array &other); - Array &operator=(const Value &value); - Array(const Array &other); - Array(const Value &value); - protected: - static bool parse(std::istream& input, Array& array); - container values_; -}; - -// A value could be a number, an array, a string, an object, a -// boolean, or null -class Value { - public: - - Value(); - ~Value() { reset(); } - void reset(); - - template - void import( const T & ) { - reset(); - type_ = INVALID_; - // debug - // std::cout << "[WARN] No support for " << typeid(t).name() << std::endl; - } - void import( const bool &b ) { - reset(); - type_ = BOOL_; - bool_value_ = b; - } -#define dnumber(TYPE) \ - void import( const TYPE &n ) { \ - reset(); \ - type_ = NUMBER_; \ - number_value_ = static_cast(n); \ - } - dnumber( char ) - dnumber( int ) - dnumber( long ) - dnumber( long long ) - dnumber( unsigned char ) - dnumber( unsigned int ) - dnumber( unsigned long ) - dnumber( unsigned long long ) - dnumber( float ) - dnumber( double ) - dnumber( long double ) -#undef dnumber -#if JSONXX_COMPILER_HAS_CXX11 > 0 - void import( const std::nullptr_t & ) { - reset(); - type_ = NULL_; - } -#endif - void import( const Null & ) { - reset(); - type_ = NULL_; - } - void import( const String &s ) { - reset(); - type_ = STRING_; - *( string_value_ = new String() ) = s; - } - void import( const Array &a ) { - reset(); - type_ = ARRAY_; - *( array_value_ = new Array() ) = a; - } - void import( const Object &o ) { - reset(); - type_ = OBJECT_; - *( object_value_ = new Object() ) = o; - } - void import( const Value &other ) { - if (this != &other) - switch (other.type_) { - case NULL_: - import( Null() ); - break; - case BOOL_: - import( other.bool_value_ ); - break; - case NUMBER_: - import( other.number_value_ ); - break; - case STRING_: - import( *other.string_value_ ); - break; - case ARRAY_: - import( *other.array_value_ ); - break; - case OBJECT_: - import( *other.object_value_ ); - break; - case INVALID_: - type_ = INVALID_; - break; - default: - JSONXX_ASSERT( ! static_cast ("not implemented") ); - } - } - template - Value &operator <<( const T &t ) { - import(t); - return *this; - } - template - Value &operator =( const T &t ) { - reset(); - import(t); - return *this; - } - Value(const Value &other); - template - Value( const T&t ) : type_(INVALID_) { import(t); } - template - Value( const char (&t)[N] ) : type_(INVALID_) { import( std::string(t) ); } - - bool parse(std::istream &input); - bool parse(const std::string &input); - - template - bool is() const; - template - T& get(); - template - const T& get() const; - - bool empty() const; - - public: - enum { - NUMBER_, - STRING_, - BOOL_, - NULL_, - ARRAY_, - OBJECT_, - INVALID_ - } type_; - union { - Number number_value_; - String* string_value_; - Boolean bool_value_; - Array* array_value_; - Object* object_value_; - }; - -protected: - static bool parse(std::istream& input, Value& value); -}; - -template -bool Array::has(unsigned int i) const { - if (i >= size()) { - return false; - } else { - Value* v = values_.at(i); - return v->is(); - } -} - -template -T& Array::get(unsigned int i) { - JSONXX_ASSERT(i < size()); - Value* v = values_.at(i); - return v->get(); -} - -template -const T& Array::get(unsigned int i) const { - JSONXX_ASSERT(i < size()); - const Value* v = values_.at(i); - return v->get(); -} - -template -const T& Array::get(unsigned int i, const typename identity::type& default_value) const { - if(has(i)) { - const Value* v = values_.at(i); - return v->get(); - } else { - return default_value; - } -} - -template -bool Object::has(const std::string& key) const { - container::const_iterator it(value_map_.find(key)); - return it != value_map_.end() && it->second->is(); -} - -template -T& Object::get(const std::string& key) { - JSONXX_ASSERT(has(key)); - return value_map_.find(key)->second->get(); -} - -template -const T& Object::get(const std::string& key) const { - JSONXX_ASSERT(has(key)); - return value_map_.find(key)->second->get(); -} - -template -const T& Object::get(const std::string& key, const typename identity::type& default_value) const { - if (has(key)) { - return value_map_.find(key)->second->get(); - } else { - return default_value; - } -} - -template<> -inline bool Value::is() const { - return true; -} - -template<> -inline bool Value::is() const { - return type_ == NULL_; -} - -template<> -inline bool Value::is() const { - return type_ == BOOL_; -} - -template<> -inline bool Value::is() const { - return type_ == STRING_; -} - -template<> -inline bool Value::is() const { - return type_ == NUMBER_; -} - -template<> -inline bool Value::is() const { - return type_ == ARRAY_; -} - -template<> -inline bool Value::is() const { - return type_ == OBJECT_; -} - -template<> -inline Value& Value::get() { - return *this; -} - -template<> -inline const Value& Value::get() const { - return *this; -} - -template<> -inline bool& Value::get() { - JSONXX_ASSERT(is()); - return bool_value_; -} - -template<> -inline std::string& Value::get() { - JSONXX_ASSERT(is()); - return *string_value_; -} - -template<> -inline Number& Value::get() { - JSONXX_ASSERT(is()); - return number_value_; -} - -template<> -inline Array& Value::get() { - JSONXX_ASSERT(is()); - return *array_value_; -} - -template<> -inline Object& Value::get() { - JSONXX_ASSERT(is()); - return *object_value_; -} - -template<> -inline const Boolean& Value::get() const { - JSONXX_ASSERT(is()); - return bool_value_; -} - -template<> -inline const String& Value::get() const { - JSONXX_ASSERT(is()); - return *string_value_; -} - -template<> -inline const Number& Value::get() const { - JSONXX_ASSERT(is()); - return number_value_; -} - -template<> -inline const Array& Value::get() const { - JSONXX_ASSERT(is()); - return *array_value_; -} - -template<> -inline const Object& Value::get() const { - JSONXX_ASSERT(is()); - return *object_value_; -} - -template -inline Object &Object::operator<<(const T &value) { - return static_cast(*this << Value(value)), *this; -} - -} // namespace jsonxx - -std::ostream& operator<<(std::ostream& stream, const jsonxx::Value& v); -std::ostream& operator<<(std::ostream& stream, const jsonxx::Object& v); -std::ostream& operator<<(std::ostream& stream, const jsonxx::Array& v); diff --git a/ldap/logic.cpp b/ldap/logic.cpp deleted file mode 100644 index 4c0a8c6bf..000000000 --- a/ldap/logic.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -/* - - Public LDAP test server: - http://www.forumsys.com/en/tutorials/integration-how-to/ldap/online-ldap-test-server/ - - Examples of search queries against the test server: - - ldapsearch -D "cn=read-only-admin,dc=example,dc=com" -w password -h ldap.forumsys.com -p 389 -b "dc=example,dc=com" -s sub "(objectclass=*)" - - ldapsearch -D "uid=boyle,dc=example,dc=com" -w password -h ldap.forumsys.com -p 389 - - ldapsearch -h ldap.forumsys.com -p 389 -w password -D "cn=read-only-admin,dc=example,dc=com" -b "dc=example,dc=com" -s sub "(objectclass=*)" - - ldapsearch -H ldap://ldap.forumsys.com -D "cn=read-only-admin,dc=example,dc=com" -w password -b "dc=example,dc=com" -s sub "(objectclass=*)" - - ldapsearch -H ldap://ldap.forumsys.com -D "uid=boyle,dc=example,dc=com" -w password -b "dc=example,dc=com" -s sub "(uid=boyle)" - - ldapsearch -H ldap://192.168.2.12 -D "cn=admin,dc=test,dc=com" -w openldap -b "dc=test,dc=com" -s sub "(objectClass=*)" - - ldapsearch -H ldap://192.168.2.12 -D "cn=user,dc=test,dc=com" -w benschop -b "dc=test,dc=com" -s sub "(cn=user)" - - */ - - -// These global variables contain the settings for the OpenLDAP server -// to query for user credentials. -string ldap_logic_uri {}; -string ldap_logic_binddn {}; -string ldap_logic_basedn {}; -string ldap_logic_scope {}; -string ldap_logic_filter {}; -string ldap_logic_role {}; - - -// Initialize the configuration for accessing an OpenLDAP server. -void ldap_logic_initialize () -{ - // Check if the OpenLDAP configuration file exists. - const string path = filter_url_create_root_path ({config::logic::config_folder (), "ldap.conf"}); - if (file_or_dir_exists (path)) { - // Parse the configuration file. - const string contents = filter_url_file_get_contents (path); - const vector lines = filter::strings::explode (contents, '\n'); - for (auto line : lines) { - line = filter::strings::trim (line); - if (line.empty ()) continue; - if (line.substr (0, 1) == "#") continue; - size_t pos = line.find ("="); - const string key = filter::strings::trim (line.substr (0, pos)); - line.erase (0, ++pos); - line = filter::strings::trim (line); - if (key == "uri" ) ldap_logic_uri = line; - if (key == "binddn") ldap_logic_binddn = line; - if (key == "basedn") ldap_logic_basedn = line; - if (key == "scope" ) ldap_logic_scope = line; - if (key == "filter") ldap_logic_filter = line; - if (key == "role" ) ldap_logic_role = line; - } - // Log the results. - if (ldap_logic_is_on (true)) { - Database_Logs::log ("Using LDAP for authentication"); - } - } -} - - -// Clear LDAP configuration. -void ldap_logic_clear () -{ - ldap_logic_uri.clear (); - ldap_logic_binddn.clear (); - ldap_logic_basedn.clear (); - ldap_logic_scope.clear (); - ldap_logic_filter.clear (); - ldap_logic_role.clear (); -} - - -// Returns true if authentication through OpenLDAP is on. -bool ldap_logic_is_on (bool log) -{ - if (ldap_logic_uri.empty ()) { - if (log) Database_Logs::log ("LDAP server configuration lacks the URI"); - return false; - } - if (ldap_logic_binddn.empty ()) { - if (log) Database_Logs::log ("LDAP server configuration lacks the bind dn"); - return false; - } - if (ldap_logic_basedn.empty ()) { - if (log) Database_Logs::log ("LDAP server configuration lacks the base dn"); - return false; - } - if (ldap_logic_scope.empty ()) { - if (log) Database_Logs::log ("LDAP server configuration lacks the scope"); - return false; - } - if (ldap_logic_filter.empty ()) { - if (log) Database_Logs::log ("LDAP server configuration lacks the search filter"); - return false; - } - if (ldap_logic_role.empty ()) { - if (log) Database_Logs::log ("LDAP server configuration lacks the role field"); - return false; - } - return true; -} - - -// Queries the LDAP server with credentials $user and $password. -// Parameter $access indicates whether the credentials have access to the server. -// Parameter $mail returns the email address. -// Parameter $role returns the user's role. -// If the query was done successfully, the function returns true. -bool ldap_logic_fetch (const string& user, const string& password, bool& access, string& email, int& role, bool log) -{ - // Initialize result values for the caller. - access = false; - email.clear (); - role = Filter_Roles::guest (); - - // Insert the user name where appropriate. - const string binddn = filter::strings::replace ("[user]", user, ldap_logic_binddn); - const string filter = filter::strings::replace ("[user]", user, ldap_logic_filter); - - // Query the LDAP server. - string output {}; - const int result = filter_shell_vfork (output, "", "ldapsearch", - "-H", ldap_logic_uri.c_str (), - "-D", binddn.c_str (), - "-w", password.c_str (), - "-b", ldap_logic_basedn.c_str (), - "-s", ldap_logic_scope.c_str(), - filter.c_str()); - - // Logging. - if (log) { - const string command = "ldapsearch -H " + ldap_logic_uri + " -D " + binddn + " -w " + password + " -b " + ldap_logic_basedn + " -s " + ldap_logic_scope + " " + filter; - Database_Logs::log ("LDAP query\n" + command + "\n" + output, Filter_Roles::admin ()); - } - - // Check on invalid credentials. - if (result == 12544) { - return true; - } - - // Parse server response. - if (result == 0) { - access = true; - const vector lines = filter::strings::explode (output, '\n'); - for (const auto& line : lines) { - if (line.find ("mail:") == 0) { - email = filter::strings::trim (line.substr (5)); - } - if (line.find (ldap_logic_role + ":") == 0) { - const string fragment = filter::strings::unicode_string_casefold (filter::strings::trim (line.substr (3))); - for (int r = Filter_Roles::lowest (); r <= Filter_Roles::highest (); r++) { - if (fragment.find (filter::strings::unicode_string_casefold (Filter_Roles::english (r))) != std::string::npos) { - role = r; - } - } - } - } - return true; - } - - // Communication failure or another error. - return false; -} diff --git a/ldap/logic.h b/ldap/logic.h deleted file mode 100644 index 48fec4855..000000000 --- a/ldap/logic.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void ldap_logic_initialize (); -void ldap_logic_clear (); -bool ldap_logic_is_on (bool log = false); -bool ldap_logic_fetch (const std::string& user, const std::string& password, bool& access, std::string& email, int& role, bool log); diff --git a/lexicon/definition.cpp b/lexicon/definition.cpp deleted file mode 100644 index 4c005634a..000000000 --- a/lexicon/definition.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string lexicon_definition_url () -{ - return "lexicon/definition"; -} - - -bool lexicon_definition_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ()); -} - - -string lexicon_definition (Webserver_Request& webserver_request) -{ - // Retrieve the id: It may contain a Strong's number or a lemma. - string id = webserver_request.query["id"]; - - vector renderings; - - if (!id.empty ()) { - - string letter = id.substr (0, 1); - - // ETCBC4 database. - if (letter == HEBREW_ETCBC4_PREFIX) { - renderings.push_back (lexicon_logic_render_etcbc4_morphology (id)); - } - - // King James Bible with Strong's numbers. - else if (letter == KJV_LEXICON_PREFIX) { - Database_Kjv database_kjv; - string strong = database_kjv.strong (filter::strings::convert_to_int (id.substr (1))); - string rendering = lexicon_logic_render_strongs_definition (strong); - if (!rendering.empty ()) renderings.push_back (rendering); - rendering = lexicon_logic_render_abbott_smiths_definition("", strong); - if (!rendering.empty ()) renderings.push_back (rendering); - } - - // Open Scriptures Hebrew with Strong's numbers and morphology. - else if (letter == OSHB_PREFIX) { - int rowid = filter::strings::convert_to_int (id.substr (1)); - Database_OsHb database_oshb; - string morph = database_oshb.morph (rowid); - renderings.push_back (lexicon_logic_hebrew_morphology_render (morph)); - string lemma = database_oshb.lemma (rowid); - vector strongs; - vector bdbs; - lexicon_logic_convert_morphhb_parsing_to_strong (lemma, strongs, bdbs); - for (size_t i = 0; i < strongs.size (); i++) { - string rendering1 = lexicon_logic_render_strongs_definition (strongs[i]); - if (!rendering1.empty ()) renderings.push_back (rendering1); - stringstream rendering2; - rendering2 << "Brown Driver Briggs"; - renderings.push_back (rendering2.str()); - } - } - - // SBL Greek New Testament plus morphology. - else if (letter == SBLGNT_PREFIX) { - Database_MorphGnt database_morphgnt; - Database_Strong database_strong; - int rowid = filter::strings::convert_to_int (id.substr (1)); - // The part of speech. - string pos = database_morphgnt.pos (rowid); - string rendering = lexicon_logic_render_morphgnt_part_of_speech (pos); - rendering.append (" "); - // The parsing. - string parsing = database_morphgnt.parsing (rowid); - rendering.append (lexicon_logic_render_morphgnt_parsing_code (parsing)); - renderings.push_back (rendering); - // The lemma. - string lemma = database_morphgnt.lemma (rowid); - vector strongs = database_strong.strong (lemma); - for (auto & lexicon_id : strongs) { - rendering = lexicon_logic_render_strongs_definition (lexicon_id); - if (!rendering.empty ()) renderings.push_back (rendering); - } - rendering = lexicon_logic_render_abbott_smiths_definition(lemma, ""); - if (!rendering.empty ()) renderings.push_back (rendering); - } - - // Strong's Hebrew. - else if (letter == "H") { - string rendering = lexicon_logic_render_strongs_definition (id); - if (!rendering.empty ()) renderings.push_back (rendering); - } - - // Strong's Greek. - else if (letter == "G") { - string rendering = lexicon_logic_render_strongs_definition (id); - if (!rendering.empty ()) renderings.push_back (rendering); - } - - // Brown Driver Briggs lexicon. - else if (letter == BDB_PREFIX) { - string rendering = lexicon_logic_render_bdb_entry (id.substr (1)); - if (!rendering.empty ()) renderings.push_back (rendering); - } - - // Unknown definition request. - else { - renderings.push_back (id); - } - - } - - return filter::strings::implode (renderings, "
    "); -} diff --git a/lexicon/definition.h b/lexicon/definition.h deleted file mode 100644 index 10c3f4b4b..000000000 --- a/lexicon/definition.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string lexicon_definition_url (); -bool lexicon_definition_acl (Webserver_Request& webserver_request); -std::string lexicon_definition (Webserver_Request& webserver_request); diff --git a/lexicon/logic.cpp b/lexicon/logic.cpp deleted file mode 100644 index 79f8ad6ea..000000000 --- a/lexicon/logic.cpp +++ /dev/null @@ -1,1558 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -#include -using namespace std; -using namespace pugi; - - -#define BETH_STRONG 10000 -#define CONJUNCTION_STRONG 10001 -#define DEFINITE_ARTICLE_STRONG 10002 -#define INDEFINITE_ARTICLE_STRONG 10003 -#define KAF_STRONG 10004 -#define LAMED_STRONG 10005 -#define MEM_STRONG 10006 -#define SHIN_STRONG 10007 - - -// Internal function declarations. -string lexicon_logic_render_part_of_speech_pop_front (vector & parts); - - -// The names of the available lexicon resources. -vector lexicon_logic_resource_names () -{ - return { - HEBREW_ETCBC4_NAME, - KJV_LEXICON_NAME, - OSHB_NAME, - SBLGNT_NAME - }; -} - - -// Gets the HTMl for displaying the book/chapter/verse of the $lexicon. -string lexicon_logic_get_html ([[maybe_unused]] Webserver_Request& webserver_request, string lexicon, int book, int chapter, int verse) -{ - string html; - - if (lexicon == HEBREW_ETCBC4_NAME) { - string prefix = HEBREW_ETCBC4_PREFIX; - Database_Etcbc4 database_etcbc4; - // Data from the ETCBC4 database. - vector rowids = database_etcbc4.rowids (book, chapter, verse); - stringstream ss; - if (!rowids.empty ()) { - string id = "lexicontxt" + prefix; - ss << "
    " << std::endl; - for (auto rowid : rowids) { - ss << ""; - ss << ""; - ss << ""; - ss << ""; - ss << ""; - ss << ""; - ss << ""; - ss << "
    "; - string word = database_etcbc4.word (rowid); - ss << "" << word << ""; - ss << "
    "; - string gloss = database_etcbc4.gloss (rowid); - gloss = filter::strings::escape_special_xml_characters (gloss); - ss << gloss; - ss << "
    "; - } - ss << "
    "; - ss << lexicon_logic_get_script (prefix); - } - html.append(ss.str()); - } - - if (lexicon == KJV_LEXICON_NAME) { - string prefix = KJV_LEXICON_PREFIX; - Database_Kjv database_kjv; - vector rowids = database_kjv.rowids (book, chapter, verse); - if (!rowids.empty ()) { - stringstream ss; - string id = "lexicontxt" + prefix; - ss << "
    " << std::endl; - for (size_t i = 0; i < rowids.size (); i++) { - int rowid = rowids[i]; - string english = database_kjv.english (rowid); - ss << "" << english << ""; - } - ss << "
    "; - ss << lexicon_logic_get_script (prefix); - html.append(ss.str()); - } - } - - if (lexicon == OSHB_NAME) { - string prefix = OSHB_PREFIX; - Database_OsHb database_oshb; - vector rowids = database_oshb.rowids (book, chapter, verse); - if (!rowids.empty ()) { - stringstream ss; - string id = "lexicontxt" + prefix; - ss << "
    " << std::endl; - for (size_t i = 0; i < rowids.size (); i++) { - int rowid = rowids[i]; - string word = database_oshb.word (rowid); - // Give more spacing where needed. - if (word == "׀") word = " ׀ "; - ss << "" << word << ""; - } - ss << "
    "; - ss << lexicon_logic_get_script (prefix); - html.append(ss.str()); - } - } - - if (lexicon == SBLGNT_NAME) { - string prefix = SBLGNT_PREFIX; - Database_MorphGnt database_morphgnt; - vector rowids = database_morphgnt.rowids (book, chapter, verse); - if (!rowids.empty ()) { - stringstream ss; - string id = "lexicontxt" + prefix; - ss << "
    " << std::endl; - for (size_t i = 0; i < rowids.size (); i++) { - if (i) ss << " "; - int rowid = rowids[i]; - string word = database_morphgnt.word (rowid); - ss << "" << word << ""; - } - ss << "
    "; - ss << lexicon_logic_get_script (prefix); - html.append (ss.str()); - } - } - - return html; -} - - -// The script to put into the html for a lexicon's defined $prefix. -string lexicon_logic_get_script (string prefix) -{ - string defid = "lexicondef" + prefix; - string txtid = "lexicontxt" + prefix; - - string script = R"( -
    - - )"; - - script = filter::strings::replace ("defid", defid, script); - script = filter::strings::replace ("txtid", txtid, script); - - return script; -} - - -// Clean up the Strong's number. -string lexicon_logic_strong_number_cleanup (string strong) -{ - // Remove the leading zero from a Hebrew Strong's number. - strong = filter::strings::replace ("H0", "H", strong); - - return strong; -} - - -// Converts a parsing from the Open Scriptures Hebrew database to Strong's numbers. -// It also provides the links to call BDB entries. -void lexicon_logic_convert_morphhb_parsing_to_strong (string parsing, - vector & strongs, - vector & bdbs) -{ - strongs.clear (); - bdbs.clear (); - vector bits = filter::strings::explode (parsing, '/'); - for (auto & bit : bits) { - // Remove the space that is in the parsings, e.g. change "1254 a" to "1254a". - bit = filter::strings::replace (" ", "", bit); - bdbs.push_back (bit); - int strong = filter::strings::convert_to_int (bit); - if (strong == 0) { - if (bit == "b") { - // The Hebrew letter beth ב֖. - strong = BETH_STRONG; - } - else if (bit == "c") { - // Conjunction וְ. - strong = CONJUNCTION_STRONG; - } - if (bit == "d") { - // Definite article הַ. - strong = DEFINITE_ARTICLE_STRONG; - } - else if (bit == "i") { - // The indefinite article הַ. - strong = INDEFINITE_ARTICLE_STRONG; - } - else if (bit == "k") { - // The Hebrew letter kaf כַּ. - strong = KAF_STRONG; - } - else if (bit == "l") { - // The Hebrew letter lamed לָ. - strong = LAMED_STRONG; - } - else if (bit == "m") { - // The Hebrew letter mem מִ. - strong = MEM_STRONG; - } - else if (bit == "s") { - // The Hebrew letter shin שֶׁ. - strong = SHIN_STRONG; - } - } - strongs.push_back ("H" + filter::strings::convert_to_string (strong)); - } -} - - -string lexicon_logic_render_strongs_definition (string strong) -{ - vector renderings; - Database_Strong database_strong; - Database_HebrewLexicon database_hebrewlexicon; - string definition = database_strong.definition (lexicon_logic_strong_number_cleanup (strong)); - if (definition.empty ()) { - definition = database_hebrewlexicon.getstrong (lexicon_logic_strong_number_cleanup (strong)); - } - definition = filter::strings::replace ("/>", "/>\n", definition); - vector lines = filter::strings::explode (definition, '\n'); - for (auto & line : lines) { - line = filter::strings::trim (line); - line = filter::strings::collapse_whitespace (line); - size_t position; - // The first element describes it. - position = line.find ("", "", line); - // Elements referring to the source/derivation can be removed. - line = filter::strings::replace ("", "", line); - line = filter::strings::replace ("", "", line); - line = filter::strings::replace ("", "", line); - line = filter::strings::replace ("", "", line); - // Remove elements referring to the meaning. - line = filter::strings::replace ("", "", line); - line = filter::strings::replace ("", "", line); - line = filter::strings::replace ("", "", line); - line = filter::strings::replace ("", "", line); - // Transform markup for usage in the King James Bible. - line = filter::strings::replace ("", "; usage in King James Bible: ", line); - line = filter::strings::replace ("", "", line); - line = filter::strings::replace ("", "; usage in King James Bible", line); - line = filter::strings::replace ("", "", line); - // Mark the definitions. - line = filter::strings::replace ("", "", line); - line = filter::strings::replace ("", "", line); - // Clarify Strong's number. - line = filter::strings::replace ("", "Strong's ", line); - line = filter::strings::replace ("", "", line); - // Get the line to extract information from it. - position = line.find ("", position); - if (position2 != std::string::npos) { - string greek = line.substr (position, position2 - position + 2); - string xml = greek; - // Greek in Unicode. - string unicode = lexicon_logic_get_remove_attribute (xml, "unicode"); - // Greek in transliteration. - string translit = lexicon_logic_get_remove_attribute (xml, "translit"); - // Put the updated fragment back. - line = filter::strings::replace (greek, unicode + " " + translit, line); - } - } - // Get the line to extract information from it. - position = line.find ("", position); - if (position2 != std::string::npos) { - string pronunciation = line.substr (position, position2 - position + 2); - string xml = pronunciation; - // Greek in strongs. - string strongs = lexicon_logic_get_remove_attribute (xml, "strongs"); - // Put the updated fragment back. - line = filter::strings::replace (pronunciation, strongs, line); - } - } - // Get the line to extract information from it. - // Do the same for the . - // The difference is that the entire line is removed, and the other one converted. - for (int i = 0; i <= 1; i++) { - string tag = "see"; - if (i) tag = "strongsref"; - position = line.find ("<" + tag + " "); - if (position != std::string::npos) { - size_t position2 = line.find ("/>", position); - if (position2 != std::string::npos) { - string see_strongsref = line.substr (position, position2 - position + 2); - string xml = see_strongsref; - // Strong's reference. - string strongs = lexicon_logic_get_remove_attribute (xml, "strongs"); - // Language. - string language = lexicon_logic_get_remove_attribute (xml, "language"); - // Put the updated fragment back, with a link. - string replacement; - if (i) { - replacement = R"()" + strongs + ""; - } - line = filter::strings::replace (see_strongsref, replacement, line); - } - } - } - // Add the updated line to the rendering. - renderings.push_back (line); - } - } - string rendering = filter::strings::implode (renderings, " "); - rendering = filter::strings::trim (rendering); - - // If no rendering has been found yet, try the user-defined Strong's definitions. - if (rendering.empty ()) { - rendering = lexicon_logic_define_user_strong (strong); - } - - // Remove bits. - rendering = filter::strings::replace ("×", "", rendering); - - return rendering; -} - - -string lexicon_logic_render_part_of_speech_pop_front (vector & parts) -{ - string part; - if (!parts.empty ()) { - part = parts[0]; - parts.erase (parts.begin ()); - } - return part; -} - - -// Render the part of speech. -string lexicon_logic_render_strongs_part_of_speech (string value) -{ - if (value == filter::strings::unicode_string_casefold (value)) { - // Deal with Strong's parsings. - vector parts = filter::strings::explode (value, ' '); - value.clear (); - for (auto part : parts) { - value.append (" "); - if (part == "a") { - value.append ("adjective"); - } else if (part == "a-f") { - value.append ("adjective feminine"); - } else if (part == "a-m") { - value.append ("adjective masculine"); - } else if (part == "adv") { - value.append ("adverb"); - } else if (part == "conj") { - value.append ("conjunction"); - } else if (part == "d") { - value.append ("demonstrative"); - } else if (part == "dp") { - value.append ("demonstrative particle"); - } else if (part == "i") { - value.append ("interrogative"); - } else if (part == "inj") { - value.append ("interjection"); - } else if (part == "n") { - value.append ("noun"); - } else if (part == "n-f") { - value.append ("noun feminine"); - } else if (part == "n-m") { - value.append ("noun masculine"); - } else if (part == "n-pr-m") { - value.append ("noun proper masculine"); - } else if (part == "n-pr") { - value.append ("noun proper"); - } else if (part == "n-pr-f") { - value.append ("noun proper feminine"); - } else if (part == "n-pr-loc") { - value.append ("noun proper location"); - } else if (part == "a-gent") { - value.append ("adjective gent"); - } else if (part == "np") { - value.append ("negative particle"); - } else if (part == "p") { - value.append ("pronoun"); - } else if (part == "prep") { - value.append ("preposition"); - } else if (part == "pron") { - value.append ("pron"); - } else if (part == "prt") { - value.append ("particle"); - } else if (part == "r") { - value.append ("relative"); - } else if (part == "v") { - value.append ("verb"); - } else if (part == "x") { - value.append ("unparsed"); - } else { - value.append (part); - } - } - - } else { - // Deal with the BDB parsings. - vector parts = filter::strings::explode (value, '-'); - value.clear (); - string word = lexicon_logic_render_part_of_speech_pop_front (parts); - value.append (" "); - // BDB. - if (word == "A") { - value.append ("adjective"); - } else if (word == "C") { - value.append ("conjunction"); - } else if (word == "D") { - value.append ("adverb"); - } else if (word == "N") { - value.append ("noun"); - } else if (word == "P") { - value.append ("pronoun"); - } else if (word == "R") { - value.append ("preposition"); - } else if (word == "S") { - value.append ("suffix"); - } else if (word == "T") { - value.append ("particle"); - } else if (word == "V") { - value.append ("verb"); - } - } - - value.append (" "); - - return value; -} - - -string lexicon_logic_render_strongs_part_of_speech_stem (string abbrev) -{ - return abbrev; -} - - -string lexicon_logic_render_strongs_part_of_speech_person (string abbrev) -{ - return abbrev; -} - - -string lexicon_logic_render_strongs_part_of_speech_gender (string abbrev) -{ - return abbrev; -} - - -string lexicon_logic_render_strongs_part_of_speech_number (string abbrev) -{ - return abbrev; -} - - -string lexicon_logic_render_strongs_part_of_speech_state (string abbrev) -{ - return abbrev; -} - - -// Define user-defined Strong's numbers. -string lexicon_logic_define_user_strong (string strong) -{ - string definition; - if (!strong.empty ()) { - if (strong.substr (0, 1) == "H") { - strong.erase (0, 1); - int number = filter::strings::convert_to_int (strong); - if (number == BETH_STRONG) { - definition = "particle preposition ב: in, at, by, with, among"; - } - else if (number == CONJUNCTION_STRONG) { - definition = "particle conjunction ו: and, so, then, when, now, or, but, that"; - } - else if (number == DEFINITE_ARTICLE_STRONG) { - definition = "particle definite article ה: the"; - } - else if (number == INDEFINITE_ARTICLE_STRONG) { - definition = "particle indefinite article ה: a"; - } - else if (number == KAF_STRONG) { - definition = "particle preposition כ: like, as, at, according to, after, when, if"; - } - else if (number == LAMED_STRONG) { - definition = "particle preposition ל: to, for, towards, belonging to, in regard to, according to, in"; - } - else if (number == MEM_STRONG) { - definition = "particle preposition מ: from, out of, by, by reason of, at, because of, more than"; - } - else if (number == SHIN_STRONG) { - definition = "particle relative ש: that"; - } - } - } - return definition; -} - - -string lexicon_logic_render_morphgnt_part_of_speech (string pos) -{ - pos = filter::strings::replace ("-", "", pos); - string rendering; - if (pos == "N") rendering = "noun"; - if (pos == "V") rendering = "verb"; - if (pos == "RA") rendering = "definite article"; - if (pos == "C") rendering = "conjunction"; - if (pos == "RP") rendering = "personal pronoun"; - if (pos == "P") rendering = "preposition"; - if (pos == "RR") rendering = "relative pronoun"; - if (pos == "A") rendering = "adjective"; - if (pos == "D") rendering = "adverb"; - if (pos == "RD") rendering = "demonstrative pronoun"; - if (pos == "X") rendering = "interjection"; - if (pos == "RI") rendering = "indefinite adjective"; - if (pos == "I") rendering = "interjection"; - return rendering; -} - - -string lexicon_logic_render_morphgnt_parsing_code (string parsing) -{ - vector renderings; - // person. - if (!parsing.empty ()) { - string p = parsing.substr (0, 1); - parsing = parsing.substr (1); - if (p == "1") renderings.push_back ("first person"); - if (p == "2") renderings.push_back ("second person"); - if (p == "3") renderings.push_back ("third person"); - } - // tense - if (!parsing.empty ()) { - string p = parsing.substr (0, 1); - parsing = parsing.substr (1); - if (p == "A") renderings.push_back ("aorist"); - if (p == "F") renderings.push_back ("future"); - if (p == "I") renderings.push_back ("imperfect"); - if (p == "P") renderings.push_back ("present"); - if (p == "X") renderings.push_back ("perfect"); - if (p == "Y") renderings.push_back ("pluperfect"); - } - // voice - if (!parsing.empty ()) { - string p = parsing.substr (0, 1); - parsing = parsing.substr (1); - if (p == "A") renderings.push_back ("active"); - if (p == "M") renderings.push_back ("middle"); - if (p == "P") renderings.push_back ("passive"); - } - // mood - if (!parsing.empty ()) { - string p = parsing.substr (0, 1); - parsing = parsing.substr (1); - if (p == "D") renderings.push_back ("imperative"); - if (p == "I") renderings.push_back ("indicative"); - if (p == "N") renderings.push_back ("infinitive"); - if (p == "O") renderings.push_back ("optative"); - if (p == "P") renderings.push_back ("participle"); - if (p == "S") renderings.push_back ("subjunctive"); - } - // case - if (!parsing.empty ()) { - string p = parsing.substr (0, 1); - parsing = parsing.substr (1); - if (p == "A") renderings.push_back ("accusative"); - if (p == "D") renderings.push_back ("dative"); - if (p == "G") renderings.push_back ("genetive"); - if (p == "N") renderings.push_back ("nominative"); - if (p == "V") renderings.push_back ("vocative"); - } - // number - if (!parsing.empty ()) { - string p = parsing.substr (0, 1); - parsing = parsing.substr (1); - if (p == "P") renderings.push_back ("plural"); - if (p == "S") renderings.push_back ("singular"); - } - // gender - if (!parsing.empty ()) { - string p = parsing.substr (0, 1); - parsing = parsing.substr (1); - if (p == "F") renderings.push_back ("female"); - if (p == "M") renderings.push_back ("male"); - if (p == "N") renderings.push_back ("neuter"); - } - // degree - if (!parsing.empty ()) { - string p = parsing.substr (0, 1); - parsing = parsing.substr (1); - if (p == "C") renderings.push_back ("comparative"); - if (p == "S") renderings.push_back ("superlative"); - } - return filter::strings::implode (renderings, " "); -} - - -string lexicon_logic_render_etcbc4_morphology (string rowid) -{ - // The order of the rendered morphological information is such - // that the pieces of information most relevant to the Bible translator come first, - // and the remaining bits come after. - - vector renderings; - int row = filter::strings::convert_to_int (rowid.substr (1)); - Database_Etcbc4 database_etcbc4; - - string pos = database_etcbc4.pos (row); - if (pos == "art") pos = "article"; - if (pos == "verb") pos = "verb"; - if (pos == "subs") pos = "noun"; - if (pos == "nmpr") pos = "proper noun"; - if (pos == "advb") pos = "adverb"; - if (pos == "prep") pos = "preposition"; - if (pos == "conj") pos = "conjunction"; - if (pos == "prps") pos = "personal pronoun"; - if (pos == "prde") pos = "demonstrative pronoun"; - if (pos == "prin") pos = "interrogative pronoun"; - if (pos == "intj") pos = "interjection"; - if (pos == "nega") pos = "negative particle"; - if (pos == "inrg") pos = "interrogative particle"; - if (pos == "adjv") pos = "adjective"; - //renderings.push_back (";"); - //renderings.push_back ("part of speech:"); - renderings.push_back (pos); - - string lexical_set = database_etcbc4.subpos (row); - if (lexical_set == "nmdi") lexical_set = "distributive noun"; - if (lexical_set == "nmcp") lexical_set = "copulative noun"; - if (lexical_set == "padv") lexical_set = "potential adverb"; - if (lexical_set == "afad") lexical_set = "anaphoric adverb"; - if (lexical_set == "ppre") lexical_set = "potential preposition"; - if (lexical_set == "cjad") lexical_set = "conjunctive adverb"; - if (lexical_set == "ordn") lexical_set = "ordinal"; - if (lexical_set == "vbcp") lexical_set = "copulative verb"; - if (lexical_set == "mult") lexical_set = "noun of multitude"; - if (lexical_set == "focp") lexical_set = "focus particle"; - if (lexical_set == "ques") lexical_set = "interrogative particle"; - if (lexical_set == "gntl") lexical_set = "gentilic"; - if (lexical_set == "quot") lexical_set = "quotation verb"; - if (lexical_set == "card") lexical_set = "cardinal"; - if (lexical_set == "none") lexical_set = ""; - if (!lexical_set.empty ()) { - // renderings.push_back (";"); - // renderings.push_back ("lexical set:"); - renderings.push_back ("(" + lexical_set + ")"); - } - - string stem = database_etcbc4.stem (row); - if (stem == "hif") stem = "hif‘il"; - if (stem == "hit") stem = "hitpa“el"; - if (stem == "hof") stem = "hof‘al"; - if (stem == "nif") stem = "nif‘al"; - if (stem == "piel") stem = "pi“el"; - if (stem == "pual") stem = "pu“al"; - if (stem == "qal") stem = "qal"; - if (stem == "afel") stem = "af‘el"; - if (stem == "etpa") stem = "etpa“al"; - if (stem == "etpe") stem = "etpe‘el"; - if (stem == "haf") stem = "haf‘el"; - if (stem == "hop") stem = "hotpa“al"; - if (stem == "hsht") stem = "hishtaf‘al"; - if (stem == "htpa") stem = "hitpa“al"; - if (stem == "htpe") stem = "hitpe‘el"; - if (stem == "nit") stem = "nitpa“el"; - if (stem == "pael") stem = "pa“el"; - if (stem == "peal") stem = "pe‘al"; - if (stem == "peil") stem = "pe‘il"; - if (stem == "shaf") stem = "shaf‘el"; - if (stem == "tif") stem = "tif‘al"; - if (stem == "pasq") stem = "passiveqal"; - if (stem == "NA") stem.clear (); - if (!stem.empty ()) { - //renderings.push_back (";"); - //renderings.push_back ("stem:"); - renderings.push_back (stem); - } - - string tense = database_etcbc4.tense (row); - if (tense == "perf") tense = "perfect"; - if (tense == "impf") tense = "imperfect"; - if (tense == "wayq") tense = "wayyiqtol"; - if (tense == "impv") tense = "imperative"; - if (tense == "infa") tense = "infinitive (absolute)"; - if (tense == "infc") tense = "infinitive (construct)"; - if (tense == "ptca") tense = "participle"; - if (tense == "ptcp") tense = "participle (passive)"; - if (tense == "NA") tense.clear (); - if (!tense.empty ()) { - //renderings.push_back (";"); - //renderings.push_back ("tense:"); - renderings.push_back (tense); - } - - string person = database_etcbc4.person (row); - if (person == "p1") person = "first person"; - if (person == "p2") person = "second person"; - if (person == "p3") person = "third person"; - if (person == "NA") person.clear (); - if (person == "unknown") person = "unknown person"; - if (!person.empty ()) { - //renderings.push_back (";"); - //renderings.push_back ("person:"); - renderings.push_back (person); - } - - string gender = database_etcbc4.gender (row); - if (gender == "m") gender = "masculine"; - if (gender == "f") gender = "feminine"; - if (gender == "NA") gender.clear (); - if (gender == "unknown") gender = "unknown gender"; - if (!gender.empty ()) { - // renderings.push_back (";"); - // renderings.push_back ("gender:"); - renderings.push_back (gender); - } - - string number = database_etcbc4.number (row); - if (number == "sg") number = "singular"; - if (number == "du") number = "dual"; - if (number == "pl") number = "plural"; - if (number == "NA") number.clear (); - if (number == "unknown") number = "unknown number"; - if (!number.empty ()) { - // renderings.push_back (";"); - // renderings.push_back ("number:"); - renderings.push_back (number); - } - - string state = database_etcbc4.state (row); - if (state == "a") state = "absolute"; - if (state == "c") state = "construct"; - if (state == "e") state = "emphatic"; - if (state == "NA") state.clear (); - if (!state.empty ()) { - // renderings.push_back (";"); - // renderings.push_back ("state:"); - renderings.push_back (state); - } - - string gloss = database_etcbc4.gloss (row); - //renderings.push_back (";"); - //renderings.push_back ("gloss:"); - renderings.push_back ("-"); - renderings.push_back (filter::strings::escape_special_xml_characters (gloss)); - - renderings.push_back ("
    "); - - string word = database_etcbc4.word (row); - renderings.push_back ("word:"); - renderings.push_back (word); - - string vocalized_lexeme = database_etcbc4.vocalized_lexeme (row); - renderings.push_back (";"); - renderings.push_back ("vocalized lexeme:"); - renderings.push_back (vocalized_lexeme); - - string consonantal_lexeme = database_etcbc4.consonantal_lexeme (row); - renderings.push_back (";"); - renderings.push_back ("consonantal lexeme:"); - renderings.push_back (consonantal_lexeme); - - string phrase_function = database_etcbc4.phrase_function (row); - if (phrase_function == "Adju") phrase_function = "adjunct"; - if (phrase_function == "Cmpl") phrase_function = "complement"; - if (phrase_function == "Conj") phrase_function = "conjunction"; - if (phrase_function == "EPPr") phrase_function = "enclitic personal pronoun"; - if (phrase_function == "ExsS") phrase_function = "existence with subject suffix"; - if (phrase_function == "Exst") phrase_function = "existence"; - if (phrase_function == "Frnt") phrase_function = "fronted element"; - if (phrase_function == "Intj") phrase_function = "interjection"; - if (phrase_function == "IntS") phrase_function = "interjection with subject suffix"; - if (phrase_function == "Loca") phrase_function = "locative"; - if (phrase_function == "Modi") phrase_function = "modifier"; - if (phrase_function == "ModS") phrase_function = "modifier with subject suffix"; - if (phrase_function == "NCop") phrase_function = "negative copula"; - if (phrase_function == "NCoS") phrase_function = "negative copula with subject suffix"; - if (phrase_function == "Nega") phrase_function = "negation"; - if (phrase_function == "Objc") phrase_function = "object"; - if (phrase_function == "PrAd") phrase_function = "predicative adjunct"; - if (phrase_function == "PrcS") phrase_function = "predicate complement with subject suffix"; - if (phrase_function == "PreC") phrase_function = "predicate complement"; - if (phrase_function == "Pred") phrase_function = "predicate"; - if (phrase_function == "PreO") phrase_function = "predicate with object suffix"; - if (phrase_function == "PreS") phrase_function = "predicate with subject suffix"; - if (phrase_function == "PtcO") phrase_function = "participle with object suffix"; - if (phrase_function == "Ques") phrase_function = "question"; - if (phrase_function == "Rela") phrase_function = "relative"; - if (phrase_function == "Subj") phrase_function = "subject"; - if (phrase_function == "Supp") phrase_function = "supplementary constituent"; - if (phrase_function == "Time") phrase_function = "time reference"; - if (phrase_function == "Unkn") phrase_function.clear (); // "unknown"; - if (phrase_function == "Voct") phrase_function = "vocative"; - if (!phrase_function.empty ()) { - renderings.push_back (";"); - renderings.push_back ("phrase function:"); - renderings.push_back (phrase_function); - } - - string phrase_type = database_etcbc4.phrase_type (row); - if (phrase_type == "VP") phrase_type = "verbal phrase"; - if (phrase_type == "NP") phrase_type = "nominal phrase"; - if (phrase_type == "PrNP") phrase_type = "proper-noun phrase"; - if (phrase_type == "AdvP") phrase_type = "adverbial phrase"; - if (phrase_type == "PP") phrase_type = "prepositional phrase"; - if (phrase_type == "CP") phrase_type = "conjunctive phrase"; - if (phrase_type == "PPrP") phrase_type = "personal pronoun phrase"; - if (phrase_type == "DPrP") phrase_type = "demonstrative pronoun phrase"; - if (phrase_type == "IPrP") phrase_type = "interrogative pronoun phrase"; - if (phrase_type == "InjP") phrase_type = "interjectional phrase"; - if (phrase_type == "NegP") phrase_type = "negative phrase"; - if (phrase_type == "InrP") phrase_type = "interrogative phrase"; - if (phrase_type == "AdjP") phrase_type = "adjective phrase"; - renderings.push_back (";"); - renderings.push_back ("phrase type:"); - renderings.push_back (phrase_type); - - string phrase_relation = database_etcbc4.phrase_relation (row); - if (phrase_relation == "PrAd") phrase_relation = "predicative adjunct"; - if (phrase_relation == "Resu") phrase_relation = "resumption"; - if (phrase_relation == "NA") phrase_relation.clear (); - if (!phrase_relation.empty ()) { - renderings.push_back (";"); - renderings.push_back ("phrase relation:"); - renderings.push_back (phrase_relation); - } - - string phrase_a_relation = database_etcbc4.phrase_a_relation (row); - if (phrase_a_relation == "Appo") phrase_a_relation = "apposition"; - if (phrase_a_relation == "Sfxs") phrase_a_relation = "suffix specification"; - if (phrase_a_relation == "Link") phrase_a_relation = "conjunction"; - if (phrase_a_relation == "Spec") phrase_a_relation = "specification"; - if (phrase_a_relation == "Para") phrase_a_relation = "parallel"; - if (phrase_a_relation == "NA") phrase_a_relation.clear (); - if (!phrase_a_relation.empty ()) { - renderings.push_back (";"); - renderings.push_back ("phrase atom relation:"); - renderings.push_back (phrase_a_relation); - } - - string clause_text_type = database_etcbc4.clause_text_type (row); - string rendering; - while (!clause_text_type.empty ()) { - string type = clause_text_type.substr (clause_text_type.length () - 1); - clause_text_type.erase (clause_text_type.length () - 1, 1); - if (type == "?") type.clear (); - if (type == "N") type = "narrative"; - if (type == "D") type = "discursive"; - if (type == "Q") type = "quotation"; - if (!type.empty ()) { - if (!rendering.empty ()) rendering.append (" in a "); - rendering.append (type); - } - } - if (!rendering.empty ()) { - renderings.push_back (";"); - renderings.push_back ("text type:"); - renderings.push_back (rendering); - } - - string clause_type = database_etcbc4.clause_type (row); - if (clause_type == "AjCl") clause_type = "adjective clause"; - if (clause_type == "CPen") clause_type = "casus pendens"; - if (clause_type == "Defc") clause_type = "defective clause atom"; - if (clause_type == "Ellp") clause_type = "ellipsis"; - if (clause_type == "InfA") clause_type = "infinitive absolute clause"; - if (clause_type == "InfC") clause_type = "infinitive construct clause"; - if (clause_type == "MSyn") clause_type = "macrosyntactic sign"; - if (clause_type == "NmCl") clause_type = "nominal clause"; - if (clause_type == "Ptcp") clause_type = "participle clause"; - if (clause_type == "Reop") clause_type = "reopening"; - if (clause_type == "Unkn") clause_type.clear (); // Unknown"; - if (clause_type == "Voct") clause_type = "vocative clause"; - if (clause_type == "Way0") clause_type = "wayyiqtol-null clause"; - if (clause_type == "WayX") clause_type = "wayyiqtol-X clause"; - if (clause_type == "WIm0") clause_type = "we-imperative-null clause"; - if (clause_type == "WImX") clause_type = "we-imperative-X clause"; - if (clause_type == "WQt0") clause_type = "we-qatal-null clause"; - if (clause_type == "WQtX") clause_type = "we-qatal-X clause"; - if (clause_type == "WxI0") clause_type = "we-x-imperative-null clause"; - if (clause_type == "WXIm") clause_type = "we-X-imperative clause"; - if (clause_type == "WxIX") clause_type = "we-x-imperative-X clause"; - if (clause_type == "WxQ0") clause_type = "we-x-qatal-null clause"; - if (clause_type == "WXQt") clause_type = "we-X-qatal clause"; - if (clause_type == "WxQX") clause_type = "we-x-qatal-X clause"; - if (clause_type == "WxY0") clause_type = "we-x-yiqtol-null clause"; - if (clause_type == "WXYq") clause_type = "we-X-yiqtol clause"; - if (clause_type == "WxYX") clause_type = "we-x-yiqtol-X clause"; - if (clause_type == "WYq0") clause_type = "we-yiqtol-null clause"; - if (clause_type == "WYqX") clause_type = "we-yiqtol-X clause"; - if (clause_type == "xIm0") clause_type = "x-imperative-null clause"; - if (clause_type == "XImp") clause_type = "X-imperative clause"; - if (clause_type == "xImX") clause_type = "x-imperative-X clause"; - if (clause_type == "XPos") clause_type = "extraposition"; - if (clause_type == "xQt0") clause_type = "x-qatal-null clause"; - if (clause_type == "XQtl") clause_type = "X-qatal clause"; - if (clause_type == "xQtX") clause_type = "x-qatal-X clause"; - if (clause_type == "xYq0") clause_type = "x-yiqtol-null clause"; - if (clause_type == "XYqt") clause_type = "X-yiqtol clause"; - if (clause_type == "xYqX") clause_type = "x-yiqtol-X clause"; - if (clause_type == "ZIm0") clause_type = "zero-imperative-null clause"; - if (clause_type == "ZImX") clause_type = "zero-imperative-X clause"; - if (clause_type == "ZQt0") clause_type = "zero-qatal-null clause"; - if (clause_type == "ZQtX") clause_type = "zero-qatal-X clause"; - if (clause_type == "ZYq0") clause_type = "zero-yiqtol-null clause"; - if (clause_type == "ZYqX") clause_type = "zero-yiqtol-X clause"; - if (!clause_type.empty ()) { - renderings.push_back (";"); - renderings.push_back ("clause type:"); - renderings.push_back (clause_type); - } - - string clause_relation = database_etcbc4.clause_relation (row); - if (clause_relation == "Adju") clause_relation = "adjunctive clause"; - if (clause_relation == "Attr") clause_relation = "attributive clause"; - if (clause_relation == "Cmpl") clause_relation = "complement clause"; - if (clause_relation == "Coor") clause_relation = "coordinated clause"; - if (clause_relation == "Objc") clause_relation = "object clause"; - if (clause_relation == "PrAd") clause_relation = "predicative adjunct clause"; - if (clause_relation == "PreC") clause_relation = "predicative complement clause"; - if (clause_relation == "ReVo") clause_relation = "referral to the vocative"; - if (clause_relation == "ReSu") clause_relation = "resumptive clause"; - if (clause_relation == "RgRc") clause_relation = "regens/rectum connection"; - if (clause_relation == "Spec") clause_relation = "specification clause"; - if (clause_relation == "Subj") clause_relation = "subject clause"; - if (clause_relation == "NA") clause_relation.clear (); - if (!clause_relation.empty ()) { - renderings.push_back (";"); - renderings.push_back ("clause relation:"); - renderings.push_back (clause_relation); - } - - return filter::strings::implode (renderings, " "); -} - - -// Converts a code from MorphHb into a rendered BDB entry from the HebrewLexicon. -string lexicon_logic_render_bdb_entry (string code) -{ - Database_HebrewLexicon database_hebrewlexicon; - // Get the intermediate map value between the augmented Strong's numbers and the BDB lexicon. - string map = database_hebrewlexicon.getaug (code); - // Get the BDB entry ID. - string bdb = database_hebrewlexicon.getmap (map); - // Get the BDB definition. - string definition = database_hebrewlexicon.getbdb (bdb); - // Remove XML elements. - filter::strings::replace_between (definition, "<", ">", ""); - // Convert new lines to
    to retain some formatting. - definition = filter::strings::replace ("\n\n", "\n", definition); - definition = filter::strings::replace ("\n\n", "\n", definition); - definition = filter::strings::replace ("\n", "
    ", definition); - // Done. - return definition; -} - - -// Gets and removes an attribute from $xml, and updates $xml. -// Returns the attribute. -string lexicon_logic_get_remove_attribute (string & xml, const char * key) -{ - string value; - xml_document document; - xml_parse_result result = document.load_string (xml.c_str(), parse_ws_pcdata_single); - if (result) { - xml_node child = document.first_child (); - xml_attribute attribute = child.attribute (key); - if (attribute) { - value = attribute.value (); - child.remove_attribute (attribute); - stringstream output; - child.print (output, "", format_raw); - xml = output.str (); - } - } - return value; -} - - -// Gets the text contents of the $xml node. -string lexicon_logic_get_text (string & xml) -{ - string value; - xml_document document; - xml_parse_result result = document.load_string (xml.c_str(), parse_ws_pcdata_single); - if (result) { - xml_node child = document.first_child (); - xml_text text = child.text (); - if (text) { - value = text.get (); - text.set (""); - stringstream output; - child.print (output, "", format_raw); - xml = output.str (); - } - } - return value; -} - - -string lexicon_logic_hebrew_morphology_render (string value) -{ - // No data: bail out. - if (value.empty ()) return value; - - // A morphology item in the Open Scriptures Hebrew Bible starts with a language code. - // One language code is prefixed to the entire morphological parsing string, including prefixes, main word and suffixes. - string language = value.substr (0, 1); - bool hebrew = (language == "H"); - bool aramaic = (language == "A"); - // At times the parser may have ommitted the language code. Take Hebrew in that case. - if (hebrew || aramaic) value.erase (0, 1); - if (!hebrew && !aramaic) hebrew = true; - - // Description of the Hebrew Morphology Codes: - // http://openscriptures.github.io/morphhb/parsing/HebrewMorphologyCodes.html - - vector renderings; - - // A slash separates morphology items. - vector values = filter::strings::explode (value, '/'); - for (auto value2 : values) { - - if (value2.empty ()) continue; - - if (!renderings.empty ()) renderings.push_back (" + "); - - // Part of Speech - string part_of_speech = value2.substr (0, 1); - value2.erase (0, 1); - if (part_of_speech == "A") { - renderings.push_back ("adjective"); - // type gender number state - renderings.push_back (lexicon_logic_hebrew_morphology_render_type_adjective (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_gender (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_number (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_state (value2)); - } - else if (part_of_speech == "C") { - renderings.push_back ("conjunction"); - } - else if (part_of_speech == "D") { - renderings.push_back ("adverb"); - } - else if (part_of_speech == "N") { - renderings.push_back ("noun"); - // type gender number state - renderings.push_back (lexicon_logic_hebrew_morphology_render_type_noun (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_gender (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_number (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_state (value2)); - } - else if (part_of_speech == "P") { - renderings.push_back ("pronoun"); - // type person gender number - renderings.push_back (lexicon_logic_hebrew_morphology_render_type_pronoun (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_person (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_gender (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_number (value2)); - } - else if (part_of_speech == "R") { - renderings.push_back ("preposition"); - // type - renderings.push_back (lexicon_logic_hebrew_morphology_render_type_preposition (value2)); - } - else if (part_of_speech == "S") { - renderings.push_back ("suffix"); - // type person gender number - renderings.push_back (lexicon_logic_hebrew_morphology_render_type_suffix (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_person (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_gender (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_number (value2)); - } - else if (part_of_speech == "T") { - renderings.push_back ("particle"); - // type - renderings.push_back (lexicon_logic_hebrew_morphology_render_type_particle (value2)); - } - else if (part_of_speech == "V") { - renderings.push_back ("verb"); - // stem type person gender number state - renderings.push_back (lexicon_logic_hebrew_morphology_render_stem (hebrew, aramaic, value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_type_verb_conjugation (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_person (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_gender (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_number (value2)); - renderings.push_back (lexicon_logic_hebrew_morphology_render_state (value2)); - } - else { - renderings.push_back ("unknown"); - } - - } - - return filter::strings::implode (renderings, " "); -} - - -// Verb conjugation types -string lexicon_logic_hebrew_morphology_render_type_verb_conjugation (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "p") rendering = "perfect (qatal)"; - else if (code == "q") rendering = "sequential perfect (weqatal)"; - else if (code == "i") rendering = "imperfect (yiqtol)"; - else if (code == "w") rendering = "sequential imperfect (wayyiqtol)"; - else if (code == "h") rendering = "cohortative"; - else if (code == "j") rendering = "jussive"; - else if (code == "v") rendering = "imperative"; - else if (code == "r") rendering = "participle active"; - else if (code == "s") rendering = "participle passive"; - else if (code == "a") rendering = "infinitive absolute"; - else if (code == "c") rendering = "infinitive construct"; - else rendering = code; - } - return rendering; -} - - -// Adjective types -string lexicon_logic_hebrew_morphology_render_type_adjective (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "a") rendering = "adjective"; - else if (code == "c") rendering = "cardinal number"; - else if (code == "g") rendering = "gentilic"; - else if (code == "o") rendering = "ordinal number"; - else rendering = code; - } - return rendering; -} - - -// Noun types -string lexicon_logic_hebrew_morphology_render_type_noun (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "c") rendering = "common"; - else if (code == "g") rendering = "gentilic"; - else if (code == "p") rendering = "proper name"; - else rendering = code; - } - return rendering; -} - - -// Pronoun types -string lexicon_logic_hebrew_morphology_render_type_pronoun (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "d") rendering = "demonstrative"; - else if (code == "f") rendering = "indefinite"; - else if (code == "i") rendering = "interrogative"; - else if (code == "p") rendering = "personal"; - else if (code == "r") rendering = "relative"; - else rendering = code; - } - return rendering; -} - - -// Preposition types -string lexicon_logic_hebrew_morphology_render_type_preposition (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "d") rendering = "definite article"; - else rendering = code; - } - return rendering; -} - - -// Suffix types -string lexicon_logic_hebrew_morphology_render_type_suffix (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "d") rendering = "directional he"; - else if (code == "h") rendering = "paragogic he"; - else if (code == "n") rendering = "paragogic nun"; - else if (code == "p") rendering = "pronominal"; - else rendering = code; - } - return rendering; -} - - -// Particle types -string lexicon_logic_hebrew_morphology_render_type_particle (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "a") rendering = "affirmation"; - else if (code == "d") rendering = "definite article"; - else if (code == "e") rendering = "exhortation"; - else if (code == "i") rendering = "interrogative"; - else if (code == "j") rendering = "interjection"; - else if (code == "m") rendering = "demonstrative"; - else if (code == "n") rendering = "negative"; - else if (code == "o") rendering = "direct object marker"; - else if (code == "r") rendering = "relative"; - else rendering = code; - } - return rendering; -} - - -// Render verb stems. -string lexicon_logic_hebrew_morphology_render_stem (bool hebrew, bool aramaic, string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (hebrew) { - // Verb stems (Hebrew) - if (code == "q") rendering = "qal"; - else if (code == "N") rendering = "niphal"; - else if (code == "p") rendering = "piel"; - else if (code == "P") rendering = "pual"; - else if (code == "h") rendering = "hiphil"; - else if (code == "H") rendering = "hophal"; - else if (code == "t") rendering = "hithpael"; - else if (code == "o") rendering = "polel"; - else if (code == "O") rendering = "polal"; - else if (code == "r") rendering = "hithpolel"; - else if (code == "m") rendering = "poel"; - else if (code == "M") rendering = "poal"; - else if (code == "k") rendering = "palel"; - else if (code == "K") rendering = "pulal"; - else if (code == "Q") rendering = "qal passive"; - else if (code == "l") rendering = "pilpel"; - else if (code == "L") rendering = "polpal"; - else if (code == "f") rendering = "hithpalpel"; - else if (code == "D") rendering = "nithpael"; - else if (code == "j") rendering = "pealal"; - else if (code == "i") rendering = "pilel"; - else if (code == "u") rendering = "hothpaal"; - else if (code == "c") rendering = "tiphil"; - else if (code == "v") rendering = "hishtaphel"; - else if (code == "w") rendering = "nithpalel"; - else if (code == "y") rendering = "nithpoel"; - else if (code == "z") rendering = "hithpoel"; - else rendering = code; - } - else if (aramaic) { - // Verb stems (Aramaic) - if (code == "q") rendering = "peal"; - else if (code == "Q") rendering = "peil"; - else if (code == "u") rendering = "hithpeel"; - else if (code == "p") rendering = "pael"; - else if (code == "P") rendering = "ithpaal"; - else if (code == "M") rendering = "hithpaal"; - else if (code == "a") rendering = "aphel"; - else if (code == "h") rendering = "haphel"; - else if (code == "s") rendering = "saphel"; - else if (code == "e") rendering = "shaphel"; - else if (code == "H") rendering = "hophal"; - else if (code == "i") rendering = "ithpeel"; - else if (code == "t") rendering = "hishtaphel"; - else if (code == "v") rendering = "ishtaphel"; - else if (code == "w") rendering = "hithaphel"; - else if (code == "o") rendering = "polel"; - else if (code == "z") rendering = "ithpoel"; - else if (code == "r") rendering = "hithpolel"; - else if (code == "f") rendering = "hithpalpel"; - else if (code == "b") rendering = "hephal"; - else if (code == "c") rendering = "tiphel"; - else if (code == "m") rendering = "poel"; - else if (code == "l") rendering = "palpel"; - else if (code == "L") rendering = "ithpalpel"; - else if (code == "O") rendering = "ithpolel"; - else if (code == "G") rendering = "ittaphal"; - else rendering = code; - } - else { - rendering = code; - } - } - return rendering; -} - - -// Person -string lexicon_logic_hebrew_morphology_render_person (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "1") rendering = "first person"; - else if (code == "2") rendering = "second person"; - else if (code == "3") rendering = "third person"; - else if (code == "x") ; - // No rendering found, probable error in morphology, restore the code to not interrupt the subsequent codes. - else value.insert (0, code); - } - return rendering; -} - - -// Gender -string lexicon_logic_hebrew_morphology_render_gender (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "b") rendering = "both (noun)"; - else if (code == "c") rendering = "common (verb)"; - else if (code == "f") rendering = "feminine"; - else if (code == "m") rendering = "masculine"; - else rendering = code; - } - return rendering; -} - - -// Number -string lexicon_logic_hebrew_morphology_render_number (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "d") rendering = "dual"; - else if (code == "p") rendering = "plural"; - else if (code == "s") rendering = "singular"; - else rendering = code; - } - return rendering; -} - - -// State -string lexicon_logic_hebrew_morphology_render_state (string & value) -{ - string rendering; - if (!value.empty ()) { - string code = value.substr (0, 1); - value.erase (0, 1); - if (code == "a") rendering = "absolute"; - else if (code == "c") rendering = "construct"; - else if (code == "d") rendering = "determined"; - else rendering = code; - } - return rendering; -} - - -struct abbott_smith_walker: xml_tree_walker -{ - string text {}; - - bool text_element_already_handled {false}; - string previous_element_name {}; - - virtual bool for_each (xml_node& node) override - { - // Details of the current node. - string clas = node.attribute ("class").value (); - string name = node.name (); - - // Handle occurrences count in the New Testament. - if (name == "note") { - string type = node.attribute("type").value(); - if (type == "occurrencesNT") { - text.append ("occurs "); - text.append (node.text().get()); - text.append (" times in the New Testament, "); - text_element_already_handled = true; - return true; - } - } - - // Handle sense indicators. - if (name == "sense") { - if (previous_element_name != "sense") text.append (" sense "); - string n = node.attribute("n").value(); - if (!n.empty()) { - text.append (n); - text.append (" "); - } - } - - // Include node's text content. - if (name.empty()) { - if (!text_element_already_handled) { - text.append (node.value()); - } - text_element_already_handled = false; - } - - previous_element_name = name; - - // Continue parsing. - return true; - } -}; - - -string lexicon_logic_render_abbott_smiths_definition (string lemma, string strong) -{ - vector renderings; - - Database_AbbottSmith database_abbottsmith; - - string definition = database_abbottsmith.get (lemma, lexicon_logic_strong_number_cleanup (strong)); - - xml_document document; - document.load_string (definition.c_str()); - abbott_smith_walker tree_walker {}; - document.traverse (tree_walker); - renderings.push_back (tree_walker.text); - - string rendering = filter::strings::implode (renderings, " "); - rendering = filter::strings::trim (rendering); - - // If any rendering is given, then prefix the name of the lexicon. - if (!rendering.empty ()) { - rendering.insert(0, "Abbott Smith; "); - } - - // Done. - return rendering; -} diff --git a/lexicon/logic.h b/lexicon/logic.h deleted file mode 100644 index 6eeb409d1..000000000 --- a/lexicon/logic.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - - -#include - - -#define HEBREW_ETCBC4_NAME "Hebrew (University of Amsterdam)" -#define HEBREW_ETCBC4_PREFIX "e" -#define KJV_LEXICON_NAME "King James Bible with Lexicon" -#define KJV_LEXICON_PREFIX "k" -#define OSHB_NAME "Hebrew (Open Scriptures)" -#define OSHB_PREFIX "o" -#define SBLGNT_NAME "Greek (SBL)" -#define SBLGNT_PREFIX "s" -#define BDB_PREFIX "b" - - -class Webserver_Request; - - -std::vector lexicon_logic_resource_names (); -std::string lexicon_logic_get_html (Webserver_Request& webserver_request, std::string lexicon, int book, int chapter, int verse); -std::string lexicon_logic_get_script (std::string prefix); -std::string lexicon_logic_strong_number_cleanup (std::string strong); -void lexicon_logic_convert_morphhb_parsing_to_strong (std::string parsing, - std::vector & strongs, - std::vector & bdbs); -std::string lexicon_logic_render_strongs_definition (std::string strong); -std::string lexicon_logic_render_strongs_part_of_speech (std::string value); -std::string lexicon_logic_render_strongs_part_of_speech_stem (std::string abbrev); -std::string lexicon_logic_render_strongs_part_of_speech_person (std::string abbrev); -std::string lexicon_logic_render_strongs_part_of_speech_gender (std::string abbrev); -std::string lexicon_logic_render_strongs_part_of_speech_number (std::string abbrev); -std::string lexicon_logic_render_strongs_part_of_speech_state (std::string abbrev); -std::string lexicon_logic_define_user_strong (std::string strong); -std::string lexicon_logic_render_morphgnt_part_of_speech (std::string pos); -std::string lexicon_logic_render_morphgnt_parsing_code (std::string parsing); -std::string lexicon_logic_render_etcbc4_morphology (std::string rowid); -std::string lexicon_logic_render_bdb_entry (std::string code); -std::string lexicon_logic_get_remove_attribute (std::string & xml, const char * key); -std::string lexicon_logic_get_text (std::string & xml); - -std::string lexicon_logic_hebrew_morphology_render (std::string value); -std::string lexicon_logic_hebrew_morphology_render_type_verb_conjugation (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_type_adjective (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_type_noun (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_type_pronoun (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_type_preposition (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_type_suffix (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_type_particle (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_stem (bool hebrew, bool aramaic, std::string & value); -std::string lexicon_logic_hebrew_morphology_render_person (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_gender (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_number (std::string & value); -std::string lexicon_logic_hebrew_morphology_render_state (std::string & value); - -std::string lexicon_logic_render_abbott_smiths_definition (std::string lemma, std::string strong); - diff --git a/library/bibledit.cpp b/library/bibledit.cpp deleted file mode 100644 index ac771c908..000000000 --- a/library/bibledit.cpp +++ /dev/null @@ -1,496 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_CLIENT -#else -#include -#endif -#include -#include -#include -#include -#include -using namespace std; - - -bool bibledit_started {false}; - - -// Get Bibledit's version number. -const char * bibledit_get_version_number () -{ - return config::logic::version (); -} - - -// Get the port number that Bibledit's web server listens on. -// If the server already runs, it will give that port number. -// If the server does not yet run, on a client, it will negotiate a free port number, and give that. -const char * bibledit_get_network_port () -{ - // If the port number has already been set or negotiated, return that port number. - if (!config_globals_negotiated_port_number.empty()) return config_globals_negotiated_port_number.c_str(); - - // On a client device, negotiate a local port number. -#ifdef HAVE_CLIENT - vector ports = { 9876, 9987, 9998 }; - for (auto port : ports) { - if (!filter_url_port_can_connect ("localhost", port)) { - config_globals_negotiated_port_number = filter::strings::convert_to_string(port); - break; - } - } -#endif - - // Set the port number. - config::logic::http_network_port (); - - // Give the port number to the caller. - return config_globals_negotiated_port_number.c_str (); -} - - -// Initialize library. -// To be called once during the lifetime of the app. -// $package: The folder where the package data resides. -// $webroot: The document root folder for the web server. -void bibledit_initialize_library (const char * package, const char * webroot) -{ - // Must initialize libcurl before any threads are started. - // Only on the Cloud because it uses libcurl. - // The client does not use it. -#ifdef HAVE_CLOUD - curl_global_init (CURL_GLOBAL_ALL); -#endif - - // Thread locking. - thread_setup (); - - // Initialize SQLite: Full thread safety: https://www.sqlite.org/c3ref/threadsafe.html. - // This is supported to prevent "database locked" errors. - if (!sqlite3_threadsafe ()) { - std::cerr << "SQLite is not threadsafe" << std::endl; - } - sqlite3_config (SQLITE_CONFIG_SERIALIZED); - - // Binary file mode on Windows. -#ifdef HAVE_WINDOWS - _set_fmode (_O_BINARY); -#endif - - // Set the web root folder. - config_globals_document_root = webroot; - - // Initialize SSL/TLS (after webroot has been set). - thread ssl_tls = thread (filter_url_ssl_tls_initialize); - ssl_tls.detach (); - -#ifndef HAVE_CLIENT - // Cloud initializes OpenLDAP server access settings (after webroot has been set). - ldap_logic_initialize (); -#endif - -#ifdef HAVE_CLIENT - // Set local timezone offset in the library on Windows. - int hours = 0; -#ifdef HAVE_WINDOWS - TIME_ZONE_INFORMATION tzi; - [[maybe_unused]] auto dwRet = GetTimeZoneInformation (&tzi); - hours = 0 - (tzi.Bias / 60); -#else - // Set local timezone offset in the library on Linux. - time_t t = time (nullptr); - struct tm lt = {}; - localtime_r (&t, <); - hours = static_cast(round (lt.tm_gmtoff / 3600)); -#endif - config_globals_timezone_offset_utc = hours; - Database_Logs::log ("Timezone offset in hours: " + filter::strings::convert_to_string (hours)); -#endif - - // Initialize obfuscation data. - locale_logic_obfuscate_initialize (); - - // Read some configuration settings into memory for faster access. - config::logic::load_settings (); - - // Initialize data in a thread. - thread setup_thread = thread (setup_conditionally, package); - setup_thread.detach (); - - // Multiple start/stop guard. - bibledit_started = false; -} - - -// Sets whether the library considers any device that connects to be touch-enabled. -// This is necessary for client devices which are always logged-in. -// The detection of touch-enabled devices happens during login, -// so when the login is skipped, the device is not detected. -// Therefore the calling program can preset touch-enabled here through this library call. -void bibledit_set_touch_enabled (bool enabled) -{ - // Set global variable for use elsewhere in the library. - // A value of zero does nothing, - // so set it greater than or smaller than zero to have effect. - if (enabled) { - config_globals_touch_enabled = 1; - } - else { - config_globals_touch_enabled = -1; - } -} - - -// Start library. -// Can be called multiple times during the lifetime of the app. -void bibledit_start_library () -{ - // Repeating start guard. - if (bibledit_started) return; - bibledit_started = true; - - // Setup server behaviour. -#ifdef HAVE_CLIENT - config_globals_client_prepared = true; -#else - config_globals_client_prepared = false; -#endif - if (config::logic::demo_enabled ()) { - config_globals_open_installation = true; - } - - -#ifdef HAVE_CLOUD - // Indicate that the Cloud has started just now. - Database_Config_General::setJustStarted (true); -#endif - - - // Ignore SIGPIPE signal on Linux: When the browser cancels the request, it won't kill Bibledit. - // On Windows, this is not needed. -#ifndef HAVE_WINDOWS - signal (SIGPIPE, SIG_IGN); -#endif - - // Set running flag. - config_globals_webserver_running = true; - - // Run the plain web server in a thread. - config_globals_http_worker = new thread (http_server); - - // Run the secure web server in a thread. - config_globals_https_worker = new thread (https_server); - - // Run the timers in a thread. - config_globals_timer = new thread (timer_index); - - // Client should sync right after wake up. - sendreceive_queue_startup (); -} - - -// Gets the last page that was opened via the menu. -const char * bibledit_get_last_page () -{ - static string href = Database_Config_General::getLastMenuClick (); - return href.c_str(); -} - - -// Returns true if Bibledit is running. -bool bibledit_is_running () -{ - this_thread::sleep_for (chrono::milliseconds (10)); - if (config_globals_webserver_running) return true; - return false; -} - - -// Returns a non-empty string if the client is synchronizing with or downloading from Bibledit Cloud. -const char * bibledit_is_synchronizing () -{ - // If any of the sync tasks is running, the function considers bibledit to be synchronizing. - // On a bad network, it may happen that a task gets stuck. - // During the time that the task is stuck, till the watchdog kicks in, - // the sync is considered to be running. - // When mobile devices use this API call, - // the devices will remain awake during the time the task is stuck. - // The user may then have to manually put the device on standby. - bool syncing = false; - if (config_globals_syncing_bibles) syncing = true; - if (config_globals_syncing_changes) syncing = true; - if (config_globals_syncing_notes) syncing = true; - if (config_globals_syncing_settings) syncing = true; - if (config_globals_syncing_files) syncing = true; - if (config_globals_syncing_resources) syncing = true; - if (syncing) return "true"; - return "false"; -} - - -// Returns the last external URL the user clicked. -const char * bibledit_get_external_url () -{ - // The mechanism to return an allocated value for the clicked URL works like this: - // If there's an URL, it leaves the value untouched, increases a counter, and returns that URL. - // Next function call it sees the counter incremented, so it clears the URL plus counter. - // This way the value for the URL remains allocated while it gets returned to the caller. - // If the URL were clearer during this call, there would only be an empty string to be returned. - static int counter = 0; - if (counter) { - config_globals_external_url.clear (); - counter = 0; - } - if (!config_globals_external_url.empty ()) counter++; - // Return the URL. - return config_globals_external_url.c_str (); -} - - -// Returns the pages the calling app should open. -const char * bibledit_get_pages_to_open () -{ - config_globals_pages_to_open = Database_Config_General::getMenuInTabbedViewJSON (); - return config_globals_pages_to_open.c_str (); -} - - -// The normal shutdown procedure works by connecting to the internal webservers, -// and these connections in turn help with shutting down the listening internal webservers. -// In case all the internal webservers no longer are able to accept connections, -// the normal shutdown fails to work. -// This last-ditch function waits a few seconds, and if the app is still running then, -// it exits the app, regardless of the state of the internal webservers. -[[noreturn]] -void bibledit_last_ditch_forced_exit () -{ - this_thread::sleep_for (chrono::seconds (2)); - exit (0); -} - - -// Stop the library. -// Can be called multiple times during the lifetime of the app. -void bibledit_stop_library () -{ - // Repeating stop guard. - if (!bibledit_started) return; - bibledit_started = false; - - // Clear running flag. - config_globals_webserver_running = false; - - string url, error; - - // Connect to the plain webserver to initiate its shutdown mechanism. - url = "http://localhost:"; - url.append (config::logic::http_network_port ()); - filter_url_http_get (url, error, false); - -#ifdef RUN_SECURE_SERVER - // If the secure server runs, connect to it to initiate its shutdown mechanism. - string https_port = config::logic::https_network_port (); - if (https_port.length() > 1) { - url = "https://localhost:"; - url.append (https_port); - filter_url_http_get (url, error, false); - // Let the connection start, then close it. - // The server will then abort the TLS handshake, and shut down. - } -#endif - -#ifndef HAVE_ANDROID -#ifndef HAVE_IOS - // Schedule a timer to exit(0) the program in case the network stack fails to exit the servers. - // This should not be done on devices like Android and iOS - // because then the app would quit when the user moves the app to the background, - // whereas the user expects the app to stay alive in the background. - new thread (bibledit_last_ditch_forced_exit); -#endif -#endif - - // Wait till the servers and the timers shut down. - config_globals_http_worker->join (); - config_globals_https_worker->join (); - config_globals_timer->join (); - - // Clear memory. - delete config_globals_http_worker; - delete config_globals_https_worker; - delete config_globals_timer; -} - - -// Shut the library down. -// To be called exactly once during the lifetime of the app. -void bibledit_shutdown_library () -{ - // Remove thread locks. - thread_cleanup (); - - // Finalize SSL/TLS. - filter_url_ssl_tls_finalize (); - - // Multiple start/stop guard. - bibledit_started = false; -} - - -// Puts an entry in the journal. -void bibledit_log (const char * message) -{ - Database_Logs::log (message); -} - - -// The Bibledit outer shell calls this function when it runs on Chrome OS, -// rather than on Android. -// See https://github.com/bibledit/cloud/issues/282 -void bibledit_run_on_chrome_os () -{ - config_globals_running_on_chrome_os = true; -} - - -// Whether to disable the text selection pop-up that may occur on Chrome OS. -// See https://github.com/bibledit/cloud/issues/282 -const char * bibledit_disable_selection_popup_chrome_os () -{ - if (Database_Config_General::getDisableSelectionPopupChromeOS ()) { - return "true"; - } - return "false"; -} - - -// https://github.com/bibledit/cloud/issues/437 -// Accordance expects to receive a standardized verse reference. -// So, for instance, a reference of Psalm 13:3 in the Hebrew Bible -// will instead become the standardized (KJV-like) Psalm 13:2. -const char * bibledit_get_reference_for_accordance () -{ - // Keep the static reference always in memory as a global reference. - // The purpose is that the value remains live in memory for the caller, - // even after the function has returned, and local variables will have been destroyed. - static string reference; - - // Wait till all the data has been initialized. - // If the data is not yet initialized, return an empty reference instead. - if (!config_globals_data_initialized) return reference.c_str(); - - // Get the username on this client device. - string user = client_logic_get_username (); - - // Get the active Bible and its versification system. - Webserver_Request webserver_request; - webserver_request.session_logic()->set_username(user); - Database_Config_User database_config_user (webserver_request); - string bible = webserver_request.database_config_user ()->getBible (); - string versification = Database_Config_Bible::getVersificationSystem (bible); - - int book = Ipc_Focus::getBook (webserver_request); - int chapter = Ipc_Focus::getChapter (webserver_request); - int verse = Ipc_Focus::getVerse (webserver_request); - - // Accordance expects a verse reference in the English versification system. - vector passages; - Database_Mappings database_mappings; - if ((versification != filter::strings::english()) && !versification.empty ()) { - passages = database_mappings.translate (versification, filter::strings::english (), book, chapter, verse); - } else { - passages.push_back (Passage ("", book, chapter, filter::strings::convert_to_string (verse))); - } - if (passages.empty()) return ""; - - // Accordance expects for instance, 2 Corinthians 9:2, to be broadcast as "2CO 9:2". - book = passages[0].m_book; - chapter = passages[0].m_chapter; - string verse_s = passages[0].m_verse; - string usfm_id = database::books::get_usfm_from_id (static_cast(book)); - reference = usfm_id + " " + filter::strings::convert_to_string (chapter) + ":" + filter::strings::convert_to_string (verse_s); - - // Return the reference. - return reference.c_str (); -} - - -// https://github.com/bibledit/cloud/issues/437 -// Accordance sends a standardized verse reference. -// So, for instance, a reference of Psalm 13:3 in the Hebrew Bible -// will instead become the standardized (KJV-like) Psalm 13:2. -void bibledit_put_reference_from_accordance (const char * reference) -{ - // Get and set the user name on this client device. - string user = client_logic_get_username (); - Webserver_Request webserver_request; - webserver_request.session_logic()->set_username(user); - - // Setting whether to enable receiving verse references from Accordance. - bool enabled = webserver_request.database_config_user ()->getReceiveFocusedReferenceFromAccordance (); - if (!enabled) return; - - // Interpret the passage from Accordance, e.g. MAT 1:1. - // Accordance broadcasts for instance, 2 Corinthians 9:2, as "2CO 9:2". - vector book_rest = filter::strings::explode (reference, ' '); - if (book_rest.size() != 2) return; - int book = static_cast(database::books::get_id_from_usfm (book_rest[0])); - vector chapter_verse = filter::strings::explode(book_rest[1], ':'); - if (chapter_verse.size() != 2) return; - int chapter = filter::strings::convert_to_int(chapter_verse[0]); - int verse = filter::strings::convert_to_int(chapter_verse[1]); - - // Get the active Bible and its versification system. - Database_Config_User database_config_user (webserver_request); - string bible = webserver_request.database_config_user ()->getBible (); - string versification = Database_Config_Bible::getVersificationSystem (bible); - - // Accordance expects a verse reference in the English versification system. - vector passages; - Database_Mappings database_mappings; - if ((versification != filter::strings::english()) && !versification.empty ()) { - passages = database_mappings.translate (filter::strings::english (), versification, book, chapter, verse); - } else { - passages.push_back (Passage ("", book, chapter, filter::strings::convert_to_string (verse))); - } - if (passages.empty()) return; - - // Set the focused passage in Bibledit. - book = passages[0].m_book; - chapter = passages[0].m_chapter; - string verse_s = passages[0].m_verse; - Ipc_Focus::set (webserver_request, book, chapter, verse); -} diff --git a/library/bibledit.h b/library/bibledit.h deleted file mode 100644 index 6efc195b1..000000000 --- a/library/bibledit.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - const char * bibledit_get_version_number (); - const char * bibledit_get_network_port (); - void bibledit_initialize_library (const char * package, const char * webroot); - void bibledit_set_touch_enabled (bool enabled); - void bibledit_start_library (); - const char * bibledit_get_last_page (); - bool bibledit_is_running (); - const char * bibledit_is_synchronizing (); - const char * bibledit_get_external_url (); - const char * bibledit_get_pages_to_open (); - void bibledit_stop_library (); - void bibledit_shutdown_library (); - void bibledit_log (const char * message); - void bibledit_run_on_chrome_os (); - const char * bibledit_disable_selection_popup_chrome_os (); - const char * bibledit_get_reference_for_accordance (); - void bibledit_put_reference_from_accordance (const char * reference); - -#ifdef __cplusplus -} -#endif diff --git a/library/locks.c b/library/locks.c deleted file mode 100644 index 3bdfed84a..000000000 --- a/library/locks.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -// Config.h to be included. -#include -#include -#include -#ifndef HAVE_CLIENT -#include -#include - - -#define MUTEX_TYPE pthread_mutex_t -#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) -#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) -#define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) -#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) -#define THREAD_ID pthread_self( ) - - -/* This array will store all of the mutexes available to OpenSSL. */ -static MUTEX_TYPE *mutex_buf = NULL; - - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wunused-function" - - -static void locking_function(int mode, int n, const char * file, int line) -{ - if (mode & CRYPTO_LOCK) - MUTEX_LOCK(mutex_buf[n]); - else - MUTEX_UNLOCK(mutex_buf[n]); - if (file && line) {} -} - - -static unsigned long id_function() -{ - return ((unsigned long)THREAD_ID); -} - -#pragma clang diagnostic pop - - -#endif - - -void thread_setup () -{ -#ifndef HAVE_CLIENT - mutex_buf = malloc (CRYPTO_num_locks () * sizeof(MUTEX_TYPE)); - if (!mutex_buf) return; - int i; - for (i = 0; i < CRYPTO_num_locks (); i++) - MUTEX_SETUP (mutex_buf[i]); - CRYPTO_set_id_callback (id_function); - CRYPTO_set_locking_callback (locking_function); -#endif -} - - -void thread_cleanup () -{ -#ifndef HAVE_CLIENT - if (!mutex_buf) return; - CRYPTO_set_id_callback (NULL); - CRYPTO_set_locking_callback (NULL); - int i; - for (i = 0; i < CRYPTO_num_locks (); i++) - MUTEX_CLEANUP (mutex_buf[i]); - free (mutex_buf); - mutex_buf = NULL; -#endif -} - diff --git a/library/locks.h b/library/locks.h deleted file mode 100644 index a23138f92..000000000 --- a/library/locks.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - - void thread_setup (void); - void thread_cleanup (void); - -#ifdef __cplusplus -} -#endif diff --git a/locale/logic.cpp b/locale/logic.cpp deleted file mode 100644 index aa5a52fcc..000000000 --- a/locale/logic.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -using namespace std; - - -// Takes a month from 1 to 12, and returns its localized name. -string locale_logic_month (int month) -{ - switch (month) { - case 1: return translate ("January"); - case 2: return translate ("February"); - case 3: return translate ("March"); - case 4: return translate ("April"); - case 5: return translate ("May"); - case 6: return translate ("June"); - case 7: return translate ("July"); - case 8: return translate ("August"); - case 9: return translate ("September"); - case 10: return translate ("October"); - case 11: return translate ("November"); - case 12: return translate ("December"); - default: translate ("Month") + " " + filter::strings::convert_to_string (month); - } - return string(); -} - - -string locale_logic_date (int seconds) -{ - seconds = filter::date::local_seconds (seconds); - int day = filter::date::numerical_month_day (seconds); - int month = filter::date::numerical_month (seconds); - int year = filter::date::numerical_year (seconds); - return filter::strings::convert_to_string (day) + " " + locale_logic_month (month) + " " + filter::strings::convert_to_string (year); -} - - -string locale_logic_date_time (int seconds) -{ - // Localize the seconds. - seconds = filter::date::local_seconds (seconds); - // Convert the seconds into a human readable date and time. - string timestamp; - timestamp.append (locale_logic_date (seconds)); - timestamp.append (" "); - timestamp.append (filter::strings::fill (filter::strings::convert_to_string (filter::date::numerical_hour (seconds)), 2, '0')); - timestamp.append (":"); - timestamp.append (filter::strings::fill (filter::strings::convert_to_string (filter::date::numerical_minute (seconds)), 2, '0')); - timestamp.append (":"); - timestamp.append (filter::strings::fill (filter::strings::convert_to_string (filter::date::numerical_second (seconds)), 2, '0')); - // Done. - return timestamp; -} - - -// Return the available localizations. -map locale_logic_localizations () -{ - string directory = filter_url_create_root_path ({"locale"}); - vector files = filter_url_scandir (directory); - map localizations = {pair (std::string(), filter::strings::english ())}; - for (auto file : files) { - string suffix = filter_url_get_extension (file); - if (suffix == "po") { - string basename = filter::strings::replace ("." + suffix, "", file); - string path = filter_url_create_path ({directory, file}); - string contents = filter_url_file_get_contents (path); - string language = translate ("Unknown"); - vector lines = filter::strings::explode (contents, '\n'); - for (auto line : lines) { - if (line.find ("translation for bibledit") != std::string::npos) { - line.erase (0, 2); - line.erase (line.length () - 25); - language = line; - } - } - localizations.insert (pair (basename, language)); - } - } - return localizations; -} - - -unordered_map locale_logic_read_msgid_msgstr (string file) -{ - unordered_map translations; - string contents = filter_url_file_get_contents (file); - vector lines = filter::strings::explode (contents, '\n'); - string msgid; - string msgstr; - int stage = 0; - for (size_t i = 0; i < lines.size (); i++) { - // Clean the line up. - string line = filter::strings::trim (lines[i]); - // Skip a comment. - if (line.find ("#") == 0) continue; - // Deal with the messages. - if (line.find ("msgid") == 0) { - stage = 1; - line.erase (0, 5); - line = filter::strings::trim (line); - } - if (line.find ("msgstr") == 0) { - stage = 2; - line.erase (0, 6); - line = filter::strings::trim (line); - } - // Build msgid. - if (stage == 1) { - if (!line.empty ()) line.erase (0, 1); - if (!line.empty ()) line.erase (line.length () - 1); - msgid.append (line); - } - // Build msgstr. - if (stage == 2) { - if (line.empty ()) stage = 3; - } - if (stage == 2) { - if (!line.empty ()) line.erase (0, 1); - if (!line.empty ()) line.erase (line.length () - 1); - msgstr.append (line); - } - // Process data. - if (i == (lines.size () - 1)) stage = 3; - if (stage == 3) { - if (!msgid.empty ()) { - translations [msgid] = msgstr; - } - msgid.clear (); - msgstr.clear (); - } - } - return translations; -} - - -string locale_logic_text_loaded () -{ - return translate ("Loaded"); -} - - -string locale_logic_text_will_save () -{ - return translate ("Will save..."); -} - - -string locale_logic_text_updating () -{ - return translate ("Updating..."); -} - - -string locale_logic_text_updated () -{ - return translate ("Updated"); -} - - -string locale_logic_text_saving () -{ - return translate ("Saving..."); -} - - -string locale_logic_text_saved () -{ - return translate ("Saved"); -} - - -string locale_logic_text_retrying () -{ - return translate ("Retrying..."); -} - - -string locale_logic_text_reformat () -{ - return translate ("Reformat"); -} - - -string locale_logic_text_no_privileges_modify_book () -{ - return translate ("You do not have enough privileges to modify this book."); -} - - -string locale_logic_text_reload () -{ - return translate("Updated Bible text was loaded."); -} - - -// Returns the Unicode name of the $space. -string locale_logic_space_get_name (string space, bool english) -{ - if (space == " ") { - if (english) return "space"; - else return translate ("space"); - } - if (space == filter::strings::non_breaking_space_u00A0 ()) { - if (english) return "non-breaking space"; - else return translate ("non-breaking space"); - } - if (space == filter::strings::en_space_u2002 ()) { - if (english) return "en space"; - else return translate ("en space"); - } - if (space == filter::strings::figure_space_u2007 ()) { - if (english) return "figure space"; - else return translate ("figure space"); - } - if (space == filter::strings::narrow_non_breaking_space_u202F ()) { - if (english) return "narrow non-breaking space"; - else return translate ("narrow non-breaking space"); - } - return translate ("unknown"); -} - - -string locale_logic_deobfuscate (string value) -{ - // Replace longest strings first. - - // Change "Bbe" to "Bibledit". - value = filter::strings::replace ("Bbe", "Bibledit", value); - - // Change "bbe" to "bibledit". - value = filter::strings::replace ("bbe", "bibledit", value); - - // Change "Bb" to "Bible". - value = filter::strings::replace ("Bb", "Bible", value); - - // Change "bb" to "bible". This includes "bbe" to "Bibledit". - value = filter::strings::replace ("bb", "bible", value); - - // Done. - return value; -} - - -bool locale_logic_obfuscate_compare_internal (const string& a, const string& b) -{ - return (a.size() > b.size()); -} - - -void locale_logic_obfuscate_initialize () -{ - // Load the contents of the obfuscation configuration file - string filename = filter_url_create_root_path ({"obfuscate", "texts.txt"}); - string contents = filter_url_file_get_contents (filename); - vector lines = filter::strings::explode (contents, '\n'); - - // Container to map the original string to the obfuscated version. - map original_to_obfuscated; - - // Iterate over each line. - for (auto & line : lines) { - - // Trim lines. - line = filter::strings::trim (line); - - // Skip empty lines. - if (line.empty ()) continue; - - // Skip lines that start with the number sign #. - size_t pos = line.find ("#"); - if (pos != std::string::npos) if (pos < 3) continue; - - // Apart from texts to obfuscate, - // the settings can also contain a line to hide the Bible resources. - // Deal with it here. - pos = line.find ("HideBibleResources"); - if (pos != std::string::npos) { - config_globals_hide_bible_resources = true; - continue; - } - - // Lines require the equal sign = once. - vector obfuscation_pair = filter::strings::explode (line, '='); - if (obfuscation_pair.size () != 2) continue; - - // Deobfuscate recognized search terms. - string searchfor = locale_logic_deobfuscate (obfuscation_pair[0]); - - // Store the unsorted obfuscation data. - original_to_obfuscated [searchfor] = obfuscation_pair [1]; - locale_translate_obfuscation_search.push_back (searchfor); - } - - // Sort the original strings by their lengths. - // This enables the obfuscation to replace the longest string first, and the shortest last. - sort (locale_translate_obfuscation_search.begin(), locale_translate_obfuscation_search.end (), locale_logic_obfuscate_compare_internal); - - // Store the obfuscation data for use. - for (auto original : locale_translate_obfuscation_search) { - locale_translate_obfuscation_replace.push_back (original_to_obfuscated [original]); - } -} diff --git a/locale/logic.h b/locale/logic.h deleted file mode 100644 index 0627dba45..000000000 --- a/locale/logic.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -std::string locale_logic_month (int month); -std::string locale_logic_date (int seconds); -std::string locale_logic_date_time (int seconds); -std::map locale_logic_localizations (); -std::unordered_map locale_logic_read_msgid_msgstr (std::string file); - -std::string locale_logic_text_loaded (); -std::string locale_logic_text_will_save (); -std::string locale_logic_text_updating (); -std::string locale_logic_text_updated (); -std::string locale_logic_text_saving (); -std::string locale_logic_text_saved (); -std::string locale_logic_text_retrying (); -std::string locale_logic_text_reformat (); -std::string locale_logic_text_no_privileges_modify_book (); -std::string locale_logic_text_reload (); - -std::string locale_logic_space_get_name (std::string space, bool english); - -std::string locale_logic_deobfuscate (std::string value); -void locale_logic_obfuscate_initialize (); diff --git a/locale/translate.cpp b/locale/translate.cpp deleted file mode 100644 index 54b70496f..000000000 --- a/locale/translate.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -using namespace std; - - -// Storage for the user interface obfuscation strings. -vector locale_translate_obfuscation_search; -vector locale_translate_obfuscation_replace; - - -// Translates $english to its localized string. -string translate (string english) -{ - // Start off with the English message. - string result (english); - // Check whether a language has been set on the website or the app. - string localization = Database_Config_General::getSiteLanguage (); - if (!localization.empty ()) { - // Localize it. - Database_Localization database_localization = Database_Localization (localization); - result = database_localization.translate (english); - } - // Check whether there's obfuscation to be done. - if (!locale_translate_obfuscation_search.empty ()) { - // Obfuscate: Search and replace text. - // It replaces strings, not whole words as having certain boundaries. - for (unsigned int i = 0; i < locale_translate_obfuscation_search.size(); i++) { - result = filter::strings::replace (locale_translate_obfuscation_search [i], locale_translate_obfuscation_replace [i], result); - } - } - // Ready. - return result; -} - diff --git a/locale/translate.h b/locale/translate.h deleted file mode 100644 index 1dc2dd1c3..000000000 --- a/locale/translate.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -extern std::vector locale_translate_obfuscation_search; -extern std::vector locale_translate_obfuscation_replace; -std::string translate (std::string english); diff --git a/manage/accounts.cpp b/manage/accounts.cpp deleted file mode 100644 index b824310ac..000000000 --- a/manage/accounts.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string manage_accounts_url () -{ - return "manage/accounts"; -} - - -bool manage_accounts_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -string manage_accounts (Webserver_Request& webserver_request) -{ - bool user_updated = false; - bool privileges_updated = false; - - string page; - Assets_Header header = Assets_Header (translate("Accounts"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - page = header.run (); - - Assets_View view; - - // The user to act on. - string objectUsername = webserver_request.query["user"]; - int user_level = webserver_request.database_users ()->get_level (objectUsername); - - // Delete a user. - if (webserver_request.query.count ("delete")) { - string role = Filter_Roles::text (user_level); - string email = webserver_request.database_users ()->get_email (objectUsername); - vector users = webserver_request.database_users ()->get_users (); - vector administrators = webserver_request.database_users ()->getAdministrators (); - if (users.size () == 1) { - page += assets_page::error (translate("Cannot remove the last user")); - } else if ((user_level >= Filter_Roles::admin ()) && (administrators.size () == 1)) { - page += assets_page::error (translate("Cannot remove the last administrator")); - } else { - string message; - user_logic_delete_account (objectUsername, role, email, message); - user_updated = true; - message.append (" "); - message.append ("See the Journal for progress"); - page += assets_page::success (message); - } - } - - // Get the account creation times. - map account_creation_times; - { - vector lines = Database_Config_General::getAccountCreationTimes (); - for (auto line : lines) { - vector bits = filter::strings::explode(line, '|'); - if (bits.size() != 2) continue; - int seconds = filter::strings::convert_to_int(bits[0]); - string user = bits[1]; - account_creation_times [user] = seconds; - } - } - - // Retrieve assigned users. - const vector users = access_user::assignees (webserver_request); - for (const auto& username : users) { - - // Gather details for this user account. - user_level = webserver_request.database_users ()->get_level (username); - const string role = Filter_Roles::text (user_level); - const string email = webserver_request.database_users ()->get_email (username); - const int seconds = filter::date::seconds_since_epoch() - account_creation_times[username]; - const string days = filter::strings::convert_to_string (seconds / (3600 * 24)); - - // Pass information about this user to the flate engine for display. - view.add_iteration ("tbody", { - pair ("user", username), - pair ("days", days), - pair ("role", role), - pair ("email", email), - }); - } - - page += view.render ("manage", "accounts"); - - page += assets_page::footer (); - - if (user_updated) notes_logic_maintain_note_assignees (true); - if (privileges_updated) database_privileges_client_create (objectUsername, true); - - return page; -} diff --git a/manage/accounts.h b/manage/accounts.h deleted file mode 100644 index fb2de22c5..000000000 --- a/manage/accounts.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string manage_accounts_url (); -bool manage_accounts_acl (Webserver_Request& webserver_request); -std::string manage_accounts (Webserver_Request& webserver_request); diff --git a/manage/exports.cpp b/manage/exports.cpp deleted file mode 100644 index 76d06feec..000000000 --- a/manage/exports.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -const char * manage_exports_url () -{ - return "manage/exports"; -} - - -bool manage_exports_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::translator ()); -} - - -string space_href (string name) -{ - name = filter::strings::replace ("-", "", name); - name = filter::strings::replace (" ", "", name); - return name; -} - - -string manage_exports (Webserver_Request& webserver_request) -{ - string page; - Assets_Header header = Assets_Header (translate ("Export"), webserver_request); - header.add_bread_crumb (menu_logic_tools_menu (), menu_logic_tools_text ()); - page = header.run (); - Assets_View view; - - - if (webserver_request.query.count ("bible")) { - string bible = webserver_request.query["bible"]; - if (bible.empty()) { - Dialog_List dialog_list = Dialog_List ("exports", translate("Select a Bible"), "", ""); - vector bibles = access_bible::bibles (webserver_request); - for (const auto& bible2 : bibles) { - dialog_list.add_row (bible2, "bible", bible2); - } - page += dialog_list.run (); - return page; - } else { - webserver_request.database_config_user()->setBible (bible); - } - } - - - string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - view.set_variable ("bible", bible); - - - string checkbox = webserver_request.post ["checkbox"]; - bool checked = filter::strings::convert_to_bool (webserver_request.post ["checked"]); - - - if (webserver_request.query.count ("remove")) { - string directory = export_logic::bible_directory (bible); - filter_url_rmdir (directory); - Database_State::setExport (bible, 0, export_logic::export_needed); - view.set_variable ("success", translate("The export has been removed.")); - } - - - if (checkbox == "web") { - Database_Config_Bible::setExportWebDuringNight (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - return ""; - } - view.set_variable ("web", filter::strings::get_checkbox_status (Database_Config_Bible::getExportWebDuringNight (bible))); - - - if (webserver_request.query.count ("webnow")) { - export_logic::schedule_web (bible, true); - export_logic::schedule_web_index (bible, true); - view.set_variable ("success", translate("The Bible is being exported to Web format.")); - } - - - if (webserver_request.post.count ("emailsubmit")) { - string email = webserver_request.post["emailentry"]; - bool save = false; - if (email.empty ()) { - save = true; - view.set_variable ("success", translate("The email address for the feedback link was removed.")); - } else { - if (filter_url_email_is_valid (email)) { - save = true; - view.set_variable ("success", translate("The email address for the feedback link was saved.")); - } else { - view.set_variable ("error", translate("The email address is not valid.")); - } - } - if (save) Database_Config_Bible::setExportFeedbackEmail (bible, email); - } - view.set_variable ("email", Database_Config_Bible::getExportFeedbackEmail (bible)); - - - if (checkbox == "html") { - Database_Config_Bible::setExportHtmlDuringNight (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("html", filter::strings::get_checkbox_status (Database_Config_Bible::getExportHtmlDuringNight (bible))); - - - if (webserver_request.query.count ("htmlnow")) { - export_logic::schedule_html (bible, true); - view.set_variable ("success", translate("The Bible is being exported to Html format.")); - } - - - if (checkbox == "htmlpopup") { - Database_Config_Bible::setExportHtmlNotesOnHover (bible, checked); - } - view.set_variable ("htmlpopup", filter::strings::get_checkbox_status (Database_Config_Bible::getExportHtmlNotesOnHover (bible))); - - - if (checkbox == "usfm") { - Database_Config_Bible::setExportUsfmDuringNight (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("usfm", filter::strings::get_checkbox_status (Database_Config_Bible::getExportUsfmDuringNight (bible))); - - - if (webserver_request.query.count ("usfmnow")) { - export_logic::schedule_usfm (bible, true); - view.set_variable ("success", translate("The Bible is being exported to USFM format.")); - } - - - if (checkbox == "usfmsecure") { - Database_Config_Bible::setSecureUsfmExport (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("usfmsecure", filter::strings::get_checkbox_status (Database_Config_Bible::getSecureUsfmExport (bible))); - - - if (checkbox == "text") { - Database_Config_Bible::setExportTextDuringNight (bible, checked); - } - view.set_variable ("text", filter::strings::get_checkbox_status (Database_Config_Bible::getExportTextDuringNight (bible))); - - - if (webserver_request.query.count ("textnow")) { - export_logic::schedule_text_and_basic_usfm (bible, true); - view.set_variable ("success", translate("The Bible is being exported to basic USFM format and text.")); - } - - - if (checkbox == "odt") { - Database_Config_Bible::setExportOdtDuringNight (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("odt", filter::strings::get_checkbox_status (Database_Config_Bible::getExportOdtDuringNight (bible))); - - - if (webserver_request.query.count ("odtnow")) { - export_logic::schedule_open_document (bible, true); - view.set_variable ("success", translate("The Bible is being exported to OpenDocument format.")); - } - - - if (checkbox == "dropcaps") { - Database_Config_Bible::setExportChapterDropCapsFrames (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("dropcaps", filter::strings::get_checkbox_status (Database_Config_Bible::getExportChapterDropCapsFrames (bible))); - - - if (webserver_request.query.count ("pagewidth")) { - Dialog_Entry dialog_entry = Dialog_Entry ("exports", translate("Please enter a page width in millimeters"), Database_Config_Bible::getPageWidth (bible), "pagewidth", translate ("The width of A4 is 210 mm. The width of Letter is 216 mm.")); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("pagewidth")) { - int value = filter::strings::convert_to_int (webserver_request.post["entry"]); - if ((value >= 30) && (value <= 500)) { - Database_State::setExport (bible, 0, export_logic::export_needed); - Database_Config_Bible::setPageWidth (bible, filter::strings::convert_to_string (value)); - } - } - view.set_variable ("pagewidth", Database_Config_Bible::getPageWidth (bible)); - - - if (webserver_request.query.count ("pageheight")) { - Dialog_Entry dialog_entry = Dialog_Entry ("exports", translate("Please enter a page height in millimeters"), Database_Config_Bible::getPageHeight (bible), "pageheight", translate ("The height of A4 is 297 mm. The width of Letter is 279 mm.")); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("pageheight")) { - int value = filter::strings::convert_to_int (webserver_request.post["entry"]); - if ((value >= 40) && (value <= 600)) { - Database_State::setExport (bible, 0, export_logic::export_needed); - Database_Config_Bible::setPageHeight (bible, filter::strings::convert_to_string (value)); - } - } - view.set_variable ("pageheight", Database_Config_Bible::getPageHeight (bible)); - - - if (webserver_request.query.count ("innermargin")) { - Dialog_Entry dialog_entry = Dialog_Entry ("exports", translate("Please enter an inner margin size in millimeters"), Database_Config_Bible::getInnerMargin (bible), "innermargin", ""); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("innermargin")) { - int value = filter::strings::convert_to_int (webserver_request.post["entry"]); - if ((value >= 0) && (value <= 100)) { - Database_State::setExport (bible, 0, export_logic::export_needed); - Database_Config_Bible::setInnerMargin (bible, filter::strings::convert_to_string (value)); - } - } - view.set_variable ("innermargin", Database_Config_Bible::getInnerMargin (bible)); - - - if (webserver_request.query.count ("outermargin")) { - Dialog_Entry dialog_entry = Dialog_Entry ("exports", translate("Please enter an outer margin size in millimeters"), Database_Config_Bible::getOuterMargin (bible), "outermargin", ""); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("outermargin")) { - int value = filter::strings::convert_to_int (webserver_request.post["entry"]); - if ((value >= 0) && (value <= 100)) { - Database_State::setExport (bible, 0, export_logic::export_needed); - Database_Config_Bible::setOuterMargin (bible, filter::strings::convert_to_string (value)); - } - } - view.set_variable ("outermargin", Database_Config_Bible::getOuterMargin (bible)); - - - if (webserver_request.query.count ("topmargin")) { - Dialog_Entry dialog_entry = Dialog_Entry ("exports", translate("Please enter an top margin size in millimeters"), Database_Config_Bible::getTopMargin (bible), "topmargin", ""); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("topmargin")) { - int value = filter::strings::convert_to_int (webserver_request.post["entry"]); - if ((value >= 0) && (value <= 100)) { - Database_State::setExport (bible, 0, export_logic::export_needed); - Database_Config_Bible::setTopMargin (bible, filter::strings::convert_to_string (value)); - } - } - view.set_variable ("topmargin", Database_Config_Bible::getTopMargin (bible)); - - - if (webserver_request.query.count ("bottommargin")) { - Dialog_Entry dialog_entry = Dialog_Entry ("exports", translate("Please enter an bottom margin size in millimeters"), Database_Config_Bible::getBottomMargin (bible), "bottommargin", ""); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("bottommargin")) { - int value = filter::strings::convert_to_int (webserver_request.post["entry"]); - if ((value >= 0) && (value <= 100)) { - Database_State::setExport (bible, 0, export_logic::export_needed); - Database_Config_Bible::setBottomMargin (bible, filter::strings::convert_to_string (value)); - } - } - view.set_variable ("bottommargin", Database_Config_Bible::getBottomMargin (bible)); - - - if (checkbox == "dateinheader") { - Database_Config_Bible::setDateInHeader (bible, checked); - } - view.set_variable ("dateinheader", filter::strings::get_checkbox_status (Database_Config_Bible::getDateInHeader (bible))); - - - if (checkbox == "odtsecure") { - Database_Config_Bible::setSecureOdtExport (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("odtsecure", filter::strings::get_checkbox_status (Database_Config_Bible::getSecureOdtExport (bible))); - - - vector spaces = { " ", filter::strings::non_breaking_space_u00A0 (), filter::strings::en_space_u2002 (), filter::strings::figure_space_u2007 (), filter::strings::narrow_non_breaking_space_u202F () }; - if (webserver_request.query.count ("odtwhitespace")) { - string odtwhitespace = webserver_request.query ["odtwhitespace"]; - for (auto space : spaces) { - // Work with non-localized, English, space names. - // Then it works across localizations. - string href = space_href (locale_logic_space_get_name (space, true)); - if (odtwhitespace == href) { - Database_Config_Bible::setOdtSpaceAfterVerse (bible, space); - } - } - } - string space_setting = Database_Config_Bible::getOdtSpaceAfterVerse (bible); - for (auto space : spaces) { - string name = locale_logic_space_get_name (space, true); - string href = space_href (name); - string cssclass; - if (space == space_setting) { - cssclass = "active"; - } - name = locale_logic_space_get_name (space, false); - view.add_iteration ("spaces", { pair ("space", href), pair ("class", cssclass), pair ("name", name) } ); - } - - - if (checkbox == "odtqleft") { - Database_Config_Bible::setOdtPoetryVersesLeft (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("odtqleft", filter::strings::get_checkbox_status (Database_Config_Bible::getOdtPoetryVersesLeft (bible))); - { - Database_Styles database_styles; - vector markers = database_styles.getMarkers (styles_logic_standard_sheet ()); - vector poetry_styles; - for (auto & style : markers) { - if (filter::usfm::is_standard_q_poetry (style)) poetry_styles.push_back(style); - } - view.set_variable("poetrymarkers", filter::strings::implode(poetry_styles, " ")); - } - - - if (webserver_request.post.count ("fontsubmit")) { - string font = webserver_request.post["fontentry"]; - Database_State::setExport (bible, 0, export_logic::export_needed); - Database_Config_Bible::setExportFont (bible, font); - view.set_variable ("success", translate("The font for securing exports was saved.")); - } - view.set_variable ("font", Database_Config_Bible::getExportFont (bible)); - - - if (checkbox == "autocaller") { - Database_Config_Bible::setOdtAutomaticNoteCaller (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("autocaller", filter::strings::get_checkbox_status (Database_Config_Bible::getOdtAutomaticNoteCaller (bible))); - - - if (checkbox == "info") { - Database_Config_Bible::setGenerateInfoDuringNight (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("info", filter::strings::get_checkbox_status (Database_Config_Bible::getGenerateInfoDuringNight (bible))); - - - if (webserver_request.query.count ("infonow")) { - export_logic::schedule_info (bible, true); - view.set_variable ("success", translate("The info documents are being generated.")); - } - - - if (checkbox == "esword") { - Database_Config_Bible::setExportESwordDuringNight (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("esword", filter::strings::get_checkbox_status (Database_Config_Bible::getExportESwordDuringNight (bible))); - - - if (webserver_request.query.count ("eswordnow")) { - export_logic::schedule_e_sword (bible, true); - view.set_variable ("success", translate("The Bible is being exported to e-Sword format.")); - } - - - if (checkbox == "onlinebible") { - Database_Config_Bible::setExportOnlineBibleDuringNight (bible, checked); - Database_State::setExport (bible, 0, export_logic::export_needed); - } - view.set_variable ("onlinebible", filter::strings::get_checkbox_status (Database_Config_Bible::getExportOnlineBibleDuringNight (bible))); - - - if (webserver_request.query.count ("onlinebiblenow")) { - export_logic::schedule_online_bible (bible, true); - view.set_variable ("success", translate("The Bible is being exported to Online Bible format.")); - } - - - if (webserver_request.post.count ("passwordsubmit")) { - string password = webserver_request.post["passwordentry"]; - Database_State::setExport (bible, 0, export_logic::export_needed); - Database_Config_Bible::setExportPassword (bible, password); - view.set_variable ("success", translate("The password for securing exports was saved.")); - } - // If the password is needed, but not set, set a default password. - if (Database_Config_Bible::getSecureUsfmExport (bible) || Database_Config_Bible::getSecureOdtExport (bible)) { - if (Database_Config_Bible::getExportPassword (bible).empty ()) { - Database_State::setExport (bible, 0, export_logic::export_needed); - Database_Config_Bible::setExportPassword (bible, "password"); - } - } - view.set_variable ("password", Database_Config_Bible::getExportPassword (bible)); - - - if (webserver_request.query.count ("bibledropboxnow")) { - string username = webserver_request.session_logic()->currentUser (); - tasks_logic_queue (SUBMITBIBLEDROPBOX, { username, bible }); - string msg = translate("The Bible will be submitted to the Bible Drop Box."); - msg.append (" "); - msg.append (translate("You will receive email with further details.")); - view.set_variable ("success", msg); - } - - -#ifdef HAVE_CLIENT - view.enable_zone ("client"); - view.set_variable ("cloudlink", client_logic_link_to_cloud (manage_exports_url (), translate ("Go to Bibledit Cloud to submit the Bible there."))); -#else - view.enable_zone ("cloud"); -#endif - view.set_variable ("external", assets_external_logic_link_addon ()); - - - page += view.render ("manage", "exports"); - page += assets_page::footer (); - return page; -} diff --git a/manage/exports.h b/manage/exports.h deleted file mode 100644 index 08534fe8a..000000000 --- a/manage/exports.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -const char * manage_exports_url (); -bool manage_exports_acl (Webserver_Request& webserver_request); -std::string manage_exports (Webserver_Request& webserver_request); diff --git a/manage/hyphenate.cpp b/manage/hyphenate.cpp deleted file mode 100644 index 76bc8c7bc..000000000 --- a/manage/hyphenate.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -void manage_hyphenate (string bible, string user) -{ - Database_Bibles database_bibles; - - - string inputBible (bible); - string outputBible = inputBible + "-hyphenated"; - - - Database_Logs::log ("Reading Bible " + inputBible + ", adding soft hyphens, putting it into Bible " + outputBible); - - - // Get the two sets of characters as arrays. - // The /u switch treats the text as UTF8 Unicode. - vector firstset; - string s_firstset = Database_Config_Bible::getHyphenationFirstSet (inputBible); - size_t length = filter::strings::unicode_string_length (s_firstset); - for (size_t i = 0; i < length; i++) { - string s = filter::strings::unicode_string_substr (s_firstset, i, 1); - if (s == " ") continue; - firstset.push_back (s); - } - vector secondset; - string s_secondset = Database_Config_Bible::getHyphenationSecondSet (inputBible); - length = filter::strings::unicode_string_length (s_secondset); - for (size_t i = 0; i < length; i++) { - string s = filter::strings::unicode_string_substr (s_secondset, i, 1); - if (s == " ") continue; - secondset.push_back (s); - } - - - // Delete and (re)create the hyphenated Bible. - database_bibles.delete_bible (outputBible); - DatabasePrivileges::remove_bible (outputBible); - Database_Config_Bible::remove (outputBible); - database_bibles.create_bible (outputBible); - Webserver_Request webserver_request; - if (!access_bible::write (webserver_request, outputBible, user)) { - // Only grant access if the user does not yet have it. - // This avoid assigning the Bible to the user in case no Bible was assigned to anyone, - // in which case assigning this Bible to the user would possible withdraw privileges from other users. - DatabasePrivileges::set_bible (user, outputBible, true); - } - - - // Go through the input Bible's books and chapters. - vector books = database_bibles.get_books (inputBible); - for (auto book : books) { - Database_Logs::log (database::books::get_english_from_id (static_cast(book))); - vector chapters = database_bibles.get_chapters (inputBible, book); - for (auto chapter : chapters) { - string data = database_bibles.get_chapter (inputBible, book, chapter); - data = hyphenate_at_transition (firstset, secondset, data); - database_bibles.store_chapter (outputBible, book, chapter, data); - } - } - - - Database_Logs::log ("The Bible has been hyphenated"); -} - - -/** - * This filter inserts soft hyphens in text. - * It goes through $text character by character. - * At the transition from any character in $firstset - * to any character in $secondset, it inserts a soft hyphen. - * $firstset: vector of characters. - * $secondset: vector of characters. - * $text: A string of text to operate on. - * Returns: The hyphenated text. - */ -string hyphenate_at_transition (vector & firstset, vector & secondset, string text) -{ - // Verify the input. - if (firstset.empty ()) return text; - if (secondset.empty ()) return text; - if (text.empty ()) return text; - - // Split the text up into lines and go through each one. - vector lines = filter::strings::explode (text, '\n'); - for (string & line : lines) { - - // Split the line up into an array of UTF8 Unicode characters. - vector characters; - size_t length = filter::strings::unicode_string_length (line); - for (size_t i = 0; i < length; i++) { - string s = filter::strings::unicode_string_substr (line, i, 1); - characters.push_back (s); - } - - // Processor flags. - bool previousCharacterWasRelevant = false; - bool thisCharacterIsRelevant = false; - bool isUsfm = false; - - // Process each character. - for (unsigned int i = 0; i < characters.size (); i++) { - - string character = characters [i]; - - // Skip USFM marker. - if (character == "\\") isUsfm = true; - - if (!isUsfm) { - - // Check whether to insert the soft hyphen here. - thisCharacterIsRelevant = in_array (character, secondset); - if ((thisCharacterIsRelevant) && (previousCharacterWasRelevant)) { - if (!hyphenate_is_near_white_space (characters, static_cast (i))) { - characters[i] = filter::strings::soft_hyphen_u00AD () + character; - } - } - - // Flag for next iteration. - previousCharacterWasRelevant = in_array (character, firstset); - } - - if (isUsfm) { - // Look for the end of the USFM marker. - if (character == " ") isUsfm = false; - if (character == "*") isUsfm = false; - } - } - - // Re-assemble the line from the separate (updated) characters. - line = filter::strings::implode (characters, ""); - - } - - // Assemble the hyphenated text from the separate lines. - text = filter::strings::implode (lines, "\n"); - return text; -} - - -/** - * This filter looks whether the offset is near whitespace - * in the vector of characters. - * Returns: true or false. - */ -bool hyphenate_is_near_white_space (const vector & characters, int offset) -{ - // The constant for the nearness to the start of the word. - int start = offset - 2; - // The constant for the nearness to the end of the word. - int end = offset + 2; - if (start < 0) start = 0; - if (end > static_cast(characters.size())) end = static_cast (characters.size()); - for (size_t i = static_cast(start); i < static_cast(end); i++) { - if (characters[i] == " ") return true; - } - return false; -} - - -// Another method for hyphenation could be to rely on the routines as used by TeX. -// TeX has hyphenation patterns. -// The 'soul' package can show possible word breaks. diff --git a/manage/hyphenate.h b/manage/hyphenate.h deleted file mode 100644 index a47403813..000000000 --- a/manage/hyphenate.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -void manage_hyphenate (std::string bible, std::string user); -std::string hyphenate_at_transition (std::vector & firstset, std::vector & secondset, std::string text); -bool hyphenate_is_near_white_space (const std::vector & characters, int offset); diff --git a/manage/hyphenation.cpp b/manage/hyphenation.cpp deleted file mode 100644 index 047d1b5c1..000000000 --- a/manage/hyphenation.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -const char * manage_hyphenation_url () -{ - return "manage/hyphenation"; -} - - -bool manage_hyphenation_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -string manage_hyphenation (Webserver_Request& webserver_request) -{ - string page; - Assets_Header header = Assets_Header (translate ("Hyphenation"), webserver_request); - header.add_bread_crumb (menu_logic_tools_menu (), menu_logic_tools_text ()); - page = header.run (); - Assets_View view; - - - string bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - - - string success; - string error; - - - // Character sets submission. - if (webserver_request.post.count ("sets")) { - string firstset = webserver_request.post["firstset"]; - Database_Config_Bible::setHyphenationFirstSet (bible, firstset); - string secondset = webserver_request.post["secondset"]; - Database_Config_Bible::setHyphenationSecondSet (bible, secondset); - success = translate("The two sets of characters were saved"); - } - - - if (webserver_request.query.count ("bible")) { - string bible2 = webserver_request.query ["bible"]; - if (bible2.empty()) { - Dialog_List dialog_list = Dialog_List ("", translate("Which Bible would you like to take the data from?"), "", ""); - vector bibles = access_bible::bibles (webserver_request); - for (auto list_bible : bibles) { - dialog_list.add_row (list_bible, "bible", list_bible); - } - page += dialog_list.run (); - return page; - } else { - webserver_request.database_config_user()->setBible (bible2); - } - } - bible = access_bible::clamp (webserver_request, webserver_request.database_config_user()->getBible ()); - - - string firstset = Database_Config_Bible::getHyphenationFirstSet (bible); - string secondset = Database_Config_Bible::getHyphenationSecondSet (bible); - if (webserver_request.query.count ("run")) { - if (bible == "") { - error = translate("No Bible given"); - } else if (firstset == "") { - error = translate("No first set of characters given"); - } else if (secondset == "") { - error = translate("No second set of characters given"); - } else { - tasks_logic_queue (HYPHENATE, {bible, webserver_request.session_logic()->currentUser ()}); - redirect_browser (webserver_request, journal_index_url ()); - return ""; - } - } - - - view.set_variable ("firstset", firstset); - view.set_variable ("secondset", secondset); - view.set_variable ("bible", bible); - view.set_variable ("success", success); - view.set_variable ("error", error); - - - page += view.render ("manage", "hyphenation"); - page += assets_page::footer (); - return page; -} diff --git a/manage/hyphenation.h b/manage/hyphenation.h deleted file mode 100644 index 136aae01e..000000000 --- a/manage/hyphenation.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -const char * manage_hyphenation_url (); -bool manage_hyphenation_acl (Webserver_Request& webserver_request); -std::string manage_hyphenation (Webserver_Request& webserver_request); diff --git a/manage/index.cpp b/manage/index.cpp deleted file mode 100644 index 993d45f3f..000000000 --- a/manage/index.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string manage_index_url () -{ - return "manage/index"; -} - - -bool manage_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -string manage_index (Webserver_Request& webserver_request) -{ - string page; - Assets_Header header = Assets_Header (translate("Manage"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - page = header.run (); - Assets_View view; - page += view.render ("manage", "index"); - page += assets_page::footer (); - return page; -} diff --git a/manage/index.h b/manage/index.h deleted file mode 100644 index f8344e108..000000000 --- a/manage/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string manage_index_url (); -bool manage_index_acl (Webserver_Request& webserver_request); -std::string manage_index (Webserver_Request& webserver_request); diff --git a/manage/privileges.cpp b/manage/privileges.cpp deleted file mode 100644 index 75d50612d..000000000 --- a/manage/privileges.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string manage_privileges_url () -{ - return "manage/privileges"; -} - - -bool manage_privileges_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -string manage_privileges (Webserver_Request& webserver_request) -{ - string page {}; - Assets_Header header = Assets_Header (translate("Read/write"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (manage_users_url (), menu_logic_manage_users_text ()); - page = header.run (); - Assets_View view {}; - - - // Get the user and his/her level. - string user {webserver_request.query["user"]}; - if (user.empty()) user = webserver_request.post["val1"]; - view.set_variable ("user", user); - int level {0}; - access_logic::user_level (webserver_request, user, level); - - - // Usernames for setting default new user privilege. - set defusers = access_logic::default_privilege_usernames (); - - - bool privileges_updated {false}; - string checkbox {webserver_request.post ["checkbox"]}; - bool checked {filter::strings::convert_to_bool (webserver_request.post ["checked"])}; - bool state {false}; - - - // The privilege to view the Resources. - if (checkbox == "viewresources") { - DatabasePrivileges::set_feature (user, PRIVILEGE_VIEW_RESOURCES, checked); - privileges_updated = true; - } - state = DatabasePrivileges::get_feature (user, PRIVILEGE_VIEW_RESOURCES); - if (level >= access_logic::view_resources_role () && defusers.find (user) == defusers.end ()) { - state = true; - view.set_variable ("viewresourcesdisabled", filter::strings::get_disabled (true)); - } - view.set_variable ("viewresourceschecked", filter::strings::get_checkbox_status (state)); - - - // Privilege to view the Consultation Notes. - if (checkbox == "viewnotes") { - DatabasePrivileges::set_feature (user, PRIVILEGE_VIEW_NOTES, checked); - privileges_updated = true; - } - state = DatabasePrivileges::get_feature (user, PRIVILEGE_VIEW_NOTES); - if (level >= access_logic::view_resources_role () && defusers.find (user) == defusers.end ()) { - view.set_variable ("viewnotesdisabled", filter::strings::get_disabled (true)); - } - state = access_logic::privilege_view_notes (webserver_request, user); - view.set_variable ("viewnoteschecked", filter::strings::get_checkbox_status (state)); - - - // Privilege to create and comment on Consultation Notes. - if (checkbox == "createcommentnotes") { - DatabasePrivileges::set_feature (user, PRIVILEGE_CREATE_COMMENT_NOTES, checked); - privileges_updated = true; - } - state = DatabasePrivileges::get_feature (user, PRIVILEGE_CREATE_COMMENT_NOTES); - if (level >= access_logic::view_resources_role () && defusers.find (user) == defusers.end ()) { - view.set_variable ("createcommentnotesdisabled", filter::strings::get_disabled (true)); - } - state = access_logic::privilege_create_comment_notes (webserver_request, user); - view.set_variable ("createcommentnoteschecked", filter::strings::get_checkbox_status (state)); - - - // Privilege to delete Consultation Notes. - if (checkbox == "deletenotes") { - webserver_request.database_config_user ()->setPrivilegeDeleteConsultationNotesForUser (user, checked); - } - state = DatabasePrivileges::get_feature (user, PRIVILEGE_CREATE_COMMENT_NOTES); - if (level >= access_logic::delete_consultation_notes_role () && defusers.find (user) == defusers.end ()) { - view.set_variable ("deletenotesdisabled", filter::strings::get_disabled (true)); - } - state = access_logic::privilege_delete_consultation_notes (webserver_request, user); - view.set_variable ("deletenoteschecked", filter::strings::get_checkbox_status (state)); - - - // Privilege to use advanced mode. - if (checkbox == "useadvancedmode") { - webserver_request.database_config_user ()->setPrivilegeUseAdvancedModeForUser (user, checked); - } - if (level >= access_logic::use_advanced_mode_role () && defusers.find (user) == defusers.end ()) { - view.set_variable ("useadvancedmodedisabled", filter::strings::get_disabled (true)); - } - state = access_logic::privilege_use_advanced_mode (webserver_request, user); - view.set_variable ("useadvancedmodechecked", filter::strings::get_checkbox_status (state)); - - - // Privilege to be able to edit and set stylesheets. - if (checkbox == "editstylesheets") { - webserver_request.database_config_user ()->setPrivilegeSetStylesheetsForUser (user, checked); - } - if (level >= access_logic::set_stylesheets_role () && defusers.find (user) == defusers.end ()) { - view.set_variable ("editstylesheetsdisabled", filter::strings::get_disabled (true)); - } - state = access_logic::privilege_set_stylesheets (webserver_request, user); - view.set_variable ("editstylesheetschecked", filter::strings::get_checkbox_status (state)); - - - if (privileges_updated) database_privileges_client_create (user, true); - - - if (privileges_updated) return filter::strings::get_reload (); - - - page += view.render ("manage", "privileges"); - - page += assets_page::footer (); - - return page; -} diff --git a/manage/privileges.h b/manage/privileges.h deleted file mode 100644 index e384f23b6..000000000 --- a/manage/privileges.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string manage_privileges_url (); -bool manage_privileges_acl (Webserver_Request& webserver_request); -std::string manage_privileges (Webserver_Request& webserver_request); diff --git a/manage/users.cpp b/manage/users.cpp deleted file mode 100644 index 12121ae16..000000000 --- a/manage/users.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string manage_users_url () -{ - return "manage/users"; -} - - -bool manage_users_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -string manage_users (Webserver_Request& webserver_request) -{ - bool user_updated = false; - bool privileges_updated = false; - - - string page; - Assets_Header header = Assets_Header (translate("Users"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - page = header.run (); - - - Assets_View view; - - - int myLevel = webserver_request.session_logic ()->currentLevel (); - - - // Set the default new user role. - if (webserver_request.post.count ("defaultacl")) { - int defaultacl = filter::strings::convert_to_int (webserver_request.post ["defaultacl"]); - Database_Config_General::setDefaultNewUserAccessLevel(defaultacl); - assets_page::success (translate("The default new user is changed.")); - } - - - // Set the chosen default new user role on the option HTML tag. - string default_acl = filter::strings::convert_to_string (Database_Config_General::getDefaultNewUserAccessLevel ()); - string default_acl_html; - default_acl_html = Options_To_Select::add_selection ("Guest", filter::strings::convert_to_string(Filter_Roles::guest()), default_acl_html); - default_acl_html = Options_To_Select::add_selection ("Member", filter::strings::convert_to_string(Filter_Roles::member()), default_acl_html); - view.set_variable ("defaultacloptags", Options_To_Select::mark_selected (default_acl, default_acl_html)); - view.set_variable ("defaultacl", default_acl); - - - // New user creation. - if (webserver_request.query.count ("new")) { - Dialog_Entry dialog_entry = Dialog_Entry ("users", translate("Please enter a name for the new user"), "", "new", ""); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("new")) { - string user = webserver_request.post["entry"]; - if (webserver_request.database_users ()->usernameExists (user)) { - page += assets_page::error (translate("User already exists")); - } else { - - // Set the role of the new created user, it is set as member if no - // default has been set by an administrator. - int role = Database_Config_General::getDefaultNewUserAccessLevel (); - webserver_request.database_users ()->add_user(user, user, role, ""); - - // Set default privileges on new created user. - set defusers = access_logic::default_privilege_usernames (); - vector privileges = {PRIVILEGE_VIEW_RESOURCES, PRIVILEGE_VIEW_NOTES, PRIVILEGE_CREATE_COMMENT_NOTES}; - auto default_username = next(defusers.begin(), (unsigned)(long)(unsigned)role + 1); - for (auto & privilege : privileges) { - bool state = DatabasePrivileges::get_feature (*default_username, privilege); - DatabasePrivileges::set_feature (user, privilege, state); - } - - bool deletenotes = webserver_request.database_config_user ()->getPrivilegeDeleteConsultationNotesForUser (*default_username); - bool useadvancedmode = webserver_request.database_config_user ()->getPrivilegeUseAdvancedModeForUser (*default_username); - bool editstylesheets = webserver_request.database_config_user ()->getPrivilegeSetStylesheetsForUser (*default_username); - - if (deletenotes) webserver_request.database_config_user ()->setPrivilegeDeleteConsultationNotesForUser (user, 1); - if (useadvancedmode) webserver_request.database_config_user ()->setPrivilegeUseAdvancedModeForUser (user, 1); - if (editstylesheets) webserver_request.database_config_user ()->setPrivilegeSetStylesheetsForUser (user, 1); - - page += assets_page::error (*default_username); - - user_logic_store_account_creation (user); - user_updated = true; - page += assets_page::success (translate("User created")); - } - } - - - // The user to act on. - string objectUsername = webserver_request.query["user"]; - int objectUserLevel = webserver_request.database_users ()->get_level (objectUsername); - - - // Delete a user. - if (webserver_request.query.count ("delete")) { - string role = Filter_Roles::text (objectUserLevel); - string email = webserver_request.database_users ()->get_email (objectUsername); - vector users = webserver_request.database_users ()->get_users (); - vector administrators = webserver_request.database_users ()->getAdministrators (); - if (users.size () == 1) { - page += assets_page::error (translate("Cannot remove the last user")); - } else if ((objectUserLevel >= Filter_Roles::admin ()) && (administrators.size () == 1)) { - page += assets_page::error (translate("Cannot remove the last administrator")); - } else if (config::logic::demo_enabled () && (objectUsername == session_admin_credentials ())) { - page += assets_page::error (translate("Cannot remove the demo admin")); - } else { - string message; - user_logic_delete_account (objectUsername, role, email, message); - user_updated = true; - page += assets_page::success (message); - } - } - - - // The user's role. - if (webserver_request.query.count ("level")) { - string level = webserver_request.query ["level"]; - if (level == "") { - Dialog_List dialog_list = Dialog_List ("users", translate("Select a role for") + " " + objectUsername, "", ""); - dialog_list.add_query ("user", objectUsername); - for (int i = Filter_Roles::lowest (); i <= Filter_Roles::highest (); i++) { - if (i <= myLevel) { - dialog_list.add_row (Filter_Roles::text (i), "level", filter::strings::convert_to_string (i)); - } - } - page += dialog_list.run (); - return page; - } else { - webserver_request.database_users ()->set_level (objectUsername, filter::strings::convert_to_int (level)); - user_updated = true; - } - } - - - // User's email address. - if (webserver_request.query.count ("email")) { - string email = webserver_request.query ["email"]; - if (email == "") { - string question = translate("Please enter an email address for") + " " + objectUsername; - string value = webserver_request.database_users ()->get_email (objectUsername); - Dialog_Entry dialog_entry = Dialog_Entry ("users", question, value, "email", ""); - dialog_entry.add_query ("user", objectUsername); - page += dialog_entry.run (); - return page; - } - } - if (webserver_request.post.count ("email")) { - string email = webserver_request.post["entry"]; - if (filter_url_email_is_valid (email)) { - page += assets_page::success (translate("Email address was updated")); - webserver_request.database_users ()->updateUserEmail (objectUsername, email); - user_updated = true; - } else { - page += assets_page::error (translate("The email address is not valid")); - } - } - - - // Fetch all available Bibles. - vector allbibles = webserver_request.database_bibles()->get_bibles (); - - - // Add Bible to user account. - if (webserver_request.query.count ("addbible")) { - string addbible = webserver_request.query["addbible"]; - if (addbible == "") { - Dialog_List dialog_list = Dialog_List ("users", translate("Would you like to grant the user access to a Bible?"), "", ""); - dialog_list.add_query ("user", objectUsername); - for (auto bible : allbibles) { - dialog_list.add_row (bible, "addbible", bible); - } - page += dialog_list.run (); - return page; - } else { - assets_page::success (translate("The user has been granted access to this Bible")); - // Write access depends on whether it's a translator role or higher. - bool write = (objectUserLevel >= Filter_Roles::translator ()); - DatabasePrivileges::set_bible (objectUsername, addbible, write); - user_updated = true; - privileges_updated = true; - } - } - - - // Remove Bible from user. - if (webserver_request.query.count ("removebible")) { - string removebible = webserver_request.query ["removebible"]; - DatabasePrivileges::remove_bible_book (objectUsername, removebible, 0); - user_updated = true; - privileges_updated = true; - assets_page::success (translate("The user no longer has access to this Bible")); - } - - - // Enable or disable a user account. - if (webserver_request.query.count ("enable")) { - webserver_request.database_users ()->set_enabled (objectUsername, true); - assets_page::success (translate("The user account was enabled")); - } - if (webserver_request.query.count ("disable")) { - // Disable the user in the database. - webserver_request.database_users ()->set_enabled (objectUsername, false); - // Remove all login tokens (cookies) for this user, so the user no longer is logged in. - Database_Login::removeTokens (objectUsername); - // Feedback. - assets_page::success (translate("The user account was disabled")); - } - - - // Login on behalf of another user. - if (webserver_request.query.count ("login")) { - webserver_request.session_logic ()->switch_user (objectUsername); - redirect_browser (webserver_request, session_switch_url ()); - return string(); - } - - - // User accounts to display. - stringstream tbody; - bool ldap_on = ldap_logic_is_on (); - // Retrieve assigned users. - vector users = access_user::assignees (webserver_request); - for (const auto& username : users) { - - // Gather details for this user account. - objectUserLevel = webserver_request.database_users ()->get_level (username); - string namedrole = Filter_Roles::text (objectUserLevel); - string email = webserver_request.database_users ()->get_email (username); - if (email.empty()) email = "--"; - bool enabled = webserver_request.database_users ()->get_enabled (username); - - // New row in table. - tbody << ""; - - // Display emoji to delete this account. - tbody << ""; - tbody << "" << filter::strings::emoji_wastebasket () << " " << username; - tbody << ""; - - // Divider. - tbody << "│"; - - // The user's role is displayed when the account is enabled. - // Normally the role can be changed, but when an LDAP server is enabled, it cannot be changed here. - tbody << ""; - if (enabled) { - if (!ldap_on) tbody << ""; - tbody << namedrole << ""; - if (!ldap_on) tbody << ""; - } - tbody << ""; - - // Divider. - tbody << "│"; - - // The user's email address will be displayed when the account is enabled. - // Normally the email address can be changed here, - // but in case of authentication via an LDAP server, it cannot be changed here. - tbody << ""; - if (enabled) { - if (!ldap_on) tbody << ""; - tbody << email; - if (!ldap_on) tbody << ""; - } - tbody << ""; - - // Divider. - tbody << "│"; - - // Assigned Bibles. - tbody << ""; - if (enabled) { - if (objectUserLevel < Filter_Roles::manager ()) { - for (auto & bible : allbibles) { - bool exists = DatabasePrivileges::get_bible_book_exists (username, bible, 0); - if (exists) { - auto [ read, write ] = DatabasePrivileges::get_bible (username, bible); - if (objectUserLevel >= Filter_Roles::translator ()) write = true; - tbody << "" << filter::strings::emoji_wastebasket () << ""; - tbody << "" << bible << ""; - tbody << ""; - int readwritebooks = 0; - vector books = webserver_request.database_bibles()->get_books (bible); - for (auto book : books) { - DatabasePrivileges::get_bible_book (username, bible, book, read, write); - if (write) readwritebooks++; - } - tbody << "(" << readwritebooks << "/" << books.size () << ")"; - tbody << ""; - tbody << "|"; - } - } - } - if (objectUserLevel >= Filter_Roles::manager ()) { - // Managers and higher roles have access to all Bibles. - tbody << "(" << translate ("all") << ")"; - } else { - tbody << "" << filter::strings::emoji_heavy_plus_sign () << ""; - } - } - tbody << ""; - - // Divider. - tbody << "│"; - - // Assigned privileges to the user. - tbody << ""; - if (enabled) { - if (objectUserLevel >= Filter_Roles::manager ()) { - // Managers and higher roles have all privileges. - tbody << "(" << translate ("all") << ")"; - } else { - tbody << "" << translate ("edit") << ""; - } - } - tbody << ""; - - // Disable or enable the account. - if (myLevel >= Filter_Roles::manager ()) { - if (myLevel > objectUserLevel) { - tbody << "│"; - tbody << ""; - bool account_enabled = webserver_request.database_users ()->get_enabled (username); - if (account_enabled) { - tbody << "" << translate ("Disable") << ""; - } else { - tbody << "" << translate ("Enable") << ""; - } - tbody << ""; - } - } - - // Login on behalf of another user. - if (enabled) { - if (myLevel > objectUserLevel) { - tbody << "│"; - tbody << ""; - tbody << "" << translate ("Login") << ""; - tbody << ""; - } - } - - // Done with the row. - tbody << ""; - } - - view.set_variable ("tbody", tbody.str()); - - if (!ldap_on) { - view.enable_zone ("local"); - } - - if (webserver_request.session_logic()->currentLevel () == Filter_Roles::highest ()) view.enable_zone ("admin_settings"); - - page += view.render ("manage", "users"); - - page += assets_page::footer (); - - if (user_updated) notes_logic_maintain_note_assignees (true); - if (privileges_updated) database_privileges_client_create (objectUsername, true); - - return page; -} diff --git a/manage/users.h b/manage/users.h deleted file mode 100644 index bc98f6603..000000000 --- a/manage/users.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string manage_users_url (); -bool manage_users_acl (Webserver_Request& webserver_request); -std::string manage_users (Webserver_Request& webserver_request); diff --git a/manage/write.cpp b/manage/write.cpp deleted file mode 100644 index abdcf3185..000000000 --- a/manage/write.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string manage_write_url () -{ - return "manage/write"; -} - - -bool manage_write_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -string manage_write (Webserver_Request& webserver_request) -{ - string page {}; - - Assets_Header header = Assets_Header (translate("Read/write"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (manage_users_url (), menu_logic_manage_users_text ()); - page = header.run (); - - Assets_View view {}; - - int userid = filter::strings::user_identifier (webserver_request); - - string user {}; - if (webserver_request.query.count ("user")) { - user = webserver_request.query["user"]; - Database_Volatile::setValue (userid, "manage_write_user", user); - } - user = Database_Volatile::getValue (userid, "manage_write_user"); - view.set_variable ("user", user); - - string bible {}; - if (webserver_request.query.count ("bible")) { - bible = webserver_request.query["bible"]; - Database_Volatile::setValue (userid, "manage_write_bible", bible); - } - bible = Database_Volatile::getValue (userid, "manage_write_bible"); - view.set_variable ("bible", bible); - - auto [ bible_read_access, bible_write_access ] = DatabasePrivileges::get_bible (user, bible); - - // Toggle write access to Bible book. - if (!webserver_request.post.empty ()) { - string checkbox = webserver_request.post["checkbox"]; - string s_book (checkbox); - s_book.erase (0, 4); - int book = filter::strings::convert_to_int (s_book); - if (book) { - if (bible_read_access) { - bool checked = filter::strings::convert_to_bool (webserver_request.post ["checked"]); - DatabasePrivileges::set_bible_book (user, bible, book, checked); - database_privileges_client_create (user, true); - } - } - return string(); - } - - // Toggle write access to Testament. - string testament = webserver_request.query ["testament"]; - if (!testament.empty ()) { - // Count the majority 'write' access situation for the Bible. - int majority = 0; - vector books = webserver_request.database_bibles()->get_books (bible); - for (auto & book : books) { - string type = database::books::book_type_to_string (database::books::get_type (static_cast(book))); - if (type == testament) { - bool read, write; - DatabasePrivileges::get_bible_book (user, bible, book, read, write); - if (write) majority++; - else majority--; - } - } - // Update the write access privileges for the books of the Testament, - // by setting the write privileges to the opposite of the majority state. - for (auto & book : books) { - string type = database::books::book_type_to_string (database::books::get_type (static_cast(book))); - if (type == testament) { - DatabasePrivileges::set_bible_book (user, bible, book, (majority < 0)); - } - } - // Update privileges for the clients. - database_privileges_client_create (user, true); - } - - // Read or write access to display. - vector books = webserver_request.database_bibles()->get_books (bible); - for (size_t i = 0; i < books.size (); i++) { - int book = books[i]; - string bookname = database::books::get_english_from_id (static_cast(book)); - string checkboxname = "book" + filter::strings::convert_to_string (book); - bool read, write; - DatabasePrivileges::get_bible_book (user, bible, book, read, write); - string checked = filter::strings::get_checkbox_status (write); - view.add_iteration ("write", { pair ("bookname", bookname), pair ("checkboxname", checkboxname), pair ("checked", checked) } ); - } - - page += view.render ("manage", "write"); - - page += assets_page::footer (); - - return page; -} diff --git a/manage/write.h b/manage/write.h deleted file mode 100644 index f343845a8..000000000 --- a/manage/write.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string manage_write_url (); -bool manage_write_acl (Webserver_Request& webserver_request); -std::string manage_write (Webserver_Request& webserver_request); diff --git a/mapping/index.cpp b/mapping/index.cpp deleted file mode 100644 index a0818f372..000000000 --- a/mapping/index.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string mapping_index_url () -{ - return "mapping/index"; -} - - -bool mapping_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -string mapping_index (Webserver_Request& webserver_request) -{ - Database_Mappings database_mappings; - - string page; - - Assets_Header header = Assets_Header (translate("Verse Mappings"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - page = header.run (); - - Assets_View view; - string error; - string success; - - // Create new verse mapping. - if (webserver_request.query.count ("new")) { - Dialog_Entry dialog_entry = Dialog_Entry ("index", translate("Enter a name for the new verse mapping"), "", "new", ""); - page += dialog_entry.run (); - return page; - } - if (webserver_request.post.count ("new")) { - string name = webserver_request.post ["entry"]; - vector mappings = database_mappings.names (); - if (find (mappings.begin(), mappings.end(), name) != mappings.end ()) { - error = translate("This verse mapping already exists"); - } else { - database_mappings.create (name); - } - } - - // Delete verse mapping. - string name = webserver_request.query ["name"]; - if (webserver_request.query.count ("delete")) { - string confirm = webserver_request.query ["confirm"]; - if (confirm == "") { - Dialog_Yes dialog_yes = Dialog_Yes ("index", translate("Would you like to delete this verse mapping?")); - dialog_yes.add_query ("name", name); - dialog_yes.add_query ("delete", "1"); - page += dialog_yes.run (); - return page; - } if (confirm == "yes") { - database_mappings.erase (name); - success = translate ("The verse mapping was deleted"); - } - } - - view.set_variable ("error", error); - view.set_variable ("success", success); - - stringstream mappingsblock; - vector mappings = database_mappings.names (); - for (auto & mapping : mappings) { - mappingsblock << "

    "; - mappingsblock << mapping; - mappingsblock << " "; - mappingsblock << "[translate(" << quoted("edit") << "]"; - mappingsblock << "

    " << std::endl; - } - view.set_variable ("mappingsblock", mappingsblock.str()); - - page += view.render ("mapping", "index"); - - page += assets_page::footer (); - - return page; -} diff --git a/mapping/index.h b/mapping/index.h deleted file mode 100644 index 15ec81fd2..000000000 --- a/mapping/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string mapping_index_url (); -bool mapping_index_acl (Webserver_Request& webserver_request); -std::string mapping_index (Webserver_Request& webserver_request); diff --git a/mapping/map.cpp b/mapping/map.cpp deleted file mode 100644 index 17a543906..000000000 --- a/mapping/map.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string mapping_map_url () -{ - return "mapping/map"; -} - - -bool mapping_map_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::manager ()); -} - - -string mapping_map (Webserver_Request& webserver_request) -{ - Database_Mappings database_mappings; - - string page; - - Assets_Header header = Assets_Header (translate("Verse mappings"), webserver_request); - header.add_bread_crumb (menu_logic_settings_menu (), menu_logic_settings_text ()); - header.add_bread_crumb (mapping_index_url (), menu_logic_mapping_index_text ()); - - page = header.run (); - - Assets_View view; - string success; - - string name = webserver_request.query["name"]; - view.set_variable ("name", name); - - if (webserver_request.post.count ("submit")) { - string data = webserver_request.post["data"]; - database_mappings.import (name, data); - success = translate("The verse mapping was saved"); - } - - view.set_variable ("success", success); - - string data = database_mappings.output (name); - view.set_variable ("data", data); - - page += view.render ("mapping", "map"); - - page += assets_page::footer (); - - return page; -} diff --git a/mapping/map.h b/mapping/map.h deleted file mode 100644 index 33eae2018..000000000 --- a/mapping/map.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string mapping_map_url (); -bool mapping_map_acl (Webserver_Request& webserver_request); -std::string mapping_map (Webserver_Request& webserver_request); diff --git a/mbedtls/aes.c b/mbedtls/aes.c deleted file mode 100644 index d44223a10..000000000 --- a/mbedtls/aes.c +++ /dev/null @@ -1,2252 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * FIPS-197 compliant AES implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. - * - * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf - * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_AES_C) - -#include - -#include "mbedtls/aes.h" -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" -#if defined(MBEDTLS_PADLOCK_C) -#include "mbedtls/padlock.h" -#endif -#if defined(MBEDTLS_AESNI_C) -#include "mbedtls/aesni.h" -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_AES_ALT) - -/* Parameter validation macros based on platform_util.h */ -#define AES_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA ) -#define AES_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -#if defined(MBEDTLS_PADLOCK_C) && \ - ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) -static int aes_padlock_ace = -1; -#endif - -#if defined(MBEDTLS_AES_ROM_TABLES) -/* - * Forward S-box - */ -static const unsigned char FSb[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, - 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, - 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, - 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, - 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, - 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, - 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, - 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, - 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, - 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, - 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, - 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 -}; - -/* - * Forward tables - */ -#define FT \ -\ - V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ - V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ - V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ - V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ - V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ - V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ - V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ - V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ - V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ - V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ - V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ - V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ - V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ - V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ - V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ - V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ - V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ - V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ - V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ - V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ - V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ - V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ - V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ - V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ - V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ - V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ - V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ - V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ - V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ - V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ - V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ - V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ - V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ - V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ - V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ - V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ - V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ - V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ - V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ - V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ - V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ - V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ - V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ - V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ - V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ - V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ - V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ - V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ - V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ - V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ - V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ - V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ - V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ - V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ - V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ - V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ - V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ - V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ - V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ - V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ - V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ - V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ - V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ - V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) - -#define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t FT0[256] = { FT }; -#undef V - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - -#define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t FT1[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t FT2[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t FT3[256] = { FT }; -#undef V - -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -#undef FT - -/* - * Reverse S-box - */ -static const unsigned char RSb[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, - 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, - 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, - 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, - 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, - 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, - 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, - 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, - 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, - 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, - 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, - 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D -}; - -/* - * Reverse tables - */ -#define RT \ -\ - V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ - V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ - V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ - V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ - V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ - V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ - V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ - V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ - V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ - V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ - V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ - V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ - V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ - V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ - V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ - V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ - V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ - V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ - V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ - V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ - V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ - V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ - V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ - V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ - V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ - V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ - V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ - V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ - V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ - V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ - V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ - V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ - V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ - V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ - V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ - V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ - V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ - V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ - V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ - V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ - V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ - V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ - V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ - V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ - V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ - V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ - V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ - V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ - V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ - V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ - V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ - V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ - V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ - V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ - V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ - V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ - V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ - V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ - V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ - V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ - V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ - V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ - V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ - V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) - -#define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t RT0[256] = { RT }; -#undef V - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - -#define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t RT1[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t RT2[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t RT3[256] = { RT }; -#undef V - -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -#undef RT - -/* - * Round constants - */ -static const uint32_t RCON[10] = -{ - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x0000001B, 0x00000036 -}; - -#else /* MBEDTLS_AES_ROM_TABLES */ - -/* - * Forward S-box & tables - */ -static unsigned char FSb[256]; -static uint32_t FT0[256]; -#if !defined(MBEDTLS_AES_FEWER_TABLES) -static uint32_t FT1[256]; -static uint32_t FT2[256]; -static uint32_t FT3[256]; -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -/* - * Reverse S-box & tables - */ -static unsigned char RSb[256]; -static uint32_t RT0[256]; -#if !defined(MBEDTLS_AES_FEWER_TABLES) -static uint32_t RT1[256]; -static uint32_t RT2[256]; -static uint32_t RT3[256]; -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -/* - * Round constants - */ -static uint32_t RCON[10]; - -/* - * Tables generation code - */ -#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 ) -#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) ) -#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 ) - -static int aes_init_done = 0; - -static void aes_gen_tables( void ) -{ - int i, x, y, z; - int pow[256]; - int log[256]; - - /* - * compute pow and log tables over GF(2^8) - */ - for( i = 0, x = 1; i < 256; i++ ) - { - pow[i] = x; - log[x] = i; - x = ( x ^ XTIME( x ) ) & 0xFF; - } - - /* - * calculate the round constants - */ - for( i = 0, x = 1; i < 10; i++ ) - { - RCON[i] = (uint32_t) x; - x = XTIME( x ) & 0xFF; - } - - /* - * generate the forward and reverse S-boxes - */ - FSb[0x00] = 0x63; - RSb[0x63] = 0x00; - - for( i = 1; i < 256; i++ ) - { - x = pow[255 - log[i]]; - - y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y ^ 0x63; - - FSb[i] = (unsigned char) x; - RSb[x] = (unsigned char) i; - } - - /* - * generate the forward and reverse tables - */ - for( i = 0; i < 256; i++ ) - { - x = FSb[i]; - y = XTIME( x ) & 0xFF; - z = ( y ^ x ) & 0xFF; - - FT0[i] = ( (uint32_t) y ) ^ - ( (uint32_t) x << 8 ) ^ - ( (uint32_t) x << 16 ) ^ - ( (uint32_t) z << 24 ); - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - FT1[i] = ROTL8( FT0[i] ); - FT2[i] = ROTL8( FT1[i] ); - FT3[i] = ROTL8( FT2[i] ); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - - x = RSb[i]; - - RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ - ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ - ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ - ( (uint32_t) MUL( 0x0B, x ) << 24 ); - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - RT1[i] = ROTL8( RT0[i] ); - RT2[i] = ROTL8( RT1[i] ); - RT3[i] = ROTL8( RT2[i] ); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - } -} - -#undef ROTL8 - -#endif /* MBEDTLS_AES_ROM_TABLES */ - -#if defined(MBEDTLS_AES_FEWER_TABLES) - -#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) ) -#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) ) -#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) ) - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) ROTL8( RT0[idx] ) -#define AES_RT2(idx) ROTL16( RT0[idx] ) -#define AES_RT3(idx) ROTL24( RT0[idx] ) - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) ROTL8( FT0[idx] ) -#define AES_FT2(idx) ROTL16( FT0[idx] ) -#define AES_FT3(idx) ROTL24( FT0[idx] ) - -#else /* MBEDTLS_AES_FEWER_TABLES */ - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) RT1[idx] -#define AES_RT2(idx) RT2[idx] -#define AES_RT3(idx) RT3[idx] - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) FT1[idx] -#define AES_FT2(idx) FT2[idx] -#define AES_FT3(idx) FT3[idx] - -#endif /* MBEDTLS_AES_FEWER_TABLES */ - -void mbedtls_aes_init( mbedtls_aes_context *ctx ) -{ - AES_VALIDATE( ctx != NULL ); - - memset( ctx, 0, sizeof( mbedtls_aes_context ) ); -} - -void mbedtls_aes_free( mbedtls_aes_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) ); -} - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ) -{ - AES_VALIDATE( ctx != NULL ); - - mbedtls_aes_init( &ctx->crypt ); - mbedtls_aes_init( &ctx->tweak ); -} - -void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_aes_free( &ctx->crypt ); - mbedtls_aes_free( &ctx->tweak ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/* - * AES key schedule (encryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) -int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ) -{ - unsigned int i; - uint32_t *RK; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - switch( keybits ) - { - case 128: ctx->nr = 10; break; - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - -#if !defined(MBEDTLS_AES_ROM_TABLES) - if( aes_init_done == 0 ) - { - aes_gen_tables(); - aes_init_done = 1; - } -#endif - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) - if( aes_padlock_ace == -1 ) - aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); - - if( aes_padlock_ace ) - ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); - else -#endif - ctx->rk = RK = ctx->buf; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); -#endif - - for( i = 0; i < ( keybits >> 5 ); i++ ) - { - GET_UINT32_LE( RK[i], key, i << 2 ); - } - - switch( ctx->nr ) - { - case 10: - - for( i = 0; i < 10; i++, RK += 4 ) - { - RK[4] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); - - RK[5] = RK[1] ^ RK[4]; - RK[6] = RK[2] ^ RK[5]; - RK[7] = RK[3] ^ RK[6]; - } - break; - - case 12: - - for( i = 0; i < 8; i++, RK += 6 ) - { - RK[6] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); - - RK[7] = RK[1] ^ RK[6]; - RK[8] = RK[2] ^ RK[7]; - RK[9] = RK[3] ^ RK[8]; - RK[10] = RK[4] ^ RK[9]; - RK[11] = RK[5] ^ RK[10]; - } - break; - - case 14: - - for( i = 0; i < 7; i++, RK += 8 ) - { - RK[8] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); - - RK[9] = RK[1] ^ RK[8]; - RK[10] = RK[2] ^ RK[9]; - RK[11] = RK[3] ^ RK[10]; - - RK[12] = RK[4] ^ - ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); - - RK[13] = RK[5] ^ RK[12]; - RK[14] = RK[6] ^ RK[13]; - RK[15] = RK[7] ^ RK[14]; - } - break; - } - - return( 0 ); -} -#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ - -/* - * AES key schedule (decryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) -int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ) -{ - int i, j, ret; - mbedtls_aes_context cty; - uint32_t *RK; - uint32_t *SK; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - mbedtls_aes_init( &cty ); - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) - if( aes_padlock_ace == -1 ) - aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); - - if( aes_padlock_ace ) - ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); - else -#endif - ctx->rk = RK = ctx->buf; - - /* Also checks keybits */ - if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) - goto exit; - - ctx->nr = cty.nr; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - { - mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, - (const unsigned char *) cty.rk, ctx->nr ); - goto exit; - } -#endif - - SK = cty.rk + cty.nr * 4; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - - for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) - { - for( j = 0; j < 4; j++, SK++ ) - { - *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^ - AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^ - AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^ - AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] ); - } - } - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - -exit: - mbedtls_aes_free( &cty ); - - return( ret ); -} -#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int mbedtls_aes_xts_decode_keys( const unsigned char *key, - unsigned int keybits, - const unsigned char **key1, - unsigned int *key1bits, - const unsigned char **key2, - unsigned int *key2bits ) -{ - const unsigned int half_keybits = keybits / 2; - const unsigned int half_keybytes = half_keybits / 8; - - switch( keybits ) - { - case 256: break; - case 512: break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - - *key1bits = half_keybits; - *key2bits = half_keybits; - *key1 = &key[0]; - *key2 = &key[half_keybytes]; - - return 0; -} - -int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, - &key2, &key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set the tweak key. Always set tweak key for the encryption mode. */ - ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set crypt key for encryption. */ - return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits ); -} - -int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, - &key2, &key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set the tweak key. Always set tweak key for encryption. */ - ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); - if( ret != 0 ) - return( ret ); - - /* Set crypt key for decryption. */ - return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \ - AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \ - \ - (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \ - AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \ - \ - (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \ - AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \ - \ - (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \ - AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \ - } while( 0 ) - -#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \ - AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \ - \ - (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \ - AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \ - \ - (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \ - AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \ - \ - (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \ - AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \ - } while( 0 ) - -/* - * AES-ECB block encryption - */ -#if !defined(MBEDTLS_AES_ENCRYPT_ALT) -int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i; - uint32_t *RK = ctx->rk; - struct - { - uint32_t X[4]; - uint32_t Y[4]; - } t; - - GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++; - GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++; - GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++; - GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++; - - for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) - { - AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] ); - AES_FROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] ); - } - - AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] ); - - t.X[0] = *RK++ ^ \ - ( (uint32_t) FSb[ ( t.Y[0] ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 ); - - t.X[1] = *RK++ ^ \ - ( (uint32_t) FSb[ ( t.Y[1] ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 ); - - t.X[2] = *RK++ ^ \ - ( (uint32_t) FSb[ ( t.Y[2] ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 ); - - t.X[3] = *RK++ ^ \ - ( (uint32_t) FSb[ ( t.Y[3] ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( t.X[0], output, 0 ); - PUT_UINT32_LE( t.X[1], output, 4 ); - PUT_UINT32_LE( t.X[2], output, 8 ); - PUT_UINT32_LE( t.X[3], output, 12 ); - - mbedtls_platform_zeroize( &t, sizeof( t ) ); - - return( 0 ); -} -#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - mbedtls_internal_aes_encrypt( ctx, input, output ); -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/* - * AES-ECB block decryption - */ -#if !defined(MBEDTLS_AES_DECRYPT_ALT) -int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i; - uint32_t *RK = ctx->rk; - struct - { - uint32_t X[4]; - uint32_t Y[4]; - } t; - - GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++; - GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++; - GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++; - GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++; - - for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) - { - AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] ); - AES_RROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] ); - } - - AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] ); - - t.X[0] = *RK++ ^ \ - ( (uint32_t) RSb[ ( t.Y[0] ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 ); - - t.X[1] = *RK++ ^ \ - ( (uint32_t) RSb[ ( t.Y[1] ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 ); - - t.X[2] = *RK++ ^ \ - ( (uint32_t) RSb[ ( t.Y[2] ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 ); - - t.X[3] = *RK++ ^ \ - ( (uint32_t) RSb[ ( t.Y[3] ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( t.X[0], output, 0 ); - PUT_UINT32_LE( t.X[1], output, 4 ); - PUT_UINT32_LE( t.X[2], output, 8 ); - PUT_UINT32_LE( t.X[3], output, 12 ); - - mbedtls_platform_zeroize( &t, sizeof( t ) ); - - return( 0 ); -} -#endif /* !MBEDTLS_AES_DECRYPT_ALT */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - mbedtls_internal_aes_decrypt( ctx, input, output ); -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/* - * AES-ECB block encryption/decryption - */ -int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); -#endif - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) - if( aes_padlock_ace ) - { - if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - if( mode == MBEDTLS_AES_ENCRYPT ) - return( mbedtls_internal_aes_encrypt( ctx, input, output ) ); - else - return( mbedtls_internal_aes_decrypt( ctx, input, output ) ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * AES-CBC buffer encryption/decryption - */ -int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[16]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - if( length % 16 ) - return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) - if( aes_padlock_ace ) - { - if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - if( mode == MBEDTLS_AES_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, 16 ); - mbedtls_aes_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_aes_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - -/* Endianess with 64 bits values */ -#ifndef GET_UINT64_LE -#define GET_UINT64_LE(n,b,i) \ -{ \ - (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \ - | ( (uint64_t) (b)[(i) + 6] << 48 ) \ - | ( (uint64_t) (b)[(i) + 5] << 40 ) \ - | ( (uint64_t) (b)[(i) + 4] << 32 ) \ - | ( (uint64_t) (b)[(i) + 3] << 24 ) \ - | ( (uint64_t) (b)[(i) + 2] << 16 ) \ - | ( (uint64_t) (b)[(i) + 1] << 8 ) \ - | ( (uint64_t) (b)[(i) ] ); \ -} -#endif - -#ifndef PUT_UINT64_LE -#define PUT_UINT64_LE(n,b,i) \ -{ \ - (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \ - (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \ - (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \ - (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) ] = (unsigned char) ( (n) ); \ -} -#endif - -typedef unsigned char mbedtls_be128[16]; - -/* - * GF(2^128) multiplication function - * - * This function multiplies a field element by x in the polynomial field - * representation. It uses 64-bit word operations to gain speed but compensates - * for machine endianess and hence works correctly on both big and little - * endian machines. - */ -static void mbedtls_gf128mul_x_ble( unsigned char r[16], - const unsigned char x[16] ) -{ - uint64_t a, b, ra, rb; - - GET_UINT64_LE( a, x, 0 ); - GET_UINT64_LE( b, x, 8 ); - - ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) ); - rb = ( a >> 63 ) | ( b << 1 ); - - PUT_UINT64_LE( ra, r, 0 ); - PUT_UINT64_LE( rb, r, 8 ); -} - -/* - * AES-XTS buffer encryption/decryption - */ -int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, - int mode, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret; - size_t blocks = length / 16; - size_t leftover = length % 16; - unsigned char tweak[16]; - unsigned char prev_tweak[16]; - unsigned char tmp[16]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( data_unit != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - /* Data units must be at least 16 bytes long. */ - if( length < 16 ) - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - - /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */ - if( length > ( 1 << 20 ) * 16 ) - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - - /* Compute the tweak. */ - ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT, - data_unit, tweak ); - if( ret != 0 ) - return( ret ); - - while( blocks-- ) - { - size_t i; - - if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) - { - /* We are on the last block in a decrypt operation that has - * leftover bytes, so we need to use the next tweak for this block, - * and this tweak for the lefover bytes. Save the current tweak for - * the leftovers and then update the current tweak for use on this, - * the last full block. */ - memcpy( prev_tweak, tweak, sizeof( tweak ) ); - mbedtls_gf128mul_x_ble( tweak, tweak ); - } - - for( i = 0; i < 16; i++ ) - tmp[i] = input[i] ^ tweak[i]; - - ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); - if( ret != 0 ) - return( ret ); - - for( i = 0; i < 16; i++ ) - output[i] = tmp[i] ^ tweak[i]; - - /* Update the tweak for the next block. */ - mbedtls_gf128mul_x_ble( tweak, tweak ); - - output += 16; - input += 16; - } - - if( leftover ) - { - /* If we are on the leftover bytes in a decrypt operation, we need to - * use the previous tweak for these bytes (as saved in prev_tweak). */ - unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; - - /* We are now on the final part of the data unit, which doesn't divide - * evenly by 16. It's time for ciphertext stealing. */ - size_t i; - unsigned char *prev_output = output - 16; - - /* Copy ciphertext bytes from the previous block to our output for each - * byte of cyphertext we won't steal. At the same time, copy the - * remainder of the input for this final round (since the loop bounds - * are the same). */ - for( i = 0; i < leftover; i++ ) - { - output[i] = prev_output[i]; - tmp[i] = input[i] ^ t[i]; - } - - /* Copy ciphertext bytes from the previous block for input in this - * round. */ - for( ; i < 16; i++ ) - tmp[i] = prev_output[i] ^ t[i]; - - ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); - if( ret != 0 ) - return ret; - - /* Write the result back to the previous block, overriding the previous - * output we copied. */ - for( i = 0; i < 16; i++ ) - prev_output[i] = tmp[i] ^ t[i]; - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int c; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv_off != NULL ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *iv_off; - - if( n > 15 ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - c = *input++; - *output++ = (unsigned char)( c ^ iv[n] ); - iv[n] = (unsigned char) c; - - n = ( n + 1 ) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} - -/* - * AES-CFB8 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - unsigned char c; - unsigned char ov[17]; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || - mode == MBEDTLS_AES_DECRYPT ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - while( length-- ) - { - memcpy( ov, iv, 16 ); - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - if( mode == MBEDTLS_AES_DECRYPT ) - ov[16] = *input; - - c = *output++ = (unsigned char)( iv[0] ^ *input++ ); - - if( mode == MBEDTLS_AES_ENCRYPT ) - ov[16] = c; - - memcpy( iv, ov + 1, 16 ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB (Output Feedback Mode) buffer encryption/decryption - */ -int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret = 0; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( iv_off != NULL ); - AES_VALIDATE_RET( iv != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *iv_off; - - if( n > 15 ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) - { - ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - if( ret != 0 ) - goto exit; - } - *output++ = *input++ ^ iv[n]; - - n = ( n + 1 ) & 0x0F; - } - - *iv_off = n; - -exit: - return( ret ); -} -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR buffer encryption/decryption - */ -int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - - AES_VALIDATE_RET( ctx != NULL ); - AES_VALIDATE_RET( nc_off != NULL ); - AES_VALIDATE_RET( nonce_counter != NULL ); - AES_VALIDATE_RET( stream_block != NULL ); - AES_VALIDATE_RET( input != NULL ); - AES_VALIDATE_RET( output != NULL ); - - n = *nc_off; - - if ( n > 0x0F ) - return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block ); - - for( i = 16; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#endif /* !MBEDTLS_AES_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * AES test vectors from: - * - * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip - */ -static const unsigned char aes_test_ecb_dec[3][16] = -{ - { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, - 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, - { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, - 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, - { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, - 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } -}; - -static const unsigned char aes_test_ecb_enc[3][16] = -{ - { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, - 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, - { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, - 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, - { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, - 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const unsigned char aes_test_cbc_dec[3][16] = -{ - { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, - 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, - { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, - 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, - { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, - 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } -}; - -static const unsigned char aes_test_cbc_enc[3][16] = -{ - { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, - 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, - { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, - 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, - { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, - 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 test vectors from: - * - * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf - */ -static const unsigned char aes_test_cfb128_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char aes_test_cfb128_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_cfb128_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_cfb128_ct[3][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, - 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, - 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, - 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, - 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, - 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, - 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, - 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, - 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, - 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, - 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, - 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, - 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, - 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, - 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, - 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB test vectors from: - * - * https://csrc.nist.gov/publications/detail/sp/800-38a/final - */ -static const unsigned char aes_test_ofb_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char aes_test_ofb_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_ofb_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_ofb_ct[3][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, - 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, - 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, - 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, - 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, - 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e }, - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, - 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, - 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, - 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, - 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, - 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, - 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, - 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, - 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, - 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, - 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 } -}; -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR test vectors from: - * - * http://www.faqs.org/rfcs/rfc3686.html - */ - -static const unsigned char aes_test_ctr_key[3][16] = -{ - { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, - 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, - { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, - 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, - { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, - 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } -}; - -static const unsigned char aes_test_ctr_nonce_counter[3][16] = -{ - { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, - 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, - 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } -}; - -static const unsigned char aes_test_ctr_pt[3][48] = -{ - { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, - 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23 } -}; - -static const unsigned char aes_test_ctr_ct[3][48] = -{ - { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, - 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, - { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, - 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, - 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, - 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, - { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, - 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, - 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, - 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, - 0x25, 0xB2, 0x07, 0x2F } -}; - -static const int aes_test_ctr_len[3] = - { 16, 32, 36 }; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/* - * AES-XTS test vectors from: - * - * IEEE P1619/D16 Annex B - * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf - * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf) - */ -static const unsigned char aes_test_xts_key[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, - { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, - 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, -}; - -static const unsigned char aes_test_xts_pt32[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, -}; - -static const unsigned char aes_test_xts_ct32[][32] = -{ - { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec, - 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92, - 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85, - 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e }, - { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e, - 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b, - 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4, - 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 }, - { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a, - 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2, - 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53, - 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 }, -}; - -static const unsigned char aes_test_xts_data_unit[][16] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, -}; - -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/* - * Checkup routine - */ -int mbedtls_aes_self_test( int verbose ) -{ - int ret = 0, i, j, u, mode; - unsigned int keybits; - unsigned char key[32]; - unsigned char buf[64]; - const unsigned char *aes_tests; -#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) - unsigned char iv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char prv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_OFB) - size_t offset; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS) - int len; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - unsigned char nonce_counter[16]; - unsigned char stream_block[16]; -#endif - mbedtls_aes_context ctx; - - memset( key, 0, 32 ); - mbedtls_aes_init( &ctx ); - - /* - * ECB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-ECB-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( buf, 0, 16 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); - aes_tests = aes_test_ecb_dec[u]; - } - else - { - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - aes_tests = aes_test_ecb_enc[u]; - } - - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - for( j = 0; j < 10000; j++ ) - { - ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf ); - if( ret != 0 ) - goto exit; - } - - if( memcmp( buf, aes_tests, 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /* - * CBC mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CBC-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( iv , 0, 16 ); - memset( prv, 0, 16 ); - memset( buf, 0, 16 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); - aes_tests = aes_test_cbc_dec[u]; - } - else - { - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - aes_tests = aes_test_cbc_enc[u]; - } - - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - for( j = 0; j < 10000; j++ ) - { - if( mode == MBEDTLS_AES_ENCRYPT ) - { - unsigned char tmp[16]; - - memcpy( tmp, prv, 16 ); - memcpy( prv, buf, 16 ); - memcpy( buf, tmp, 16 ); - } - - ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - } - - if( memcmp( buf, aes_tests, 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - /* - * CFB128 mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, aes_test_cfb128_iv, 16 ); - memcpy( key, aes_test_cfb128_key[u], keybits / 8 ); - - offset = 0; - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_cfb128_ct[u], 64 ); - aes_tests = aes_test_cfb128_pt; - } - else - { - memcpy( buf, aes_test_cfb128_pt, 64 ); - aes_tests = aes_test_cfb128_ct[u]; - } - - ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, 64 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - /* - * OFB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-OFB-%3d (%s): ", keybits, - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, aes_test_ofb_iv, 16 ); - memcpy( key, aes_test_ofb_key[u], keybits / 8 ); - - offset = 0; - ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) - { - mbedtls_printf( "skipped\n" ); - continue; - } - else if( ret != 0 ) - { - goto exit; - } - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_ofb_ct[u], 64 ); - aes_tests = aes_test_ofb_pt; - } - else - { - memcpy( buf, aes_test_ofb_pt, 64 ); - aes_tests = aes_test_ofb_ct[u]; - } - - ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, 64 ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /* - * CTR mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CTR-128 (%s): ", - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); - memcpy( key, aes_test_ctr_key[u], 16 ); - - offset = 0; - if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 ) - goto exit; - - len = aes_test_ctr_len[u]; - - if( mode == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_ctr_ct[u], len ); - aes_tests = aes_test_ctr_pt[u]; - } - else - { - memcpy( buf, aes_test_ctr_pt[u], len ); - aes_tests = aes_test_ctr_ct[u]; - } - - ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, - stream_block, buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, len ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - { - static const int num_tests = - sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key); - mbedtls_aes_xts_context ctx_xts; - - /* - * XTS mode - */ - mbedtls_aes_xts_init( &ctx_xts ); - - for( i = 0; i < num_tests << 1; i++ ) - { - const unsigned char *data_unit; - u = i >> 1; - mode = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-XTS-128 (%s): ", - ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( key, 0, sizeof( key ) ); - memcpy( key, aes_test_xts_key[u], 32 ); - data_unit = aes_test_xts_data_unit[u]; - - len = sizeof( *aes_test_xts_ct32 ); - - if( mode == MBEDTLS_AES_DECRYPT ) - { - ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 ); - if( ret != 0) - goto exit; - memcpy( buf, aes_test_xts_ct32[u], len ); - aes_tests = aes_test_xts_pt32[u]; - } - else - { - ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 ); - if( ret != 0) - goto exit; - memcpy( buf, aes_test_xts_pt32[u], len ); - aes_tests = aes_test_xts_ct32[u]; - } - - - ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit, - buf, buf ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, aes_tests, len ) != 0 ) - { - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - mbedtls_aes_xts_free( &ctx_xts ); - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - - ret = 0; - -exit: - if( ret != 0 && verbose != 0 ) - mbedtls_printf( "failed\n" ); - - mbedtls_aes_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_AES_C */ diff --git a/mbedtls/aes.h b/mbedtls/aes.h deleted file mode 100644 index 91347a330..000000000 --- a/mbedtls/aes.h +++ /dev/null @@ -1,701 +0,0 @@ -#pragma GCC system_header -/** - * \file aes.h - * - * \brief This file contains AES definitions and functions. - * - * The Advanced Encryption Standard (AES) specifies a FIPS-approved - * cryptographic algorithm that can be used to protect electronic - * data. - * - * The AES algorithm is a symmetric block cipher that can - * encrypt and decrypt information. For more information, see - * FIPS Publication 197: Advanced Encryption Standard and - * ISO/IEC 18033-2:2006: Information technology -- Security - * techniques -- Encryption algorithms -- Part 2: Asymmetric - * ciphers. - * - * The AES-XTS block mode is standardized by NIST SP 800-38E - * - * and described in detail by IEEE P1619 - * . - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_AES_H -#define MBEDTLS_AES_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -/* padlock.c and aesni.c rely on these values! */ -#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */ -#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */ - -/* Error codes in range 0x0020-0x0022 */ -#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ -#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ - -/* Error codes in range 0x0021-0x0025 */ -#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */ - -/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */ -#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */ - -/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */ - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_AES_ALT) -// Regular implementation -// - -/** - * \brief The AES context-type definition. - */ -typedef struct mbedtls_aes_context -{ - int nr; /*!< The number of rounds. */ - uint32_t *rk; /*!< AES round keys. */ - uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can - hold 32 extra Bytes, which can be used for - one of the following purposes: -
    • Alignment if VIA padlock is - used.
    • -
    • Simplifying key expansion in the 256-bit - case by generating an extra round key. -
    */ -} -mbedtls_aes_context; - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief The AES XTS context-type definition. - */ -typedef struct mbedtls_aes_xts_context -{ - mbedtls_aes_context crypt; /*!< The AES context to use for AES block - encryption or decryption. */ - mbedtls_aes_context tweak; /*!< The AES context used for tweak - computation. */ -} mbedtls_aes_xts_context; -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#else /* MBEDTLS_AES_ALT */ -#include "aes_alt.h" -#endif /* MBEDTLS_AES_ALT */ - -/** - * \brief This function initializes the specified AES context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The AES context to initialize. This must not be \c NULL. - */ -void mbedtls_aes_init( mbedtls_aes_context *ctx ); - -/** - * \brief This function releases and clears the specified AES context. - * - * \param ctx The AES context to clear. - * If this is \c NULL, this function does nothing. - * Otherwise, the context must have been at least initialized. - */ -void mbedtls_aes_free( mbedtls_aes_context *ctx ); - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function initializes the specified AES XTS context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The AES XTS context to initialize. This must not be \c NULL. - */ -void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ); - -/** - * \brief This function releases and clears the specified AES XTS context. - * - * \param ctx The AES XTS context to clear. - * If this is \c NULL, this function does nothing. - * Otherwise, the context must have been at least initialized. - */ -void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/** - * \brief This function sets the encryption key. - * - * \param ctx The AES context to which the key should be bound. - * It must be initialized. - * \param key The encryption key. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of data passed in bits. Valid options are: - *
    • 128 bits
    • - *
    • 192 bits
    • - *
    • 256 bits
    - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function sets the decryption key. - * - * \param ctx The AES context to which the key should be bound. - * It must be initialized. - * \param key The decryption key. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of data passed. Valid options are: - *
    • 128 bits
    • - *
    • 192 bits
    • - *
    • 256 bits
    - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ); - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function prepares an XTS context for encryption and - * sets the encryption key. - * - * \param ctx The AES XTS context to which the key should be bound. - * It must be initialized. - * \param key The encryption key. This is comprised of the XTS key1 - * concatenated with the XTS key2. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of \p key passed in bits. Valid options are: - *
    • 256 bits (each of key1 and key2 is a 128-bit key)
    • - *
    • 512 bits (each of key1 and key2 is a 256-bit key)
    - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function prepares an XTS context for decryption and - * sets the decryption key. - * - * \param ctx The AES XTS context to which the key should be bound. - * It must be initialized. - * \param key The decryption key. This is comprised of the XTS key1 - * concatenated with the XTS key2. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of \p key passed in bits. Valid options are: - *
    • 256 bits (each of key1 and key2 is a 128-bit key)
    • - *
    • 512 bits (each of key1 and key2 is a 256-bit key)
    - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits ); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/** - * \brief This function performs an AES single-block encryption or - * decryption operation. - * - * It performs the operation defined in the \p mode parameter - * (encrypt or decrypt), on the input data buffer defined in - * the \p input parameter. - * - * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or - * mbedtls_aes_setkey_dec() must be called before the first - * call to this API with the same context. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param input The buffer holding the input data. - * It must be readable and at least \c 16 Bytes long. - * \param output The buffer where the output data will be written. - * It must be writeable and at least \c 16 Bytes long. - - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief This function performs an AES-CBC encryption or decryption operation - * on full blocks. - * - * It performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer defined in - * the \p input parameter. - * - * It can be called as many times as needed, until all the input - * data is processed. mbedtls_aes_init(), and either - * mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called - * before the first call to this API with the same context. - * - * \note This function operates on full blocks, that is, the input size - * must be a multiple of the AES block size of \c 16 Bytes. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the IV, you should - * either save it manually or use the cipher module instead. - * - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of the input data in Bytes. This must be a - * multiple of the block size (\c 16 Bytes). - * \param iv Initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH - * on failure. - */ -int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function performs an AES-XTS encryption or decryption - * operation for an entire XTS data unit. - * - * AES-XTS encrypts or decrypts blocks based on their location as - * defined by a data unit number. The data unit number must be - * provided by \p data_unit. - * - * NIST SP 800-38E limits the maximum size of a data unit to 2^20 - * AES blocks. If the data unit is larger than this, this function - * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH. - * - * \param ctx The AES XTS context to use for AES XTS operations. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of a data unit in Bytes. This can be any - * length between 16 bytes and 2^24 bytes inclusive - * (between 1 and 2^20 block cipher blocks). - * \param data_unit The address of the data unit encoded as an array of 16 - * bytes in little-endian format. For disk encryption, this - * is typically the index of the block device sector that - * contains the data. - * \param input The buffer holding the input data (which is an entire - * data unit). This function reads \p length Bytes from \p - * input. - * \param output The buffer holding the output data (which is an entire - * data unit). This function writes \p length Bytes to \p - * output. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is - * smaller than an AES block in size (16 Bytes) or if \p - * length is larger than 2^20 blocks (16 MiB). - */ -int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, - int mode, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief This function performs an AES-CFB128 encryption or decryption - * operation. - * - * It performs the operation defined in the \p mode - * parameter (encrypt or decrypt), on the input data buffer - * defined in the \p input parameter. - * - * For CFB, you must set up the context with mbedtls_aes_setkey_enc(), - * regardless of whether you are performing an encryption or decryption - * operation, that is, regardless of the \p mode parameter. This is - * because CFB mode uses the same key schedule for encryption and - * decryption. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the - * IV, you must either save it manually or use the cipher - * module instead. - * - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of the input data in Bytes. - * \param iv_off The offset in IV (updated after use). - * It must point to a valid \c size_t. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function performs an AES-CFB8 encryption or decryption - * operation. - * - * It performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer defined - * in the \p input parameter. - * - * Due to the nature of CFB, you must use the same key schedule for - * both encryption and decryption operations. Therefore, you must - * use the context initialized with mbedtls_aes_setkey_enc() for - * both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT - * \param length The length of the input data. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); -#endif /*MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/** - * \brief This function performs an AES-OFB (Output Feedback Mode) - * encryption or decryption operation. - * - * For OFB, you must set up the context with - * mbedtls_aes_setkey_enc(), regardless of whether you are - * performing an encryption or decryption operation. This is - * because OFB mode uses the same key schedule for encryption and - * decryption. - * - * The OFB operation is identical for encryption or decryption, - * therefore no operation mode needs to be specified. - * - * \note Upon exit, the content of iv, the Initialisation Vector, is - * updated so that you can call the same function again on the next - * block(s) of data and get the same result as if it was encrypted - * in one call. This allows a "streaming" usage, by initialising - * iv_off to 0 before the first call, and preserving its value - * between calls. - * - * For non-streaming use, the iv should be initialised on each call - * to a unique value, and iv_off set to 0 on each call. - * - * If you need to retain the contents of the initialisation vector, - * you must either save it manually or use the cipher module - * instead. - * - * \warning For the OFB mode, the initialisation vector must be unique - * every encryption operation. Reuse of an initialisation vector - * will compromise security. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param length The length of the input data. - * \param iv_off The offset in IV (updated after use). - * It must point to a valid \c size_t. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief This function performs an AES-CTR encryption or decryption - * operation. - * - * This function performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer - * defined in the \p input parameter. - * - * Due to the nature of CTR, you must use the same key schedule - * for both encryption and decryption operations. Therefore, you - * must use the context initialized with mbedtls_aes_setkey_enc() - * for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. - * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first 12 bytes for the - * per-message nonce, and the last 4 bytes for internal use. In that - * case, before calling this function on a new message you need to - * set the first 12 bytes of \p nonce_counter to your chosen nonce - * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p - * stream_block to be ignored). That way, you can encrypt at most - * 2**96 messages of up to 2**32 blocks each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be unique. - * The recommended way to ensure uniqueness is to use a message - * counter. An alternative is to generate random nonces, but this - * limits the number of messages that can be securely encrypted: - * for example, with 96-bit random nonces, you should not encrypt - * more than 2**32 messages with the same key. - * - * Note that for both stategies, sizes are measured in blocks and - * that an AES block is 16 bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param length The length of the input data. - * \param nc_off The offset in the current \p stream_block, for - * resuming within the current cipher stream. The - * offset pointer should be 0 at the start of a stream. - * It must point to a valid \c size_t. - * \param nonce_counter The 128-bit nonce and counter. - * It must be a readable-writeable buffer of \c 16 Bytes. - * \param stream_block The saved stream block for resuming. This is - * overwritten by the function. - * It must be a readable-writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -/** - * \brief Internal AES block encryption function. This is only - * exposed to allow overriding it using - * \c MBEDTLS_AES_ENCRYPT_ALT. - * - * \param ctx The AES context to use for encryption. - * \param input The plaintext block. - * \param output The output (ciphertext) block. - * - * \return \c 0 on success. - */ -int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -/** - * \brief Internal AES block decryption function. This is only - * exposed to allow overriding it using see - * \c MBEDTLS_AES_DECRYPT_ALT. - * - * \param ctx The AES context to use for decryption. - * \param input The ciphertext block. - * \param output The output (plaintext) block. - * - * \return \c 0 on success. - */ -int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief Deprecated internal AES block encryption function - * without return value. - * - * \disabled_deprecated Superseded by mbedtls_internal_aes_encrypt() - * - * \param ctx The AES context to use for encryption. - * \param input Plaintext block. - * \param output Output (ciphertext) block. - */ -MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -/** - * \brief Deprecated internal AES block decryption function - * without return value. - * - * \disabled_deprecated Superseded by mbedtls_internal_aes_decrypt() - * - * \param ctx The AES context to use for decryption. - * \param input Ciphertext block. - * \param output Output (plaintext) block. - */ -MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_aes_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* aes.h */ diff --git a/mbedtls/aesni.c b/mbedtls/aesni.c deleted file mode 100644 index f32333bb0..000000000 --- a/mbedtls/aesni.c +++ /dev/null @@ -1,508 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * AES-NI support functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set - * [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/ - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_AESNI_C) - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) -#warning "MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code." -#endif -#endif - -#include "mbedtls/aesni.h" - -#include - -#ifndef asm -#define asm __asm -#endif - -#if defined(MBEDTLS_HAVE_X86_64) - -/* - * AES-NI support detection routine - */ -int mbedtls_aesni_has_support( unsigned int what ) -{ - static int done = 0; - static unsigned int c = 0; - - if( ! done ) - { - asm( "movl $1, %%eax \n\t" - "cpuid \n\t" - : "=c" (c) - : - : "eax", "ebx", "edx" ); - done = 1; - } - - return( ( c & what ) != 0 ); -} - -/* - * Binutils needs to be at least 2.19 to support AES-NI instructions. - * Unfortunately, a lot of users have a lower version now (2014-04). - * Emit bytecode directly in order to support "old" version of gas. - * - * Opcodes from the Intel architecture reference manual, vol. 3. - * We always use registers, so we don't need prefixes for memory operands. - * Operand macros are in gas order (src, dst) as opposed to Intel order - * (dst, src) in order to blend better into the surrounding assembly code. - */ -#define AESDEC ".byte 0x66,0x0F,0x38,0xDE," -#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF," -#define AESENC ".byte 0x66,0x0F,0x38,0xDC," -#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD," -#define AESIMC ".byte 0x66,0x0F,0x38,0xDB," -#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF," -#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44," - -#define xmm0_xmm0 "0xC0" -#define xmm0_xmm1 "0xC8" -#define xmm0_xmm2 "0xD0" -#define xmm0_xmm3 "0xD8" -#define xmm0_xmm4 "0xE0" -#define xmm1_xmm0 "0xC1" -#define xmm1_xmm2 "0xD1" - -/* - * AES-NI AES-ECB block en(de)cryption - */ -int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - asm( "movdqu (%3), %%xmm0 \n\t" // load input - "movdqu (%1), %%xmm1 \n\t" // load round key 0 - "pxor %%xmm1, %%xmm0 \n\t" // round 0 - "add $16, %1 \n\t" // point to next round key - "subl $1, %0 \n\t" // normal rounds = nr - 1 - "test %2, %2 \n\t" // mode? - "jz 2f \n\t" // 0 = decrypt - - "1: \n\t" // encryption loop - "movdqu (%1), %%xmm1 \n\t" // load round key - AESENC xmm1_xmm0 "\n\t" // do round - "add $16, %1 \n\t" // point to next round key - "subl $1, %0 \n\t" // loop - "jnz 1b \n\t" - "movdqu (%1), %%xmm1 \n\t" // load round key - AESENCLAST xmm1_xmm0 "\n\t" // last round - "jmp 3f \n\t" - - "2: \n\t" // decryption loop - "movdqu (%1), %%xmm1 \n\t" - AESDEC xmm1_xmm0 "\n\t" // do round - "add $16, %1 \n\t" - "subl $1, %0 \n\t" - "jnz 2b \n\t" - "movdqu (%1), %%xmm1 \n\t" // load round key - AESDECLAST xmm1_xmm0 "\n\t" // last round - - "3: \n\t" - "movdqu %%xmm0, (%4) \n\t" // export output - : - : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output) - : "memory", "cc", "xmm0", "xmm1" ); - - - return( 0 ); -} - -/* - * GCM multiplication: c = a times b in GF(2^128) - * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5. - */ -void mbedtls_aesni_gcm_mult( unsigned char c[16], - const unsigned char a[16], - const unsigned char b[16] ) -{ - unsigned char aa[16], bb[16], cc[16]; - size_t i; - - /* The inputs are in big-endian order, so byte-reverse them */ - for( i = 0; i < 16; i++ ) - { - aa[i] = a[15 - i]; - bb[i] = b[15 - i]; - } - - asm( "movdqu (%0), %%xmm0 \n\t" // a1:a0 - "movdqu (%1), %%xmm1 \n\t" // b1:b0 - - /* - * Caryless multiplication xmm2:xmm1 = xmm0 * xmm1 - * using [CLMUL-WP] algorithm 1 (p. 13). - */ - "movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0 - "movdqa %%xmm1, %%xmm3 \n\t" // same - "movdqa %%xmm1, %%xmm4 \n\t" // same - PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0 - PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0 - PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0 - PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0 - "pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0 - "movdqa %%xmm4, %%xmm3 \n\t" // same - "psrldq $8, %%xmm4 \n\t" // 0:e1+f1 - "pslldq $8, %%xmm3 \n\t" // e0+f0:0 - "pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1 - "pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0 - - /* - * Now shift the result one bit to the left, - * taking advantage of [CLMUL-WP] eq 27 (p. 20) - */ - "movdqa %%xmm1, %%xmm3 \n\t" // r1:r0 - "movdqa %%xmm2, %%xmm4 \n\t" // r3:r2 - "psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1 - "psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1 - "psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63 - "psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63 - "movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63 - "pslldq $8, %%xmm3 \n\t" // r0>>63:0 - "pslldq $8, %%xmm4 \n\t" // r2>>63:0 - "psrldq $8, %%xmm5 \n\t" // 0:r1>>63 - "por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1 - "por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1 - "por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63 - - /* - * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1 - * using [CLMUL-WP] algorithm 5 (p. 20). - * Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted). - */ - /* Step 2 (1) */ - "movdqa %%xmm1, %%xmm3 \n\t" // x1:x0 - "movdqa %%xmm1, %%xmm4 \n\t" // same - "movdqa %%xmm1, %%xmm5 \n\t" // same - "psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a - "psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b - "psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c - - /* Step 2 (2) */ - "pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b - "pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c - "pslldq $8, %%xmm3 \n\t" // a+b+c:0 - "pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0 - - /* Steps 3 and 4 */ - "movdqa %%xmm1,%%xmm0 \n\t" // d:x0 - "movdqa %%xmm1,%%xmm4 \n\t" // same - "movdqa %%xmm1,%%xmm5 \n\t" // same - "psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0' - "psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0' - "psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0' - "pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0' - "pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0' - // e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing - // bits carried from d. Now get those\t bits back in. - "movdqa %%xmm1,%%xmm3 \n\t" // d:x0 - "movdqa %%xmm1,%%xmm4 \n\t" // same - "movdqa %%xmm1,%%xmm5 \n\t" // same - "psllq $63, %%xmm3 \n\t" // d<<63:stuff - "psllq $62, %%xmm4 \n\t" // d<<62:stuff - "psllq $57, %%xmm5 \n\t" // d<<57:stuff - "pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff - "pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff - "psrldq $8, %%xmm3 \n\t" // 0:missing bits of d - "pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0 - "pxor %%xmm1, %%xmm0 \n\t" // h1:h0 - "pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0 - - "movdqu %%xmm0, (%2) \n\t" // done - : - : "r" (aa), "r" (bb), "r" (cc) - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" ); - - /* Now byte-reverse the outputs */ - for( i = 0; i < 16; i++ ) - c[i] = cc[15 - i]; - - return; -} - -/* - * Compute decryption round keys from encryption round keys - */ -void mbedtls_aesni_inverse_key( unsigned char *invkey, - const unsigned char *fwdkey, int nr ) -{ - unsigned char *ik = invkey; - const unsigned char *fk = fwdkey + 16 * nr; - - memcpy( ik, fk, 16 ); - - for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 ) - asm( "movdqu (%0), %%xmm0 \n\t" - AESIMC xmm0_xmm0 "\n\t" - "movdqu %%xmm0, (%1) \n\t" - : - : "r" (fk), "r" (ik) - : "memory", "xmm0" ); - - memcpy( ik, fk, 16 ); -} - -/* - * Key expansion, 128-bit case - */ -static void aesni_setkey_enc_128( unsigned char *rk, - const unsigned char *key ) -{ - asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key - "movdqu %%xmm0, (%0) \n\t" // as round key 0 - "jmp 2f \n\t" // skip auxiliary routine - - /* - * Finish generating the next round key. - * - * On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff - * with X = rot( sub( r3 ) ) ^ RCON. - * - * On exit, xmm0 is r7:r6:r5:r4 - * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3 - * and those are written to the round key buffer. - */ - "1: \n\t" - "pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X - "pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4 - "pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0 - "pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4 - "pslldq $4, %%xmm0 \n\t" // etc - "pxor %%xmm0, %%xmm1 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time! - "add $16, %0 \n\t" // point to next round key - "movdqu %%xmm0, (%0) \n\t" // write it - "ret \n\t" - - /* Main "loop" */ - "2: \n\t" - AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t" - AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t" - : - : "r" (rk), "r" (key) - : "memory", "cc", "0" ); -} - -/* - * Key expansion, 192-bit case - */ -static void aesni_setkey_enc_192( unsigned char *rk, - const unsigned char *key ) -{ - asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key - "movdqu %%xmm0, (%0) \n\t" - "add $16, %0 \n\t" - "movq 16(%1), %%xmm1 \n\t" - "movq %%xmm1, (%0) \n\t" - "add $8, %0 \n\t" - "jmp 2f \n\t" // skip auxiliary routine - - /* - * Finish generating the next 6 quarter-keys. - * - * On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4 - * and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON. - * - * On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10 - * and those are written to the round key buffer. - */ - "1: \n\t" - "pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X - "pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4 - "pslldq $4, %%xmm0 \n\t" // etc - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6 - "movdqu %%xmm0, (%0) \n\t" - "add $16, %0 \n\t" - "pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9 - "pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10 - "pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0 - "pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10 - "movq %%xmm1, (%0) \n\t" - "add $8, %0 \n\t" - "ret \n\t" - - "2: \n\t" - AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t" - - : - : "r" (rk), "r" (key) - : "memory", "cc", "0" ); -} - -/* - * Key expansion, 256-bit case - */ -static void aesni_setkey_enc_256( unsigned char *rk, - const unsigned char *key ) -{ - asm( "movdqu (%1), %%xmm0 \n\t" - "movdqu %%xmm0, (%0) \n\t" - "add $16, %0 \n\t" - "movdqu 16(%1), %%xmm1 \n\t" - "movdqu %%xmm1, (%0) \n\t" - "jmp 2f \n\t" // skip auxiliary routine - - /* - * Finish generating the next two round keys. - * - * On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and - * xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON - * - * On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12 - * and those have been written to the output buffer. - */ - "1: \n\t" - "pshufd $0xff, %%xmm2, %%xmm2 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm2, %%xmm0 \n\t" - "add $16, %0 \n\t" - "movdqu %%xmm0, (%0) \n\t" - - /* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 ) - * and proceed to generate next round key from there */ - AESKEYGENA xmm0_xmm2 ",0x00 \n\t" - "pshufd $0xaa, %%xmm2, %%xmm2 \n\t" - "pxor %%xmm1, %%xmm2 \n\t" - "pslldq $4, %%xmm1 \n\t" - "pxor %%xmm1, %%xmm2 \n\t" - "pslldq $4, %%xmm1 \n\t" - "pxor %%xmm1, %%xmm2 \n\t" - "pslldq $4, %%xmm1 \n\t" - "pxor %%xmm2, %%xmm1 \n\t" - "add $16, %0 \n\t" - "movdqu %%xmm1, (%0) \n\t" - "ret \n\t" - - /* - * Main "loop" - Generating one more key than necessary, - * see definition of mbedtls_aes_context.buf - */ - "2: \n\t" - AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" - AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" - : - : "r" (rk), "r" (key) - : "memory", "cc", "0" ); -} - -/* - * Key expansion, wrapper - */ -int mbedtls_aesni_setkey_enc( unsigned char *rk, - const unsigned char *key, - size_t bits ) -{ - switch( bits ) - { - case 128: aesni_setkey_enc_128( rk, key ); break; - case 192: aesni_setkey_enc_192( rk, key ); break; - case 256: aesni_setkey_enc_256( rk, key ); break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - - return( 0 ); -} - -#endif /* MBEDTLS_HAVE_X86_64 */ - -#endif /* MBEDTLS_AESNI_C */ diff --git a/mbedtls/aesni.h b/mbedtls/aesni.h deleted file mode 100644 index a078c6614..000000000 --- a/mbedtls/aesni.h +++ /dev/null @@ -1,164 +0,0 @@ -#pragma GCC system_header -/** - * \file aesni.h - * - * \brief AES-NI for hardware AES acceleration on some Intel processors - * - * \warning These functions are only for internal use by other library - * functions; you must not call them directly. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_AESNI_H -#define MBEDTLS_AESNI_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "aes.h" - -#define MBEDTLS_AESNI_AES 0x02000000u -#define MBEDTLS_AESNI_CLMUL 0x00000002u - -#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \ - ( defined(__amd64__) || defined(__x86_64__) ) && \ - ! defined(MBEDTLS_HAVE_X86_64) -#define MBEDTLS_HAVE_X86_64 -#endif - -#if defined(MBEDTLS_HAVE_X86_64) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Internal function to detect the AES-NI feature in CPUs. - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param what The feature to detect - * (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL) - * - * \return 1 if CPU has support for the feature, 0 otherwise - */ -int mbedtls_aesni_has_support( unsigned int what ); - -/** - * \brief Internal AES-NI AES-ECB block encryption and decryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param input 16-byte input block - * \param output 16-byte output block - * - * \return 0 on success (cannot fail) - */ -int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); - -/** - * \brief Internal GCM multiplication: c = a * b in GF(2^128) - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param c Result - * \param a First operand - * \param b Second operand - * - * \note Both operands and result are bit strings interpreted as - * elements of GF(2^128) as per the GCM spec. - */ -void mbedtls_aesni_gcm_mult( unsigned char c[16], - const unsigned char a[16], - const unsigned char b[16] ); - -/** - * \brief Internal round key inversion. This function computes - * decryption round keys from the encryption round keys. - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param invkey Round keys for the equivalent inverse cipher - * \param fwdkey Original round keys (for encryption) - * \param nr Number of rounds (that is, number of round keys minus one) - */ -void mbedtls_aesni_inverse_key( unsigned char *invkey, - const unsigned char *fwdkey, - int nr ); - -/** - * \brief Internal key expansion for encryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param rk Destination buffer where the round keys are written - * \param key Encryption key - * \param bits Key size in bits (must be 128, 192 or 256) - * - * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH - */ -int mbedtls_aesni_setkey_enc( unsigned char *rk, - const unsigned char *key, - size_t bits ); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_HAVE_X86_64 */ - -#endif /* MBEDTLS_AESNI_H */ diff --git a/mbedtls/arc4.c b/mbedtls/arc4.c deleted file mode 100644 index eeef771d4..000000000 --- a/mbedtls/arc4.c +++ /dev/null @@ -1,239 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * An implementation of the ARCFOUR algorithm - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The ARCFOUR algorithm was publicly disclosed on 94/09. - * - * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ARC4_C) - -#include "mbedtls/arc4.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_ARC4_ALT) - -void mbedtls_arc4_init( mbedtls_arc4_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_arc4_context ) ); -} - -void mbedtls_arc4_free( mbedtls_arc4_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) ); -} - -/* - * ARC4 key schedule - */ -void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, - unsigned int keylen ) -{ - int i, j, a; - unsigned int k; - unsigned char *m; - - ctx->x = 0; - ctx->y = 0; - m = ctx->m; - - for( i = 0; i < 256; i++ ) - m[i] = (unsigned char) i; - - j = k = 0; - - for( i = 0; i < 256; i++, k++ ) - { - if( k >= keylen ) k = 0; - - a = m[i]; - j = ( j + a + key[k] ) & 0xFF; - m[i] = m[j]; - m[j] = (unsigned char) a; - } -} - -/* - * ARC4 cipher function - */ -int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, - unsigned char *output ) -{ - int x, y, a, b; - size_t i; - unsigned char *m; - - x = ctx->x; - y = ctx->y; - m = ctx->m; - - for( i = 0; i < length; i++ ) - { - x = ( x + 1 ) & 0xFF; a = m[x]; - y = ( y + a ) & 0xFF; b = m[y]; - - m[x] = (unsigned char) b; - m[y] = (unsigned char) a; - - output[i] = (unsigned char) - ( input[i] ^ m[(unsigned char)( a + b )] ); - } - - ctx->x = x; - ctx->y = y; - - return( 0 ); -} - -#endif /* !MBEDTLS_ARC4_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994: - * - * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0 - */ -static const unsigned char arc4_test_key[3][8] = -{ - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}; - -static const unsigned char arc4_test_pt[3][8] = -{ - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}; - -static const unsigned char arc4_test_ct[3][8] = -{ - { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, - { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, - { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } -}; - -/* - * Checkup routine - */ -int mbedtls_arc4_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char ibuf[8]; - unsigned char obuf[8]; - mbedtls_arc4_context ctx; - - mbedtls_arc4_init( &ctx ); - - for( i = 0; i < 3; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " ARC4 test #%d: ", i + 1 ); - - memcpy( ibuf, arc4_test_pt[i], 8 ); - - mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 ); - mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf ); - - if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -exit: - mbedtls_arc4_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ARC4_C */ diff --git a/mbedtls/arc4.h b/mbedtls/arc4.h deleted file mode 100644 index 925608e2a..000000000 --- a/mbedtls/arc4.h +++ /dev/null @@ -1,172 +0,0 @@ -#pragma GCC system_header -/** - * \file arc4.h - * - * \brief The ARCFOUR stream cipher - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers instead. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - * - */ -#ifndef MBEDTLS_ARC4_H -#define MBEDTLS_ARC4_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -/* MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED -0x0019 /**< ARC4 hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_ARC4_ALT) -// Regular implementation -// - -/** - * \brief ARC4 context structure - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers instead. - * - */ -typedef struct mbedtls_arc4_context -{ - int x; /*!< permutation index */ - int y; /*!< permutation index */ - unsigned char m[256]; /*!< permutation table */ -} -mbedtls_arc4_context; - -#else /* MBEDTLS_ARC4_ALT */ -#include "arc4_alt.h" -#endif /* MBEDTLS_ARC4_ALT */ - -/** - * \brief Initialize ARC4 context - * - * \param ctx ARC4 context to be initialized - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - * - */ -void mbedtls_arc4_init( mbedtls_arc4_context *ctx ); - -/** - * \brief Clear ARC4 context - * - * \param ctx ARC4 context to be cleared - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - * - */ -void mbedtls_arc4_free( mbedtls_arc4_context *ctx ); - -/** - * \brief ARC4 key schedule - * - * \param ctx ARC4 context to be setup - * \param key the secret key - * \param keylen length of the key, in bytes - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - * - */ -void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, - unsigned int keylen ); - -/** - * \brief ARC4 cipher function - * - * \param ctx ARC4 context - * \param length length of the input data - * \param input buffer holding the input data - * \param output buffer for the output data - * - * \return 0 if successful - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - * - */ -int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, - unsigned char *output ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - * - */ -int mbedtls_arc4_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* arc4.h */ diff --git a/mbedtls/aria.c b/mbedtls/aria.c deleted file mode 100644 index 09c8c0220..000000000 --- a/mbedtls/aria.c +++ /dev/null @@ -1,1124 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * ARIA implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * This implementation is based on the following standards: - * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf - * [2] https://tools.ietf.org/html/rfc5794 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ARIA_C) - -#include "mbedtls/aria.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_ARIA_ALT) - -#include "mbedtls/platform_util.h" - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* Parameter validation macros */ -#define ARIA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ) -#define ARIA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE( n, b, i ) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE( n, b, i ) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -/* - * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes - * - * This is submatrix P1 in [1] Appendix B.1 - * - * Common compilers fail to translate this to minimal number of instructions, - * so let's provide asm versions for common platforms with C fallback. - */ -#if defined(MBEDTLS_HAVE_ASM) -#if defined(__arm__) /* rev16 available from v6 up */ -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(__GNUC__) && \ - ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ - __ARM_ARCH >= 6 -static inline uint32_t aria_p1( uint32_t x ) -{ - uint32_t r; - __asm( "rev16 %0, %1" : "=l" (r) : "l" (x) ); - return( r ); -} -#define ARIA_P1 aria_p1 -#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ - ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) -static inline uint32_t aria_p1( uint32_t x ) -{ - uint32_t r; - __asm( "rev16 r, x" ); - return( r ); -} -#define ARIA_P1 aria_p1 -#endif -#endif /* arm */ -#if defined(__GNUC__) && \ - defined(__i386__) || defined(__amd64__) || defined( __x86_64__) -/* I couldn't find an Intel equivalent of rev16, so two instructions */ -#define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) ) -#endif /* x86 gnuc */ -#endif /* MBEDTLS_HAVE_ASM && GNUC */ -#if !defined(ARIA_P1) -#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8)) -#endif - -/* - * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits - * - * This is submatrix P2 in [1] Appendix B.1 - * - * Common compilers will translate this to a single instruction. - */ -#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16)) - -/* - * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness - * - * This is submatrix P3 in [1] Appendix B.1 - * - * Some compilers fail to translate this to a single instruction, - * so let's provide asm versions for common platforms with C fallback. - */ -#if defined(MBEDTLS_HAVE_ASM) -#if defined(__arm__) /* rev available from v6 up */ -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(__GNUC__) && \ - ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ - __ARM_ARCH >= 6 -static inline uint32_t aria_p3( uint32_t x ) -{ - uint32_t r; - __asm( "rev %0, %1" : "=l" (r) : "l" (x) ); - return( r ); -} -#define ARIA_P3 aria_p3 -#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ - ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) -static inline uint32_t aria_p3( uint32_t x ) -{ - uint32_t r; - __asm( "rev r, x" ); - return( r ); -} -#define ARIA_P3 aria_p3 -#endif -#endif /* arm */ -#if defined(__GNUC__) && \ - defined(__i386__) || defined(__amd64__) || defined( __x86_64__) -static inline uint32_t aria_p3( uint32_t x ) -{ - __asm( "bswap %0" : "=r" (x) : "0" (x) ); - return( x ); -} -#define ARIA_P3 aria_p3 -#endif /* x86 gnuc */ -#endif /* MBEDTLS_HAVE_ASM && GNUC */ -#if !defined(ARIA_P3) -#define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) ) -#endif - -/* - * ARIA Affine Transform - * (a, b, c, d) = state in/out - * - * If we denote the first byte of input by 0, ..., the last byte by f, - * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef. - * - * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple - * rearrangements on adjacent pairs, output is: - * - * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe - * = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd - * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd - * = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc - * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe - * = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc - * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef - * = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef - * - * Note: another presentation of the A transform can be found as the first - * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4. - * The implementation below uses only P1 and P2 as they are sufficient. - */ -static inline void aria_a( uint32_t *a, uint32_t *b, - uint32_t *c, uint32_t *d ) -{ - uint32_t ta, tb, tc; - ta = *b; // 4567 - *b = *a; // 0123 - *a = ARIA_P2( ta ); // 6745 - tb = ARIA_P2( *d ); // efcd - *d = ARIA_P1( *c ); // 98ba - *c = ARIA_P1( tb ); // fedc - ta ^= *d; // 4567+98ba - tc = ARIA_P2( *b ); // 2301 - ta = ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc - tb ^= ARIA_P2( *d ); // ba98+efcd - tc ^= ARIA_P1( *a ); // 2301+7654 - *b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT - tb = ARIA_P2( tb ) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc - *a ^= ARIA_P1( tb ); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT - ta = ARIA_P2( ta ); // 0123+7654+ab89+dcfe - *d ^= ARIA_P1( ta ) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT - tc = ARIA_P2( tc ); // 0123+5476 - *c ^= ARIA_P1( tc ) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT -} - -/* - * ARIA Substitution Layer SL1 / SL2 - * (a, b, c, d) = state in/out - * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below) - * - * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1 - * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2 - */ -static inline void aria_sl( uint32_t *a, uint32_t *b, - uint32_t *c, uint32_t *d, - const uint8_t sa[256], const uint8_t sb[256], - const uint8_t sc[256], const uint8_t sd[256] ) -{ - *a = ( (uint32_t) sa[ *a & 0xFF] ) ^ - (((uint32_t) sb[(*a >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *a >> 24 ]) << 24); - *b = ( (uint32_t) sa[ *b & 0xFF] ) ^ - (((uint32_t) sb[(*b >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *b >> 24 ]) << 24); - *c = ( (uint32_t) sa[ *c & 0xFF] ) ^ - (((uint32_t) sb[(*c >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *c >> 24 ]) << 24); - *d = ( (uint32_t) sa[ *d & 0xFF] ) ^ - (((uint32_t) sb[(*d >> 8) & 0xFF]) << 8) ^ - (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^ - (((uint32_t) sd[ *d >> 24 ]) << 24); -} - -/* - * S-Boxes - */ -static const uint8_t aria_sb1[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, - 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, - 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, - 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, - 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, - 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, - 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, - 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, - 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, - 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, - 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, - 0xB0, 0x54, 0xBB, 0x16 -}; - -static const uint8_t aria_sb2[256] = -{ - 0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46, - 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B, - 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B, - 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB, - 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA, - 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91, - 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38, - 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53, - 0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74, - 0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26, - 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD, - 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC, - 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E, - 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A, - 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5, - 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8, - 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24, - 0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F, - 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33, - 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D, - 0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A, - 0xAF, 0xBA, 0xB5, 0x81 -}; - -static const uint8_t aria_is1[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, - 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, - 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, - 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, - 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, - 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, - 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, - 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, - 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, - 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0C, 0x7D -}; - -static const uint8_t aria_is2[256] = -{ - 0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1, - 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3, - 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89, - 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D, - 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98, - 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58, - 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F, - 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE, - 0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23, - 0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19, - 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55, - 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A, - 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE, - 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0, - 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6, - 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5, - 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13, - 0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73, - 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94, - 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3, - 0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33, - 0x03, 0xA2, 0xAC, 0x60 -}; - -/* - * Helper for key schedule: r = FO( p, k ) ^ x - */ -static void aria_fo_xor( uint32_t r[4], const uint32_t p[4], - const uint32_t k[4], const uint32_t x[4] ) -{ - uint32_t a, b, c, d; - - a = p[0] ^ k[0]; - b = p[1] ^ k[1]; - c = p[2] ^ k[2]; - d = p[3] ^ k[3]; - - aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); - aria_a( &a, &b, &c, &d ); - - r[0] = a ^ x[0]; - r[1] = b ^ x[1]; - r[2] = c ^ x[2]; - r[3] = d ^ x[3]; -} - -/* - * Helper for key schedule: r = FE( p, k ) ^ x - */ -static void aria_fe_xor( uint32_t r[4], const uint32_t p[4], - const uint32_t k[4], const uint32_t x[4] ) -{ - uint32_t a, b, c, d; - - a = p[0] ^ k[0]; - b = p[1] ^ k[1]; - c = p[2] ^ k[2]; - d = p[3] ^ k[3]; - - aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); - aria_a( &a, &b, &c, &d ); - - r[0] = a ^ x[0]; - r[1] = b ^ x[1]; - r[2] = c ^ x[2]; - r[3] = d ^ x[3]; -} - -/* - * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup. - * - * We chose to store bytes into 32-bit words in little-endian format (see - * GET/PUT_UINT32_LE) so we need to reverse bytes here. - */ -static void aria_rot128( uint32_t r[4], const uint32_t a[4], - const uint32_t b[4], uint8_t n ) -{ - uint8_t i, j; - uint32_t t, u; - - const uint8_t n1 = n % 32; // bit offset - const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset - - j = ( n / 32 ) % 4; // initial word offset - t = ARIA_P3( b[j] ); // big endian - for( i = 0; i < 4; i++ ) - { - j = ( j + 1 ) % 4; // get next word, big endian - u = ARIA_P3( b[j] ); - t <<= n1; // rotate - t |= u >> n2; - t = ARIA_P3( t ); // back to little endian - r[i] = a[i] ^ t; // store - t = u; // move to next word - } -} - -/* - * Set encryption key - */ -int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx, - const unsigned char *key, unsigned int keybits ) -{ - /* round constant masks */ - const uint32_t rc[3][4] = - { - { 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA }, - { 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF }, - { 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 } - }; - - int i; - uint32_t w[4][4], *w2; - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( key != NULL ); - - if( keybits != 128 && keybits != 192 && keybits != 256 ) - return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); - - /* Copy key to W0 (and potential remainder to W1) */ - GET_UINT32_LE( w[0][0], key, 0 ); - GET_UINT32_LE( w[0][1], key, 4 ); - GET_UINT32_LE( w[0][2], key, 8 ); - GET_UINT32_LE( w[0][3], key, 12 ); - - memset( w[1], 0, 16 ); - if( keybits >= 192 ) - { - GET_UINT32_LE( w[1][0], key, 16 ); // 192 bit key - GET_UINT32_LE( w[1][1], key, 20 ); - } - if( keybits == 256 ) - { - GET_UINT32_LE( w[1][2], key, 24 ); // 256 bit key - GET_UINT32_LE( w[1][3], key, 28 ); - } - - i = ( keybits - 128 ) >> 6; // index: 0, 1, 2 - ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16 - - aria_fo_xor( w[1], w[0], rc[i], w[1] ); // W1 = FO(W0, CK1) ^ KR - i = i < 2 ? i + 1 : 0; - aria_fe_xor( w[2], w[1], rc[i], w[0] ); // W2 = FE(W1, CK2) ^ W0 - i = i < 2 ? i + 1 : 0; - aria_fo_xor( w[3], w[2], rc[i], w[1] ); // W3 = FO(W2, CK3) ^ W1 - - for( i = 0; i < 4; i++ ) // create round keys - { - w2 = w[(i + 1) & 3]; - aria_rot128( ctx->rk[i ], w[i], w2, 128 - 19 ); - aria_rot128( ctx->rk[i + 4], w[i], w2, 128 - 31 ); - aria_rot128( ctx->rk[i + 8], w[i], w2, 61 ); - aria_rot128( ctx->rk[i + 12], w[i], w2, 31 ); - } - aria_rot128( ctx->rk[16], w[0], w[1], 19 ); - - /* w holds enough info to reconstruct the round keys */ - mbedtls_platform_zeroize( w, sizeof( w ) ); - - return( 0 ); -} - -/* - * Set decryption key - */ -int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx, - const unsigned char *key, unsigned int keybits ) -{ - int i, j, k, ret; - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( key != NULL ); - - ret = mbedtls_aria_setkey_enc( ctx, key, keybits ); - if( ret != 0 ) - return( ret ); - - /* flip the order of round keys */ - for( i = 0, j = ctx->nr; i < j; i++, j-- ) - { - for( k = 0; k < 4; k++ ) - { - uint32_t t = ctx->rk[i][k]; - ctx->rk[i][k] = ctx->rk[j][k]; - ctx->rk[j][k] = t; - } - } - - /* apply affine transform to middle keys */ - for( i = 1; i < ctx->nr; i++ ) - { - aria_a( &ctx->rk[i][0], &ctx->rk[i][1], - &ctx->rk[i][2], &ctx->rk[i][3] ); - } - - return( 0 ); -} - -/* - * Encrypt a block - */ -int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx, - const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] ) -{ - int i; - - uint32_t a, b, c, d; - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( input != NULL ); - ARIA_VALIDATE_RET( output != NULL ); - - GET_UINT32_LE( a, input, 0 ); - GET_UINT32_LE( b, input, 4 ); - GET_UINT32_LE( c, input, 8 ); - GET_UINT32_LE( d, input, 12 ); - - i = 0; - while( 1 ) - { - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - i++; - - aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); - aria_a( &a, &b, &c, &d ); - - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - i++; - - aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); - if( i >= ctx->nr ) - break; - aria_a( &a, &b, &c, &d ); - } - - /* final key mixing */ - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - - PUT_UINT32_LE( a, output, 0 ); - PUT_UINT32_LE( b, output, 4 ); - PUT_UINT32_LE( c, output, 8 ); - PUT_UINT32_LE( d, output, 12 ); - - return( 0 ); -} - -/* Initialize context */ -void mbedtls_aria_init( mbedtls_aria_context *ctx ) -{ - ARIA_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_aria_context ) ); -} - -/* Clear context */ -void mbedtls_aria_free( mbedtls_aria_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aria_context ) ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * ARIA-CBC buffer encryption/decryption - */ -int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE]; - - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || - mode == MBEDTLS_ARIA_DECRYPT ); - ARIA_VALIDATE_RET( length == 0 || input != NULL ); - ARIA_VALIDATE_RET( length == 0 || output != NULL ); - ARIA_VALIDATE_RET( iv != NULL ); - - if( length % MBEDTLS_ARIA_BLOCKSIZE ) - return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_ARIA_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, MBEDTLS_ARIA_BLOCKSIZE ); - mbedtls_aria_crypt_ecb( ctx, input, output ); - - for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, MBEDTLS_ARIA_BLOCKSIZE ); - - input += MBEDTLS_ARIA_BLOCKSIZE; - output += MBEDTLS_ARIA_BLOCKSIZE; - length -= MBEDTLS_ARIA_BLOCKSIZE; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_aria_crypt_ecb( ctx, output, output ); - memcpy( iv, output, MBEDTLS_ARIA_BLOCKSIZE ); - - input += MBEDTLS_ARIA_BLOCKSIZE; - output += MBEDTLS_ARIA_BLOCKSIZE; - length -= MBEDTLS_ARIA_BLOCKSIZE; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * ARIA-CFB128 buffer encryption/decryption - */ -int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - unsigned char c; - size_t n; - - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || - mode == MBEDTLS_ARIA_DECRYPT ); - ARIA_VALIDATE_RET( length == 0 || input != NULL ); - ARIA_VALIDATE_RET( length == 0 || output != NULL ); - ARIA_VALIDATE_RET( iv != NULL ); - ARIA_VALIDATE_RET( iv_off != NULL ); - - n = *iv_off; - - /* An overly large value of n can lead to an unlimited - * buffer overflow. Therefore, guard against this - * outside of parameter validation. */ - if( n >= MBEDTLS_ARIA_BLOCKSIZE ) - return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_ARIA_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aria_crypt_ecb( ctx, iv, iv ); - - c = *input++; - *output++ = c ^ iv[n]; - iv[n] = c; - - n = ( n + 1 ) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aria_crypt_ecb( ctx, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * ARIA-CTR buffer encryption/decryption - */ -int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - - ARIA_VALIDATE_RET( ctx != NULL ); - ARIA_VALIDATE_RET( length == 0 || input != NULL ); - ARIA_VALIDATE_RET( length == 0 || output != NULL ); - ARIA_VALIDATE_RET( nonce_counter != NULL ); - ARIA_VALIDATE_RET( stream_block != NULL ); - ARIA_VALIDATE_RET( nc_off != NULL ); - - n = *nc_off; - /* An overly large value of n can lead to an unlimited - * buffer overflow. Therefore, guard against this - * outside of parameter validation. */ - if( n >= MBEDTLS_ARIA_BLOCKSIZE ) - return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_aria_crypt_ecb( ctx, nonce_counter, - stream_block ); - - for( i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* !MBEDTLS_ARIA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Basic ARIA ECB test vectors from RFC 5794 - */ -static const uint8_t aria_test1_ecb_key[32] = // test key -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit -}; - -static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] = // plaintext -{ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes -}; - -static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] = // ciphertext -{ - { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit - 0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 }, - { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit - 0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 }, - { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit - 0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC } -}; - -/* - * Mode tests from "Test Vectors for ARIA" Version 1.0 - * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf - */ -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_CTR)) -static const uint8_t aria_test2_key[32] = -{ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit -}; - -static const uint8_t aria_test2_pt[48] = -{ - 0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all - 0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb, - 0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc, - 0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd, - 0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa, - 0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb, -}; -#endif - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)) -static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] = -{ - 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB - 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV -}; -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertext -{ - { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key - 0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34, - 0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64, - 0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38, - 0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c, - 0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 }, - { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key - 0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f, - 0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1, - 0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5, - 0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92, - 0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e }, - { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key - 0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab, - 0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef, - 0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52, - 0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5, - 0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertext -{ - { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key - 0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00, - 0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a, - 0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01, - 0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96, - 0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b }, - { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key - 0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c, - 0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94, - 0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59, - 0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86, - 0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b }, - { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key - 0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35, - 0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70, - 0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa, - 0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c, - 0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext -{ - { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key - 0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1, - 0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1, - 0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f, - 0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71, - 0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 }, - { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key - 0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce, - 0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde, - 0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79, - 0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce, - 0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf }, - { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key - 0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2, - 0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89, - 0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f, - 0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7, - 0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#define ARIA_SELF_TEST_IF_FAIL \ - { \ - if( verbose ) \ - mbedtls_printf( "failed\n" ); \ - goto exit; \ - } else { \ - if( verbose ) \ - mbedtls_printf( "passed\n" ); \ - } - -/* - * Checkup routine - */ -int mbedtls_aria_self_test( int verbose ) -{ - int i; - uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE]; - mbedtls_aria_context ctx; - int ret = 1; - -#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR)) - size_t j; -#endif - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \ - defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_CTR)) - uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE]; -#endif - - mbedtls_aria_init( &ctx ); - - /* - * Test set 1 - */ - for( i = 0; i < 3; i++ ) - { - /* test ECB encryption */ - if( verbose ) - mbedtls_printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i ); - mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk ); - if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* test ECB decryption */ - if( verbose ) - mbedtls_printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i ); - mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk ); - if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); - - /* - * Test set 2 - */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) - for( i = 0; i < 3; i++ ) - { - /* Test CBC encryption */ - if( verbose ) - mbedtls_printf( " ARIA-CBC-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0x55, sizeof( buf ) ); - mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv, - aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* Test CBC decryption */ - if( verbose ) - mbedtls_printf( " ARIA-CBC-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0xAA, sizeof( buf ) ); - mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv, - aria_test2_cbc_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); - -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - for( i = 0; i < 3; i++ ) - { - /* Test CFB encryption */ - if( verbose ) - mbedtls_printf( " ARIA-CFB-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0x55, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv, - aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* Test CFB decryption */ - if( verbose ) - mbedtls_printf( " ARIA-CFB-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); - memset( buf, 0xAA, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j, - iv, aria_test2_cfb_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - for( i = 0; i < 3; i++ ) - { - /* Test CTR encryption */ - if( verbose ) - mbedtls_printf( " ARIA-CTR-%d (enc): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 - memset( buf, 0x55, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, - aria_test2_pt, buf ); - if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - - /* Test CTR decryption */ - if( verbose ) - mbedtls_printf( " ARIA-CTR-%d (dec): ", 128 + 64 * i ); - mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); - memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 - memset( buf, 0xAA, sizeof( buf ) ); - j = 0; - mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, - aria_test2_ctr_ct[i], buf ); - if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) - ARIA_SELF_TEST_IF_FAIL; - } - if( verbose ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - - ret = 0; - -exit: - mbedtls_aria_free( &ctx ); - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ARIA_C */ diff --git a/mbedtls/aria.h b/mbedtls/aria.h deleted file mode 100644 index 508f89129..000000000 --- a/mbedtls/aria.h +++ /dev/null @@ -1,397 +0,0 @@ -#pragma GCC system_header -/** - * \file aria.h - * - * \brief ARIA block cipher - * - * The ARIA algorithm is a symmetric block cipher that can encrypt and - * decrypt information. It is defined by the Korean Agency for - * Technology and Standards (KATS) in KS X 1213:2004 (in - * Korean, but see http://210.104.33.10/ARIA/index-e.html in English) - * and also described by the IETF in RFC 5794. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_ARIA_H -#define MBEDTLS_ARIA_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#include "platform_util.h" - -#define MBEDTLS_ARIA_ENCRYPT 1 /**< ARIA encryption. */ -#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */ - -#define MBEDTLS_ARIA_BLOCKSIZE 16 /**< ARIA block size in bytes. */ -#define MBEDTLS_ARIA_MAX_ROUNDS 16 /**< Maxiumum number of rounds in ARIA. */ -#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x005C ) -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C /**< Bad input data. */ - -#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */ - -/* MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE is deprecated and should not be used. - */ -#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE -0x005A /**< Feature not available. For example, an unsupported ARIA key size. */ - -/* MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED -0x0058 /**< ARIA hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_ARIA_ALT) -// Regular implementation -// - -/** - * \brief The ARIA context-type definition. - */ -typedef struct mbedtls_aria_context -{ - unsigned char nr; /*!< The number of rounds (12, 14 or 16) */ - /*! The ARIA round keys. */ - uint32_t rk[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4]; -} -mbedtls_aria_context; - -#else /* MBEDTLS_ARIA_ALT */ -#include "aria_alt.h" -#endif /* MBEDTLS_ARIA_ALT */ - -/** - * \brief This function initializes the specified ARIA context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The ARIA context to initialize. This must not be \c NULL. - */ -void mbedtls_aria_init( mbedtls_aria_context *ctx ); - -/** - * \brief This function releases and clears the specified ARIA context. - * - * \param ctx The ARIA context to clear. This may be \c NULL, in which - * case this function returns immediately. If it is not \c NULL, - * it must point to an initialized ARIA context. - */ -void mbedtls_aria_free( mbedtls_aria_context *ctx ); - -/** - * \brief This function sets the encryption key. - * - * \param ctx The ARIA context to which the key should be bound. - * This must be initialized. - * \param key The encryption key. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The size of \p key in Bits. Valid options are: - *
    • 128 bits
    • - *
    • 192 bits
    • - *
    • 256 bits
    - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function sets the decryption key. - * - * \param ctx The ARIA context to which the key should be bound. - * This must be initialized. - * \param key The decryption key. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The size of data passed. Valid options are: - *
    • 128 bits
    • - *
    • 192 bits
    • - *
    • 256 bits
    - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function performs an ARIA single-block encryption or - * decryption operation. - * - * It performs encryption or decryption (depending on whether - * the key was set for encryption on decryption) on the input - * data buffer defined in the \p input parameter. - * - * mbedtls_aria_init(), and either mbedtls_aria_setkey_enc() or - * mbedtls_aria_setkey_dec() must be called before the first - * call to this API with the same context. - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param input The 16-Byte buffer holding the input data. - * \param output The 16-Byte buffer holding the output data. - - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx, - const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief This function performs an ARIA-CBC encryption or decryption operation - * on full blocks. - * - * It performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer defined in - * the \p input parameter. - * - * It can be called as many times as needed, until all the input - * data is processed. mbedtls_aria_init(), and either - * mbedtls_aria_setkey_enc() or mbedtls_aria_setkey_dec() must be called - * before the first call to this API with the same context. - * - * \note This function operates on aligned blocks, that is, the input size - * must be a multiple of the ARIA block size of 16 Bytes. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the IV, you should - * either save it manually or use the cipher module instead. - * - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_ARIA_ENCRYPT for encryption, or - * #MBEDTLS_ARIA_DECRYPT for decryption. - * \param length The length of the input data in Bytes. This must be a - * multiple of the block size (16 Bytes). - * \param iv Initialization vector (updated after use). - * This must be a readable buffer of size 16 Bytes. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must - * be a writable buffer of length \p length Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief This function performs an ARIA-CFB128 encryption or decryption - * operation. - * - * It performs the operation defined in the \p mode - * parameter (encrypt or decrypt), on the input data buffer - * defined in the \p input parameter. - * - * For CFB, you must set up the context with mbedtls_aria_setkey_enc(), - * regardless of whether you are performing an encryption or decryption - * operation, that is, regardless of the \p mode parameter. This is - * because CFB mode uses the same key schedule for encryption and - * decryption. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the - * IV, you must either save it manually or use the cipher - * module instead. - * - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_ARIA_ENCRYPT for encryption, or - * #MBEDTLS_ARIA_DECRYPT for decryption. - * \param length The length of the input data \p input in Bytes. - * \param iv_off The offset in IV (updated after use). - * This must not be larger than 15. - * \param iv The initialization vector (updated after use). - * This must be a readable buffer of size 16 Bytes. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must - * be a writable buffer of length \p length Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief This function performs an ARIA-CTR encryption or decryption - * operation. - * - * This function performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer - * defined in the \p input parameter. - * - * Due to the nature of CTR, you must use the same key schedule - * for both encryption and decryption operations. Therefore, you - * must use the context initialized with mbedtls_aria_setkey_enc() - * for both #MBEDTLS_ARIA_ENCRYPT and #MBEDTLS_ARIA_DECRYPT. - * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first 12 bytes for the - * per-message nonce, and the last 4 bytes for internal use. In that - * case, before calling this function on a new message you need to - * set the first 12 bytes of \p nonce_counter to your chosen nonce - * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p - * stream_block to be ignored). That way, you can encrypt at most - * 2**96 messages of up to 2**32 blocks each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be unique. - * The recommended way to ensure uniqueness is to use a message - * counter. An alternative is to generate random nonces, but this - * limits the number of messages that can be securely encrypted: - * for example, with 96-bit random nonces, you should not encrypt - * more than 2**32 messages with the same key. - * - * Note that for both stategies, sizes are measured in blocks and - * that an ARIA block is 16 bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param length The length of the input data \p input in Bytes. - * \param nc_off The offset in Bytes in the current \p stream_block, - * for resuming within the current cipher stream. The - * offset pointer should be \c 0 at the start of a - * stream. This must not be larger than \c 15 Bytes. - * \param nonce_counter The 128-bit nonce and counter. This must point to - * a read/write buffer of length \c 16 bytes. - * \param stream_block The saved stream block for resuming. This must - * point to a read/write buffer of length \c 16 bytes. - * This is overwritten by the function. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must - * be a writable buffer of length \p length Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine. - * - * \return \c 0 on success, or \c 1 on failure. - */ -int mbedtls_aria_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* aria.h */ diff --git a/mbedtls/asn1.h b/mbedtls/asn1.h deleted file mode 100644 index 81b1de923..000000000 --- a/mbedtls/asn1.h +++ /dev/null @@ -1,384 +0,0 @@ -#pragma GCC system_header -/** - * \file asn1.h - * - * \brief Generic ASN.1 parsing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_ASN1_H -#define MBEDTLS_ASN1_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#if defined(MBEDTLS_BIGNUM_C) -#include "bignum.h" -#endif - -/** - * \addtogroup asn1_module - * \{ - */ - -/** - * \name ASN1 Error codes - * These error codes are OR'ed to X509 error codes for - * higher error granularity. - * ASN1 is a standard to specify data structures. - * \{ - */ -#define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */ -#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */ -#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */ -#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */ -#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */ -#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */ -#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */ - -/* \} name */ - -/** - * \name DER constants - * These constants comply with the DER encoded ASN.1 type tags. - * DER encoding uses hexadecimal representation. - * An example DER sequence is:\n - * - 0x02 -- tag indicating INTEGER - * - 0x01 -- length in octets - * - 0x05 -- value - * Such sequences are typically read into \c ::mbedtls_x509_buf. - * \{ - */ -#define MBEDTLS_ASN1_BOOLEAN 0x01 -#define MBEDTLS_ASN1_INTEGER 0x02 -#define MBEDTLS_ASN1_BIT_STRING 0x03 -#define MBEDTLS_ASN1_OCTET_STRING 0x04 -#define MBEDTLS_ASN1_NULL 0x05 -#define MBEDTLS_ASN1_OID 0x06 -#define MBEDTLS_ASN1_UTF8_STRING 0x0C -#define MBEDTLS_ASN1_SEQUENCE 0x10 -#define MBEDTLS_ASN1_SET 0x11 -#define MBEDTLS_ASN1_PRINTABLE_STRING 0x13 -#define MBEDTLS_ASN1_T61_STRING 0x14 -#define MBEDTLS_ASN1_IA5_STRING 0x16 -#define MBEDTLS_ASN1_UTC_TIME 0x17 -#define MBEDTLS_ASN1_GENERALIZED_TIME 0x18 -#define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C -#define MBEDTLS_ASN1_BMP_STRING 0x1E -#define MBEDTLS_ASN1_PRIMITIVE 0x00 -#define MBEDTLS_ASN1_CONSTRUCTED 0x20 -#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80 - -/* - * Bit masks for each of the components of an ASN.1 tag as specified in - * ITU X.690 (08/2015), section 8.1 "General rules for encoding", - * paragraph 8.1.2.2: - * - * Bit 8 7 6 5 1 - * +-------+-----+------------+ - * | Class | P/C | Tag number | - * +-------+-----+------------+ - */ -#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0 -#define MBEDTLS_ASN1_TAG_PC_MASK 0x20 -#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F - -/* \} name */ -/* \} addtogroup asn1_module */ - -/** Returns the size of the binary string, without the trailing \\0 */ -#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1) - -/** - * Compares an mbedtls_asn1_buf structure to a reference OID. - * - * Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a - * 'unsigned char *oid' here! - */ -#define MBEDTLS_OID_CMP(oid_str, oid_buf) \ - ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \ - memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 ) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name Functions to parse ASN.1 data structures - * \{ - */ - -/** - * Type-length-value structure that allows for ASN1 using DER. - */ -typedef struct mbedtls_asn1_buf -{ - int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */ - size_t len; /**< ASN1 length, in octets. */ - unsigned char *p; /**< ASN1 data, e.g. in ASCII. */ -} -mbedtls_asn1_buf; - -/** - * Container for ASN1 bit strings. - */ -typedef struct mbedtls_asn1_bitstring -{ - size_t len; /**< ASN1 length, in octets. */ - unsigned char unused_bits; /**< Number of unused bits at the end of the string */ - unsigned char *p; /**< Raw ASN1 data for the bit string */ -} -mbedtls_asn1_bitstring; - -/** - * Container for a sequence of ASN.1 items - */ -typedef struct mbedtls_asn1_sequence -{ - mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */ - struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */ -} -mbedtls_asn1_sequence; - -/** - * Container for a sequence or list of 'named' ASN.1 data items - */ -typedef struct mbedtls_asn1_named_data -{ - mbedtls_asn1_buf oid; /**< The object identifier. */ - mbedtls_asn1_buf val; /**< The named value. */ - struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */ - unsigned char next_merged; /**< Merge next item into the current one? */ -} -mbedtls_asn1_named_data; - -/** - * \brief Get the length of an ASN.1 element. - * Updates the pointer to immediately behind the length. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param len The variable that will receive the value - * - * \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching - * end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is - * unparseable. - */ -int mbedtls_asn1_get_len( unsigned char **p, - const unsigned char *end, - size_t *len ); - -/** - * \brief Get the tag and length of the tag. Check for the requested tag. - * Updates the pointer to immediately behind the tag and length. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param len The variable that will receive the length - * \param tag The expected tag - * - * \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did - * not match requested tag, or another specific ASN.1 error code. - */ -int mbedtls_asn1_get_tag( unsigned char **p, - const unsigned char *end, - size_t *len, int tag ); - -/** - * \brief Retrieve a boolean ASN.1 tag and its value. - * Updates the pointer to immediately behind the full tag. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param val The variable that will receive the value - * - * \return 0 if successful or a specific ASN.1 error code. - */ -int mbedtls_asn1_get_bool( unsigned char **p, - const unsigned char *end, - int *val ); - -/** - * \brief Retrieve an integer ASN.1 tag and its value. - * Updates the pointer to immediately behind the full tag. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param val The variable that will receive the value - * - * \return 0 if successful or a specific ASN.1 error code. - */ -int mbedtls_asn1_get_int( unsigned char **p, - const unsigned char *end, - int *val ); - -/** - * \brief Retrieve a bitstring ASN.1 tag and its value. - * Updates the pointer to immediately behind the full tag. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param bs The variable that will receive the value - * - * \return 0 if successful or a specific ASN.1 error code. - */ -int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, - mbedtls_asn1_bitstring *bs); - -/** - * \brief Retrieve a bitstring ASN.1 tag without unused bits and its - * value. - * Updates the pointer to the beginning of the bit/octet string. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param len Length of the actual bit/octect string in bytes - * - * \return 0 if successful or a specific ASN.1 error code. - */ -int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, - size_t *len ); - -/** - * \brief Parses and splits an ASN.1 "SEQUENCE OF " - * Updated the pointer to immediately behind the full sequence tag. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param cur First variable in the chain to fill - * \param tag Type of sequence - * - * \return 0 if successful or a specific ASN.1 error code. - */ -int mbedtls_asn1_get_sequence_of( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_sequence *cur, - int tag); - -#if defined(MBEDTLS_BIGNUM_C) -/** - * \brief Retrieve a MPI value from an integer ASN.1 tag. - * Updates the pointer to immediately behind the full tag. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param X The MPI that will receive the value - * - * \return 0 if successful or a specific ASN.1 or MPI error code. - */ -int mbedtls_asn1_get_mpi( unsigned char **p, - const unsigned char *end, - mbedtls_mpi *X ); -#endif /* MBEDTLS_BIGNUM_C */ - -/** - * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence. - * Updates the pointer to immediately behind the full - * AlgorithmIdentifier. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param alg The buffer to receive the OID - * \param params The buffer to receive the params (if any) - * - * \return 0 if successful or a specific ASN.1 or MPI error code. - */ -int mbedtls_asn1_get_alg( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ); - -/** - * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no - * params. - * Updates the pointer to immediately behind the full - * AlgorithmIdentifier. - * - * \param p The position in the ASN.1 data - * \param end End of data - * \param alg The buffer to receive the OID - * - * \return 0 if successful or a specific ASN.1 or MPI error code. - */ -int mbedtls_asn1_get_alg_null( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg ); - -/** - * \brief Find a specific named_data entry in a sequence or list based on - * the OID. - * - * \param list The list to seek through - * \param oid The OID to look for - * \param len Size of the OID - * - * \return NULL if not found, or a pointer to the existing entry. - */ -mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, - const char *oid, size_t len ); - -/** - * \brief Free a mbedtls_asn1_named_data entry - * - * \param entry The named data entry to free - */ -void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry ); - -/** - * \brief Free all entries in a mbedtls_asn1_named_data list - * Head will be set to NULL - * - * \param head Pointer to the head of the list of named data entries to free - */ -void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ); - -#ifdef __cplusplus -} -#endif - -#endif /* asn1.h */ diff --git a/mbedtls/asn1parse.c b/mbedtls/asn1parse.c deleted file mode 100644 index 2e7cf6779..000000000 --- a/mbedtls/asn1parse.c +++ /dev/null @@ -1,427 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Generic ASN.1 parsing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) - -#include "mbedtls/asn1.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -/* - * ASN.1 DER decoding routines - */ -int mbedtls_asn1_get_len( unsigned char **p, - const unsigned char *end, - size_t *len ) -{ - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( ( **p & 0x80 ) == 0 ) - *len = *(*p)++; - else - { - switch( **p & 0x7F ) - { - case 1: - if( ( end - *p ) < 2 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - *len = (*p)[1]; - (*p) += 2; - break; - - case 2: - if( ( end - *p ) < 3 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2]; - (*p) += 3; - break; - - case 3: - if( ( end - *p ) < 4 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - *len = ( (size_t)(*p)[1] << 16 ) | - ( (size_t)(*p)[2] << 8 ) | (*p)[3]; - (*p) += 4; - break; - - case 4: - if( ( end - *p ) < 5 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) | - ( (size_t)(*p)[3] << 8 ) | (*p)[4]; - (*p) += 5; - break; - - default: - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - } - } - - if( *len > (size_t) ( end - *p ) ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - return( 0 ); -} - -int mbedtls_asn1_get_tag( unsigned char **p, - const unsigned char *end, - size_t *len, int tag ) -{ - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( **p != tag ) - return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - (*p)++; - - return( mbedtls_asn1_get_len( p, end, len ) ); -} - -int mbedtls_asn1_get_bool( unsigned char **p, - const unsigned char *end, - int *val ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 ) - return( ret ); - - if( len != 1 ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - *val = ( **p != 0 ) ? 1 : 0; - (*p)++; - - return( 0 ); -} - -int mbedtls_asn1_get_int( unsigned char **p, - const unsigned char *end, - int *val ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) - return( ret ); - - if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - *val = 0; - - while( len-- > 0 ) - { - *val = ( *val << 8 ) | **p; - (*p)++; - } - - return( 0 ); -} - -#if defined(MBEDTLS_BIGNUM_C) -int mbedtls_asn1_get_mpi( unsigned char **p, - const unsigned char *end, - mbedtls_mpi *X ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) - return( ret ); - - ret = mbedtls_mpi_read_binary( X, *p, len ); - - *p += len; - - return( ret ); -} -#endif /* MBEDTLS_BIGNUM_C */ - -int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, - mbedtls_asn1_bitstring *bs) -{ - int ret; - - /* Certificate type is a single byte bitstring */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) - return( ret ); - - /* Check length, subtract one for actual bit string length */ - if( bs->len < 1 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - bs->len -= 1; - - /* Get number of unused bits, ensure unused bits <= 7 */ - bs->unused_bits = **p; - if( bs->unused_bits > 7 ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - (*p)++; - - /* Get actual bitstring */ - bs->p = *p; - *p += bs->len; - - if( *p != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * Get a bit string without unused bits - */ -int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, - size_t *len ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) - return( ret ); - - if( (*len)-- < 2 || *(*p)++ != 0 ) - return( MBEDTLS_ERR_ASN1_INVALID_DATA ); - - return( 0 ); -} - - - -/* - * Parses and splits an ASN.1 "SEQUENCE OF " - */ -int mbedtls_asn1_get_sequence_of( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_sequence *cur, - int tag) -{ - int ret; - size_t len; - mbedtls_asn1_buf *buf; - - /* Get main sequence tag */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - while( *p < end ) - { - buf = &(cur->buf); - buf->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) - return( ret ); - - buf->p = *p; - *p += buf->len; - - /* Allocate and assign next pointer */ - if( *p < end ) - { - cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, - sizeof( mbedtls_asn1_sequence ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); - - cur = cur->next; - } - } - - /* Set final sequence entry's next pointer to NULL */ - cur->next = NULL; - - if( *p != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -int mbedtls_asn1_get_alg( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - alg->tag = **p; - end = *p + len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) - return( ret ); - - alg->p = *p; - *p += alg->len; - - if( *p == end ) - { - mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) ); - return( 0 ); - } - - params->tag = **p; - (*p)++; - - if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) - return( ret ); - - params->p = *p; - *p += params->len; - - if( *p != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -int mbedtls_asn1_get_alg_null( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg ) -{ - int ret; - mbedtls_asn1_buf params; - - memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); - - if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) - return( ret ); - - if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) - return( MBEDTLS_ERR_ASN1_INVALID_DATA ); - - return( 0 ); -} - -void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) -{ - if( cur == NULL ) - return; - - mbedtls_free( cur->oid.p ); - mbedtls_free( cur->val.p ); - - mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); -} - -void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) -{ - mbedtls_asn1_named_data *cur; - - while( ( cur = *head ) != NULL ) - { - *head = cur->next; - mbedtls_asn1_free_named_data( cur ); - mbedtls_free( cur ); - } -} - -mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, - const char *oid, size_t len ) -{ - while( list != NULL ) - { - if( list->oid.len == len && - memcmp( list->oid.p, oid, len ) == 0 ) - { - break; - } - - list = list->next; - } - - return( list ); -} - -#endif /* MBEDTLS_ASN1_PARSE_C */ diff --git a/mbedtls/asn1write.c b/mbedtls/asn1write.c deleted file mode 100644 index a0b1b447e..000000000 --- a/mbedtls/asn1write.c +++ /dev/null @@ -1,459 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * ASN.1 buffer writing functionality - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ASN1_WRITE_C) - -#include "mbedtls/asn1write.h" - -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) -{ - if( len < 0x80 ) - { - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = (unsigned char) len; - return( 1 ); - } - - if( len <= 0xFF ) - { - if( *p - start < 2 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = (unsigned char) len; - *--(*p) = 0x81; - return( 2 ); - } - - if( len <= 0xFFFF ) - { - if( *p - start < 3 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = ( len ) & 0xFF; - *--(*p) = ( len >> 8 ) & 0xFF; - *--(*p) = 0x82; - return( 3 ); - } - - if( len <= 0xFFFFFF ) - { - if( *p - start < 4 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = ( len ) & 0xFF; - *--(*p) = ( len >> 8 ) & 0xFF; - *--(*p) = ( len >> 16 ) & 0xFF; - *--(*p) = 0x83; - return( 4 ); - } - -#if SIZE_MAX > 0xFFFFFFFF - if( len <= 0xFFFFFFFF ) -#endif - { - if( *p - start < 5 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = ( len ) & 0xFF; - *--(*p) = ( len >> 8 ) & 0xFF; - *--(*p) = ( len >> 16 ) & 0xFF; - *--(*p) = ( len >> 24 ) & 0xFF; - *--(*p) = 0x84; - return( 5 ); - } - -#if SIZE_MAX > 0xFFFFFFFF - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); -#endif -} - -int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) -{ - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = tag; - - return( 1 ); -} - -int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t size ) -{ - size_t len = 0; - - if( *p < start || (size_t)( *p - start ) < size ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - len = size; - (*p) -= len; - memcpy( *p, buf, len ); - - return( (int) len ); -} - -#if defined(MBEDTLS_BIGNUM_C) -int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X ) -{ - int ret; - size_t len = 0; - - // Write the MPI - // - len = mbedtls_mpi_size( X ); - - if( *p < start || (size_t)( *p - start ) < len ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - (*p) -= len; - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) ); - - // DER format assumes 2s complement for numbers, so the leftmost bit - // should be 0 for positive numbers and 1 for negative numbers. - // - if( X->s ==1 && **p & 0x80 ) - { - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = 0x00; - len += 1; - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); - - ret = (int) len; - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_BIGNUM_C */ - -int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ) -{ - int ret; - size_t len = 0; - - // Write NULL - // - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len ) -{ - int ret; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, - (const unsigned char *) oid, oid_len ) ); - MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len, - size_t par_len ) -{ - int ret; - size_t len = 0; - - if( par_len == 0 ) - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) ); - else - len += par_len; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) -{ - int ret; - size_t len = 0; - - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = (boolean) ? 255 : 0; - len++; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) -{ - int ret; - size_t len = 0; - - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - len += 1; - *--(*p) = val; - - if( val > 0 && **p & 0x80 ) - { - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = 0x00; - len += 1; - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag, - const char *text, size_t text_len ) -{ - int ret; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, - (const unsigned char *) text, text_len ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ) -{ - return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len) ); -} - -int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ) -{ - return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, text_len) ); -} - -int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ) -{ - return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) ); -} - -int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t bits ) -{ - int ret; - size_t len = 0; - size_t unused_bits, byte_len; - - byte_len = ( bits + 7 ) / 8; - unused_bits = ( byte_len * 8 ) - bits; - - if( *p < start || (size_t)( *p - start ) < byte_len + 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - len = byte_len + 1; - - /* Write the bitstring. Ensure the unused bits are zeroed */ - if( byte_len > 0 ) - { - byte_len--; - *--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 ); - ( *p ) -= byte_len; - memcpy( *p, buf, byte_len ); - } - - /* Write unused bits */ - *--( *p ) = (unsigned char)unused_bits; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); - - return( (int) len ); -} - -int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t size ) -{ - int ret; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); - - return( (int) len ); -} - - -/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(), - * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */ -static mbedtls_asn1_named_data *asn1_find_named_data( - mbedtls_asn1_named_data *list, - const char *oid, size_t len ) -{ - while( list != NULL ) - { - if( list->oid.len == len && - memcmp( list->oid.p, oid, len ) == 0 ) - { - break; - } - - list = list->next; - } - - return( list ); -} - -mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( - mbedtls_asn1_named_data **head, - const char *oid, size_t oid_len, - const unsigned char *val, - size_t val_len ) -{ - mbedtls_asn1_named_data *cur; - - if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) - { - // Add new entry if not present yet based on OID - // - cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1, - sizeof(mbedtls_asn1_named_data) ); - if( cur == NULL ) - return( NULL ); - - cur->oid.len = oid_len; - cur->oid.p = mbedtls_calloc( 1, oid_len ); - if( cur->oid.p == NULL ) - { - mbedtls_free( cur ); - return( NULL ); - } - - memcpy( cur->oid.p, oid, oid_len ); - - cur->val.len = val_len; - cur->val.p = mbedtls_calloc( 1, val_len ); - if( cur->val.p == NULL ) - { - mbedtls_free( cur->oid.p ); - mbedtls_free( cur ); - return( NULL ); - } - - cur->next = *head; - *head = cur; - } - else if( cur->val.len < val_len ) - { - /* - * Enlarge existing value buffer if needed - * Preserve old data until the allocation succeeded, to leave list in - * a consistent state in case allocation fails. - */ - void *p = mbedtls_calloc( 1, val_len ); - if( p == NULL ) - return( NULL ); - - mbedtls_free( cur->val.p ); - cur->val.p = p; - cur->val.len = val_len; - } - - if( val != NULL ) - memcpy( cur->val.p, val, val_len ); - - return( cur ); -} -#endif /* MBEDTLS_ASN1_WRITE_C */ diff --git a/mbedtls/asn1write.h b/mbedtls/asn1write.h deleted file mode 100644 index 6b57f9eb2..000000000 --- a/mbedtls/asn1write.h +++ /dev/null @@ -1,355 +0,0 @@ -#pragma GCC system_header -/** - * \file asn1write.h - * - * \brief ASN.1 buffer writing functionality - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_ASN1_WRITE_H -#define MBEDTLS_ASN1_WRITE_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "asn1.h" - -#define MBEDTLS_ASN1_CHK_ADD(g, f) \ - do \ - { \ - if( ( ret = (f) ) < 0 ) \ - return( ret ); \ - else \ - (g) += ret; \ - } while( 0 ) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Write a length field in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param len The length value to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, - size_t len ); -/** - * \brief Write an ASN.1 tag in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param tag The tag to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, - unsigned char tag ); - -/** - * \brief Write raw buffer data. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param buf The data buffer to write. - * \param size The length of the data buffer. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t size ); - -#if defined(MBEDTLS_BIGNUM_C) -/** - * \brief Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER) - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param X The MPI to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, - const mbedtls_mpi *X ); -#endif /* MBEDTLS_BIGNUM_C */ - -/** - * \brief Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ); - -/** - * \brief Write an OID tag (#MBEDTLS_ASN1_OID) and data - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param oid The OID to write. - * \param oid_len The length of the OID. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len ); - -/** - * \brief Write an AlgorithmIdentifier sequence in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param oid The OID of the algorithm to write. - * \param oid_len The length of the algorithm's OID. - * \param par_len The length of the parameters, which must be already written. - * If 0, NULL parameters are added - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, - unsigned char *start, - const char *oid, size_t oid_len, - size_t par_len ); - -/** - * \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param boolean The boolean value to write, either \c 0 or \c 1. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, - int boolean ); - -/** - * \brief Write an int tag (#MBEDTLS_ASN1_INTEGER) and value - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param val The integer value to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ); - -/** - * \brief Write a string in ASN.1 format using a specific - * string encoding tag. - - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param tag The string encoding tag to write, e.g. - * #MBEDTLS_ASN1_UTF8_STRING. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, - int tag, const char *text, - size_t text_len ); - -/** - * \brief Write a string in ASN.1 format using the PrintableString - * string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING). - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_printable_string( unsigned char **p, - unsigned char *start, - const char *text, size_t text_len ); - -/** - * \brief Write a UTF8 string in ASN.1 format using the UTF8String - * string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING). - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ); - -/** - * \brief Write a string in ASN.1 format using the IA5String - * string encoding tag (#MBEDTLS_ASN1_IA5_STRING). - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, - const char *text, size_t text_len ); - -/** - * \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and - * value in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param buf The bitstring to write. - * \param bits The total number of bits in the bitstring. - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t bits ); - -/** - * \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING) - * and value in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param buf The buffer holding the data to write. - * \param size The length of the data buffer \p buf. - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, - const unsigned char *buf, size_t size ); - -/** - * \brief Create or find a specific named_data entry for writing in a - * sequence or list based on the OID. If not already in there, - * a new entry is added to the head of the list. - * Warning: Destructive behaviour for the val data! - * - * \param list The pointer to the location of the head of the list to seek - * through (will be updated in case of a new entry). - * \param oid The OID to look for. - * \param oid_len The size of the OID. - * \param val The data to store (can be \c NULL if you want to fill - * it by hand). - * \param val_len The minimum length of the data buffer needed. - * - * \return A pointer to the new / existing entry on success. - * \return \c NULL if if there was a memory allocation error. - */ -mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list, - const char *oid, size_t oid_len, - const unsigned char *val, - size_t val_len ); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_ASN1_WRITE_H */ diff --git a/mbedtls/base64.c b/mbedtls/base64.c deleted file mode 100644 index 2cc8f7eb6..000000000 --- a/mbedtls/base64.c +++ /dev/null @@ -1,440 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * RFC 1521 base64 encoding/decoding - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_BASE64_C) - -#include "mbedtls/base64.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#include -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -static const unsigned char base64_enc_map[64] = -{ - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/' -}; - -static const unsigned char base64_dec_map[128] = -{ - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, - 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 127, 127, 127, 127, 127 -}; - -#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ - -/* - * Constant flow conditional assignment to unsigned char - */ -static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src, - unsigned char condition ) -{ - /* MSVC has a warning about unary minus on unsigned integer types, - * but this is well-defined and precisely what we want to do here. */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - - /* Generate bitmask from condition, mask will either be 0xFF or 0 */ - unsigned char mask = ( condition | -condition ); - mask >>= 7; - mask = -mask; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask ); -} - -/* - * Constant flow conditional assignment to uint_32 - */ -static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t src, - uint32_t condition ) -{ - /* MSVC has a warning about unary minus on unsigned integer types, - * but this is well-defined and precisely what we want to do here. */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - - /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */ - uint32_t mask = ( condition | -condition ); - mask >>= 31; - mask = -mask; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - *dest = ( src & mask ) | ( ( *dest ) & ~mask ); -} - -/* - * Constant flow check for equality - */ -static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b ) -{ - size_t difference = in_a ^ in_b; - - /* MSVC has a warning about unary minus on unsigned integer types, - * but this is well-defined and precisely what we want to do here. */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - - difference |= -difference; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - /* cope with the varying size of size_t per platform */ - difference >>= ( sizeof( difference ) * 8 - 1 ); - - return (unsigned char) ( 1 ^ difference ); -} - -/* - * Constant flow lookup into table. - */ -static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table, - const size_t table_size, const size_t table_index ) -{ - size_t i; - unsigned char result = 0; - - for( i = 0; i < table_size; ++i ) - { - mbedtls_base64_cond_assign_uchar( &result, &table[i], mbedtls_base64_eq( i, table_index ) ); - } - - return result; -} - -/* - * Encode a buffer into base64 format - */ -int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ) -{ - size_t i, n; - int C1, C2, C3; - unsigned char *p; - - if( slen == 0 ) - { - *olen = 0; - return( 0 ); - } - - n = slen / 3 + ( slen % 3 != 0 ); - - if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 ) - { - *olen = BASE64_SIZE_T_MAX; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - n *= 4; - - if( ( dlen < n + 1 ) || ( NULL == dst ) ) - { - *olen = n + 1; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - n = ( slen / 3 ) * 3; - - for( i = 0, p = dst; i < n; i += 3 ) - { - C1 = *src++; - C2 = *src++; - C3 = *src++; - - *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ), - ( ( C1 >> 2 ) & 0x3F ) ); - - *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ), - ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) ); - - *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ), - ( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) ); - - *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ), - ( C3 & 0x3F ) ); - } - - if( i < slen ) - { - C1 = *src++; - C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; - - *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ), - ( ( C1 >> 2 ) & 0x3F ) ); - - *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ), - ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) ); - - if( ( i + 1 ) < slen ) - *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ), - ( ( ( C2 & 15 ) << 2 ) & 0x3F ) ); - else *p++ = '='; - - *p++ = '='; - } - - *olen = p - dst; - *p = 0; - - return( 0 ); -} - -/* - * Decode a base64-formatted buffer - */ -int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ) -{ - size_t i, n; - uint32_t j, x; - unsigned char *p; - unsigned char dec_map_lookup; - - /* First pass: check for validity and get output length */ - for( i = n = j = 0; i < slen; i++ ) - { - /* Skip spaces before checking for EOL */ - x = 0; - while( i < slen && src[i] == ' ' ) - { - ++i; - ++x; - } - - /* Spaces at end of buffer are OK */ - if( i == slen ) - break; - - if( ( slen - i ) >= 2 && - src[i] == '\r' && src[i + 1] == '\n' ) - continue; - - if( src[i] == '\n' ) - continue; - - /* Space inside a line is an error */ - if( x != 0 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - if( src[i] == '=' && ++j > 2 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] ); - - if( src[i] > 127 || dec_map_lookup == 127 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - if( dec_map_lookup < 64 && j != 0 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - n++; - } - - if( n == 0 ) - { - *olen = 0; - return( 0 ); - } - - /* The following expression is to calculate the following formula without - * risk of integer overflow in n: - * n = ( ( n * 6 ) + 7 ) >> 3; - */ - n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 ); - n -= j; - - if( dst == NULL || dlen < n ) - { - *olen = n; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) - { - if( *src == '\r' || *src == '\n' || *src == ' ' ) - continue; - - dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src ); - - mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) ); - x = ( x << 6 ) | ( dec_map_lookup & 0x3F ); - - if( ++n == 4 ) - { - n = 0; - if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); - if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); - if( j > 2 ) *p++ = (unsigned char)( x ); - } - } - - *olen = p - dst; - - return( 0 ); -} - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char base64_test_dec[64] = -{ - 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, - 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, - 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, - 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, - 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, - 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, - 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, - 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 -}; - -static const unsigned char base64_test_enc[] = - "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" - "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; - -/* - * Checkup routine - */ -int mbedtls_base64_self_test( int verbose ) -{ - size_t len; - const unsigned char *src; - unsigned char buffer[128]; - - if( verbose != 0 ) - mbedtls_printf( " Base64 encoding test: " ); - - src = base64_test_dec; - - if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 || - memcmp( base64_test_enc, buffer, 88 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n Base64 decoding test: " ); - - src = base64_test_enc; - - if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 || - memcmp( base64_test_dec, buffer, 64 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_BASE64_C */ diff --git a/mbedtls/base64.h b/mbedtls/base64.h deleted file mode 100644 index 788b74024..000000000 --- a/mbedtls/base64.h +++ /dev/null @@ -1,124 +0,0 @@ -#pragma GCC system_header -/** - * \file base64.h - * - * \brief RFC 1521 base64 encoding/decoding - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_BASE64_H -#define MBEDTLS_BASE64_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ -#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Encode a buffer into base64 format - * - * \param dst destination buffer - * \param dlen size of the destination buffer - * \param olen number of bytes written - * \param src source buffer - * \param slen amount of data to be encoded - * - * \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL. - * *olen is always updated to reflect the amount - * of data that has (or would have) been written. - * If that length cannot be represented, then no data is - * written to the buffer and *olen is set to the maximum - * length representable as a size_t. - * - * \note Call this function with dlen = 0 to obtain the - * required buffer size in *olen - */ -int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ); - -/** - * \brief Decode a base64-formatted buffer - * - * \param dst destination buffer (can be NULL for checking size) - * \param dlen size of the destination buffer - * \param olen number of bytes written - * \param src source buffer - * \param slen amount of data to be decoded - * - * \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or - * MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is - * not correct. *olen is always updated to reflect the amount - * of data that has (or would have) been written. - * - * \note Call this function with *dst = NULL or dlen = 0 to obtain - * the required buffer size in *olen - */ -int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_base64_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* base64.h */ diff --git a/mbedtls/bignum.c b/mbedtls/bignum.c deleted file mode 100644 index 6e5c04936..000000000 --- a/mbedtls/bignum.c +++ /dev/null @@ -1,3193 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Multi-precision integer library - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * The following sources were referenced in the design of this Multi-precision - * Integer library: - * - * [1] Handbook of Applied Cryptography - 1997 - * Menezes, van Oorschot and Vanstone - * - * [2] Multi-Precision Math - * Tom St Denis - * https://github.com/libtom/libtommath/blob/develop/tommath.pdf - * - * [3] GNU Multi-Precision Arithmetic Library - * https://gmplib.org/manual/index.html - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_BIGNUM_C) - -#include "mbedtls/bignum.h" -#include "mbedtls/bn_mul.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#define MPI_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA ) -#define MPI_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ -#define biL (ciL << 3) /* bits in limb */ -#define biH (ciL << 2) /* half limb size */ - -#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ - -/* - * Convert between bits/chars and number of limbs - * Divide first in order to avoid potential overflows - */ -#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) ) -#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) ) - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) -{ - mbedtls_platform_zeroize( v, ciL * n ); -} - -/* - * Initialize one MPI - */ -void mbedtls_mpi_init( mbedtls_mpi *X ) -{ - MPI_VALIDATE( X != NULL ); - - X->s = 1; - X->n = 0; - X->p = NULL; -} - -/* - * Unallocate one MPI - */ -void mbedtls_mpi_free( mbedtls_mpi *X ) -{ - if( X == NULL ) - return; - - if( X->p != NULL ) - { - mbedtls_mpi_zeroize( X->p, X->n ); - mbedtls_free( X->p ); - } - - X->s = 1; - X->n = 0; - X->p = NULL; -} - -/* - * Enlarge to the specified number of limbs - */ -int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ) -{ - mbedtls_mpi_uint *p; - MPI_VALIDATE_RET( X != NULL ); - - if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - if( X->n < nblimbs ) - { - if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - if( X->p != NULL ) - { - memcpy( p, X->p, X->n * ciL ); - mbedtls_mpi_zeroize( X->p, X->n ); - mbedtls_free( X->p ); - } - - X->n = nblimbs; - X->p = p; - } - - return( 0 ); -} - -/* - * Resize down as much as possible, - * while keeping at least the specified number of limbs - */ -int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) -{ - mbedtls_mpi_uint *p; - size_t i; - MPI_VALIDATE_RET( X != NULL ); - - if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - /* Actually resize up if there are currently fewer than nblimbs limbs. */ - if( X->n <= nblimbs ) - return( mbedtls_mpi_grow( X, nblimbs ) ); - /* After this point, then X->n > nblimbs and in particular X->n > 0. */ - - for( i = X->n - 1; i > 0; i-- ) - if( X->p[i] != 0 ) - break; - i++; - - if( i < nblimbs ) - i = nblimbs; - - if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - if( X->p != NULL ) - { - memcpy( p, X->p, i * ciL ); - mbedtls_mpi_zeroize( X->p, X->n ); - mbedtls_free( X->p ); - } - - X->n = i; - X->p = p; - - return( 0 ); -} - -/* - * Copy the contents of Y into X - */ -int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ) -{ - int ret = 0; - size_t i; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - if( X == Y ) - return( 0 ); - - if( Y->n == 0 ) - { - mbedtls_mpi_free( X ); - return( 0 ); - } - - for( i = Y->n - 1; i > 0; i-- ) - if( Y->p[i] != 0 ) - break; - i++; - - X->s = Y->s; - - if( X->n < i ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) ); - } - else - { - memset( X->p + i, 0, ( X->n - i ) * ciL ); - } - - memcpy( X->p, Y->p, i * ciL ); - -cleanup: - - return( ret ); -} - -/* - * Swap the contents of X and Y - */ -void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ) -{ - mbedtls_mpi T; - MPI_VALIDATE( X != NULL ); - MPI_VALIDATE( Y != NULL ); - - memcpy( &T, X, sizeof( mbedtls_mpi ) ); - memcpy( X, Y, sizeof( mbedtls_mpi ) ); - memcpy( Y, &T, sizeof( mbedtls_mpi ) ); -} - -/** - * Select between two sign values in constant-time. - * - * This is functionally equivalent to second ? a : b but uses only bit - * operations in order to avoid branches. - * - * \param[in] a The first sign; must be either +1 or -1. - * \param[in] b The second sign; must be either +1 or -1. - * \param[in] second Must be either 1 (return b) or 0 (return a). - * - * \return The selected sign value. - */ -static int mpi_safe_cond_select_sign( int a, int b, unsigned char second ) -{ - /* In order to avoid questions about what we can reasonnably assume about - * the representations of signed integers, move everything to unsigned - * by taking advantage of the fact that a and b are either +1 or -1. */ - unsigned ua = a + 1; - unsigned ub = b + 1; - - /* second was 0 or 1, mask is 0 or 2 as are ua and ub */ - const unsigned mask = second << 1; - - /* select ua or ub */ - unsigned ur = ( ua & ~mask ) | ( ub & mask ); - - /* ur is now 0 or 2, convert back to -1 or +1 */ - return( (int) ur - 1 ); -} - -/* - * Conditionally assign dest = src, without leaking information - * about whether the assignment was made or not. - * dest and src must be arrays of limbs of size n. - * assign must be 0 or 1. - */ -static void mpi_safe_cond_assign( size_t n, - mbedtls_mpi_uint *dest, - const mbedtls_mpi_uint *src, - unsigned char assign ) -{ - size_t i; - - /* MSVC has a warning about unary minus on unsigned integer types, - * but this is well-defined and precisely what we want to do here. */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - - /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */ - const mbedtls_mpi_uint mask = -assign; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - for( i = 0; i < n; i++ ) - dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask ); -} - -/* - * Conditionally assign X = Y, without leaking information - * about whether the assignment was made or not. - * (Leaking information about the respective sizes of X and Y is ok however.) - */ -int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ) -{ - int ret = 0; - size_t i; - mbedtls_mpi_uint limb_mask; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - /* MSVC has a warning about unary minus on unsigned integer types, - * but this is well-defined and precisely what we want to do here. */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - - /* make sure assign is 0 or 1 in a time-constant manner */ - assign = (assign | (unsigned char)-assign) >> (sizeof( assign ) * 8 - 1); - /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */ - limb_mask = -assign; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) ); - - X->s = mpi_safe_cond_select_sign( X->s, Y->s, assign ); - - mpi_safe_cond_assign( Y->n, X->p, Y->p, assign ); - - for( i = Y->n; i < X->n; i++ ) - X->p[i] &= ~limb_mask; - -cleanup: - return( ret ); -} - -/* - * Conditionally swap X and Y, without leaking information - * about whether the swap was made or not. - * Here it is not ok to simply swap the pointers, which whould lead to - * different memory access patterns when X and Y are used afterwards. - */ -int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap ) -{ - int ret, s; - size_t i; - mbedtls_mpi_uint limb_mask; - mbedtls_mpi_uint tmp; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - if( X == Y ) - return( 0 ); - - /* MSVC has a warning about unary minus on unsigned integer types, - * but this is well-defined and precisely what we want to do here. */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - - /* make sure swap is 0 or 1 in a time-constant manner */ - swap = (swap | (unsigned char)-swap) >> (sizeof( swap ) * 8 - 1); - /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */ - limb_mask = -swap; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) ); - - s = X->s; - X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap ); - Y->s = mpi_safe_cond_select_sign( Y->s, s, swap ); - - - for( i = 0; i < X->n; i++ ) - { - tmp = X->p[i]; - X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask ); - Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask ); - } - -cleanup: - return( ret ); -} - -/* - * Set value from integer - */ -int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ) -{ - int ret; - MPI_VALIDATE_RET( X != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) ); - memset( X->p, 0, X->n * ciL ); - - X->p[0] = ( z < 0 ) ? -z : z; - X->s = ( z < 0 ) ? -1 : 1; - -cleanup: - - return( ret ); -} - -/* - * Get a specific bit - */ -int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ) -{ - MPI_VALIDATE_RET( X != NULL ); - - if( X->n * biL <= pos ) - return( 0 ); - - return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 ); -} - -/* Get a specific byte, without range checks. */ -#define GET_BYTE( X, i ) \ - ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff ) - -/* - * Set a bit to a specific value of 0 or 1 - */ -int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ) -{ - int ret = 0; - size_t off = pos / biL; - size_t idx = pos % biL; - MPI_VALIDATE_RET( X != NULL ); - - if( val != 0 && val != 1 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - if( X->n * biL <= pos ) - { - if( val == 0 ) - return( 0 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) ); - } - - X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx ); - X->p[off] |= (mbedtls_mpi_uint) val << idx; - -cleanup: - - return( ret ); -} - -/* - * Return the number of less significant zero-bits - */ -size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ) -{ - size_t i, j, count = 0; - MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 ); - - for( i = 0; i < X->n; i++ ) - for( j = 0; j < biL; j++, count++ ) - if( ( ( X->p[i] >> j ) & 1 ) != 0 ) - return( count ); - - return( 0 ); -} - -/* - * Count leading zero bits in a given integer - */ -static size_t mbedtls_clz( const mbedtls_mpi_uint x ) -{ - size_t j; - mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1); - - for( j = 0; j < biL; j++ ) - { - if( x & mask ) break; - - mask >>= 1; - } - - return j; -} - -/* - * Return the number of bits - */ -size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X ) -{ - size_t i, j; - - if( X->n == 0 ) - return( 0 ); - - for( i = X->n - 1; i > 0; i-- ) - if( X->p[i] != 0 ) - break; - - j = biL - mbedtls_clz( X->p[i] ); - - return( ( i * biL ) + j ); -} - -/* - * Return the total size in bytes - */ -size_t mbedtls_mpi_size( const mbedtls_mpi *X ) -{ - return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 ); -} - -/* - * Convert an ASCII character to digit value - */ -static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c ) -{ - *d = 255; - - if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; - if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; - if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; - - if( *d >= (mbedtls_mpi_uint) radix ) - return( MBEDTLS_ERR_MPI_INVALID_CHARACTER ); - - return( 0 ); -} - -/* - * Import from an ASCII string - */ -int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) -{ - int ret; - size_t i, j, slen, n; - int sign = 1; - mbedtls_mpi_uint d; - mbedtls_mpi T; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( s != NULL ); - - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &T ); - - if( s[0] == '-' ) - { - ++s; - sign = -1; - } - - slen = strlen( s ); - - if( radix == 16 ) - { - if( slen > MPI_SIZE_T_MAX >> 2 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - n = BITS_TO_LIMBS( slen << 2 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - for( i = slen, j = 0; i > 0; i--, j++ ) - { - MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); - X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 ); - } - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - for( i = 0; i < slen; i++ ) - { - MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) ); - } - } - - if( sign < 0 && mbedtls_mpi_bitlen( X ) != 0 ) - X->s = -1; - -cleanup: - - mbedtls_mpi_free( &T ); - - return( ret ); -} - -/* - * Helper to write the digits high-order first. - */ -static int mpi_write_hlp( mbedtls_mpi *X, int radix, - char **p, const size_t buflen ) -{ - int ret; - mbedtls_mpi_uint r; - size_t length = 0; - char *p_end = *p + buflen; - - do - { - if( length >= buflen ) - { - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) ); - /* - * Write the residue in the current position, as an ASCII character. - */ - if( r < 0xA ) - *(--p_end) = (char)( '0' + r ); - else - *(--p_end) = (char)( 'A' + ( r - 0xA ) ); - - length++; - } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 ); - - memmove( *p, p_end, length ); - *p += length; - -cleanup: - - return( ret ); -} - -/* - * Export into an ASCII string - */ -int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, - char *buf, size_t buflen, size_t *olen ) -{ - int ret = 0; - size_t n; - char *p; - mbedtls_mpi T; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( olen != NULL ); - MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); - - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */ - if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present - * `n`. If radix > 4, this might be a strict - * overapproximation of the number of - * radix-adic digits needed to present `n`. */ - if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to - * present `n`. */ - - n += 1; /* Terminating null byte */ - n += 1; /* Compensate for the divisions above, which round down `n` - * in case it's not even. */ - n += 1; /* Potential '-'-sign. */ - n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing, - * which always uses an even number of hex-digits. */ - - if( buflen < n ) - { - *olen = n; - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - } - - p = buf; - mbedtls_mpi_init( &T ); - - if( X->s == -1 ) - { - *p++ = '-'; - buflen--; - } - - if( radix == 16 ) - { - int c; - size_t i, j, k; - - for( i = X->n, k = 0; i > 0; i-- ) - { - for( j = ciL; j > 0; j-- ) - { - c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; - - if( c == 0 && k == 0 && ( i + j ) != 2 ) - continue; - - *(p++) = "0123456789ABCDEF" [c / 16]; - *(p++) = "0123456789ABCDEF" [c % 16]; - k = 1; - } - } - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) ); - - if( T.s == -1 ) - T.s = 1; - - MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) ); - } - - *p++ = '\0'; - *olen = p - buf; - -cleanup: - - mbedtls_mpi_free( &T ); - - return( ret ); -} - -#if defined(MBEDTLS_FS_IO) -/* - * Read X from an opened file - */ -int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ) -{ - mbedtls_mpi_uint d; - size_t slen; - char *p; - /* - * Buffer should have space for (short) label and decimal formatted MPI, - * newline characters and '\0' - */ - char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( fin != NULL ); - - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - memset( s, 0, sizeof( s ) ); - if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) - return( MBEDTLS_ERR_MPI_FILE_IO_ERROR ); - - slen = strlen( s ); - if( slen == sizeof( s ) - 2 ) - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - - if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } - if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } - - p = s + slen; - while( p-- > s ) - if( mpi_get_digit( &d, radix, *p ) != 0 ) - break; - - return( mbedtls_mpi_read_string( X, radix, p + 1 ) ); -} - -/* - * Write X into an opened file (or stdout if fout == NULL) - */ -int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout ) -{ - int ret; - size_t n, slen, plen; - /* - * Buffer should have space for (short) label and decimal formatted MPI, - * newline characters and '\0' - */ - char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; - MPI_VALIDATE_RET( X != NULL ); - - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - memset( s, 0, sizeof( s ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) ); - - if( p == NULL ) p = ""; - - plen = strlen( p ); - slen = strlen( s ); - s[slen++] = '\r'; - s[slen++] = '\n'; - - if( fout != NULL ) - { - if( fwrite( p, 1, plen, fout ) != plen || - fwrite( s, 1, slen, fout ) != slen ) - return( MBEDTLS_ERR_MPI_FILE_IO_ERROR ); - } - else - mbedtls_printf( "%s%s", p, s ); - -cleanup: - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - - -/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint - * into the storage form used by mbedtls_mpi. */ - -static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x ) -{ - uint8_t i; - unsigned char *x_ptr; - mbedtls_mpi_uint tmp = 0; - - for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ ) - { - tmp <<= CHAR_BIT; - tmp |= (mbedtls_mpi_uint) *x_ptr; - } - - return( tmp ); -} - -static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x ) -{ -#if defined(__BYTE_ORDER__) - -/* Nothing to do on bigendian systems. */ -#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ) - return( x ); -#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */ - -#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) - -/* For GCC and Clang, have builtins for byte swapping. */ -#if defined(__GNUC__) && defined(__GNUC_PREREQ) -#if __GNUC_PREREQ(4,3) -#define have_bswap -#endif -#endif - -#if defined(__clang__) && defined(__has_builtin) -#if __has_builtin(__builtin_bswap32) && \ - __has_builtin(__builtin_bswap64) -#define have_bswap -#endif -#endif - -#if defined(have_bswap) - /* The compiler is hopefully able to statically evaluate this! */ - switch( sizeof(mbedtls_mpi_uint) ) - { - case 4: - return( __builtin_bswap32(x) ); - case 8: - return( __builtin_bswap64(x) ); - } -#endif -#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */ -#endif /* __BYTE_ORDER__ */ - - /* Fall back to C-based reordering if we don't know the byte order - * or we couldn't use a compiler-specific builtin. */ - return( mpi_uint_bigendian_to_host_c( x ) ); -} - -static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs ) -{ - mbedtls_mpi_uint *cur_limb_left; - mbedtls_mpi_uint *cur_limb_right; - if( limbs == 0 ) - return; - - /* - * Traverse limbs and - * - adapt byte-order in each limb - * - swap the limbs themselves. - * For that, simultaneously traverse the limbs from left to right - * and from right to left, as long as the left index is not bigger - * than the right index (it's not a problem if limbs is odd and the - * indices coincide in the last iteration). - */ - for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 ); - cur_limb_left <= cur_limb_right; - cur_limb_left++, cur_limb_right-- ) - { - mbedtls_mpi_uint tmp; - /* Note that if cur_limb_left == cur_limb_right, - * this code effectively swaps the bytes only once. */ - tmp = mpi_uint_bigendian_to_host( *cur_limb_left ); - *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right ); - *cur_limb_right = tmp; - } -} - -/* - * Import X from unsigned binary data, big endian - */ -int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ) -{ - int ret; - size_t const limbs = CHARS_TO_LIMBS( buflen ); - size_t const overhead = ( limbs * ciL ) - buflen; - unsigned char *Xp; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); - - /* Ensure that target MPI has exactly the necessary number of limbs */ - if( X->n != limbs ) - { - mbedtls_mpi_free( X ); - mbedtls_mpi_init( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); - } - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - /* Avoid calling `memcpy` with NULL source argument, - * even if buflen is 0. */ - if( buf != NULL ) - { - Xp = (unsigned char*) X->p; - memcpy( Xp + overhead, buf, buflen ); - - mpi_bigendian_to_host( X->p, limbs ); - } - -cleanup: - - return( ret ); -} - -/* - * Export X into unsigned binary data, big endian - */ -int mbedtls_mpi_write_binary( const mbedtls_mpi *X, - unsigned char *buf, size_t buflen ) -{ - size_t stored_bytes; - size_t bytes_to_copy; - unsigned char *p; - size_t i; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); - - stored_bytes = X->n * ciL; - - if( stored_bytes < buflen ) - { - /* There is enough space in the output buffer. Write initial - * null bytes and record the position at which to start - * writing the significant bytes. In this case, the execution - * trace of this function does not depend on the value of the - * number. */ - bytes_to_copy = stored_bytes; - p = buf + buflen - stored_bytes; - memset( buf, 0, buflen - stored_bytes ); - } - else - { - /* The output buffer is smaller than the allocated size of X. - * However X may fit if its leading bytes are zero. */ - bytes_to_copy = buflen; - p = buf; - for( i = bytes_to_copy; i < stored_bytes; i++ ) - { - if( GET_BYTE( X, i ) != 0 ) - return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - } - } - - for( i = 0; i < bytes_to_copy; i++ ) - p[bytes_to_copy - i - 1] = GET_BYTE( X, i ); - - return( 0 ); -} - -/* - * Left-shift: X <<= count - */ -int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ) -{ - int ret; - size_t i, v0, t1; - mbedtls_mpi_uint r0 = 0, r1; - MPI_VALIDATE_RET( X != NULL ); - - v0 = count / (biL ); - t1 = count & (biL - 1); - - i = mbedtls_mpi_bitlen( X ) + count; - - if( X->n * biL < i ) - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) ); - - ret = 0; - - /* - * shift by count / limb_size - */ - if( v0 > 0 ) - { - for( i = X->n; i > v0; i-- ) - X->p[i - 1] = X->p[i - v0 - 1]; - - for( ; i > 0; i-- ) - X->p[i - 1] = 0; - } - - /* - * shift by count % limb_size - */ - if( t1 > 0 ) - { - for( i = v0; i < X->n; i++ ) - { - r1 = X->p[i] >> (biL - t1); - X->p[i] <<= t1; - X->p[i] |= r0; - r0 = r1; - } - } - -cleanup: - - return( ret ); -} - -/* - * Right-shift: X >>= count - */ -int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ) -{ - size_t i, v0, v1; - mbedtls_mpi_uint r0 = 0, r1; - MPI_VALIDATE_RET( X != NULL ); - - v0 = count / biL; - v1 = count & (biL - 1); - - if( v0 > X->n || ( v0 == X->n && v1 > 0 ) ) - return mbedtls_mpi_lset( X, 0 ); - - /* - * shift by count / limb_size - */ - if( v0 > 0 ) - { - for( i = 0; i < X->n - v0; i++ ) - X->p[i] = X->p[i + v0]; - - for( ; i < X->n; i++ ) - X->p[i] = 0; - } - - /* - * shift by count % limb_size - */ - if( v1 > 0 ) - { - for( i = X->n; i > 0; i-- ) - { - r1 = X->p[i - 1] << (biL - v1); - X->p[i - 1] >>= v1; - X->p[i - 1] |= r0; - r0 = r1; - } - } - - return( 0 ); -} - -/* - * Compare unsigned values - */ -int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ) -{ - size_t i, j; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - for( i = X->n; i > 0; i-- ) - if( X->p[i - 1] != 0 ) - break; - - for( j = Y->n; j > 0; j-- ) - if( Y->p[j - 1] != 0 ) - break; - - if( i == 0 && j == 0 ) - return( 0 ); - - if( i > j ) return( 1 ); - if( j > i ) return( -1 ); - - for( ; i > 0; i-- ) - { - if( X->p[i - 1] > Y->p[i - 1] ) return( 1 ); - if( X->p[i - 1] < Y->p[i - 1] ) return( -1 ); - } - - return( 0 ); -} - -/* - * Compare signed values - */ -int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ) -{ - size_t i, j; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - - for( i = X->n; i > 0; i-- ) - if( X->p[i - 1] != 0 ) - break; - - for( j = Y->n; j > 0; j-- ) - if( Y->p[j - 1] != 0 ) - break; - - if( i == 0 && j == 0 ) - return( 0 ); - - if( i > j ) return( X->s ); - if( j > i ) return( -Y->s ); - - if( X->s > 0 && Y->s < 0 ) return( 1 ); - if( Y->s > 0 && X->s < 0 ) return( -1 ); - - for( ; i > 0; i-- ) - { - if( X->p[i - 1] > Y->p[i - 1] ) return( X->s ); - if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s ); - } - - return( 0 ); -} - -/** Decide if an integer is less than the other, without branches. - * - * \param x First integer. - * \param y Second integer. - * - * \return 1 if \p x is less than \p y, 0 otherwise - */ -static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x, - const mbedtls_mpi_uint y ) -{ - mbedtls_mpi_uint ret; - mbedtls_mpi_uint cond; - - /* - * Check if the most significant bits (MSB) of the operands are different. - */ - cond = ( x ^ y ); - /* - * If the MSB are the same then the difference x-y will be negative (and - * have its MSB set to 1 during conversion to unsigned) if and only if x> ( biL - 1 ); - - return (unsigned) ret; -} - -/* - * Compare signed values in constant time - */ -int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y, - unsigned *ret ) -{ - size_t i; - /* The value of any of these variables is either 0 or 1 at all times. */ - unsigned cond, done, X_is_negative, Y_is_negative; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( Y != NULL ); - MPI_VALIDATE_RET( ret != NULL ); - - if( X->n != Y->n ) - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - - /* - * Set sign_N to 1 if N >= 0, 0 if N < 0. - * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0. - */ - X_is_negative = ( X->s & 2 ) >> 1; - Y_is_negative = ( Y->s & 2 ) >> 1; - - /* - * If the signs are different, then the positive operand is the bigger. - * That is if X is negative (X_is_negative == 1), then X < Y is true and it - * is false if X is positive (X_is_negative == 0). - */ - cond = ( X_is_negative ^ Y_is_negative ); - *ret = cond & X_is_negative; - - /* - * This is a constant-time function. We might have the result, but we still - * need to go through the loop. Record if we have the result already. - */ - done = cond; - - for( i = X->n; i > 0; i-- ) - { - /* - * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both - * X and Y are negative. - * - * Again even if we can make a decision, we just mark the result and - * the fact that we are done and continue looping. - */ - cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] ); - *ret |= cond & ( 1 - done ) & X_is_negative; - done |= cond; - - /* - * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both - * X and Y are positive. - * - * Again even if we can make a decision, we just mark the result and - * the fact that we are done and continue looping. - */ - cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] ); - *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative ); - done |= cond; - } - - return( 0 ); -} - -/* - * Compare signed values - */ -int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ) -{ - mbedtls_mpi Y; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - - *p = ( z < 0 ) ? -z : z; - Y.s = ( z < 0 ) ? -1 : 1; - Y.n = 1; - Y.p = p; - - return( mbedtls_mpi_cmp_mpi( X, &Y ) ); -} - -/* - * Unsigned addition: X = |A| + |B| (HAC 14.7) - */ -int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret; - size_t i, j; - mbedtls_mpi_uint *o, *p, c, tmp; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - if( X == B ) - { - const mbedtls_mpi *T = A; A = X; B = T; - } - - if( X != A ) - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) ); - - /* - * X should always be positive as a result of unsigned additions. - */ - X->s = 1; - - for( j = B->n; j > 0; j-- ) - if( B->p[j - 1] != 0 ) - break; - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); - - o = B->p; p = X->p; c = 0; - - /* - * tmp is used because it might happen that p == o - */ - for( i = 0; i < j; i++, o++, p++ ) - { - tmp= *o; - *p += c; c = ( *p < c ); - *p += tmp; c += ( *p < tmp ); - } - - while( c != 0 ) - { - if( i >= X->n ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) ); - p = X->p + i; - } - - *p += c; c = ( *p < c ); i++; p++; - } - -cleanup: - - return( ret ); -} - -/** - * Helper for mbedtls_mpi subtraction. - * - * Calculate d - s where d and s have the same size. - * This function operates modulo (2^ciL)^n and returns the carry - * (1 if there was a wraparound, i.e. if `d < s`, and 0 otherwise). - * - * \param n Number of limbs of \p d and \p s. - * \param[in,out] d On input, the left operand. - * On output, the result of the subtraction: - * \param[in] s The right operand. - * - * \return 1 if `d < s`. - * 0 if `d >= s`. - */ -static mbedtls_mpi_uint mpi_sub_hlp( size_t n, - mbedtls_mpi_uint *d, - const mbedtls_mpi_uint *s ) -{ - size_t i; - mbedtls_mpi_uint c, z; - - for( i = c = 0; i < n; i++, s++, d++ ) - { - z = ( *d < c ); *d -= c; - c = ( *d < *s ) + z; *d -= *s; - } - - return( c ); -} - -/* - * Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10) - */ -int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - mbedtls_mpi TB; - int ret; - size_t n; - mbedtls_mpi_uint carry; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - mbedtls_mpi_init( &TB ); - - if( X == B ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); - B = &TB; - } - - if( X != A ) - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) ); - - /* - * X should always be positive as a result of unsigned subtractions. - */ - X->s = 1; - - ret = 0; - - for( n = B->n; n > 0; n-- ) - if( B->p[n - 1] != 0 ) - break; - if( n > A->n ) - { - /* B >= (2^ciL)^n > A */ - ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE; - goto cleanup; - } - - carry = mpi_sub_hlp( n, X->p, B->p ); - if( carry != 0 ) - { - /* Propagate the carry to the first nonzero limb of X. */ - for( ; n < X->n && X->p[n] == 0; n++ ) - --X->p[n]; - /* If we ran out of space for the carry, it means that the result - * is negative. */ - if( n == X->n ) - { - ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE; - goto cleanup; - } - --X->p[n]; - } - -cleanup: - - mbedtls_mpi_free( &TB ); - - return( ret ); -} - -/* - * Signed addition: X = A + B - */ -int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret, s; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - s = A->s; - if( A->s * B->s < 0 ) - { - if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); - X->s = s; - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); - X->s = -s; - } - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) ); - X->s = s; - } - -cleanup: - - return( ret ); -} - -/* - * Signed subtraction: X = A - B - */ -int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret, s; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - s = A->s; - if( A->s * B->s > 0 ) - { - if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); - X->s = s; - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); - X->s = -s; - } - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) ); - X->s = s; - } - -cleanup: - - return( ret ); -} - -/* - * Signed addition: X = A + b - */ -int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ) -{ - mbedtls_mpi _B; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mbedtls_mpi_add_mpi( X, A, &_B ) ); -} - -/* - * Signed subtraction: X = A - b - */ -int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ) -{ - mbedtls_mpi _B; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mbedtls_mpi_sub_mpi( X, A, &_B ) ); -} - -/* - * Helper for mbedtls_mpi multiplication - */ -static -#if defined(__APPLE__) && defined(__arm__) -/* - * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) - * appears to need this to prevent bad ARM code generation at -O3. - */ -__attribute__ ((noinline)) -#endif -void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b ) -{ - mbedtls_mpi_uint c = 0, t = 0; - -#if defined(MULADDC_HUIT) - for( ; i >= 8; i -= 8 ) - { - MULADDC_INIT - MULADDC_HUIT - MULADDC_STOP - } - - for( ; i > 0; i-- ) - { - MULADDC_INIT - MULADDC_CORE - MULADDC_STOP - } -#else /* MULADDC_HUIT */ - for( ; i >= 16; i -= 16 ) - { - MULADDC_INIT - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_STOP - } - - for( ; i >= 8; i -= 8 ) - { - MULADDC_INIT - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_STOP - } - - for( ; i > 0; i-- ) - { - MULADDC_INIT - MULADDC_CORE - MULADDC_STOP - } -#endif /* MULADDC_HUIT */ - - t++; - - do { - *d += c; c = ( *d < c ); d++; - } - while( c != 0 ); -} - -/* - * Baseline multiplication: X = A * B (HAC 14.12) - */ -int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret; - size_t i, j; - mbedtls_mpi TA, TB; - int result_is_zero = 0; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); - - if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; } - if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; } - - for( i = A->n; i > 0; i-- ) - if( A->p[i - 1] != 0 ) - break; - if( i == 0 ) - result_is_zero = 1; - - for( j = B->n; j > 0; j-- ) - if( B->p[j - 1] != 0 ) - break; - if( j == 0 ) - result_is_zero = 1; - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - for( ; j > 0; j-- ) - mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] ); - - /* If the result is 0, we don't shortcut the operation, which reduces - * but does not eliminate side channels leaking the zero-ness. We do - * need to take care to set the sign bit properly since the library does - * not fully support an MPI object with a value of 0 and s == -1. */ - if( result_is_zero ) - X->s = 1; - else - X->s = A->s * B->s; - -cleanup: - - mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA ); - - return( ret ); -} - -/* - * Baseline multiplication: X = A * b - */ -int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b ) -{ - mbedtls_mpi _B; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - - _B.s = 1; - _B.n = 1; - _B.p = p; - p[0] = b; - - return( mbedtls_mpi_mul_mpi( X, A, &_B ) ); -} - -/* - * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and - * mbedtls_mpi_uint divisor, d - */ -static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1, - mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r ) -{ -#if defined(MBEDTLS_HAVE_UDBL) - mbedtls_t_udbl dividend, quotient; -#else - const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH; - const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1; - mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient; - mbedtls_mpi_uint u0_msw, u0_lsw; - size_t s; -#endif - - /* - * Check for overflow - */ - if( 0 == d || u1 >= d ) - { - if (r != NULL) *r = ~0; - - return ( ~0 ); - } - -#if defined(MBEDTLS_HAVE_UDBL) - dividend = (mbedtls_t_udbl) u1 << biL; - dividend |= (mbedtls_t_udbl) u0; - quotient = dividend / d; - if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 ) - quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1; - - if( r != NULL ) - *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) ); - - return (mbedtls_mpi_uint) quotient; -#else - - /* - * Algorithm D, Section 4.3.1 - The Art of Computer Programming - * Vol. 2 - Seminumerical Algorithms, Knuth - */ - - /* - * Normalize the divisor, d, and dividend, u0, u1 - */ - s = mbedtls_clz( d ); - d = d << s; - - u1 = u1 << s; - u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) ); - u0 = u0 << s; - - d1 = d >> biH; - d0 = d & uint_halfword_mask; - - u0_msw = u0 >> biH; - u0_lsw = u0 & uint_halfword_mask; - - /* - * Find the first quotient and remainder - */ - q1 = u1 / d1; - r0 = u1 - d1 * q1; - - while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) ) - { - q1 -= 1; - r0 += d1; - - if ( r0 >= radix ) break; - } - - rAX = ( u1 * radix ) + ( u0_msw - q1 * d ); - q0 = rAX / d1; - r0 = rAX - q0 * d1; - - while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) ) - { - q0 -= 1; - r0 += d1; - - if ( r0 >= radix ) break; - } - - if (r != NULL) - *r = ( rAX * radix + u0_lsw - q0 * d ) >> s; - - quotient = q1 * radix + q0; - - return quotient; -#endif -} - -/* - * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20) - */ -int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B ) -{ - int ret; - size_t i, n, t, k; - mbedtls_mpi X, Y, Z, T1, T2; - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - if( mbedtls_mpi_cmp_int( B, 0 ) == 0 ) - return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); - - mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); - mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); - - if( mbedtls_mpi_cmp_abs( A, B ) < 0 ) - { - if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) ); - if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) ); - return( 0 ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) ); - X.s = Y.s = 1; - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) ); - - k = mbedtls_mpi_bitlen( &Y ) % biL; - if( k < biL - 1 ) - { - k = biL - 1 - k; - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) ); - } - else k = 0; - - n = X.n - 1; - t = Y.n - 1; - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) ); - - while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 ) - { - Z.p[n - t]++; - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) ); - } - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) ); - - for( i = n; i > t ; i-- ) - { - if( X.p[i] >= Y.p[t] ) - Z.p[i - t - 1] = ~0; - else - { - Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1], - Y.p[t], NULL); - } - - Z.p[i - t - 1]++; - do - { - Z.p[i - t - 1]--; - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) ); - T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1]; - T1.p[1] = Y.p[t]; - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) ); - T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2]; - T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1]; - T2.p[2] = X.p[i]; - } - while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); - - if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) ); - Z.p[i - t - 1]--; - } - } - - if( Q != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) ); - Q->s = A->s * B->s; - } - - if( R != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) ); - X.s = A->s; - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) ); - - if( mbedtls_mpi_cmp_int( R, 0 ) == 0 ) - R->s = 1; - } - -cleanup: - - mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); - mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); - - return( ret ); -} - -/* - * Division by int: A = Q * b + R - */ -int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, - const mbedtls_mpi *A, - mbedtls_mpi_sint b ) -{ - mbedtls_mpi _B; - mbedtls_mpi_uint p[1]; - MPI_VALIDATE_RET( A != NULL ); - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) ); -} - -/* - * Modulo: R = A mod B - */ -int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret; - MPI_VALIDATE_RET( R != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - if( mbedtls_mpi_cmp_int( B, 0 ) < 0 ) - return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) ); - - while( mbedtls_mpi_cmp_int( R, 0 ) < 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); - - while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); - -cleanup: - - return( ret ); -} - -/* - * Modulo: r = A mod b - */ -int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b ) -{ - size_t i; - mbedtls_mpi_uint x, y, z; - MPI_VALIDATE_RET( r != NULL ); - MPI_VALIDATE_RET( A != NULL ); - - if( b == 0 ) - return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); - - if( b < 0 ) - return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); - - /* - * handle trivial cases - */ - if( b == 1 ) - { - *r = 0; - return( 0 ); - } - - if( b == 2 ) - { - *r = A->p[0] & 1; - return( 0 ); - } - - /* - * general case - */ - for( i = A->n, y = 0; i > 0; i-- ) - { - x = A->p[i - 1]; - y = ( y << biH ) | ( x >> biH ); - z = y / b; - y -= z * b; - - x <<= biH; - y = ( y << biH ) | ( x >> biH ); - z = y / b; - y -= z * b; - } - - /* - * If A is negative, then the current y represents a negative value. - * Flipping it to the positive side. - */ - if( A->s < 0 && y != 0 ) - y = b - y; - - *r = y; - - return( 0 ); -} - -/* - * Fast Montgomery initialization (thanks to Tom St Denis) - */ -static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N ) -{ - mbedtls_mpi_uint x, m0 = N->p[0]; - unsigned int i; - - x = m0; - x += ( ( m0 + 2 ) & 4 ) << 1; - - for( i = biL; i >= 8; i /= 2 ) - x *= ( 2 - ( m0 * x ) ); - - *mm = ~x + 1; -} - -/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) - * - * \param[in,out] A One of the numbers to multiply. - * It must have at least as many limbs as N - * (A->n >= N->n), and any limbs beyond n are ignored. - * On successful completion, A contains the result of - * the multiplication A * B * R^-1 mod N where - * R = (2^ciL)^n. - * \param[in] B One of the numbers to multiply. - * It must be nonzero and must not have more limbs than N - * (B->n <= N->n). - * \param[in] N The modulo. N must be odd. - * \param mm The value calculated by `mpi_montg_init(&mm, N)`. - * This is -N^-1 mod 2^ciL. - * \param[in,out] T A bignum for temporary storage. - * It must be at least twice the limb size of N plus 2 - * (T->n >= 2 * (N->n + 1)). - * Its initial content is unused and - * its final content is indeterminate. - * Note that unlike the usual convention in the library - * for `const mbedtls_mpi*`, the content of T can change. - */ -static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm, - const mbedtls_mpi *T ) -{ - size_t i, n, m; - mbedtls_mpi_uint u0, u1, *d; - - memset( T->p, 0, T->n * ciL ); - - d = T->p; - n = N->n; - m = ( B->n < n ) ? B->n : n; - - for( i = 0; i < n; i++ ) - { - /* - * T = (T + u0*B + u1*N) / 2^biL - */ - u0 = A->p[i]; - u1 = ( d[0] + u0 * B->p[0] ) * mm; - - mpi_mul_hlp( m, B->p, d, u0 ); - mpi_mul_hlp( n, N->p, d, u1 ); - - *d++ = u0; d[n + 1] = 0; - } - - /* At this point, d is either the desired result or the desired result - * plus N. We now potentially subtract N, avoiding leaking whether the - * subtraction is performed through side channels. */ - - /* Copy the n least significant limbs of d to A, so that - * A = d if d < N (recall that N has n limbs). */ - memcpy( A->p, d, n * ciL ); - /* If d >= N then we want to set A to d - N. To prevent timing attacks, - * do the calculation without using conditional tests. */ - /* Set d to d0 + (2^biL)^n - N where d0 is the current value of d. */ - d[n] += 1; - d[n] -= mpi_sub_hlp( n, d, N->p ); - /* If d0 < N then d < (2^biL)^n - * so d[n] == 0 and we want to keep A as it is. - * If d0 >= N then d >= (2^biL)^n, and d <= (2^biL)^n + N < 2 * (2^biL)^n - * so d[n] == 1 and we want to set A to the result of the subtraction - * which is d - (2^biL)^n, i.e. the n least significant limbs of d. - * This exactly corresponds to a conditional assignment. */ - mpi_safe_cond_assign( n, A->p, d, (unsigned char) d[n] ); -} - -/* - * Montgomery reduction: A = A * R^-1 mod N - * - * See mpi_montmul() regarding constraints and guarantees on the parameters. - */ -static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, - mbedtls_mpi_uint mm, const mbedtls_mpi *T ) -{ - mbedtls_mpi_uint z = 1; - mbedtls_mpi U; - - U.n = U.s = (int) z; - U.p = &z; - - mpi_montmul( A, &U, N, mm, T ); -} - -/* - * Constant-flow boolean "equal" comparison: - * return x == y - * - * This function can be used to write constant-time code by replacing branches - * with bit operations - it can be used in conjunction with - * mbedtls_ssl_cf_mask_from_bit(). - * - * This function is implemented without using comparison operators, as those - * might be translated to branches by some compilers on some platforms. - */ -static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y ) -{ - /* diff = 0 if x == y, non-zero otherwise */ - const size_t diff = x ^ y; - - /* MSVC has a warning about unary minus on unsigned integer types, - * but this is well-defined and precisely what we want to do here. */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - - /* diff_msb's most significant bit is equal to x != y */ - const size_t diff_msb = ( diff | (size_t) -diff ); - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - /* diff1 = (x != y) ? 1 : 0 */ - const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 ); - - return( 1 ^ diff1 ); -} - -/** - * Select an MPI from a table without leaking the index. - * - * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it - * reads the entire table in order to avoid leaking the value of idx to an - * attacker able to observe memory access patterns. - * - * \param[out] R Where to write the selected MPI. - * \param[in] T The table to read from. - * \param[in] T_size The number of elements in the table. - * \param[in] idx The index of the element to select; - * this must satisfy 0 <= idx < T_size. - * - * \return \c 0 on success, or a negative error code. - */ -static int mpi_select( mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx ) -{ - int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - size_t i; - - for( i = 0; i < T_size; i++ ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i], - (unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) ); - } - -cleanup: - return( ret ); -} - -/* - * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) - */ -int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *_RR ) -{ - int ret; - size_t wbits, wsize, one = 1; - size_t i, j, nblimbs; - size_t bufsize, nbits; - mbedtls_mpi_uint ei, mm, state; - mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos; - int neg; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( E != NULL ); - MPI_VALIDATE_RET( N != NULL ); - - if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - if( mbedtls_mpi_bitlen( E ) > MBEDTLS_MPI_MAX_BITS || - mbedtls_mpi_bitlen( N ) > MBEDTLS_MPI_MAX_BITS ) - return ( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - /* - * Init temps and window size - */ - mpi_montg_init( &mm, N ); - mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T ); - mbedtls_mpi_init( &Apos ); - mbedtls_mpi_init( &WW ); - memset( W, 0, sizeof( W ) ); - - i = mbedtls_mpi_bitlen( E ); - - wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : - ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; - -#if( MBEDTLS_MPI_WINDOW_SIZE < 6 ) - if( wsize > MBEDTLS_MPI_WINDOW_SIZE ) - wsize = MBEDTLS_MPI_WINDOW_SIZE; -#endif - - j = N->n + 1; - /* All W[i] and X must have at least N->n limbs for the mpi_montmul() - * and mpi_montred() calls later. Here we ensure that W[1] and X are - * large enough, and later we'll grow other W[i] to the same length. - * They must not be shrunk midway through this function! - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) ); - - /* - * Compensate for negative A (and correct at the end) - */ - neg = ( A->s == -1 ); - if( neg ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) ); - Apos.s = 1; - A = &Apos; - } - - /* - * If 1st call, pre-compute R^2 mod N - */ - if( _RR == NULL || _RR->p == NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) ); - - if( _RR != NULL ) - memcpy( _RR, &RR, sizeof( mbedtls_mpi ) ); - } - else - memcpy( &RR, _RR, sizeof( mbedtls_mpi ) ); - - /* - * W[1] = A * R^2 * R^-1 mod N = A * R mod N - */ - if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) ); - else - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) ); - /* Re-grow W[1] if necessary. This should be only necessary in one corner - * case: when A == 0 represented with A.n == 0, mbedtls_mpi_copy shrinks - * W[1] to 0 limbs. */ - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n +1 ) ); - - mpi_montmul( &W[1], &RR, N, mm, &T ); - - /* - * X = R^2 * R^-1 mod N = R mod N - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) ); - mpi_montred( X, N, mm, &T ); - - if( wsize > 1 ) - { - /* - * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) - */ - j = one << ( wsize - 1 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) ); - - for( i = 0; i < wsize - 1; i++ ) - mpi_montmul( &W[j], &W[j], N, mm, &T ); - - /* - * W[i] = W[i - 1] * W[1] - */ - for( i = j + 1; i < ( one << wsize ); i++ ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) ); - - mpi_montmul( &W[i], &W[1], N, mm, &T ); - } - } - - nblimbs = E->n; - bufsize = 0; - nbits = 0; - wbits = 0; - state = 0; - - while( 1 ) - { - if( bufsize == 0 ) - { - if( nblimbs == 0 ) - break; - - nblimbs--; - - bufsize = sizeof( mbedtls_mpi_uint ) << 3; - } - - bufsize--; - - ei = (E->p[nblimbs] >> bufsize) & 1; - - /* - * skip leading 0s - */ - if( ei == 0 && state == 0 ) - continue; - - if( ei == 0 && state == 1 ) - { - /* - * out of window, square X - */ - mpi_montmul( X, X, N, mm, &T ); - continue; - } - - /* - * add ei to current window - */ - state = 2; - - nbits++; - wbits |= ( ei << ( wsize - nbits ) ); - - if( nbits == wsize ) - { - /* - * X = X^wsize R^-1 mod N - */ - for( i = 0; i < wsize; i++ ) - mpi_montmul( X, X, N, mm, &T ); - - /* - * X = X * W[wbits] R^-1 mod N - */ - MBEDTLS_MPI_CHK( mpi_select( &WW, W, (size_t) 1 << wsize, wbits ) ); - mpi_montmul( X, &WW, N, mm, &T ); - - state--; - nbits = 0; - wbits = 0; - } - } - - /* - * process the remaining bits - */ - for( i = 0; i < nbits; i++ ) - { - mpi_montmul( X, X, N, mm, &T ); - - wbits <<= 1; - - if( ( wbits & ( one << wsize ) ) != 0 ) - mpi_montmul( X, &W[1], N, mm, &T ); - } - - /* - * X = A^E * R * R^-1 mod N = A^E mod N - */ - mpi_montred( X, N, mm, &T ); - - if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 ) - { - X->s = -1; - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) ); - } - -cleanup: - - for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) - mbedtls_mpi_free( &W[i] ); - - mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos ); - mbedtls_mpi_free( &WW ); - - if( _RR == NULL || _RR->p == NULL ) - mbedtls_mpi_free( &RR ); - - return( ret ); -} - -/* - * Greatest common divisor: G = gcd(A, B) (HAC 14.54) - */ -int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ) -{ - int ret; - size_t lz, lzt; - mbedtls_mpi TG, TA, TB; - - MPI_VALIDATE_RET( G != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( B != NULL ); - - mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); - - lz = mbedtls_mpi_lsb( &TA ); - lzt = mbedtls_mpi_lsb( &TB ); - - /* The loop below gives the correct result when A==0 but not when B==0. - * So have a special case for B==0. Leverage the fact that we just - * calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test - * slightly more efficient than cmp_int(). */ - if( lzt == 0 && mbedtls_mpi_get_bit( &TB, 0 ) == 0 ) - { - ret = mbedtls_mpi_copy( G, A ); - goto cleanup; - } - - if( lzt < lz ) - lz = lzt; - - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) ); - - TA.s = TB.s = 1; - - /* We mostly follow the procedure described in HAC 14.54, but with some - * minor differences: - * - Sequences of multiplications or divisions by 2 are grouped into a - * single shift operation. - * - The procedure in HAC assumes that 0 < TB <= TA. - * - The condition TB <= TA is not actually necessary for correctness. - * TA and TB have symmetric roles except for the loop termination - * condition, and the shifts at the beginning of the loop body - * remove any significance from the ordering of TA vs TB before - * the shifts. - * - If TA = 0, the loop goes through 0 iterations and the result is - * correctly TB. - * - The case TB = 0 was short-circuited above. - * - * For the correctness proof below, decompose the original values of - * A and B as - * A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1 - * B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1 - * Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'), - * and gcd(A',B') is odd or 0. - * - * At the beginning, we have TA = |A|/2^a and TB = |B|/2^b. - * The code maintains the following invariant: - * gcd(A,B) = 2^k * gcd(TA,TB) for some k (I) - */ - - /* Proof that the loop terminates: - * At each iteration, either the right-shift by 1 is made on a nonzero - * value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases - * by at least 1, or the right-shift by 1 is made on zero and then - * TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted - * since in that case TB is calculated from TB-TA with the condition TB>TA). - */ - while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 ) - { - /* Divisions by 2 preserve the invariant (I). */ - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) ); - - /* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd, - * TA-TB is even so the division by 2 has an integer result. - * Invariant (I) is preserved since any odd divisor of both TA and TB - * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2 - * also divides TB, and any odd divisior of both TB and |TA-TB|/2 also - * divides TA. - */ - if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) ); - } - /* Note that one of TA or TB is still odd. */ - } - - /* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k. - * At the loop exit, TA = 0, so gcd(TA,TB) = TB. - * - If there was at least one loop iteration, then one of TA or TB is odd, - * and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case, - * lz = min(a,b) so gcd(A,B) = 2^lz * TB. - * - If there was no loop iteration, then A was 0, and gcd(A,B) = B. - * In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well. - */ - - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) ); - -cleanup: - - mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB ); - - return( ret ); -} - -/* - * Fill X with size bytes of random. - * - * Use a temporary bytes representation to make sure the result is the same - * regardless of the platform endianness (useful when f_rng is actually - * deterministic, eg for tests). - */ -int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - size_t const limbs = CHARS_TO_LIMBS( size ); - size_t const overhead = ( limbs * ciL ) - size; - unsigned char *Xp; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - /* Ensure that target MPI has exactly the necessary number of limbs */ - if( X->n != limbs ) - { - mbedtls_mpi_free( X ); - mbedtls_mpi_init( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); - } - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - - Xp = (unsigned char*) X->p; - MBEDTLS_MPI_CHK( f_rng( p_rng, Xp + overhead, size ) ); - - mpi_bigendian_to_host( X->p, limbs ); - -cleanup: - return( ret ); -} - -/* - * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) - */ -int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N ) -{ - int ret; - mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( A != NULL ); - MPI_VALIDATE_RET( N != NULL ); - - if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 ); - mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV ); - mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) ); - - if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) - { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) ); - - do - { - while( ( TU.p[0] & 1 ) == 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) ); - - if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) ); - } - - while( ( TV.p[0] & 1 ) == 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) ); - - if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) ); - } - - if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) ); - } - } - while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 ); - - while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) ); - - while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) ); - -cleanup: - - mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 ); - mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV ); - mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 ); - - return( ret ); -} - -#if defined(MBEDTLS_GENPRIME) - -static const int small_prime[] = -{ - 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, - 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, - 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251, 257, 263, 269, - 271, 277, 281, 283, 293, 307, 311, 313, - 317, 331, 337, 347, 349, 353, 359, 367, - 373, 379, 383, 389, 397, 401, 409, 419, - 421, 431, 433, 439, 443, 449, 457, 461, - 463, 467, 479, 487, 491, 499, 503, 509, - 521, 523, 541, 547, 557, 563, 569, 571, - 577, 587, 593, 599, 601, 607, 613, 617, - 619, 631, 641, 643, 647, 653, 659, 661, - 673, 677, 683, 691, 701, 709, 719, 727, - 733, 739, 743, 751, 757, 761, 769, 773, - 787, 797, 809, 811, 821, 823, 827, 829, - 839, 853, 857, 859, 863, 877, 881, 883, - 887, 907, 911, 919, 929, 937, 941, 947, - 953, 967, 971, 977, 983, 991, 997, -103 -}; - -/* - * Small divisors test (X must be positive) - * - * Return values: - * 0: no small factor (possible prime, more tests needed) - * 1: certain prime - * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime - * other negative: error - */ -static int mpi_check_small_factors( const mbedtls_mpi *X ) -{ - int ret = 0; - size_t i; - mbedtls_mpi_uint r; - - if( ( X->p[0] & 1 ) == 0 ) - return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - - for( i = 0; small_prime[i] > 0; i++ ) - { - if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 ) - return( 1 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) ); - - if( r == 0 ) - return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - } - -cleanup: - return( ret ); -} - -/* - * Miller-Rabin pseudo-primality test (HAC 4.24) - */ -static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret, count; - size_t i, j, k, s; - mbedtls_mpi W, R, T, A, RR; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); - mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A ); - mbedtls_mpi_init( &RR ); - - /* - * W = |X| - 1 - * R = W >> lsb( W ) - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) ); - s = mbedtls_mpi_lsb( &W ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) ); - - for( i = 0; i < rounds; i++ ) - { - /* - * pick a random A, 1 < A < |X| - 1 - */ - count = 0; - do { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) ); - - j = mbedtls_mpi_bitlen( &A ); - k = mbedtls_mpi_bitlen( &W ); - if (j > k) { - A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1; - } - - if (count++ > 30) { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - - } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 || - mbedtls_mpi_cmp_int( &A, 1 ) <= 0 ); - - /* - * A = A^R mod |X| - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) ); - - if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 || - mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) - continue; - - j = 1; - while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ) - { - /* - * A = A * A mod |X| - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) ); - - if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) - break; - - j++; - } - - /* - * not prime if A != |X| - 1 or A == 1 - */ - if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 || - mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) - { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - break; - } - } - -cleanup: - mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); - mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A ); - mbedtls_mpi_free( &RR ); - - return( ret ); -} - -/* - * Pseudo-primality test: small factors, then Miller-Rabin - */ -int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_mpi XX; - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - XX.s = 1; - XX.n = X->n; - XX.p = X->p; - - if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 || - mbedtls_mpi_cmp_int( &XX, 1 ) == 0 ) - return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - - if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 ) - return( 0 ); - - if( ( ret = mpi_check_small_factors( &XX ) ) != 0 ) - { - if( ret == 1 ) - return( 0 ); - - return( ret ); - } - - return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/* - * Pseudo-primality test, error probability 2^-80 - */ -int mbedtls_mpi_is_prime( const mbedtls_mpi *X, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - /* - * In the past our key generation aimed for an error rate of at most - * 2^-80. Since this function is deprecated, aim for the same certainty - * here as well. - */ - return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) ); -} -#endif - -/* - * Prime number generation - * - * To generate an RSA key in a way recommended by FIPS 186-4, both primes must - * be either 1024 bits or 1536 bits long, and flags must contain - * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR. - */ -int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ -#ifdef MBEDTLS_HAVE_INT64 -// ceil(2^63.5) -#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL -#else -// ceil(2^31.5) -#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U -#endif - int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - size_t k, n; - int rounds; - mbedtls_mpi_uint r; - mbedtls_mpi Y; - - MPI_VALIDATE_RET( X != NULL ); - MPI_VALIDATE_RET( f_rng != NULL ); - - if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &Y ); - - n = BITS_TO_LIMBS( nbits ); - - if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 ) - { - /* - * 2^-80 error probability, number of rounds chosen per HAC, table 4.4 - */ - rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 : - ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 : - ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 ); - } - else - { - /* - * 2^-100 error probability, number of rounds computed based on HAC, - * fact 4.48 - */ - rounds = ( ( nbits >= 1450 ) ? 4 : ( nbits >= 1150 ) ? 5 : - ( nbits >= 1000 ) ? 6 : ( nbits >= 850 ) ? 7 : - ( nbits >= 750 ) ? 8 : ( nbits >= 500 ) ? 13 : - ( nbits >= 250 ) ? 28 : ( nbits >= 150 ) ? 40 : 51 ); - } - - while( 1 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); - /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */ - if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue; - - k = n * biL; - if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) ); - X->p[0] |= 1; - - if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 ) - { - ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng ); - - if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - } - else - { - /* - * An necessary condition for Y and X = 2Y + 1 to be prime - * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). - * Make sure it is satisfied, while keeping X = 3 mod 4 - */ - - X->p[0] |= 2; - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) ); - if( r == 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) ); - else if( r == 1 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) ); - - /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) ); - - while( 1 ) - { - /* - * First, check small factors for X and Y - * before doing Miller-Rabin on any of them - */ - if( ( ret = mpi_check_small_factors( X ) ) == 0 && - ( ret = mpi_check_small_factors( &Y ) ) == 0 && - ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) ) - == 0 && - ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) ) - == 0 ) - goto cleanup; - - if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - - /* - * Next candidates. We want to preserve Y = (X-1) / 2 and - * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) - * so up Y by 6 and X by 12. - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) ); - } - } - } - -cleanup: - - mbedtls_mpi_free( &Y ); - - return( ret ); -} - -#endif /* MBEDTLS_GENPRIME */ - -#if defined(MBEDTLS_SELF_TEST) - -#define GCD_PAIR_COUNT 3 - -static const int gcd_pairs[GCD_PAIR_COUNT][3] = -{ - { 693, 609, 21 }, - { 1764, 868, 28 }, - { 768454923, 542167814, 1 } -}; - -/* - * Checkup routine - */ -int mbedtls_mpi_self_test( int verbose ) -{ - int ret, i; - mbedtls_mpi A, E, N, X, Y, U, V; - - mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X ); - mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16, - "EFE021C2645FD1DC586E69184AF4A31E" \ - "D5F53E93B5F123FA41680867BA110131" \ - "944FE7952E2517337780CB0DB80E61AA" \ - "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16, - "B2E7EFD37075B9F03FF989C7C5051C20" \ - "34D2A323810251127E7BF8625A4F49A5" \ - "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ - "5B5C25763222FEFCCFC38B832366C29E" ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16, - "0066A198186C18C10B2F5ED9B522752A" \ - "9830B69916E535C8F047518A889A43A5" \ - "94B6BED27A168D31D4A52F88925AA8F5" ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, - "602AB7ECA597A3D6B56FF9829A5E8B85" \ - "9E857EA95A03512E2BAE7391688D264A" \ - "A5663B0341DB9CCFD2C4C5F421FEC814" \ - "8001B72E848A38CAE1C65F78E56ABDEF" \ - "E12D3C039B8A02D6BE593F0BBBDA56F1" \ - "ECF677152EF804370C1A305CAF3B5BF1" \ - "30879B56C61DE584A0F53A2447A51E" ) ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #1 (mul_mpi): " ); - - if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, - "256567336059E52CAE22925474705F39A94" ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16, - "6613F26162223DF488E9CD48CC132C7A" \ - "0AC93C701B001B092E4E5B9F73BCD27B" \ - "9EE50D0657C77F374E903CDFA4C642" ) ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #2 (div_mpi): " ); - - if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 || - mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, - "36E139AEA55215609D2816998ED020BB" \ - "BD96C37890F65171D948E9BC7CBAA4D9" \ - "325D24D6A3C12710F10A09FA08AB87" ) ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #3 (exp_mod): " ); - - if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, - "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ - "C3DBA76456363A10869622EAC2DD84EC" \ - "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #4 (inv_mod): " ); - - if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " MPI test #5 (simple gcd): " ); - - for( i = 0; i < GCD_PAIR_COUNT; i++ ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) ); - - if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed at %d\n", i ); - - ret = 1; - goto cleanup; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -cleanup: - - if( ret != 0 && verbose != 0 ) - mbedtls_printf( "Unexpected error, return code = %08X\n", ret ); - - mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X ); - mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_BIGNUM_C */ diff --git a/mbedtls/bignum.h b/mbedtls/bignum.h deleted file mode 100644 index 07a6c92d6..000000000 --- a/mbedtls/bignum.h +++ /dev/null @@ -1,1010 +0,0 @@ -#pragma GCC system_header -/** - * \file bignum.h - * - * \brief Multi-precision integer library - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_BIGNUM_H -#define MBEDTLS_BIGNUM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -#define MBEDTLS_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */ -#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */ -#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */ -#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */ -#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */ -#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ -#define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */ - -#define MBEDTLS_MPI_CHK(f) \ - do \ - { \ - if( ( ret = (f) ) != 0 ) \ - goto cleanup; \ - } while( 0 ) - -/* - * Maximum size MPIs are allowed to grow to in number of limbs. - */ -#define MBEDTLS_MPI_MAX_LIMBS 10000 - -#if !defined(MBEDTLS_MPI_WINDOW_SIZE) -/* - * Maximum window size used for modular exponentiation. Default: 6 - * Minimum value: 1. Maximum value: 6. - * - * Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used - * for the sliding window calculation. (So 64 by default) - * - * Reduction in size, reduces speed. - */ -#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ -#endif /* !MBEDTLS_MPI_WINDOW_SIZE */ - -#if !defined(MBEDTLS_MPI_MAX_SIZE) -/* - * Maximum size of MPIs allowed in bits and bytes for user-MPIs. - * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) - * - * Note: Calculations can temporarily result in larger MPIs. So the number - * of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher. - */ -#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ -#endif /* !MBEDTLS_MPI_MAX_SIZE */ - -#define MBEDTLS_MPI_MAX_BITS ( 8 * MBEDTLS_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */ - -/* - * When reading from files with mbedtls_mpi_read_file() and writing to files with - * mbedtls_mpi_write_file() the buffer should have space - * for a (short) label, the MPI (in the provided radix), the newline - * characters and the '\0'. - * - * By default we assume at least a 10 char label, a minimum radix of 10 - * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars). - * Autosized at compile time for at least a 10 char label, a minimum radix - * of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size. - * - * This used to be statically sized to 1250 for a maximum of 4096 bit - * numbers (1234 decimal chars). - * - * Calculate using the formula: - * MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) + - * LabelSize + 6 - */ -#define MBEDTLS_MPI_MAX_BITS_SCALE100 ( 100 * MBEDTLS_MPI_MAX_BITS ) -#define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332 -#define MBEDTLS_MPI_RW_BUFFER_SIZE ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 ) - -/* - * Define the base integer type, architecture-wise. - * - * 32 or 64-bit integer types can be forced regardless of the underlying - * architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 - * respectively and undefining MBEDTLS_HAVE_ASM. - * - * Double-width integers (e.g. 128-bit in 64-bit architectures) can be - * disabled by defining MBEDTLS_NO_UDBL_DIVISION. - */ -#if !defined(MBEDTLS_HAVE_INT32) - #if defined(_MSC_VER) && defined(_M_AMD64) - /* Always choose 64-bit when using MSC */ - #if !defined(MBEDTLS_HAVE_INT64) - #define MBEDTLS_HAVE_INT64 - #endif /* !MBEDTLS_HAVE_INT64 */ - typedef int64_t mbedtls_mpi_sint; - typedef uint64_t mbedtls_mpi_uint; - #elif defined(__GNUC__) && ( \ - defined(__amd64__) || defined(__x86_64__) || \ - defined(__ppc64__) || defined(__powerpc64__) || \ - defined(__ia64__) || defined(__alpha__) || \ - ( defined(__sparc__) && defined(__arch64__) ) || \ - defined(__s390x__) || defined(__mips64) ) - #if !defined(MBEDTLS_HAVE_INT64) - #define MBEDTLS_HAVE_INT64 - #endif /* MBEDTLS_HAVE_INT64 */ - typedef int64_t mbedtls_mpi_sint; - typedef uint64_t mbedtls_mpi_uint; - #if !defined(MBEDTLS_NO_UDBL_DIVISION) - /* mbedtls_t_udbl defined as 128-bit unsigned int */ - typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); - #define MBEDTLS_HAVE_UDBL - #endif /* !MBEDTLS_NO_UDBL_DIVISION */ - #elif defined(__ARMCC_VERSION) && defined(__aarch64__) - /* - * __ARMCC_VERSION is defined for both armcc and armclang and - * __aarch64__ is only defined by armclang when compiling 64-bit code - */ - #if !defined(MBEDTLS_HAVE_INT64) - #define MBEDTLS_HAVE_INT64 - #endif /* !MBEDTLS_HAVE_INT64 */ - typedef int64_t mbedtls_mpi_sint; - typedef uint64_t mbedtls_mpi_uint; - #if !defined(MBEDTLS_NO_UDBL_DIVISION) - /* mbedtls_t_udbl defined as 128-bit unsigned int */ - typedef __uint128_t mbedtls_t_udbl; - #define MBEDTLS_HAVE_UDBL - #endif /* !MBEDTLS_NO_UDBL_DIVISION */ - #elif defined(MBEDTLS_HAVE_INT64) - /* Force 64-bit integers with unknown compiler */ - typedef int64_t mbedtls_mpi_sint; - typedef uint64_t mbedtls_mpi_uint; - #endif -#endif /* !MBEDTLS_HAVE_INT32 */ - -#if !defined(MBEDTLS_HAVE_INT64) - /* Default to 32-bit compilation */ - #if !defined(MBEDTLS_HAVE_INT32) - #define MBEDTLS_HAVE_INT32 - #endif /* !MBEDTLS_HAVE_INT32 */ - typedef int32_t mbedtls_mpi_sint; - typedef uint32_t mbedtls_mpi_uint; - #if !defined(MBEDTLS_NO_UDBL_DIVISION) - typedef uint64_t mbedtls_t_udbl; - #define MBEDTLS_HAVE_UDBL - #endif /* !MBEDTLS_NO_UDBL_DIVISION */ -#endif /* !MBEDTLS_HAVE_INT64 */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MPI structure - */ -typedef struct mbedtls_mpi -{ - int s; /*!< Sign: -1 if the mpi is negative, 1 otherwise */ - size_t n; /*!< total # of limbs */ - mbedtls_mpi_uint *p; /*!< pointer to limbs */ -} -mbedtls_mpi; - -/** - * \brief Initialize an MPI context. - * - * This makes the MPI ready to be set or freed, - * but does not define a value for the MPI. - * - * \param X The MPI context to initialize. This must not be \c NULL. - */ -void mbedtls_mpi_init( mbedtls_mpi *X ); - -/** - * \brief This function frees the components of an MPI context. - * - * \param X The MPI context to be cleared. This may be \c NULL, - * in which case this function is a no-op. If it is - * not \c NULL, it must point to an initialized MPI. - */ -void mbedtls_mpi_free( mbedtls_mpi *X ); - -/** - * \brief Enlarge an MPI to the specified number of limbs. - * - * \note This function does nothing if the MPI is - * already large enough. - * - * \param X The MPI to grow. It must be initialized. - * \param nblimbs The target number of limbs. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ); - -/** - * \brief This function resizes an MPI downwards, keeping at least the - * specified number of limbs. - * - * If \c X is smaller than \c nblimbs, it is resized up - * instead. - * - * \param X The MPI to shrink. This must point to an initialized MPI. - * \param nblimbs The minimum number of limbs to keep. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed - * (this can only happen when resizing up). - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ); - -/** - * \brief Make a copy of an MPI. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param Y The source MPI. This must point to an initialized MPI. - * - * \note The limb-buffer in the destination MPI is enlarged - * if necessary to hold the value in the source MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ); - -/** - * \brief Swap the contents of two MPIs. - * - * \param X The first MPI. It must be initialized. - * \param Y The second MPI. It must be initialized. - */ -void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ); - -/** - * \brief Perform a safe conditional copy of MPI which doesn't - * reveal whether the condition was true or not. - * - * \param X The MPI to conditionally assign to. This must point - * to an initialized MPI. - * \param Y The MPI to be assigned from. This must point to an - * initialized MPI. - * \param assign The condition deciding whether to perform the - * assignment or not. Possible values: - * * \c 1: Perform the assignment `X = Y`. - * * \c 0: Keep the original value of \p X. - * - * \note This function is equivalent to - * `if( assign ) mbedtls_mpi_copy( X, Y );` - * except that it avoids leaking any information about whether - * the assignment was done or not (the above code may leak - * information through branch prediction and/or memory access - * patterns analysis). - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ); - -/** - * \brief Perform a safe conditional swap which doesn't - * reveal whether the condition was true or not. - * - * \param X The first MPI. This must be initialized. - * \param Y The second MPI. This must be initialized. - * \param assign The condition deciding whether to perform - * the swap or not. Possible values: - * * \c 1: Swap the values of \p X and \p Y. - * * \c 0: Keep the original values of \p X and \p Y. - * - * \note This function is equivalent to - * if( assign ) mbedtls_mpi_swap( X, Y ); - * except that it avoids leaking any information about whether - * the assignment was done or not (the above code may leak - * information through branch prediction and/or memory access - * patterns analysis). - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - * - */ -int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign ); - -/** - * \brief Store integer value in MPI. - * - * \param X The MPI to set. This must be initialized. - * \param z The value to use. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ); - -/** - * \brief Get a specific bit from an MPI. - * - * \param X The MPI to query. This must be initialized. - * \param pos Zero-based index of the bit to query. - * - * \return \c 0 or \c 1 on success, depending on whether bit \c pos - * of \c X is unset or set. - * \return A negative error code on failure. - */ -int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ); - -/** - * \brief Modify a specific bit in an MPI. - * - * \note This function will grow the target MPI if necessary to set a - * bit to \c 1 in a not yet existing limb. It will not grow if - * the bit should be set to \c 0. - * - * \param X The MPI to modify. This must be initialized. - * \param pos Zero-based index of the bit to modify. - * \param val The desired value of bit \c pos: \c 0 or \c 1. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ); - -/** - * \brief Return the number of bits of value \c 0 before the - * least significant bit of value \c 1. - * - * \note This is the same as the zero-based index of - * the least significant bit of value \c 1. - * - * \param X The MPI to query. - * - * \return The number of bits of value \c 0 before the least significant - * bit of value \c 1 in \p X. - */ -size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ); - -/** - * \brief Return the number of bits up to and including the most - * significant bit of value \c 1. - * - * * \note This is same as the one-based index of the most - * significant bit of value \c 1. - * - * \param X The MPI to query. This must point to an initialized MPI. - * - * \return The number of bits up to and including the most - * significant bit of value \c 1. - */ -size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X ); - -/** - * \brief Return the total size of an MPI value in bytes. - * - * \param X The MPI to use. This must point to an initialized MPI. - * - * \note The value returned by this function may be less than - * the number of bytes used to store \p X internally. - * This happens if and only if there are trailing bytes - * of value zero. - * - * \return The least number of bytes capable of storing - * the absolute value of \p X. - */ -size_t mbedtls_mpi_size( const mbedtls_mpi *X ); - -/** - * \brief Import an MPI from an ASCII string. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param radix The numeric base of the input string. - * \param s Null-terminated string buffer. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ); - -/** - * \brief Export an MPI to an ASCII string. - * - * \param X The source MPI. This must point to an initialized MPI. - * \param radix The numeric base of the output string. - * \param buf The buffer to write the string to. This must be writable - * buffer of length \p buflen Bytes. - * \param buflen The available size in Bytes of \p buf. - * \param olen The address at which to store the length of the string - * written, including the final \c NULL byte. This must - * not be \c NULL. - * - * \note You can call this function with `buflen == 0` to obtain the - * minimum required buffer size in `*olen`. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf - * is too small to hold the value of \p X in the desired base. - * In this case, `*olen` is nonetheless updated to contain the - * size of \p buf required for a successful call. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, - char *buf, size_t buflen, size_t *olen ); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Read an MPI from a line in an opened file. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param radix The numeric base of the string representation used - * in the source line. - * \param fin The input file handle to use. This must not be \c NULL. - * - * \note On success, this function advances the file stream - * to the end of the current line or to EOF. - * - * The function returns \c 0 on an empty line. - * - * Leading whitespaces are ignored, as is a - * '0x' prefix for radix \c 16. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer - * is too small. - * \return Another negative error code on failure. - */ -int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ); - -/** - * \brief Export an MPI into an opened file. - * - * \param p A string prefix to emit prior to the MPI data. - * For example, this might be a label, or "0x" when - * printing in base \c 16. This may be \c NULL if no prefix - * is needed. - * \param X The source MPI. This must point to an initialized MPI. - * \param radix The numeric base to be used in the emitted string. - * \param fout The output file handle. This may be \c NULL, in which case - * the output is written to \c stdout. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, - int radix, FILE *fout ); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief Import an MPI from unsigned big endian binary data. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param buf The input buffer. This must be a readable buffer of length - * \p buflen Bytes. - * \param buflen The length of the input buffer \p p in Bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, - size_t buflen ); - -/** - * \brief Export an MPI into unsigned big endian binary data - * of fixed size. - * - * \param X The source MPI. This must point to an initialized MPI. - * \param buf The output buffer. This must be a writable buffer of length - * \p buflen Bytes. - * \param buflen The size of the output buffer \p buf in Bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't - * large enough to hold the value of \p X. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, - size_t buflen ); - -/** - * \brief Perform a left-shift on an MPI: X <<= count - * - * \param X The MPI to shift. This must point to an initialized MPI. - * \param count The number of bits to shift by. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ); - -/** - * \brief Perform a right-shift on an MPI: X >>= count - * - * \param X The MPI to shift. This must point to an initialized MPI. - * \param count The number of bits to shift by. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ); - -/** - * \brief Compare the absolute values of two MPIs. - * - * \param X The left-hand MPI. This must point to an initialized MPI. - * \param Y The right-hand MPI. This must point to an initialized MPI. - * - * \return \c 1 if `|X|` is greater than `|Y|`. - * \return \c -1 if `|X|` is lesser than `|Y|`. - * \return \c 0 if `|X|` is equal to `|Y|`. - */ -int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ); - -/** - * \brief Compare two MPIs. - * - * \param X The left-hand MPI. This must point to an initialized MPI. - * \param Y The right-hand MPI. This must point to an initialized MPI. - * - * \return \c 1 if \p X is greater than \p Y. - * \return \c -1 if \p X is lesser than \p Y. - * \return \c 0 if \p X is equal to \p Y. - */ -int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ); - -/** - * \brief Check if an MPI is less than the other in constant time. - * - * \param X The left-hand MPI. This must point to an initialized MPI - * with the same allocated length as Y. - * \param Y The right-hand MPI. This must point to an initialized MPI - * with the same allocated length as X. - * \param ret The result of the comparison: - * \c 1 if \p X is less than \p Y. - * \c 0 if \p X is greater than or equal to \p Y. - * - * \return 0 on success. - * \return MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of - * the two input MPIs is not the same. - */ -int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y, - unsigned *ret ); - -/** - * \brief Compare an MPI with an integer. - * - * \param X The left-hand MPI. This must point to an initialized MPI. - * \param z The integer value to compare \p X to. - * - * \return \c 1 if \p X is greater than \p z. - * \return \c -1 if \p X is lesser than \p z. - * \return \c 0 if \p X is equal to \p z. - */ -int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ); - -/** - * \brief Perform an unsigned addition of MPIs: X = |A| + |B| - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first summand. This must point to an initialized MPI. - * \param B The second summand. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); - -/** - * \brief Perform an unsigned subtraction of MPIs: X = |A| - |B| - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The minuend. This must point to an initialized MPI. - * \param B The subtrahend. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A. - * \return Another negative error code on different kinds of failure. - * - */ -int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); - -/** - * \brief Perform a signed addition of MPIs: X = A + B - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first summand. This must point to an initialized MPI. - * \param B The second summand. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); - -/** - * \brief Perform a signed subtraction of MPIs: X = A - B - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The minuend. This must point to an initialized MPI. - * \param B The subtrahend. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); - -/** - * \brief Perform a signed addition of an MPI and an integer: X = A + b - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first summand. This must point to an initialized MPI. - * \param b The second summand. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, - mbedtls_mpi_sint b ); - -/** - * \brief Perform a signed subtraction of an MPI and an integer: - * X = A - b - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The minuend. This must point to an initialized MPI. - * \param b The subtrahend. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, - mbedtls_mpi_sint b ); - -/** - * \brief Perform a multiplication of two MPIs: X = A * B - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first factor. This must point to an initialized MPI. - * \param B The second factor. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - * - */ -int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B ); - -/** - * \brief Perform a multiplication of an MPI with an unsigned integer: - * X = A * b - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first factor. This must point to an initialized MPI. - * \param b The second factor. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - * - */ -int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, - mbedtls_mpi_uint b ); - -/** - * \brief Perform a division with remainder of two MPIs: - * A = Q * B + R - * - * \param Q The destination MPI for the quotient. - * This may be \c NULL if the value of the - * quotient is not needed. - * \param R The destination MPI for the remainder value. - * This may be \c NULL if the value of the - * remainder is not needed. - * \param A The dividend. This must point to an initialized MPi. - * \param B The divisor. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B ); - -/** - * \brief Perform a division with remainder of an MPI by an integer: - * A = Q * b + R - * - * \param Q The destination MPI for the quotient. - * This may be \c NULL if the value of the - * quotient is not needed. - * \param R The destination MPI for the remainder value. - * This may be \c NULL if the value of the - * remainder is not needed. - * \param A The dividend. This must point to an initialized MPi. - * \param b The divisor. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - mbedtls_mpi_sint b ); - -/** - * \brief Perform a modular reduction. R = A mod B - * - * \param R The destination MPI for the residue value. - * This must point to an initialized MPI. - * \param A The MPI to compute the residue of. - * This must point to an initialized MPI. - * \param B The base of the modular reduction. - * This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative. - * \return Another negative error code on different kinds of failure. - * - */ -int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B ); - -/** - * \brief Perform a modular reduction with respect to an integer. - * r = A mod b - * - * \param r The address at which to store the residue. - * This must not be \c NULL. - * \param A The MPI to compute the residue of. - * This must point to an initialized MPi. - * \param b The integer base of the modular reduction. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, - mbedtls_mpi_sint b ); - -/** - * \brief Perform a sliding-window exponentiation: X = A^E mod N - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The base of the exponentiation. - * This must point to an initialized MPI. - * \param E The exponent MPI. This must point to an initialized MPI. - * \param N The base for the modular reduction. This must point to an - * initialized MPI. - * \param _RR A helper MPI depending solely on \p N which can be used to - * speed-up multiple modular exponentiations for the same value - * of \p N. This may be \c NULL. If it is not \c NULL, it must - * point to an initialized MPI. If it hasn't been used after - * the call to mbedtls_mpi_init(), this function will compute - * the helper value and store it in \p _RR for reuse on - * subsequent calls to this function. Otherwise, the function - * will assume that \p _RR holds the helper value set by a - * previous call to mbedtls_mpi_exp_mod(), and reuse it. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or - * even, or if \c E is negative. - * \return Another negative error code on different kinds of failures. - * - */ -int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *_RR ); - -/** - * \brief Fill an MPI with a number of random bytes. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param size The number of random bytes to generate. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on failure. - * - * \note The bytes obtained from the RNG are interpreted - * as a big-endian representation of an MPI; this can - * be relevant in applications like deterministic ECDSA. - */ -int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief Compute the greatest common divisor: G = gcd(A, B) - * - * \param G The destination MPI. This must point to an initialized MPI. - * \param A The first operand. This must point to an initialized MPI. - * \param B The second operand. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, - const mbedtls_mpi *B ); - -/** - * \brief Compute the modular inverse: X = A^-1 mod N - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The MPI to calculate the modular inverse of. This must point - * to an initialized MPI. - * \param N The base of the modular inversion. This must point to an - * initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than - * or equal to one. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse - * with respect to \p N. - */ -int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *N ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief Perform a Miller-Rabin primality test with error - * probability of 2-80. - * - * \disabled_deprecated Superseded by mbedtls_mpi_is_prime_ext() which allows - * specifying the number of Miller-Rabin rounds. - * - * \param X The MPI to check for primality. - * This must point to an initialized MPI. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't use a - * context parameter. - * - * \return \c 0 if successful, i.e. \p X is probably prime. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. - * \return Another negative error code on other kinds of failure. - */ -MBEDTLS_DEPRECATED int mbedtls_mpi_is_prime( const mbedtls_mpi *X, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Miller-Rabin primality test. - * - * \warning If \p X is potentially generated by an adversary, for example - * when validating cryptographic parameters that you didn't - * generate yourself and that are supposed to be prime, then - * \p rounds should be at least the half of the security - * strength of the cryptographic algorithm. On the other hand, - * if \p X is chosen uniformly or non-adversially (as is the - * case when mbedtls_mpi_gen_prime calls this function), then - * \p rounds can be much lower. - * - * \param X The MPI to check for primality. - * This must point to an initialized MPI. - * \param rounds The number of bases to perform the Miller-Rabin primality - * test for. The probability of returning 0 on a composite is - * at most 2-2*\p rounds. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't use - * a context parameter. - * - * \return \c 0 if successful, i.e. \p X is probably prime. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -/** - * \brief Flags for mbedtls_mpi_gen_prime() - * - * Each of these flags is a constraint on the result X returned by - * mbedtls_mpi_gen_prime(). - */ -typedef enum { - MBEDTLS_MPI_GEN_PRIME_FLAG_DH = 0x0001, /**< (X-1)/2 is prime too */ - MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR = 0x0002, /**< lower error rate from 2-80 to 2-128 */ -} mbedtls_mpi_gen_prime_flag_t; - -/** - * \brief Generate a prime number. - * - * \param X The destination MPI to store the generated prime in. - * This must point to an initialized MPi. - * \param nbits The required size of the destination MPI in bits. - * This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS. - * \param flags A mask of flags of type #mbedtls_mpi_gen_prime_flag_t. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't use - * a context parameter. - * - * \return \c 0 if successful, in which case \p X holds a - * probably prime number. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between - * \c 3 and #MBEDTLS_MPI_MAX_BITS. - */ -int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_mpi_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* bignum.h */ diff --git a/mbedtls/blowfish.c b/mbedtls/blowfish.c deleted file mode 100644 index 4f934f7a3..000000000 --- a/mbedtls/blowfish.c +++ /dev/null @@ -1,734 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Blowfish implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The Blowfish block cipher was designed by Bruce Schneier in 1993. - * http://www.schneier.com/blowfish.html - * http://en.wikipedia.org/wiki/Blowfish_%28cipher%29 - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_BLOWFISH_C) - -#include "mbedtls/blowfish.h" -#include "mbedtls/platform_util.h" - -#include - -#if !defined(MBEDTLS_BLOWFISH_ALT) - -/* Parameter validation macros */ -#define BLOWFISH_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ) -#define BLOWFISH_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = { - 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, - 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, - 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, - 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, - 0x9216D5D9L, 0x8979FB1BL -}; - -/* declarations of data at the end of this file */ -static const uint32_t S[4][256]; - -static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x ) -{ - unsigned short a, b, c, d; - uint32_t y; - - d = (unsigned short)(x & 0xFF); - x >>= 8; - c = (unsigned short)(x & 0xFF); - x >>= 8; - b = (unsigned short)(x & 0xFF); - x >>= 8; - a = (unsigned short)(x & 0xFF); - y = ctx->S[0][a] + ctx->S[1][b]; - y = y ^ ctx->S[2][c]; - y = y + ctx->S[3][d]; - - return( y ); -} - -static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) -{ - uint32_t Xl, Xr, temp; - short i; - - Xl = *xl; - Xr = *xr; - - for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i ) - { - Xl = Xl ^ ctx->P[i]; - Xr = F( ctx, Xl ) ^ Xr; - - temp = Xl; - Xl = Xr; - Xr = temp; - } - - temp = Xl; - Xl = Xr; - Xr = temp; - - Xr = Xr ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS]; - Xl = Xl ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS + 1]; - - *xl = Xl; - *xr = Xr; -} - -static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) -{ - uint32_t Xl, Xr, temp; - short i; - - Xl = *xl; - Xr = *xr; - - for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i ) - { - Xl = Xl ^ ctx->P[i]; - Xr = F( ctx, Xl ) ^ Xr; - - temp = Xl; - Xl = Xr; - Xr = temp; - } - - temp = Xl; - Xl = Xr; - Xr = temp; - - Xr = Xr ^ ctx->P[1]; - Xl = Xl ^ ctx->P[0]; - - *xl = Xl; - *xr = Xr; -} - -void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx ) -{ - BLOWFISH_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_blowfish_context ) ); -} - -void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_blowfish_context ) ); -} - -/* - * Blowfish key schedule - */ -int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, - const unsigned char *key, - unsigned int keybits ) -{ - unsigned int i, j, k; - uint32_t data, datal, datar; - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( key != NULL ); - - if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || - keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS || - keybits % 8 != 0 ) - { - return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ); - } - - keybits >>= 3; - - for( i = 0; i < 4; i++ ) - { - for( j = 0; j < 256; j++ ) - ctx->S[i][j] = S[i][j]; - } - - j = 0; - for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i ) - { - data = 0x00000000; - for( k = 0; k < 4; ++k ) - { - data = ( data << 8 ) | key[j++]; - if( j >= keybits ) - j = 0; - } - ctx->P[i] = P[i] ^ data; - } - - datal = 0x00000000; - datar = 0x00000000; - - for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 ) - { - blowfish_enc( ctx, &datal, &datar ); - ctx->P[i] = datal; - ctx->P[i + 1] = datar; - } - - for( i = 0; i < 4; i++ ) - { - for( j = 0; j < 256; j += 2 ) - { - blowfish_enc( ctx, &datal, &datar ); - ctx->S[i][j] = datal; - ctx->S[i][j + 1] = datar; - } - } - return( 0 ); -} - -/* - * Blowfish-ECB block encryption/decryption - */ -int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, - int mode, - const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE], - unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] ) -{ - uint32_t X0, X1; - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT || - mode == MBEDTLS_BLOWFISH_DECRYPT ); - BLOWFISH_VALIDATE_RET( input != NULL ); - BLOWFISH_VALIDATE_RET( output != NULL ); - - GET_UINT32_BE( X0, input, 0 ); - GET_UINT32_BE( X1, input, 4 ); - - if( mode == MBEDTLS_BLOWFISH_DECRYPT ) - { - blowfish_dec( ctx, &X0, &X1 ); - } - else /* MBEDTLS_BLOWFISH_ENCRYPT */ - { - blowfish_enc( ctx, &X0, &X1 ); - } - - PUT_UINT32_BE( X0, output, 0 ); - PUT_UINT32_BE( X1, output, 4 ); - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * Blowfish-CBC buffer encryption/decryption - */ -int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE]; - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT || - mode == MBEDTLS_BLOWFISH_DECRYPT ); - BLOWFISH_VALIDATE_RET( iv != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || input != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || output != NULL ); - - if( length % MBEDTLS_BLOWFISH_BLOCKSIZE ) - return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_BLOWFISH_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE ); - mbedtls_blowfish_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE ); - - input += MBEDTLS_BLOWFISH_BLOCKSIZE; - output += MBEDTLS_BLOWFISH_BLOCKSIZE; - length -= MBEDTLS_BLOWFISH_BLOCKSIZE; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_blowfish_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE ); - - input += MBEDTLS_BLOWFISH_BLOCKSIZE; - output += MBEDTLS_BLOWFISH_BLOCKSIZE; - length -= MBEDTLS_BLOWFISH_BLOCKSIZE; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * Blowfish CFB buffer encryption/decryption - */ -int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int c; - size_t n; - - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT || - mode == MBEDTLS_BLOWFISH_DECRYPT ); - BLOWFISH_VALIDATE_RET( iv != NULL ); - BLOWFISH_VALIDATE_RET( iv_off != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || input != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || output != NULL ); - - n = *iv_off; - if( n >= 8 ) - return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_BLOWFISH_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); - - c = *input++; - *output++ = (unsigned char)( c ^ iv[n] ); - iv[n] = (unsigned char) c; - - n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; - } - } - - *iv_off = n; - - return( 0 ); -} -#endif /*MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * Blowfish CTR buffer encryption/decryption - */ -int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - BLOWFISH_VALIDATE_RET( ctx != NULL ); - BLOWFISH_VALIDATE_RET( nonce_counter != NULL ); - BLOWFISH_VALIDATE_RET( stream_block != NULL ); - BLOWFISH_VALIDATE_RET( nc_off != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || input != NULL ); - BLOWFISH_VALIDATE_RET( length == 0 || output != NULL ); - - n = *nc_off; - if( n >= 8 ) - return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter, - stream_block ); - - for( i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static const uint32_t S[4][256] = { - { 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, - 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, - 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, - 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL, - 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL, - 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, - 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, - 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL, - 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L, - 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L, - 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, - 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, - 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL, - 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L, - 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L, - 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, - 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L, - 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L, - 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL, - 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L, - 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, - 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, - 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L, - 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL, - 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L, - 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, - 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, - 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L, - 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL, - 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L, - 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, - 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, - 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L, - 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL, - 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L, - 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, - 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, - 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L, - 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL, - 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L, - 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, - 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, - 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L, - 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L, - 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L, - 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, - 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, - 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL, - 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL, - 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L, - 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, - 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, - 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L, - 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL, - 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L, - 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, - 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, - 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L, - 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L, - 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L, - 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, - 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, - 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L, - 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL }, - { 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L, - 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L, - 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L, - 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL, - 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L, - 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L, - 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL, - 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L, - 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L, - 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L, - 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL, - 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL, - 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L, - 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L, - 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L, - 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L, - 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL, - 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL, - 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL, - 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L, - 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL, - 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L, - 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L, - 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL, - 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL, - 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L, - 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL, - 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L, - 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL, - 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL, - 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L, - 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L, - 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L, - 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L, - 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L, - 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L, - 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L, - 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL, - 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L, - 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL, - 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L, - 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L, - 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L, - 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L, - 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L, - 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L, - 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L, - 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L, - 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L, - 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L, - 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L, - 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L, - 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L, - 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L, - 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L, - 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L, - 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL, - 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL, - 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L, - 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL, - 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L, - 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L, - 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L, - 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L }, - { 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L, - 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L, - 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL, - 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L, - 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L, - 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L, - 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL, - 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL, - 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL, - 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L, - 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L, - 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL, - 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L, - 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL, - 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L, - 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL, - 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L, - 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL, - 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L, - 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL, - 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L, - 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L, - 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL, - 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L, - 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L, - 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L, - 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L, - 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL, - 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L, - 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL, - 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L, - 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL, - 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L, - 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL, - 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL, - 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL, - 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L, - 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L, - 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL, - 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL, - 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL, - 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL, - 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL, - 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L, - 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L, - 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L, - 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L, - 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL, - 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL, - 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L, - 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L, - 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L, - 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L, - 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L, - 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L, - 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L, - 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L, - 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L, - 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L, - 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL, - 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L, - 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL, - 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L, - 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L }, - { 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, - 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, - 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL, - 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L, - 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L, - 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, - 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, - 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L, - 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L, - 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L, - 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, - 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, - 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L, - 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L, - 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L, - 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, - 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, - 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L, - 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL, - 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL, - 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, - 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, - 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL, - 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL, - 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L, - 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, - 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L, - 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L, - 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL, - 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL, - 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, - 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, - 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L, - 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL, - 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L, - 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, - 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, - 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL, - 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L, - 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L, - 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, - 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, - 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL, - 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L, - 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L, - 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, - 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, - 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL, - 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L, - 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL, - 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, - 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, - 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L, - 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL, - 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L, - 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, - 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, - 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL, - 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L, - 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L, - 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, - 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, - 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, - 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L } -}; - -#endif /* !MBEDTLS_BLOWFISH_ALT */ -#endif /* MBEDTLS_BLOWFISH_C */ diff --git a/mbedtls/blowfish.h b/mbedtls/blowfish.h deleted file mode 100644 index 47d8304e2..000000000 --- a/mbedtls/blowfish.h +++ /dev/null @@ -1,313 +0,0 @@ -#pragma GCC system_header -/** - * \file blowfish.h - * - * \brief Blowfish block cipher - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_BLOWFISH_H -#define MBEDTLS_BLOWFISH_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#include "platform_util.h" - -#define MBEDTLS_BLOWFISH_ENCRYPT 1 -#define MBEDTLS_BLOWFISH_DECRYPT 0 -#define MBEDTLS_BLOWFISH_MAX_KEY_BITS 448 -#define MBEDTLS_BLOWFISH_MIN_KEY_BITS 32 -#define MBEDTLS_BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */ -#define MBEDTLS_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0016 ) -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016 /**< Bad input data. */ - -#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */ - -/* MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED is deprecated and should not be used. - */ -#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED -0x0017 /**< Blowfish hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_BLOWFISH_ALT) -// Regular implementation -// - -/** - * \brief Blowfish context structure - */ -typedef struct mbedtls_blowfish_context -{ - uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */ - uint32_t S[4][256]; /*!< key dependent S-boxes */ -} -mbedtls_blowfish_context; - -#else /* MBEDTLS_BLOWFISH_ALT */ -#include "blowfish_alt.h" -#endif /* MBEDTLS_BLOWFISH_ALT */ - -/** - * \brief Initialize a Blowfish context. - * - * \param ctx The Blowfish context to be initialized. - * This must not be \c NULL. - */ -void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx ); - -/** - * \brief Clear a Blowfish context. - * - * \param ctx The Blowfish context to be cleared. - * This may be \c NULL, in which case this function - * returns immediately. If it is not \c NULL, it must - * point to an initialized Blowfish context. - */ -void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx ); - -/** - * \brief Perform a Blowfish key schedule operation. - * - * \param ctx The Blowfish context to perform the key schedule on. - * \param key The encryption key. This must be a readable buffer of - * length \p keybits Bits. - * \param keybits The length of \p key in Bits. This must be between - * \c 32 and \c 448 and a multiple of \c 8. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key, - unsigned int keybits ); - -/** - * \brief Perform a Blowfish-ECB block encryption/decryption operation. - * - * \param ctx The Blowfish context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. Possible values are - * #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or - * #MBEDTLS_BLOWFISH_DECRYPT for decryption. - * \param input The input block. This must be a readable buffer - * of size \c 8 Bytes. - * \param output The output block. This must be a writable buffer - * of size \c 8 Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, - int mode, - const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE], - unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief Perform a Blowfish-CBC buffer encryption/decryption operation. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx The Blowfish context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. Possible values are - * #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or - * #MBEDTLS_BLOWFISH_DECRYPT for decryption. - * \param length The length of the input data in Bytes. This must be - * multiple of \c 8. - * \param iv The initialization vector. This must be a read/write buffer - * of length \c 8 Bytes. It is updated by this function. - * \param input The input data. This must be a readable buffer of length - * \p length Bytes. - * \param output The output data. This must be a writable buffer of length - * \p length Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief Perform a Blowfish CFB buffer encryption/decryption operation. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx The Blowfish context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. Possible values are - * #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or - * #MBEDTLS_BLOWFISH_DECRYPT for decryption. - * \param length The length of the input data in Bytes. - * \param iv_off The offset in the initialiation vector. - * The value pointed to must be smaller than \c 8 Bytes. - * It is updated by this function to support the aforementioned - * streaming usage. - * \param iv The initialization vector. This must be a read/write buffer - * of size \c 8 Bytes. It is updated after use. - * \param input The input data. This must be a readable buffer of length - * \p length Bytes. - * \param output The output data. This must be a writable buffer of length - * \p length Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ); -#endif /*MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief Perform a Blowfish-CTR buffer encryption/decryption operation. - * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**64 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first 4 bytes for the - * per-message nonce, and the last 4 bytes for internal use. In that - * case, before calling this function on a new message you need to - * set the first 4 bytes of \p nonce_counter to your chosen nonce - * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p - * stream_block to be ignored). That way, you can encrypt at most - * 2**32 messages of up to 2**32 blocks each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be unique. - * The recommended way to ensure uniqueness is to use a message - * counter. - * - * Note that for both stategies, sizes are measured in blocks and - * that a Blowfish block is 8 bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The Blowfish context to use. This must be initialized - * and bound to a key. - * \param length The length of the input data in Bytes. - * \param nc_off The offset in the current stream_block (for resuming - * within current cipher stream). The offset pointer - * should be \c 0 at the start of a stream and must be - * smaller than \c 8. It is updated by this function. - * \param nonce_counter The 64-bit nonce and counter. This must point to a - * read/write buffer of length \c 8 Bytes. - * \param stream_block The saved stream-block for resuming. This must point to - * a read/write buffer of length \c 8 Bytes. - * \param input The input data. This must be a readable buffer of - * length \p length Bytes. - * \param output The output data. This must be a writable buffer of - * length \p length Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#ifdef __cplusplus -} -#endif - -#endif /* blowfish.h */ diff --git a/mbedtls/bn_mul.h b/mbedtls/bn_mul.h deleted file mode 100644 index b62eb4fe4..000000000 --- a/mbedtls/bn_mul.h +++ /dev/null @@ -1,982 +0,0 @@ -#pragma GCC system_header -/** - * \file bn_mul.h - * - * \brief Multi-precision integer library - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * Multiply source vector [s] with b, add result - * to destination vector [d] and set carry c. - * - * Currently supports: - * - * . IA-32 (386+) . AMD64 / EM64T - * . IA-32 (SSE2) . Motorola 68000 - * . PowerPC, 32-bit . MicroBlaze - * . PowerPC, 64-bit . TriCore - * . SPARC v8 . ARM v3+ - * . Alpha . MIPS32 - * . C, longlong . C, generic - */ -#ifndef MBEDTLS_BN_MUL_H -#define MBEDTLS_BN_MUL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "bignum.h" - - -/* - * Conversion macros for embedded constants: - * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2 - */ -#if defined(MBEDTLS_HAVE_INT32) - -#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ) \ - ( (mbedtls_mpi_uint) (a) << 0 ) | \ - ( (mbedtls_mpi_uint) (b) << 8 ) | \ - ( (mbedtls_mpi_uint) (c) << 16 ) | \ - ( (mbedtls_mpi_uint) (d) << 24 ) - -#define MBEDTLS_BYTES_TO_T_UINT_2( a, b ) \ - MBEDTLS_BYTES_TO_T_UINT_4( a, b, 0, 0 ) - -#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ - MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ), \ - MBEDTLS_BYTES_TO_T_UINT_4( e, f, g, h ) - -#else /* 64-bits */ - -#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ - ( (mbedtls_mpi_uint) (a) << 0 ) | \ - ( (mbedtls_mpi_uint) (b) << 8 ) | \ - ( (mbedtls_mpi_uint) (c) << 16 ) | \ - ( (mbedtls_mpi_uint) (d) << 24 ) | \ - ( (mbedtls_mpi_uint) (e) << 32 ) | \ - ( (mbedtls_mpi_uint) (f) << 40 ) | \ - ( (mbedtls_mpi_uint) (g) << 48 ) | \ - ( (mbedtls_mpi_uint) (h) << 56 ) - -#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ) \ - MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 ) - -#define MBEDTLS_BYTES_TO_T_UINT_2( a, b ) \ - MBEDTLS_BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 ) - -#endif /* bits in mbedtls_mpi_uint */ - -#if defined(MBEDTLS_HAVE_ASM) - -#ifndef asm -#define asm __asm -#endif - -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(__GNUC__) && \ - ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) - -/* - * Disable use of the i386 assembly code below if option -O0, to disable all - * compiler optimisations, is passed, detected with __OPTIMIZE__ - * This is done as the number of registers used in the assembly code doesn't - * work with the -O0 option. - */ -#if defined(__i386__) && defined(__OPTIMIZE__) - -#define MULADDC_INIT \ - asm( \ - "movl %%ebx, %0 \n\t" \ - "movl %5, %%esi \n\t" \ - "movl %6, %%edi \n\t" \ - "movl %7, %%ecx \n\t" \ - "movl %8, %%ebx \n\t" - -#define MULADDC_CORE \ - "lodsl \n\t" \ - "mull %%ebx \n\t" \ - "addl %%ecx, %%eax \n\t" \ - "adcl $0, %%edx \n\t" \ - "addl (%%edi), %%eax \n\t" \ - "adcl $0, %%edx \n\t" \ - "movl %%edx, %%ecx \n\t" \ - "stosl \n\t" - -#if defined(MBEDTLS_HAVE_SSE2) - -#define MULADDC_HUIT \ - "movd %%ecx, %%mm1 \n\t" \ - "movd %%ebx, %%mm0 \n\t" \ - "movd (%%edi), %%mm3 \n\t" \ - "paddq %%mm3, %%mm1 \n\t" \ - "movd (%%esi), %%mm2 \n\t" \ - "pmuludq %%mm0, %%mm2 \n\t" \ - "movd 4(%%esi), %%mm4 \n\t" \ - "pmuludq %%mm0, %%mm4 \n\t" \ - "movd 8(%%esi), %%mm6 \n\t" \ - "pmuludq %%mm0, %%mm6 \n\t" \ - "movd 12(%%esi), %%mm7 \n\t" \ - "pmuludq %%mm0, %%mm7 \n\t" \ - "paddq %%mm2, %%mm1 \n\t" \ - "movd 4(%%edi), %%mm3 \n\t" \ - "paddq %%mm4, %%mm3 \n\t" \ - "movd 8(%%edi), %%mm5 \n\t" \ - "paddq %%mm6, %%mm5 \n\t" \ - "movd 12(%%edi), %%mm4 \n\t" \ - "paddq %%mm4, %%mm7 \n\t" \ - "movd %%mm1, (%%edi) \n\t" \ - "movd 16(%%esi), %%mm2 \n\t" \ - "pmuludq %%mm0, %%mm2 \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "movd 20(%%esi), %%mm4 \n\t" \ - "pmuludq %%mm0, %%mm4 \n\t" \ - "paddq %%mm3, %%mm1 \n\t" \ - "movd 24(%%esi), %%mm6 \n\t" \ - "pmuludq %%mm0, %%mm6 \n\t" \ - "movd %%mm1, 4(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "movd 28(%%esi), %%mm3 \n\t" \ - "pmuludq %%mm0, %%mm3 \n\t" \ - "paddq %%mm5, %%mm1 \n\t" \ - "movd 16(%%edi), %%mm5 \n\t" \ - "paddq %%mm5, %%mm2 \n\t" \ - "movd %%mm1, 8(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm7, %%mm1 \n\t" \ - "movd 20(%%edi), %%mm5 \n\t" \ - "paddq %%mm5, %%mm4 \n\t" \ - "movd %%mm1, 12(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm2, %%mm1 \n\t" \ - "movd 24(%%edi), %%mm5 \n\t" \ - "paddq %%mm5, %%mm6 \n\t" \ - "movd %%mm1, 16(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm4, %%mm1 \n\t" \ - "movd 28(%%edi), %%mm5 \n\t" \ - "paddq %%mm5, %%mm3 \n\t" \ - "movd %%mm1, 20(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm6, %%mm1 \n\t" \ - "movd %%mm1, 24(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm3, %%mm1 \n\t" \ - "movd %%mm1, 28(%%edi) \n\t" \ - "addl $32, %%edi \n\t" \ - "addl $32, %%esi \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "movd %%mm1, %%ecx \n\t" - -#define MULADDC_STOP \ - "emms \n\t" \ - "movl %4, %%ebx \n\t" \ - "movl %%ecx, %1 \n\t" \ - "movl %%edi, %2 \n\t" \ - "movl %%esi, %3 \n\t" \ - : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ - : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ - : "eax", "ebx", "ecx", "edx", "esi", "edi" \ - ); - -#else - -#define MULADDC_STOP \ - "movl %4, %%ebx \n\t" \ - "movl %%ecx, %1 \n\t" \ - "movl %%edi, %2 \n\t" \ - "movl %%esi, %3 \n\t" \ - : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ - : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ - : "eax", "ebx", "ecx", "edx", "esi", "edi" \ - ); -#endif /* SSE2 */ -#endif /* i386 */ - -#if defined(__amd64__) || defined (__x86_64__) - -#define MULADDC_INIT \ - asm( \ - "xorq %%r8, %%r8\n" - -#define MULADDC_CORE \ - "movq (%%rsi), %%rax\n" \ - "mulq %%rbx\n" \ - "addq $8, %%rsi\n" \ - "addq %%rcx, %%rax\n" \ - "movq %%r8, %%rcx\n" \ - "adcq $0, %%rdx\n" \ - "nop \n" \ - "addq %%rax, (%%rdi)\n" \ - "adcq %%rdx, %%rcx\n" \ - "addq $8, %%rdi\n" - -#define MULADDC_STOP \ - : "+c" (c), "+D" (d), "+S" (s) \ - : "b" (b) \ - : "rax", "rdx", "r8" \ - ); - -#endif /* AMD64 */ - -#if defined(__mc68020__) || defined(__mcpu32__) - -#define MULADDC_INIT \ - asm( \ - "movl %3, %%a2 \n\t" \ - "movl %4, %%a3 \n\t" \ - "movl %5, %%d3 \n\t" \ - "movl %6, %%d2 \n\t" \ - "moveq #0, %%d0 \n\t" - -#define MULADDC_CORE \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "moveq #0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "addxl %%d4, %%d3 \n\t" - -#define MULADDC_STOP \ - "movl %%d3, %0 \n\t" \ - "movl %%a3, %1 \n\t" \ - "movl %%a2, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "d0", "d1", "d2", "d3", "d4", "a2", "a3" \ - ); - -#define MULADDC_HUIT \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addxl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d3:%%d1 \n\t" \ - "addxl %%d4, %%d1 \n\t" \ - "addxl %%d0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addxl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d3:%%d1 \n\t" \ - "addxl %%d4, %%d1 \n\t" \ - "addxl %%d0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addxl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d3:%%d1 \n\t" \ - "addxl %%d4, %%d1 \n\t" \ - "addxl %%d0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addxl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d3:%%d1 \n\t" \ - "addxl %%d4, %%d1 \n\t" \ - "addxl %%d0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "addxl %%d0, %%d3 \n\t" - -#endif /* MC68000 */ - -#if defined(__powerpc64__) || defined(__ppc64__) - -#if defined(__MACH__) && defined(__APPLE__) - -#define MULADDC_INIT \ - asm( \ - "ld r3, %3 \n\t" \ - "ld r4, %4 \n\t" \ - "ld r5, %5 \n\t" \ - "ld r6, %6 \n\t" \ - "addi r3, r3, -8 \n\t" \ - "addi r4, r4, -8 \n\t" \ - "addic r5, r5, 0 \n\t" - -#define MULADDC_CORE \ - "ldu r7, 8(r3) \n\t" \ - "mulld r8, r7, r6 \n\t" \ - "mulhdu r9, r7, r6 \n\t" \ - "adde r8, r8, r5 \n\t" \ - "ld r7, 8(r4) \n\t" \ - "addze r5, r9 \n\t" \ - "addc r8, r8, r7 \n\t" \ - "stdu r8, 8(r4) \n\t" - -#define MULADDC_STOP \ - "addze r5, r5 \n\t" \ - "addi r4, r4, 8 \n\t" \ - "addi r3, r3, 8 \n\t" \ - "std r5, %0 \n\t" \ - "std r4, %1 \n\t" \ - "std r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ - ); - - -#else /* __MACH__ && __APPLE__ */ - -#define MULADDC_INIT \ - asm( \ - "ld %%r3, %3 \n\t" \ - "ld %%r4, %4 \n\t" \ - "ld %%r5, %5 \n\t" \ - "ld %%r6, %6 \n\t" \ - "addi %%r3, %%r3, -8 \n\t" \ - "addi %%r4, %%r4, -8 \n\t" \ - "addic %%r5, %%r5, 0 \n\t" - -#define MULADDC_CORE \ - "ldu %%r7, 8(%%r3) \n\t" \ - "mulld %%r8, %%r7, %%r6 \n\t" \ - "mulhdu %%r9, %%r7, %%r6 \n\t" \ - "adde %%r8, %%r8, %%r5 \n\t" \ - "ld %%r7, 8(%%r4) \n\t" \ - "addze %%r5, %%r9 \n\t" \ - "addc %%r8, %%r8, %%r7 \n\t" \ - "stdu %%r8, 8(%%r4) \n\t" - -#define MULADDC_STOP \ - "addze %%r5, %%r5 \n\t" \ - "addi %%r4, %%r4, 8 \n\t" \ - "addi %%r3, %%r3, 8 \n\t" \ - "std %%r5, %0 \n\t" \ - "std %%r4, %1 \n\t" \ - "std %%r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ - ); - -#endif /* __MACH__ && __APPLE__ */ - -#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */ - -#if defined(__MACH__) && defined(__APPLE__) - -#define MULADDC_INIT \ - asm( \ - "lwz r3, %3 \n\t" \ - "lwz r4, %4 \n\t" \ - "lwz r5, %5 \n\t" \ - "lwz r6, %6 \n\t" \ - "addi r3, r3, -4 \n\t" \ - "addi r4, r4, -4 \n\t" \ - "addic r5, r5, 0 \n\t" - -#define MULADDC_CORE \ - "lwzu r7, 4(r3) \n\t" \ - "mullw r8, r7, r6 \n\t" \ - "mulhwu r9, r7, r6 \n\t" \ - "adde r8, r8, r5 \n\t" \ - "lwz r7, 4(r4) \n\t" \ - "addze r5, r9 \n\t" \ - "addc r8, r8, r7 \n\t" \ - "stwu r8, 4(r4) \n\t" - -#define MULADDC_STOP \ - "addze r5, r5 \n\t" \ - "addi r4, r4, 4 \n\t" \ - "addi r3, r3, 4 \n\t" \ - "stw r5, %0 \n\t" \ - "stw r4, %1 \n\t" \ - "stw r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ - ); - -#else /* __MACH__ && __APPLE__ */ - -#define MULADDC_INIT \ - asm( \ - "lwz %%r3, %3 \n\t" \ - "lwz %%r4, %4 \n\t" \ - "lwz %%r5, %5 \n\t" \ - "lwz %%r6, %6 \n\t" \ - "addi %%r3, %%r3, -4 \n\t" \ - "addi %%r4, %%r4, -4 \n\t" \ - "addic %%r5, %%r5, 0 \n\t" - -#define MULADDC_CORE \ - "lwzu %%r7, 4(%%r3) \n\t" \ - "mullw %%r8, %%r7, %%r6 \n\t" \ - "mulhwu %%r9, %%r7, %%r6 \n\t" \ - "adde %%r8, %%r8, %%r5 \n\t" \ - "lwz %%r7, 4(%%r4) \n\t" \ - "addze %%r5, %%r9 \n\t" \ - "addc %%r8, %%r8, %%r7 \n\t" \ - "stwu %%r8, 4(%%r4) \n\t" - -#define MULADDC_STOP \ - "addze %%r5, %%r5 \n\t" \ - "addi %%r4, %%r4, 4 \n\t" \ - "addi %%r3, %%r3, 4 \n\t" \ - "stw %%r5, %0 \n\t" \ - "stw %%r4, %1 \n\t" \ - "stw %%r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ - ); - -#endif /* __MACH__ && __APPLE__ */ - -#endif /* PPC32 */ - -/* - * The Sparc(64) assembly is reported to be broken. - * Disable it for now, until we're able to fix it. - */ -#if 0 && defined(__sparc__) -#if defined(__sparc64__) - -#define MULADDC_INIT \ - asm( \ - "ldx %3, %%o0 \n\t" \ - "ldx %4, %%o1 \n\t" \ - "ld %5, %%o2 \n\t" \ - "ld %6, %%o3 \n\t" - -#define MULADDC_CORE \ - "ld [%%o0], %%o4 \n\t" \ - "inc 4, %%o0 \n\t" \ - "ld [%%o1], %%o5 \n\t" \ - "umul %%o3, %%o4, %%o4 \n\t" \ - "addcc %%o4, %%o2, %%o4 \n\t" \ - "rd %%y, %%g1 \n\t" \ - "addx %%g1, 0, %%g1 \n\t" \ - "addcc %%o4, %%o5, %%o4 \n\t" \ - "st %%o4, [%%o1] \n\t" \ - "addx %%g1, 0, %%o2 \n\t" \ - "inc 4, %%o1 \n\t" - - #define MULADDC_STOP \ - "st %%o2, %0 \n\t" \ - "stx %%o1, %1 \n\t" \ - "stx %%o0, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "g1", "o0", "o1", "o2", "o3", "o4", \ - "o5" \ - ); - -#else /* __sparc64__ */ - -#define MULADDC_INIT \ - asm( \ - "ld %3, %%o0 \n\t" \ - "ld %4, %%o1 \n\t" \ - "ld %5, %%o2 \n\t" \ - "ld %6, %%o3 \n\t" - -#define MULADDC_CORE \ - "ld [%%o0], %%o4 \n\t" \ - "inc 4, %%o0 \n\t" \ - "ld [%%o1], %%o5 \n\t" \ - "umul %%o3, %%o4, %%o4 \n\t" \ - "addcc %%o4, %%o2, %%o4 \n\t" \ - "rd %%y, %%g1 \n\t" \ - "addx %%g1, 0, %%g1 \n\t" \ - "addcc %%o4, %%o5, %%o4 \n\t" \ - "st %%o4, [%%o1] \n\t" \ - "addx %%g1, 0, %%o2 \n\t" \ - "inc 4, %%o1 \n\t" - -#define MULADDC_STOP \ - "st %%o2, %0 \n\t" \ - "st %%o1, %1 \n\t" \ - "st %%o0, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "g1", "o0", "o1", "o2", "o3", "o4", \ - "o5" \ - ); - -#endif /* __sparc64__ */ -#endif /* __sparc__ */ - -#if defined(__microblaze__) || defined(microblaze) - -#define MULADDC_INIT \ - asm( \ - "lwi r3, %3 \n\t" \ - "lwi r4, %4 \n\t" \ - "lwi r5, %5 \n\t" \ - "lwi r6, %6 \n\t" \ - "andi r7, r6, 0xffff \n\t" \ - "bsrli r6, r6, 16 \n\t" - -#define MULADDC_CORE \ - "lhui r8, r3, 0 \n\t" \ - "addi r3, r3, 2 \n\t" \ - "lhui r9, r3, 0 \n\t" \ - "addi r3, r3, 2 \n\t" \ - "mul r10, r9, r6 \n\t" \ - "mul r11, r8, r7 \n\t" \ - "mul r12, r9, r7 \n\t" \ - "mul r13, r8, r6 \n\t" \ - "bsrli r8, r10, 16 \n\t" \ - "bsrli r9, r11, 16 \n\t" \ - "add r13, r13, r8 \n\t" \ - "add r13, r13, r9 \n\t" \ - "bslli r10, r10, 16 \n\t" \ - "bslli r11, r11, 16 \n\t" \ - "add r12, r12, r10 \n\t" \ - "addc r13, r13, r0 \n\t" \ - "add r12, r12, r11 \n\t" \ - "addc r13, r13, r0 \n\t" \ - "lwi r10, r4, 0 \n\t" \ - "add r12, r12, r10 \n\t" \ - "addc r13, r13, r0 \n\t" \ - "add r12, r12, r5 \n\t" \ - "addc r5, r13, r0 \n\t" \ - "swi r12, r4, 0 \n\t" \ - "addi r4, r4, 4 \n\t" - -#define MULADDC_STOP \ - "swi r5, %0 \n\t" \ - "swi r4, %1 \n\t" \ - "swi r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", \ - "r9", "r10", "r11", "r12", "r13" \ - ); - -#endif /* MicroBlaze */ - -#if defined(__tricore__) - -#define MULADDC_INIT \ - asm( \ - "ld.a %%a2, %3 \n\t" \ - "ld.a %%a3, %4 \n\t" \ - "ld.w %%d4, %5 \n\t" \ - "ld.w %%d1, %6 \n\t" \ - "xor %%d5, %%d5 \n\t" - -#define MULADDC_CORE \ - "ld.w %%d0, [%%a2+] \n\t" \ - "madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \ - "ld.w %%d0, [%%a3] \n\t" \ - "addx %%d2, %%d2, %%d0 \n\t" \ - "addc %%d3, %%d3, 0 \n\t" \ - "mov %%d4, %%d3 \n\t" \ - "st.w [%%a3+], %%d2 \n\t" - -#define MULADDC_STOP \ - "st.w %0, %%d4 \n\t" \ - "st.a %1, %%a3 \n\t" \ - "st.a %2, %%a2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "d0", "d1", "e2", "d4", "a2", "a3" \ - ); - -#endif /* TriCore */ - -/* - * Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about - * our use of r7 below, unless -fomit-frame-pointer is passed. - * - * On the other hand, -fomit-frame-pointer is implied by any -Ox options with - * x !=0, which we can detect using __OPTIMIZE__ (which is also defined by - * clang and armcc5 under the same conditions). - * - * So, only use the optimized assembly below for optimized build, which avoids - * the build error and is pretty reasonable anyway. - */ -#if defined(__GNUC__) && !defined(__OPTIMIZE__) -#define MULADDC_CANNOT_USE_R7 -#endif - -#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7) - -#if defined(__thumb__) && !defined(__thumb2__) - -#define MULADDC_INIT \ - asm( \ - "ldr r0, %3 \n\t" \ - "ldr r1, %4 \n\t" \ - "ldr r2, %5 \n\t" \ - "ldr r3, %6 \n\t" \ - "lsr r7, r3, #16 \n\t" \ - "mov r9, r7 \n\t" \ - "lsl r7, r3, #16 \n\t" \ - "lsr r7, r7, #16 \n\t" \ - "mov r8, r7 \n\t" - -#define MULADDC_CORE \ - "ldmia r0!, {r6} \n\t" \ - "lsr r7, r6, #16 \n\t" \ - "lsl r6, r6, #16 \n\t" \ - "lsr r6, r6, #16 \n\t" \ - "mov r4, r8 \n\t" \ - "mul r4, r6 \n\t" \ - "mov r3, r9 \n\t" \ - "mul r6, r3 \n\t" \ - "mov r5, r9 \n\t" \ - "mul r5, r7 \n\t" \ - "mov r3, r8 \n\t" \ - "mul r7, r3 \n\t" \ - "lsr r3, r6, #16 \n\t" \ - "add r5, r5, r3 \n\t" \ - "lsr r3, r7, #16 \n\t" \ - "add r5, r5, r3 \n\t" \ - "add r4, r4, r2 \n\t" \ - "mov r2, #0 \n\t" \ - "adc r5, r2 \n\t" \ - "lsl r3, r6, #16 \n\t" \ - "add r4, r4, r3 \n\t" \ - "adc r5, r2 \n\t" \ - "lsl r3, r7, #16 \n\t" \ - "add r4, r4, r3 \n\t" \ - "adc r5, r2 \n\t" \ - "ldr r3, [r1] \n\t" \ - "add r4, r4, r3 \n\t" \ - "adc r2, r5 \n\t" \ - "stmia r1!, {r4} \n\t" - -#define MULADDC_STOP \ - "str r2, %0 \n\t" \ - "str r1, %1 \n\t" \ - "str r0, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r0", "r1", "r2", "r3", "r4", "r5", \ - "r6", "r7", "r8", "r9", "cc" \ - ); - -#elif (__ARM_ARCH >= 6) && \ - defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1) - -#define MULADDC_INIT \ - asm( - -#define MULADDC_CORE \ - "ldr r0, [%0], #4 \n\t" \ - "ldr r1, [%1] \n\t" \ - "umaal r1, %2, %3, r0 \n\t" \ - "str r1, [%1], #4 \n\t" - -#define MULADDC_STOP \ - : "=r" (s), "=r" (d), "=r" (c) \ - : "r" (b), "0" (s), "1" (d), "2" (c) \ - : "r0", "r1", "memory" \ - ); - -#else - -#define MULADDC_INIT \ - asm( \ - "ldr r0, %3 \n\t" \ - "ldr r1, %4 \n\t" \ - "ldr r2, %5 \n\t" \ - "ldr r3, %6 \n\t" - -#define MULADDC_CORE \ - "ldr r4, [r0], #4 \n\t" \ - "mov r5, #0 \n\t" \ - "ldr r6, [r1] \n\t" \ - "umlal r2, r5, r3, r4 \n\t" \ - "adds r7, r6, r2 \n\t" \ - "adc r2, r5, #0 \n\t" \ - "str r7, [r1], #4 \n\t" - -#define MULADDC_STOP \ - "str r2, %0 \n\t" \ - "str r1, %1 \n\t" \ - "str r0, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r0", "r1", "r2", "r3", "r4", "r5", \ - "r6", "r7", "cc" \ - ); - -#endif /* Thumb */ - -#endif /* ARMv3 */ - -#if defined(__alpha__) - -#define MULADDC_INIT \ - asm( \ - "ldq $1, %3 \n\t" \ - "ldq $2, %4 \n\t" \ - "ldq $3, %5 \n\t" \ - "ldq $4, %6 \n\t" - -#define MULADDC_CORE \ - "ldq $6, 0($1) \n\t" \ - "addq $1, 8, $1 \n\t" \ - "mulq $6, $4, $7 \n\t" \ - "umulh $6, $4, $6 \n\t" \ - "addq $7, $3, $7 \n\t" \ - "cmpult $7, $3, $3 \n\t" \ - "ldq $5, 0($2) \n\t" \ - "addq $7, $5, $7 \n\t" \ - "cmpult $7, $5, $5 \n\t" \ - "stq $7, 0($2) \n\t" \ - "addq $2, 8, $2 \n\t" \ - "addq $6, $3, $3 \n\t" \ - "addq $5, $3, $3 \n\t" - -#define MULADDC_STOP \ - "stq $3, %0 \n\t" \ - "stq $2, %1 \n\t" \ - "stq $1, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "$1", "$2", "$3", "$4", "$5", "$6", "$7" \ - ); -#endif /* Alpha */ - -#if defined(__mips__) && !defined(__mips64) - -#define MULADDC_INIT \ - asm( \ - "lw $10, %3 \n\t" \ - "lw $11, %4 \n\t" \ - "lw $12, %5 \n\t" \ - "lw $13, %6 \n\t" - -#define MULADDC_CORE \ - "lw $14, 0($10) \n\t" \ - "multu $13, $14 \n\t" \ - "addi $10, $10, 4 \n\t" \ - "mflo $14 \n\t" \ - "mfhi $9 \n\t" \ - "addu $14, $12, $14 \n\t" \ - "lw $15, 0($11) \n\t" \ - "sltu $12, $14, $12 \n\t" \ - "addu $15, $14, $15 \n\t" \ - "sltu $14, $15, $14 \n\t" \ - "addu $12, $12, $9 \n\t" \ - "sw $15, 0($11) \n\t" \ - "addu $12, $12, $14 \n\t" \ - "addi $11, $11, 4 \n\t" - -#define MULADDC_STOP \ - "sw $12, %0 \n\t" \ - "sw $11, %1 \n\t" \ - "sw $10, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "lo", "hi" \ - ); - -#endif /* MIPS */ -#endif /* GNUC */ - -#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) - -#define MULADDC_INIT \ - __asm mov esi, s \ - __asm mov edi, d \ - __asm mov ecx, c \ - __asm mov ebx, b - -#define MULADDC_CORE \ - __asm lodsd \ - __asm mul ebx \ - __asm add eax, ecx \ - __asm adc edx, 0 \ - __asm add eax, [edi] \ - __asm adc edx, 0 \ - __asm mov ecx, edx \ - __asm stosd - -#if defined(MBEDTLS_HAVE_SSE2) - -#define EMIT __asm _emit - -#define MULADDC_HUIT \ - EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ - EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ - EMIT 0x0F EMIT 0x6E EMIT 0x1F \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ - EMIT 0x0F EMIT 0x6E EMIT 0x16 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ - EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ - EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ - EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ - EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ - EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ - EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ - EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ - EMIT 0x0F EMIT 0x7E EMIT 0x0F \ - EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ - EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ - EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ - EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ - EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ - EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0x7E EMIT 0xC9 - -#define MULADDC_STOP \ - EMIT 0x0F EMIT 0x77 \ - __asm mov c, ecx \ - __asm mov d, edi \ - __asm mov s, esi \ - -#else - -#define MULADDC_STOP \ - __asm mov c, ecx \ - __asm mov d, edi \ - __asm mov s, esi \ - -#endif /* SSE2 */ -#endif /* MSVC */ - -#endif /* MBEDTLS_HAVE_ASM */ - -#if !defined(MULADDC_CORE) -#if defined(MBEDTLS_HAVE_UDBL) - -#define MULADDC_INIT \ -{ \ - mbedtls_t_udbl r; \ - mbedtls_mpi_uint r0, r1; - -#define MULADDC_CORE \ - r = *(s++) * (mbedtls_t_udbl) b; \ - r0 = (mbedtls_mpi_uint) r; \ - r1 = (mbedtls_mpi_uint)( r >> biL ); \ - r0 += c; r1 += (r0 < c); \ - r0 += *d; r1 += (r0 < *d); \ - c = r1; *(d++) = r0; - -#define MULADDC_STOP \ -} - -#else -#define MULADDC_INIT \ -{ \ - mbedtls_mpi_uint s0, s1, b0, b1; \ - mbedtls_mpi_uint r0, r1, rx, ry; \ - b0 = ( b << biH ) >> biH; \ - b1 = ( b >> biH ); - -#define MULADDC_CORE \ - s0 = ( *s << biH ) >> biH; \ - s1 = ( *s >> biH ); s++; \ - rx = s0 * b1; r0 = s0 * b0; \ - ry = s1 * b0; r1 = s1 * b1; \ - r1 += ( rx >> biH ); \ - r1 += ( ry >> biH ); \ - rx <<= biH; ry <<= biH; \ - r0 += rx; r1 += (r0 < rx); \ - r0 += ry; r1 += (r0 < ry); \ - r0 += c; r1 += (r0 < c); \ - r0 += *d; r1 += (r0 < *d); \ - c = r1; *(d++) = r0; - -#define MULADDC_STOP \ -} - -#endif /* C (generic) */ -#endif /* C (longlong) */ - -#endif /* bn_mul.h */ diff --git a/mbedtls/camellia.c b/mbedtls/camellia.c deleted file mode 100644 index 08fb86a54..000000000 --- a/mbedtls/camellia.c +++ /dev/null @@ -1,1154 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Camellia implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The Camellia block cipher was designed by NTT and Mitsubishi Electric - * Corporation. - * - * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CAMELLIA_C) - -#include "mbedtls/camellia.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_CAMELLIA_ALT) - -/* Parameter validation macros */ -#define CAMELLIA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ) -#define CAMELLIA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -static const unsigned char SIGMA_CHARS[6][8] = -{ - { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b }, - { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 }, - { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe }, - { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c }, - { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d }, - { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd } -}; - -#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) - -static const unsigned char FSb[256] = -{ - 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65, - 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189, - 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26, - 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77, - 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153, - 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215, - 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34, - 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80, - 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210, - 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148, - 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226, - 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46, - 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89, - 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250, - 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164, - 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158 -}; - -#define SBOX1(n) FSb[(n)] -#define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff) -#define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff) -#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff] - -#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ - -static const unsigned char FSb[256] = -{ - 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, - 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, - 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, - 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, - 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, - 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, - 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, - 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, - 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, - 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, - 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, - 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, - 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, - 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, - 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, - 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 -}; - -static const unsigned char FSb2[256] = -{ - 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, - 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, - 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, - 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, - 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, - 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, - 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, - 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, - 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, - 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, - 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, - 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, - 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, - 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, - 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, - 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 -}; - -static const unsigned char FSb3[256] = -{ - 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, - 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, - 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, - 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, - 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, - 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, - 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, - 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, - 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, - 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, - 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, - 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, - 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, - 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, - 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, - 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 -}; - -static const unsigned char FSb4[256] = -{ - 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, - 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, - 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, - 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, - 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, - 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, - 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, - 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, - 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, - 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, - 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, - 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, - 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, - 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, - 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, - 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 -}; - -#define SBOX1(n) FSb[(n)] -#define SBOX2(n) FSb2[(n)] -#define SBOX3(n) FSb3[(n)] -#define SBOX4(n) FSb4[(n)] - -#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ - -static const unsigned char shifts[2][4][4] = -{ - { - { 1, 1, 1, 1 }, /* KL */ - { 0, 0, 0, 0 }, /* KR */ - { 1, 1, 1, 1 }, /* KA */ - { 0, 0, 0, 0 } /* KB */ - }, - { - { 1, 0, 1, 1 }, /* KL */ - { 1, 1, 0, 1 }, /* KR */ - { 1, 1, 1, 0 }, /* KA */ - { 1, 1, 0, 1 } /* KB */ - } -}; - -static const signed char indexes[2][4][20] = -{ - { - { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39, - 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */ - { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */ - { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, - 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */ - { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */ - }, - { - { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1, - -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */ - { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17, - 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */ - { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59, - 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */ - { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21, - 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */ - } -}; - -static const signed char transposes[2][20] = -{ - { - 21, 22, 23, 20, - -1, -1, -1, -1, - 18, 19, 16, 17, - 11, 8, 9, 10, - 15, 12, 13, 14 - }, - { - 25, 26, 27, 24, - 29, 30, 31, 28, - 18, 19, 16, 17, - -1, -1, -1, -1, - -1, -1, -1, -1 - } -}; - -/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */ -#define ROTL(DEST, SRC, SHIFT) \ -{ \ - (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \ - (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \ - (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \ - (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \ -} - -#define FL(XL, XR, KL, KR) \ -{ \ - (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \ - (XL) = ((XR) | (KR)) ^ (XL); \ -} - -#define FLInv(YL, YR, KL, KR) \ -{ \ - (YL) = ((YR) | (KR)) ^ (YL); \ - (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \ -} - -#define SHIFT_AND_PLACE(INDEX, OFFSET) \ -{ \ - TK[0] = KC[(OFFSET) * 4 + 0]; \ - TK[1] = KC[(OFFSET) * 4 + 1]; \ - TK[2] = KC[(OFFSET) * 4 + 2]; \ - TK[3] = KC[(OFFSET) * 4 + 3]; \ - \ - for( i = 1; i <= 4; i++ ) \ - if( shifts[(INDEX)][(OFFSET)][i -1] ) \ - ROTL(TK + i * 4, TK, ( 15 * i ) % 32); \ - \ - for( i = 0; i < 20; i++ ) \ - if( indexes[(INDEX)][(OFFSET)][i] != -1 ) { \ - RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \ - } \ -} - -static void camellia_feistel( const uint32_t x[2], const uint32_t k[2], - uint32_t z[2]) -{ - uint32_t I0, I1; - I0 = x[0] ^ k[0]; - I1 = x[1] ^ k[1]; - - I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) | - ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) | - ((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) | - ((uint32_t) SBOX4((I0 ) & 0xFF) ); - I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) | - ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) | - ((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) | - ((uint32_t) SBOX1((I1 ) & 0xFF) ); - - I0 ^= (I1 << 8) | (I1 >> 24); - I1 ^= (I0 << 16) | (I0 >> 16); - I0 ^= (I1 >> 8) | (I1 << 24); - I1 ^= (I0 >> 8) | (I0 << 24); - - z[0] ^= I1; - z[1] ^= I0; -} - -void mbedtls_camellia_init( mbedtls_camellia_context *ctx ) -{ - CAMELLIA_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_camellia_context ) ); -} - -void mbedtls_camellia_free( mbedtls_camellia_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_camellia_context ) ); -} - -/* - * Camellia key schedule (encryption) - */ -int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits ) -{ - int idx; - size_t i; - uint32_t *RK; - unsigned char t[64]; - uint32_t SIGMA[6][2]; - uint32_t KC[16]; - uint32_t TK[20]; - - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( key != NULL ); - - RK = ctx->rk; - - memset( t, 0, 64 ); - memset( RK, 0, sizeof(ctx->rk) ); - - switch( keybits ) - { - case 128: ctx->nr = 3; idx = 0; break; - case 192: - case 256: ctx->nr = 4; idx = 1; break; - default : return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ); - } - - for( i = 0; i < keybits / 8; ++i ) - t[i] = key[i]; - - if( keybits == 192 ) { - for( i = 0; i < 8; i++ ) - t[24 + i] = ~t[16 + i]; - } - - /* - * Prepare SIGMA values - */ - for( i = 0; i < 6; i++ ) { - GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 ); - GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 ); - } - - /* - * Key storage in KC - * Order: KL, KR, KA, KB - */ - memset( KC, 0, sizeof(KC) ); - - /* Store KL, KR */ - for( i = 0; i < 8; i++ ) - GET_UINT32_BE( KC[i], t, i * 4 ); - - /* Generate KA */ - for( i = 0; i < 4; ++i ) - KC[8 + i] = KC[i] ^ KC[4 + i]; - - camellia_feistel( KC + 8, SIGMA[0], KC + 10 ); - camellia_feistel( KC + 10, SIGMA[1], KC + 8 ); - - for( i = 0; i < 4; ++i ) - KC[8 + i] ^= KC[i]; - - camellia_feistel( KC + 8, SIGMA[2], KC + 10 ); - camellia_feistel( KC + 10, SIGMA[3], KC + 8 ); - - if( keybits > 128 ) { - /* Generate KB */ - for( i = 0; i < 4; ++i ) - KC[12 + i] = KC[4 + i] ^ KC[8 + i]; - - camellia_feistel( KC + 12, SIGMA[4], KC + 14 ); - camellia_feistel( KC + 14, SIGMA[5], KC + 12 ); - } - - /* - * Generating subkeys - */ - - /* Manipulating KL */ - SHIFT_AND_PLACE( idx, 0 ); - - /* Manipulating KR */ - if( keybits > 128 ) { - SHIFT_AND_PLACE( idx, 1 ); - } - - /* Manipulating KA */ - SHIFT_AND_PLACE( idx, 2 ); - - /* Manipulating KB */ - if( keybits > 128 ) { - SHIFT_AND_PLACE( idx, 3 ); - } - - /* Do transpositions */ - for( i = 0; i < 20; i++ ) { - if( transposes[idx][i] != -1 ) { - RK[32 + 12 * idx + i] = RK[transposes[idx][i]]; - } - } - - return( 0 ); -} - -/* - * Camellia key schedule (decryption) - */ -int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits ) -{ - int idx, ret; - size_t i; - mbedtls_camellia_context cty; - uint32_t *RK; - uint32_t *SK; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( key != NULL ); - - mbedtls_camellia_init( &cty ); - - /* Also checks keybits */ - if( ( ret = mbedtls_camellia_setkey_enc( &cty, key, keybits ) ) != 0 ) - goto exit; - - ctx->nr = cty.nr; - idx = ( ctx->nr == 4 ); - - RK = ctx->rk; - SK = cty.rk + 24 * 2 + 8 * idx * 2; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - - for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 ) - { - *RK++ = *SK++; - *RK++ = *SK++; - } - - SK -= 2; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - -exit: - mbedtls_camellia_free( &cty ); - - return( ret ); -} - -/* - * Camellia-ECB block encryption/decryption - */ -int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - int NR; - uint32_t *RK, X[4]; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT || - mode == MBEDTLS_CAMELLIA_DECRYPT ); - CAMELLIA_VALIDATE_RET( input != NULL ); - CAMELLIA_VALIDATE_RET( output != NULL ); - - ( (void) mode ); - - NR = ctx->nr; - RK = ctx->rk; - - GET_UINT32_BE( X[0], input, 0 ); - GET_UINT32_BE( X[1], input, 4 ); - GET_UINT32_BE( X[2], input, 8 ); - GET_UINT32_BE( X[3], input, 12 ); - - X[0] ^= *RK++; - X[1] ^= *RK++; - X[2] ^= *RK++; - X[3] ^= *RK++; - - while( NR ) { - --NR; - camellia_feistel( X, RK, X + 2 ); - RK += 2; - camellia_feistel( X + 2, RK, X ); - RK += 2; - camellia_feistel( X, RK, X + 2 ); - RK += 2; - camellia_feistel( X + 2, RK, X ); - RK += 2; - camellia_feistel( X, RK, X + 2 ); - RK += 2; - camellia_feistel( X + 2, RK, X ); - RK += 2; - - if( NR ) { - FL(X[0], X[1], RK[0], RK[1]); - RK += 2; - FLInv(X[2], X[3], RK[0], RK[1]); - RK += 2; - } - } - - X[2] ^= *RK++; - X[3] ^= *RK++; - X[0] ^= *RK++; - X[1] ^= *RK++; - - PUT_UINT32_BE( X[2], output, 0 ); - PUT_UINT32_BE( X[3], output, 4 ); - PUT_UINT32_BE( X[0], output, 8 ); - PUT_UINT32_BE( X[1], output, 12 ); - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * Camellia-CBC buffer encryption/decryption - */ -int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[16]; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT || - mode == MBEDTLS_CAMELLIA_DECRYPT ); - CAMELLIA_VALIDATE_RET( iv != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || input != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || output != NULL ); - - if( length % 16 ) - return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_CAMELLIA_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, 16 ); - mbedtls_camellia_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_camellia_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * Camellia-CFB128 buffer encryption/decryption - */ -int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int c; - size_t n; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT || - mode == MBEDTLS_CAMELLIA_DECRYPT ); - CAMELLIA_VALIDATE_RET( iv != NULL ); - CAMELLIA_VALIDATE_RET( iv_off != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || input != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || output != NULL ); - - n = *iv_off; - if( n >= 16 ) - return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ); - - if( mode == MBEDTLS_CAMELLIA_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv ); - - c = *input++; - *output++ = (unsigned char)( c ^ iv[n] ); - iv[n] = (unsigned char) c; - - n = ( n + 1 ) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * Camellia-CTR buffer encryption/decryption - */ -int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n; - CAMELLIA_VALIDATE_RET( ctx != NULL ); - CAMELLIA_VALIDATE_RET( nonce_counter != NULL ); - CAMELLIA_VALIDATE_RET( stream_block != NULL ); - CAMELLIA_VALIDATE_RET( nc_off != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || input != NULL ); - CAMELLIA_VALIDATE_RET( length == 0 || output != NULL ); - - n = *nc_off; - if( n >= 16 ) - return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ); - - while( length-- ) - { - if( n == 0 ) { - mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter, - stream_block ); - - for( i = 16; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* !MBEDTLS_CAMELLIA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Camellia test vectors from: - * - * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html: - * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt - * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt - * (For each bitlength: Key 0, Nr 39) - */ -#define CAMELLIA_TESTS_ECB 2 - -static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] = -{ - { - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, - { - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, - { - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, -}; - -static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] = -{ - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}; - -static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] = -{ - { - { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, - 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, - { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE, - 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 } - }, - { - { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, - 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, - { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9, - 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 } - }, - { - { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, - 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, - { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C, - 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 } - } -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define CAMELLIA_TESTS_CBC 3 - -static const unsigned char camellia_test_cbc_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C } - , - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B } - , - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char camellia_test_cbc_iv[16] = - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F } -; - -static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] = -{ - { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A }, - { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 }, - { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF } - -}; - -static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] = -{ - { - { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0, - 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB }, - { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78, - 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 }, - { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B, - 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 } - }, - { - { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2, - 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 }, - { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42, - 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 }, - { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8, - 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 } - }, - { - { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A, - 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA }, - { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40, - 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 }, - { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA, - 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 } - } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * Camellia-CTR test vectors from: - * - * http://www.faqs.org/rfcs/rfc5528.html - */ - -static const unsigned char camellia_test_ctr_key[3][16] = -{ - { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, - 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, - { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, - 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, - { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, - 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } -}; - -static const unsigned char camellia_test_ctr_nonce_counter[3][16] = -{ - { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, - 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, - 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } -}; - -static const unsigned char camellia_test_ctr_pt[3][48] = -{ - { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, - 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23 } -}; - -static const unsigned char camellia_test_ctr_ct[3][48] = -{ - { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A, - 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F }, - { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4, - 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44, - 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7, - 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 }, - { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88, - 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73, - 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1, - 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD, - 0xDF, 0x50, 0x86, 0x96 } -}; - -static const int camellia_test_ctr_len[3] = - { 16, 32, 36 }; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -/* - * Checkup routine - */ -int mbedtls_camellia_self_test( int verbose ) -{ - int i, j, u, v; - unsigned char key[32]; - unsigned char buf[64]; - unsigned char src[16]; - unsigned char dst[16]; -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char iv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - size_t offset, len; - unsigned char nonce_counter[16]; - unsigned char stream_block[16]; -#endif - int ret = 1; - - mbedtls_camellia_context ctx; - - mbedtls_camellia_init( &ctx ); - memset( key, 0, 32 ); - - for( j = 0; j < 6; j++ ) { - u = j >> 1; - v = j & 1; - - if( verbose != 0 ) - mbedtls_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64, - (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc"); - - for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) { - memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u ); - - if( v == MBEDTLS_CAMELLIA_DECRYPT ) { - mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); - memcpy( src, camellia_test_ecb_cipher[u][i], 16 ); - memcpy( dst, camellia_test_ecb_plain[i], 16 ); - } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ - mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); - memcpy( src, camellia_test_ecb_plain[i], 16 ); - memcpy( dst, camellia_test_ecb_cipher[u][i], 16 ); - } - - mbedtls_camellia_crypt_ecb( &ctx, v, src, buf ); - - if( memcmp( buf, dst, 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - goto exit; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /* - * CBC mode - */ - for( j = 0; j < 6; j++ ) - { - u = j >> 1; - v = j & 1; - - if( verbose != 0 ) - mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, - ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); - - memcpy( src, camellia_test_cbc_iv, 16 ); - memcpy( dst, camellia_test_cbc_iv, 16 ); - memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u ); - - if( v == MBEDTLS_CAMELLIA_DECRYPT ) { - mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); - } else { - mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); - } - - for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { - - if( v == MBEDTLS_CAMELLIA_DECRYPT ) { - memcpy( iv , src, 16 ); - memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); - memcpy( dst, camellia_test_cbc_plain[i], 16 ); - } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ - memcpy( iv , dst, 16 ); - memcpy( src, camellia_test_cbc_plain[i], 16 ); - memcpy( dst, camellia_test_cbc_cipher[u][i], 16 ); - } - - mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf ); - - if( memcmp( buf, dst, 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - goto exit; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /* - * CTR mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " CAMELLIA-CTR-128 (%s): ", - ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); - - memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 ); - memcpy( key, camellia_test_ctr_key[u], 16 ); - - offset = 0; - mbedtls_camellia_setkey_enc( &ctx, key, 128 ); - - if( v == MBEDTLS_CAMELLIA_DECRYPT ) - { - len = camellia_test_ctr_len[u]; - memcpy( buf, camellia_test_ctr_ct[u], len ); - - mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, - buf, buf ); - - if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - goto exit; - } - } - else - { - len = camellia_test_ctr_len[u]; - memcpy( buf, camellia_test_ctr_pt[u], len ); - - mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, - buf, buf ); - - if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - goto exit; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - - ret = 0; - -exit: - mbedtls_camellia_free( &ctx ); - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CAMELLIA_C */ diff --git a/mbedtls/camellia.h b/mbedtls/camellia.h deleted file mode 100644 index 6282bb7e7..000000000 --- a/mbedtls/camellia.h +++ /dev/null @@ -1,352 +0,0 @@ -#pragma GCC system_header -/** - * \file camellia.h - * - * \brief Camellia block cipher - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_CAMELLIA_H -#define MBEDTLS_CAMELLIA_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#include "platform_util.h" - -#define MBEDTLS_CAMELLIA_ENCRYPT 1 -#define MBEDTLS_CAMELLIA_DECRYPT 0 - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0024 ) -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 /**< Bad input data. */ - -#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */ - -/* MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED is deprecated and should not be used. - */ -#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED -0x0027 /**< Camellia hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_CAMELLIA_ALT) -// Regular implementation -// - -/** - * \brief CAMELLIA context structure - */ -typedef struct mbedtls_camellia_context -{ - int nr; /*!< number of rounds */ - uint32_t rk[68]; /*!< CAMELLIA round keys */ -} -mbedtls_camellia_context; - -#else /* MBEDTLS_CAMELLIA_ALT */ -#include "camellia_alt.h" -#endif /* MBEDTLS_CAMELLIA_ALT */ - -/** - * \brief Initialize a CAMELLIA context. - * - * \param ctx The CAMELLIA context to be initialized. - * This must not be \c NULL. - */ -void mbedtls_camellia_init( mbedtls_camellia_context *ctx ); - -/** - * \brief Clear a CAMELLIA context. - * - * \param ctx The CAMELLIA context to be cleared. This may be \c NULL, - * in which case this function returns immediately. If it is not - * \c NULL, it must be initialized. - */ -void mbedtls_camellia_free( mbedtls_camellia_context *ctx ); - -/** - * \brief Perform a CAMELLIA key schedule operation for encryption. - * - * \param ctx The CAMELLIA context to use. This must be initialized. - * \param key The encryption key to use. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The length of \p key in Bits. This must be either \c 128, - * \c 192 or \c 256. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief Perform a CAMELLIA key schedule operation for decryption. - * - * \param ctx The CAMELLIA context to use. This must be initialized. - * \param key The decryption key. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The length of \p key in Bits. This must be either \c 128, - * \c 192 or \c 256. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief Perform a CAMELLIA-ECB block encryption/decryption operation. - * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * \param input The input block. This must be a readable buffer - * of size \c 16 Bytes. - * \param output The output block. This must be a writable buffer - * of size \c 16 Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief Perform a CAMELLIA-CBC buffer encryption/decryption operation. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * \param length The length in Bytes of the input data \p input. - * This must be a multiple of \c 16 Bytes. - * \param iv The initialization vector. This must be a read/write buffer - * of length \c 16 Bytes. It is updated to allow streaming - * use as explained above. - * \param input The buffer holding the input data. This must point to a - * readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must point to a - * writable buffer of length \p length Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief Perform a CAMELLIA-CFB128 buffer encryption/decryption - * operation. - * - * \note Due to the nature of CFB mode, you should use the same - * key for both encryption and decryption. In particular, calls - * to this function should be preceded by a key-schedule via - * mbedtls_camellia_setkey_enc() regardless of whether \p mode - * is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * \param length The length of the input data \p input. Any value is allowed. - * \param iv_off The current offset in the IV. This must be smaller - * than \c 16 Bytes. It is updated after this call to allow - * the aforementioned streaming usage. - * \param iv The initialization vector. This must be a read/write buffer - * of length \c 16 Bytes. It is updated after this call to - * allow the aforementioned streaming usage. - * \param input The buffer holding the input data. This must be a readable - * buffer of size \p length Bytes. - * \param output The buffer to hold the output data. This must be a writable - * buffer of length \p length Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief Perform a CAMELLIA-CTR buffer encryption/decryption operation. - * - * *note Due to the nature of CTR mode, you should use the same - * key for both encryption and decryption. In particular, calls - * to this function should be preceded by a key-schedule via - * mbedtls_camellia_setkey_enc() regardless of whether \p mode - * is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first \c 12 Bytes for the - * per-message nonce, and the last \c 4 Bytes for internal use. - * In that case, before calling this function on a new message you - * need to set the first \c 12 Bytes of \p nonce_counter to your - * chosen nonce value, the last four to \c 0, and \p nc_off to \c 0 - * (which will cause \p stream_block to be ignored). That way, you - * can encrypt at most \c 2**96 messages of up to \c 2**32 blocks - * each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be - * unique. The recommended way to ensure uniqueness is to use a - * message counter. An alternative is to generate random nonces, - * but this limits the number of messages that can be securely - * encrypted: for example, with 96-bit random nonces, you should - * not encrypt more than 2**32 messages with the same key. - * - * Note that for both stategies, sizes are measured in blocks and - * that a CAMELLIA block is \c 16 Bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param length The length of the input data \p input in Bytes. - * Any value is allowed. - * \param nc_off The offset in the current \p stream_block (for resuming - * within current cipher stream). The offset pointer to - * should be \c 0 at the start of a stream. It is updated - * at the end of this call. - * \param nonce_counter The 128-bit nonce and counter. This must be a read/write - * buffer of length \c 16 Bytes. - * \param stream_block The saved stream-block for resuming. This must be a - * read/write buffer of length \c 16 Bytes. - * \param input The input data stream. This must be a readable buffer of - * size \p length Bytes. - * \param output The output data stream. This must be a writable buffer - * of size \p length Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_camellia_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* camellia.h */ diff --git a/mbedtls/ccm.c b/mbedtls/ccm.c deleted file mode 100644 index 9b54fcec3..000000000 --- a/mbedtls/ccm.c +++ /dev/null @@ -1,583 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * NIST SP800-38C compliant CCM implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * Definition of CCM: - * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf - * RFC 3610 "Counter with CBC-MAC (CCM)" - * - * Related: - * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CCM_C) - -#include "mbedtls/ccm.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#if !defined(MBEDTLS_CCM_ALT) - -#define CCM_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT ) -#define CCM_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define CCM_ENCRYPT 0 -#define CCM_DECRYPT 1 - -/* - * Initialize context - */ -void mbedtls_ccm_init( mbedtls_ccm_context *ctx ) -{ - CCM_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_ccm_context ) ); -} - -int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( key != NULL ); - - cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - if( cipher_info->block_size != 16 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - mbedtls_cipher_free( &ctx->cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Free context - */ -void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) -{ - if( ctx == NULL ) - return; - mbedtls_cipher_free( &ctx->cipher_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); -} - -/* - * Macros for common operations. - * Results in smaller compiled code than static inline functions. - */ - -/* - * Update the CBC-MAC state in y using a block in b - * (Always using b as the source helps the compiler optimise a bit better.) - */ -#define UPDATE_CBC_MAC \ - for( i = 0; i < 16; i++ ) \ - y[i] ^= b[i]; \ - \ - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ - return( ret ); - -/* - * Encrypt or decrypt a partial block with CTR - * Warning: using b for temporary storage! src and dst must not be b! - * This avoids allocating one more 16 bytes buffer while allowing src == dst. - */ -#define CTR_CRYPT( dst, src, len ) \ - do \ - { \ - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, \ - 16, b, &olen ) ) != 0 ) \ - { \ - return( ret ); \ - } \ - \ - for( i = 0; i < (len); i++ ) \ - (dst)[i] = (src)[i] ^ b[i]; \ - } while( 0 ) - -/* - * Authenticated encryption or decryption - */ -static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ) -{ - int ret; - unsigned char i; - unsigned char q; - size_t len_left, olen; - unsigned char b[16]; - unsigned char y[16]; - unsigned char ctr[16]; - const unsigned char *src; - unsigned char *dst; - - /* - * Check length requirements: SP800-38C A.1 - * Additional requirement: a < 2^16 - 2^8 to simplify the code. - * 'length' checked later (when writing it to the first block) - * - * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4). - */ - if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - /* Also implies q is within bounds */ - if( iv_len < 7 || iv_len > 13 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - if( add_len > 0xFF00 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - q = 16 - 1 - (unsigned char) iv_len; - - /* - * First block B_0: - * 0 .. 0 flags - * 1 .. iv_len nonce (aka iv) - * iv_len+1 .. 15 length - * - * With flags as (bits): - * 7 0 - * 6 add present? - * 5 .. 3 (t - 2) / 2 - * 2 .. 0 q - 1 - */ - b[0] = 0; - b[0] |= ( add_len > 0 ) << 6; - b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; - b[0] |= q - 1; - - memcpy( b + 1, iv, iv_len ); - - for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) - b[15-i] = (unsigned char)( len_left & 0xFF ); - - if( len_left > 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - - /* Start CBC-MAC with first block */ - memset( y, 0, 16 ); - UPDATE_CBC_MAC; - - /* - * If there is additional data, update CBC-MAC with - * add_len, add, 0 (padding to a block boundary) - */ - if( add_len > 0 ) - { - size_t use_len; - len_left = add_len; - src = add; - - memset( b, 0, 16 ); - b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); - b[1] = (unsigned char)( ( add_len ) & 0xFF ); - - use_len = len_left < 16 - 2 ? len_left : 16 - 2; - memcpy( b + 2, src, use_len ); - len_left -= use_len; - src += use_len; - - UPDATE_CBC_MAC; - - while( len_left > 0 ) - { - use_len = len_left > 16 ? 16 : len_left; - - memset( b, 0, 16 ); - memcpy( b, src, use_len ); - UPDATE_CBC_MAC; - - len_left -= use_len; - src += use_len; - } - } - - /* - * Prepare counter block for encryption: - * 0 .. 0 flags - * 1 .. iv_len nonce (aka iv) - * iv_len+1 .. 15 counter (initially 1) - * - * With flags as (bits): - * 7 .. 3 0 - * 2 .. 0 q - 1 - */ - ctr[0] = q - 1; - memcpy( ctr + 1, iv, iv_len ); - memset( ctr + 1 + iv_len, 0, q ); - ctr[15] = 1; - - /* - * Authenticate and {en,de}crypt the message. - * - * The only difference between encryption and decryption is - * the respective order of authentication and {en,de}cryption. - */ - len_left = length; - src = input; - dst = output; - - while( len_left > 0 ) - { - size_t use_len = len_left > 16 ? 16 : len_left; - - if( mode == CCM_ENCRYPT ) - { - memset( b, 0, 16 ); - memcpy( b, src, use_len ); - UPDATE_CBC_MAC; - } - - CTR_CRYPT( dst, src, use_len ); - - if( mode == CCM_DECRYPT ) - { - memset( b, 0, 16 ); - memcpy( b, dst, use_len ); - UPDATE_CBC_MAC; - } - - dst += use_len; - src += use_len; - len_left -= use_len; - - /* - * Increment counter. - * No need to check for overflow thanks to the length check above. - */ - for( i = 0; i < q; i++ ) - if( ++ctr[15-i] != 0 ) - break; - } - - /* - * Authentication: reset counter and crypt/mask internal tag - */ - for( i = 0; i < q; i++ ) - ctr[15-i] = 0; - - CTR_CRYPT( y, y, 16 ); - memcpy( tag, y, tag_len ); - - return( 0 ); -} - -/* - * Authenticated encryption - */ -int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ) -{ - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add_len == 0 || add != NULL ); - CCM_VALIDATE_RET( length == 0 || input != NULL ); - CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); - return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, - add, add_len, input, output, tag, tag_len ) ); -} - -int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ) -{ - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add_len == 0 || add != NULL ); - CCM_VALIDATE_RET( length == 0 || input != NULL ); - CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( tag_len == 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add, - add_len, input, output, tag, tag_len ) ); -} - -/* - * Authenticated decryption - */ -int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len ) -{ - int ret; - unsigned char check_tag[16]; - unsigned char i; - int diff; - - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add_len == 0 || add != NULL ); - CCM_VALIDATE_RET( length == 0 || input != NULL ); - CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); - - if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, - iv, iv_len, add, add_len, - input, output, check_tag, tag_len ) ) != 0 ) - { - return( ret ); - } - - /* Check tag in "constant-time" */ - for( diff = 0, i = 0; i < tag_len; i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) - { - mbedtls_platform_zeroize( output, length ); - return( MBEDTLS_ERR_CCM_AUTH_FAILED ); - } - - return( 0 ); -} - -int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len ) -{ - CCM_VALIDATE_RET( ctx != NULL ); - CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add_len == 0 || add != NULL ); - CCM_VALIDATE_RET( length == 0 || input != NULL ); - CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); - - if( tag_len == 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add, - add_len, input, output, tag, tag_len ) ); -} -#endif /* !MBEDTLS_CCM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/* - * Examples 1 to 3 from SP800-38C Appendix C - */ - -#define NB_TESTS 3 -#define CCM_SELFTEST_PT_MAX_LEN 24 -#define CCM_SELFTEST_CT_MAX_LEN 32 -/* - * The data is the same for all tests, only the used length changes - */ -static const unsigned char key[] = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f -}; - -static const unsigned char iv[] = { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b -}; - -static const unsigned char ad[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13 -}; - -static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = { - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -}; - -static const size_t iv_len [NB_TESTS] = { 7, 8, 12 }; -static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; -static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; -static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; - -static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = { - { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, - { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, - 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, - 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, - { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, - 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, - 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, - 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } -}; - -int mbedtls_ccm_self_test( int verbose ) -{ - mbedtls_ccm_context ctx; - /* - * Some hardware accelerators require the input and output buffers - * would be in RAM, because the flash is not accessible. - * Use buffers on the stack to hold the test vectors data. - */ - unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN]; - unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN]; - size_t i; - int ret; - - mbedtls_ccm_init( &ctx ); - - if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " CCM: setup failed" ); - - return( 1 ); - } - - for( i = 0; i < NB_TESTS; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); - - memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN ); - memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN ); - memcpy( plaintext, msg, msg_len[i] ); - - ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i], - iv, iv_len[i], ad, add_len[i], - plaintext, ciphertext, - ciphertext + msg_len[i], tag_len[i] ); - - if( ret != 0 || - memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN ); - - ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i], - iv, iv_len[i], ad, add_len[i], - ciphertext, plaintext, - ciphertext + msg_len[i], tag_len[i] ); - - if( ret != 0 || - memcmp( plaintext, msg, msg_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - mbedtls_ccm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_CCM_C */ diff --git a/mbedtls/ccm.h b/mbedtls/ccm.h deleted file mode 100644 index 07548fe06..000000000 --- a/mbedtls/ccm.h +++ /dev/null @@ -1,336 +0,0 @@ -#pragma GCC system_header -/** - * \file ccm.h - * - * \brief This file provides an API for the CCM authenticated encryption - * mode for block ciphers. - * - * CCM combines Counter mode encryption with CBC-MAC authentication - * for 128-bit block ciphers. - * - * Input to CCM includes the following elements: - *
    • Payload - data that is both authenticated and encrypted.
    • - *
    • Associated data (Adata) - data that is authenticated but not - * encrypted, For example, a header.
    • - *
    • Nonce - A unique value that is assigned to the payload and the - * associated data.
    - * - * Definition of CCM: - * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf - * RFC 3610 "Counter with CBC-MAC (CCM)" - * - * Related: - * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" - * - * Definition of CCM*: - * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks - * Integer representation is fixed most-significant-octet-first order and - * the representation of octets is most-significant-bit-first order. This is - * consistent with RFC 3610. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_CCM_H -#define MBEDTLS_CCM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "cipher.h" - -#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */ -#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ - -/* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_CCM_ALT) -// Regular implementation -// - -/** - * \brief The CCM context-type definition. The CCM context is passed - * to the APIs called. - */ -typedef struct mbedtls_ccm_context -{ - mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ -} -mbedtls_ccm_context; - -#else /* MBEDTLS_CCM_ALT */ -#include "ccm_alt.h" -#endif /* MBEDTLS_CCM_ALT */ - -/** - * \brief This function initializes the specified CCM context, - * to make references valid, and prepare the context - * for mbedtls_ccm_setkey() or mbedtls_ccm_free(). - * - * \param ctx The CCM context to initialize. This must not be \c NULL. - */ -void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); - -/** - * \brief This function initializes the CCM context set in the - * \p ctx parameter and sets the encryption key. - * - * \param ctx The CCM context to initialize. This must be an initialized - * context. - * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. This must not be \c NULL. - * \param keybits The key size in bits. This must be acceptable by the cipher. - * - * \return \c 0 on success. - * \return A CCM or cipher-specific error code on failure. - */ -int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function releases and clears the specified CCM context - * and underlying cipher sub-context. - * - * \param ctx The CCM context to clear. If this is \c NULL, the function - * has no effect. Otherwise, this must be initialized. - */ -void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); - -/** - * \brief This function encrypts a buffer using CCM. - * - * \note The tag is written to a separate buffer. To concatenate - * the \p tag with the \p output, as done in RFC-3610: - * Counter with CBC-MAC (CCM), use - * \p tag = \p output + \p length, and make sure that the - * output buffer is at least \p length + \p tag_len wide. - * - * \param ctx The CCM context to use for encryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param add The additional data field. If \p add_len is greater than - * zero, \p add must be a readable buffer of at least that - * length. - * \param add_len The length of additional data in Bytes. - * This must be less than `2^16 - 2^8`. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * writable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field to generate in Bytes: - * 4, 6, 8, 10, 12, 14 or 16. - * - * \return \c 0 on success. - * \return A CCM or cipher-specific error code on failure. - */ -int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ); - -/** - * \brief This function encrypts a buffer using CCM*. - * - * \note The tag is written to a separate buffer. To concatenate - * the \p tag with the \p output, as done in RFC-3610: - * Counter with CBC-MAC (CCM), use - * \p tag = \p output + \p length, and make sure that the - * output buffer is at least \p length + \p tag_len wide. - * - * \note When using this function in a variable tag length context, - * the tag length has to be encoded into the \p iv passed to - * this function. - * - * \param ctx The CCM context to use for encryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param add The additional data field. This must be a readable buffer of - * at least \p add_len Bytes. - * \param add_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * writable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field to generate in Bytes: - * 0, 4, 6, 8, 10, 12, 14 or 16. - * - * \warning Passing \c 0 as \p tag_len means that the message is no - * longer authenticated. - * - * \return \c 0 on success. - * \return A CCM or cipher-specific error code on failure. - */ -int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ); - -/** - * \brief This function performs a CCM authenticated decryption of a - * buffer. - * - * \param ctx The CCM context to use for decryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param add The additional data field. This must be a readable buffer - * of at least that \p add_len Bytes.. - * \param add_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field to generate in Bytes: - * 4, 6, 8, 10, 12, 14 or 16. - * - * \return \c 0 on success. This indicates that the message is authentic. - * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. - * \return A cipher-specific error code on calculation failure. - */ -int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len ); - -/** - * \brief This function performs a CCM* authenticated decryption of a - * buffer. - * - * \note When using this function in a variable tag length context, - * the tag length has to be decoded from \p iv and passed to - * this function as \p tag_len. (\p tag needs to be adjusted - * accordingly.) - * - * \param ctx The CCM context to use for decryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param add The additional data field. This must be a readable buffer of - * at least that \p add_len Bytes. - * \param add_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field in Bytes. - * 0, 4, 6, 8, 10, 12, 14 or 16. - * - * \warning Passing \c 0 as \p tag_len means that the message is nos - * longer authenticated. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. - * \return A cipher-specific error code on calculation failure. - */ -int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len ); - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/** - * \brief The CCM checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_ccm_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CCM_H */ diff --git a/mbedtls/certs.c b/mbedtls/certs.c deleted file mode 100644 index 6cc2b4cab..000000000 --- a/mbedtls/certs.c +++ /dev/null @@ -1,1791 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * X.509 test certificates - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "mbedtls/certs.h" - -#if defined(MBEDTLS_CERTS_C) - -/* - * Test CA Certificates - * - * We define test CA certificates for each choice of the following parameters: - * - PEM or DER encoding - * - SHA-1 or SHA-256 hash - * - RSA or EC key - * - * Things to add: - * - multiple EC curve types - * - */ - -/* This is taken from tests/data_files/test-ca2.crt */ -/* BEGIN FILE string macro TEST_CA_CRT_EC_PEM tests/data_files/test-ca2.crt */ -#define TEST_CA_CRT_EC_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIICBDCCAYigAwIBAgIJAMFD4n5iQ8zoMAwGCCqGSM49BAMCBQAwPjELMAkGA1UE\r\n" \ - "BhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRwwGgYDVQQDDBNQb2xhcnNzbCBUZXN0\r\n" \ - "IEVDIENBMB4XDTE5MDIxMDE0NDQwMFoXDTI5MDIxMDE0NDQwMFowPjELMAkGA1UE\r\n" \ - "BhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRwwGgYDVQQDDBNQb2xhcnNzbCBUZXN0\r\n" \ - "IEVDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEw9orNEE3WC+HVv78ibopQ0tO\r\n" \ - "4G7DDldTMzlY1FK0kZU5CyPfXxckYkj8GpUpziwth8KIUoCv1mqrId240xxuWLjK\r\n" \ - "6LJpjvNBrSnDtF91p0dv1RkpVWmaUzsgtGYWYDMeo1AwTjAMBgNVHRMEBTADAQH/\r\n" \ - "MB0GA1UdDgQWBBSdbSAkSQE/K8t4tRm8fiTJ2/s2fDAfBgNVHSMEGDAWgBSdbSAk\r\n" \ - "SQE/K8t4tRm8fiTJ2/s2fDAMBggqhkjOPQQDAgUAA2gAMGUCMFHKrjAPpHB0BN1a\r\n" \ - "LH8TwcJ3vh0AxeKZj30mRdOKBmg/jLS3rU3g8VQBHpn8sOTTBwIxANxPO5AerimZ\r\n" \ - "hCjMe0d4CTHf1gFZMF70+IqEP+o5VHsIp2Cqvflb0VGWFC5l9a4cQg==\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/test-ca2.crt.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_CRT_EC_DER tests/data_files/test-ca2.crt.der */ -#define TEST_CA_CRT_EC_DER { \ - 0x30, 0x82, 0x02, 0x04, 0x30, 0x82, 0x01, 0x88, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x09, 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, \ - 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, \ - 0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, \ - 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, \ - 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x50, \ - 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, \ - 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, \ - 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x17, \ - 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, \ - 0x30, 0x5a, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, \ - 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, \ - 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x50, \ - 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, \ - 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, \ - 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, \ - 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0xc3, 0xda, 0x2b, 0x34, 0x41, 0x37, \ - 0x58, 0x2f, 0x87, 0x56, 0xfe, 0xfc, 0x89, 0xba, 0x29, 0x43, 0x4b, 0x4e, \ - 0xe0, 0x6e, 0xc3, 0x0e, 0x57, 0x53, 0x33, 0x39, 0x58, 0xd4, 0x52, 0xb4, \ - 0x91, 0x95, 0x39, 0x0b, 0x23, 0xdf, 0x5f, 0x17, 0x24, 0x62, 0x48, 0xfc, \ - 0x1a, 0x95, 0x29, 0xce, 0x2c, 0x2d, 0x87, 0xc2, 0x88, 0x52, 0x80, 0xaf, \ - 0xd6, 0x6a, 0xab, 0x21, 0xdd, 0xb8, 0xd3, 0x1c, 0x6e, 0x58, 0xb8, 0xca, \ - 0xe8, 0xb2, 0x69, 0x8e, 0xf3, 0x41, 0xad, 0x29, 0xc3, 0xb4, 0x5f, 0x75, \ - 0xa7, 0x47, 0x6f, 0xd5, 0x19, 0x29, 0x55, 0x69, 0x9a, 0x53, 0x3b, 0x20, \ - 0xb4, 0x66, 0x16, 0x60, 0x33, 0x1e, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x0c, \ - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, \ - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, \ - 0x6d, 0x20, 0x24, 0x49, 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, \ - 0x7e, 0x24, 0xc9, 0xdb, 0xfb, 0x36, 0x7c, 0x30, 0x1f, 0x06, 0x03, 0x55, \ - 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, \ - 0x49, 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, \ - 0xdb, 0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ - 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, \ - 0x30, 0x51, 0xca, 0xae, 0x30, 0x0f, 0xa4, 0x70, 0x74, 0x04, 0xdd, 0x5a, \ - 0x2c, 0x7f, 0x13, 0xc1, 0xc2, 0x77, 0xbe, 0x1d, 0x00, 0xc5, 0xe2, 0x99, \ - 0x8f, 0x7d, 0x26, 0x45, 0xd3, 0x8a, 0x06, 0x68, 0x3f, 0x8c, 0xb4, 0xb7, \ - 0xad, 0x4d, 0xe0, 0xf1, 0x54, 0x01, 0x1e, 0x99, 0xfc, 0xb0, 0xe4, 0xd3, \ - 0x07, 0x02, 0x31, 0x00, 0xdc, 0x4f, 0x3b, 0x90, 0x1e, 0xae, 0x29, 0x99, \ - 0x84, 0x28, 0xcc, 0x7b, 0x47, 0x78, 0x09, 0x31, 0xdf, 0xd6, 0x01, 0x59, \ - 0x30, 0x5e, 0xf4, 0xf8, 0x8a, 0x84, 0x3f, 0xea, 0x39, 0x54, 0x7b, 0x08, \ - 0xa7, 0x60, 0xaa, 0xbd, 0xf9, 0x5b, 0xd1, 0x51, 0x96, 0x14, 0x2e, 0x65, \ - 0xf5, 0xae, 0x1c, 0x42 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/test-ca2.key.enc */ -/* BEGIN FILE string macro TEST_CA_KEY_EC_PEM tests/data_files/test-ca2.key.enc */ -#define TEST_CA_KEY_EC_PEM \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "Proc-Type: 4,ENCRYPTED\r\n" \ - "DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n" \ - "\r\n" \ - "IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n" \ - "ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n" \ - "UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" \ - "a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" -/* END FILE */ - -#define TEST_CA_PWD_EC_PEM "PolarSSLTest" - -/* This is generated from tests/data_files/test-ca2.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_KEY_EC_DER tests/data_files/test-ca2.key.der */ -#define TEST_CA_KEY_EC_DER { \ - 0x30, 0x81, 0xa4, 0x02, 0x01, 0x01, 0x04, 0x30, 0x83, 0xd9, 0x15, 0x0e, \ - 0xa0, 0x71, 0xf0, 0x57, 0x10, 0x33, 0xa3, 0x38, 0xb8, 0x86, 0xc1, 0xa6, \ - 0x11, 0x5d, 0x6d, 0xb4, 0x03, 0xe1, 0x29, 0x76, 0x45, 0xd7, 0x87, 0x6f, \ - 0x23, 0xab, 0x44, 0x20, 0xea, 0x64, 0x7b, 0x85, 0xb1, 0x76, 0xe7, 0x85, \ - 0x95, 0xaa, 0x74, 0xd6, 0xd1, 0xa4, 0x5e, 0xea, 0xa0, 0x07, 0x06, 0x05, \ - 0x2b, 0x81, 0x04, 0x00, 0x22, 0xa1, 0x64, 0x03, 0x62, 0x00, 0x04, 0xc3, \ - 0xda, 0x2b, 0x34, 0x41, 0x37, 0x58, 0x2f, 0x87, 0x56, 0xfe, 0xfc, 0x89, \ - 0xba, 0x29, 0x43, 0x4b, 0x4e, 0xe0, 0x6e, 0xc3, 0x0e, 0x57, 0x53, 0x33, \ - 0x39, 0x58, 0xd4, 0x52, 0xb4, 0x91, 0x95, 0x39, 0x0b, 0x23, 0xdf, 0x5f, \ - 0x17, 0x24, 0x62, 0x48, 0xfc, 0x1a, 0x95, 0x29, 0xce, 0x2c, 0x2d, 0x87, \ - 0xc2, 0x88, 0x52, 0x80, 0xaf, 0xd6, 0x6a, 0xab, 0x21, 0xdd, 0xb8, 0xd3, \ - 0x1c, 0x6e, 0x58, 0xb8, 0xca, 0xe8, 0xb2, 0x69, 0x8e, 0xf3, 0x41, 0xad, \ - 0x29, 0xc3, 0xb4, 0x5f, 0x75, 0xa7, 0x47, 0x6f, 0xd5, 0x19, 0x29, 0x55, \ - 0x69, 0x9a, 0x53, 0x3b, 0x20, 0xb4, 0x66, 0x16, 0x60, 0x33, 0x1e \ -} -/* END FILE */ - -/* This is taken from tests/data_files/test-ca-sha256.crt. */ -/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA256_PEM tests/data_files/test-ca-sha256.crt */ -#define TEST_CA_CRT_RSA_SHA256_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDAwWhcNMjkwMjEwMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ - "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ - "mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ - "50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ - "YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ - "R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ - "KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ - "UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ - "MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBCwUA\r\n" \ - "A4IBAQA4qFSCth2q22uJIdE4KGHJsJjVEfw2/xn+MkTvCMfxVrvmRvqCtjE4tKDl\r\n" \ - "oK4MxFOek07oDZwvtAT9ijn1hHftTNS7RH9zd/fxNpfcHnMZXVC4w4DNA1fSANtW\r\n" \ - "5sY1JB5Je9jScrsLSS+mAjyv0Ow3Hb2Bix8wu7xNNrV5fIf7Ubm+wt6SqEBxu3Kb\r\n" \ - "+EfObAT4huf3czznhH3C17ed6NSbXwoXfby7stWUDeRJv08RaFOykf/Aae7bY5PL\r\n" \ - "yTVrkAnikMntJ9YI+hNNYt3inqq11A5cN0+rVTst8UKCxzQ4GpvroSwPKTFkbMw4\r\n" \ - "/anT1dVxr/BtwJfiESoK3/4CeXR1\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/test-ca-sha256.crt.der - * using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA256_DER tests/data_files/test-ca-sha256.crt.der */ -#define TEST_CA_CRT_RSA_SHA256_DER { \ - 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \ - 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \ - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \ - 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \ - 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \ - 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \ - 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \ - 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \ - 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \ - 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \ - 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \ - 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \ - 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \ - 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \ - 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \ - 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \ - 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \ - 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \ - 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \ - 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \ - 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \ - 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \ - 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \ - 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \ - 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \ - 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \ - 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \ - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \ - 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \ - 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \ - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \ - 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \ - 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \ - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, \ - 0x03, 0x82, 0x01, 0x01, 0x00, 0x38, 0xa8, 0x54, 0x82, 0xb6, 0x1d, 0xaa, \ - 0xdb, 0x6b, 0x89, 0x21, 0xd1, 0x38, 0x28, 0x61, 0xc9, 0xb0, 0x98, 0xd5, \ - 0x11, 0xfc, 0x36, 0xff, 0x19, 0xfe, 0x32, 0x44, 0xef, 0x08, 0xc7, 0xf1, \ - 0x56, 0xbb, 0xe6, 0x46, 0xfa, 0x82, 0xb6, 0x31, 0x38, 0xb4, 0xa0, 0xe5, \ - 0xa0, 0xae, 0x0c, 0xc4, 0x53, 0x9e, 0x93, 0x4e, 0xe8, 0x0d, 0x9c, 0x2f, \ - 0xb4, 0x04, 0xfd, 0x8a, 0x39, 0xf5, 0x84, 0x77, 0xed, 0x4c, 0xd4, 0xbb, \ - 0x44, 0x7f, 0x73, 0x77, 0xf7, 0xf1, 0x36, 0x97, 0xdc, 0x1e, 0x73, 0x19, \ - 0x5d, 0x50, 0xb8, 0xc3, 0x80, 0xcd, 0x03, 0x57, 0xd2, 0x00, 0xdb, 0x56, \ - 0xe6, 0xc6, 0x35, 0x24, 0x1e, 0x49, 0x7b, 0xd8, 0xd2, 0x72, 0xbb, 0x0b, \ - 0x49, 0x2f, 0xa6, 0x02, 0x3c, 0xaf, 0xd0, 0xec, 0x37, 0x1d, 0xbd, 0x81, \ - 0x8b, 0x1f, 0x30, 0xbb, 0xbc, 0x4d, 0x36, 0xb5, 0x79, 0x7c, 0x87, 0xfb, \ - 0x51, 0xb9, 0xbe, 0xc2, 0xde, 0x92, 0xa8, 0x40, 0x71, 0xbb, 0x72, 0x9b, \ - 0xf8, 0x47, 0xce, 0x6c, 0x04, 0xf8, 0x86, 0xe7, 0xf7, 0x73, 0x3c, 0xe7, \ - 0x84, 0x7d, 0xc2, 0xd7, 0xb7, 0x9d, 0xe8, 0xd4, 0x9b, 0x5f, 0x0a, 0x17, \ - 0x7d, 0xbc, 0xbb, 0xb2, 0xd5, 0x94, 0x0d, 0xe4, 0x49, 0xbf, 0x4f, 0x11, \ - 0x68, 0x53, 0xb2, 0x91, 0xff, 0xc0, 0x69, 0xee, 0xdb, 0x63, 0x93, 0xcb, \ - 0xc9, 0x35, 0x6b, 0x90, 0x09, 0xe2, 0x90, 0xc9, 0xed, 0x27, 0xd6, 0x08, \ - 0xfa, 0x13, 0x4d, 0x62, 0xdd, 0xe2, 0x9e, 0xaa, 0xb5, 0xd4, 0x0e, 0x5c, \ - 0x37, 0x4f, 0xab, 0x55, 0x3b, 0x2d, 0xf1, 0x42, 0x82, 0xc7, 0x34, 0x38, \ - 0x1a, 0x9b, 0xeb, 0xa1, 0x2c, 0x0f, 0x29, 0x31, 0x64, 0x6c, 0xcc, 0x38, \ - 0xfd, 0xa9, 0xd3, 0xd5, 0xd5, 0x71, 0xaf, 0xf0, 0x6d, 0xc0, 0x97, 0xe2, \ - 0x11, 0x2a, 0x0a, 0xdf, 0xfe, 0x02, 0x79, 0x74, 0x75 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/test-ca-sha1.crt. */ -/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA1_PEM tests/data_files/test-ca-sha1.crt */ -#define TEST_CA_CRT_RSA_SHA1_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDAwWhcNMjkwMjEwMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ - "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ - "mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ - "50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ - "YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ - "R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ - "KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ - "UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ - "MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBBQUA\r\n" \ - "A4IBAQB0ZiNRFdia6kskaPnhrqejIRq8YMEGAf2oIPnyZ78xoyERgc35lHGyMtsL\r\n" \ - "hWicNjP4d/hS9As4j5KA2gdNGi5ETA1X7SowWOGsryivSpMSHVy1+HdfWlsYQOzm\r\n" \ - "8o+faQNUm8XzPVmttfAVspxeHSxJZ36Oo+QWZ5wZlCIEyjEdLUId+Tm4Bz3B5jRD\r\n" \ - "zZa/SaqDokq66N2zpbgKKAl3GU2O++fBqP2dSkdQykmTxhLLWRN8FJqhYATyQntZ\r\n" \ - "0QSi3W9HfSZPnFTcPIXeoiPd2pLlxt1hZu8dws2LTXE63uP6MM4LHvWxiuJaWkP/\r\n" \ - "mtxyUALj2pQxRitopORFQdn7AOY5\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is taken from tests/data_files/test-ca-sha1.crt.der. */ -/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA1_DER tests/data_files/test-ca-sha1.crt.der */ -#define TEST_CA_CRT_RSA_SHA1_DER { \ - 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \ - 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \ - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \ - 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \ - 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \ - 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \ - 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \ - 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \ - 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \ - 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \ - 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \ - 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \ - 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \ - 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \ - 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \ - 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \ - 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \ - 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \ - 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \ - 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \ - 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \ - 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \ - 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \ - 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \ - 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \ - 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \ - 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \ - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \ - 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \ - 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \ - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \ - 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \ - 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \ - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, \ - 0x03, 0x82, 0x01, 0x01, 0x00, 0x74, 0x66, 0x23, 0x51, 0x15, 0xd8, 0x9a, \ - 0xea, 0x4b, 0x24, 0x68, 0xf9, 0xe1, 0xae, 0xa7, 0xa3, 0x21, 0x1a, 0xbc, \ - 0x60, 0xc1, 0x06, 0x01, 0xfd, 0xa8, 0x20, 0xf9, 0xf2, 0x67, 0xbf, 0x31, \ - 0xa3, 0x21, 0x11, 0x81, 0xcd, 0xf9, 0x94, 0x71, 0xb2, 0x32, 0xdb, 0x0b, \ - 0x85, 0x68, 0x9c, 0x36, 0x33, 0xf8, 0x77, 0xf8, 0x52, 0xf4, 0x0b, 0x38, \ - 0x8f, 0x92, 0x80, 0xda, 0x07, 0x4d, 0x1a, 0x2e, 0x44, 0x4c, 0x0d, 0x57, \ - 0xed, 0x2a, 0x30, 0x58, 0xe1, 0xac, 0xaf, 0x28, 0xaf, 0x4a, 0x93, 0x12, \ - 0x1d, 0x5c, 0xb5, 0xf8, 0x77, 0x5f, 0x5a, 0x5b, 0x18, 0x40, 0xec, 0xe6, \ - 0xf2, 0x8f, 0x9f, 0x69, 0x03, 0x54, 0x9b, 0xc5, 0xf3, 0x3d, 0x59, 0xad, \ - 0xb5, 0xf0, 0x15, 0xb2, 0x9c, 0x5e, 0x1d, 0x2c, 0x49, 0x67, 0x7e, 0x8e, \ - 0xa3, 0xe4, 0x16, 0x67, 0x9c, 0x19, 0x94, 0x22, 0x04, 0xca, 0x31, 0x1d, \ - 0x2d, 0x42, 0x1d, 0xf9, 0x39, 0xb8, 0x07, 0x3d, 0xc1, 0xe6, 0x34, 0x43, \ - 0xcd, 0x96, 0xbf, 0x49, 0xaa, 0x83, 0xa2, 0x4a, 0xba, 0xe8, 0xdd, 0xb3, \ - 0xa5, 0xb8, 0x0a, 0x28, 0x09, 0x77, 0x19, 0x4d, 0x8e, 0xfb, 0xe7, 0xc1, \ - 0xa8, 0xfd, 0x9d, 0x4a, 0x47, 0x50, 0xca, 0x49, 0x93, 0xc6, 0x12, 0xcb, \ - 0x59, 0x13, 0x7c, 0x14, 0x9a, 0xa1, 0x60, 0x04, 0xf2, 0x42, 0x7b, 0x59, \ - 0xd1, 0x04, 0xa2, 0xdd, 0x6f, 0x47, 0x7d, 0x26, 0x4f, 0x9c, 0x54, 0xdc, \ - 0x3c, 0x85, 0xde, 0xa2, 0x23, 0xdd, 0xda, 0x92, 0xe5, 0xc6, 0xdd, 0x61, \ - 0x66, 0xef, 0x1d, 0xc2, 0xcd, 0x8b, 0x4d, 0x71, 0x3a, 0xde, 0xe3, 0xfa, \ - 0x30, 0xce, 0x0b, 0x1e, 0xf5, 0xb1, 0x8a, 0xe2, 0x5a, 0x5a, 0x43, 0xff, \ - 0x9a, 0xdc, 0x72, 0x50, 0x02, 0xe3, 0xda, 0x94, 0x31, 0x46, 0x2b, 0x68, \ - 0xa4, 0xe4, 0x45, 0x41, 0xd9, 0xfb, 0x00, 0xe6, 0x39 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/test-ca.key */ -/* BEGIN FILE string macro TEST_CA_KEY_RSA_PEM tests/data_files/test-ca.key */ -#define TEST_CA_KEY_RSA_PEM \ - "-----BEGIN RSA PRIVATE KEY-----\r\n" \ - "Proc-Type: 4,ENCRYPTED\r\n" \ - "DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n" \ - "\r\n" \ - "9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n" \ - "7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n" \ - "Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n" \ - "PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n" \ - "GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n" \ - "gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n" \ - "QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n" \ - "PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n" \ - "vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n" \ - "WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n" \ - "JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n" \ - "KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n" \ - "Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n" \ - "9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n" \ - "iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n" \ - "tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n" \ - "P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n" \ - "1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n" \ - "nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n" \ - "X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n" \ - "rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n" \ - "L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n" \ - "I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n" \ - "wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" \ - "P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" \ - "-----END RSA PRIVATE KEY-----\r\n" -/* END FILE */ - -#define TEST_CA_PWD_RSA_PEM "PolarSSLTest" - -/* This was generated from test-ca.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CA_KEY_RSA_DER tests/data_files/test-ca.key.der */ -#define TEST_CA_KEY_RSA_DER { \ - 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ - 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, 0x86, 0xde, \ - 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, 0x99, 0xd4, \ - 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, 0x9b, 0xc5, \ - 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, 0xc0, 0x8d, \ - 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, 0x93, 0xe8, \ - 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, 0xe7, 0x40, \ - 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, 0xf9, 0x3e, \ - 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, 0x29, 0x00, \ - 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, 0xbd, 0x83, \ - 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, 0x60, 0xc3, \ - 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, 0x32, 0xbe, \ - 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, 0xfb, 0xf5, \ - 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, 0xee, 0xe2, \ - 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, 0x47, 0xb1, \ - 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, 0xf1, 0x79, \ - 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, 0x6f, 0x27, \ - 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, 0xa1, 0x30, \ - 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, 0x28, 0xd1, \ - 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, 0x09, 0xea, \ - 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, 0xc9, 0xab, \ - 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, 0x9e, 0x99, \ - 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ - 0x00, 0x3f, 0xf7, 0x07, 0xd3, 0x34, 0x6f, 0xdb, 0xc9, 0x37, 0xb7, 0x84, \ - 0xdc, 0x37, 0x45, 0xe1, 0x63, 0xad, 0xb8, 0xb6, 0x75, 0xb1, 0xc7, 0x35, \ - 0xb4, 0x77, 0x2a, 0x5b, 0x77, 0xf9, 0x7e, 0xe0, 0xc1, 0xa3, 0xd1, 0xb7, \ - 0xcb, 0xa9, 0x5a, 0xc1, 0x87, 0xda, 0x5a, 0xfa, 0x17, 0xe4, 0xd5, 0x38, \ - 0x03, 0xde, 0x68, 0x98, 0x81, 0xec, 0xb5, 0xf2, 0x2a, 0x8d, 0xe9, 0x2c, \ - 0xf3, 0xa6, 0xe5, 0x32, 0x17, 0x7f, 0x33, 0x81, 0xe8, 0x38, 0x72, 0xd5, \ - 0x9c, 0xfa, 0x4e, 0xfb, 0x26, 0xf5, 0x15, 0x0b, 0xaf, 0x84, 0x66, 0xab, \ - 0x02, 0xe0, 0x18, 0xd5, 0x91, 0x7c, 0xd6, 0x8f, 0xc9, 0x4b, 0x76, 0x08, \ - 0x2b, 0x1d, 0x81, 0x68, 0x30, 0xe1, 0xfa, 0x70, 0x6c, 0x13, 0x4e, 0x10, \ - 0x03, 0x35, 0x3e, 0xc5, 0xca, 0x58, 0x20, 0x8a, 0x21, 0x18, 0x38, 0xa0, \ - 0x0f, 0xed, 0xc4, 0xbb, 0x45, 0x6f, 0xf5, 0x84, 0x5b, 0xb0, 0xcf, 0x4e, \ - 0x9d, 0x58, 0x13, 0x6b, 0x35, 0x35, 0x69, 0xa1, 0xd2, 0xc4, 0xf2, 0xc1, \ - 0x48, 0x04, 0x20, 0x51, 0xb9, 0x6b, 0xa4, 0x5d, 0xa5, 0x4b, 0x84, 0x88, \ - 0x43, 0x48, 0x99, 0x2c, 0xbb, 0xa4, 0x97, 0xd6, 0xd6, 0x18, 0xf6, 0xec, \ - 0x5c, 0xd1, 0x31, 0x49, 0xc9, 0xf2, 0x8f, 0x0b, 0x4d, 0xef, 0x09, 0x02, \ - 0xfe, 0x7d, 0xfd, 0xbb, 0xaf, 0x2b, 0x83, 0x94, 0x22, 0xc4, 0xa7, 0x3e, \ - 0x66, 0xf5, 0xe0, 0x57, 0xdc, 0xf2, 0xed, 0x2c, 0x3e, 0x81, 0x74, 0x76, \ - 0x1e, 0x96, 0x6f, 0x74, 0x1e, 0x32, 0x0e, 0x14, 0x31, 0xd0, 0x74, 0xf0, \ - 0xf4, 0x07, 0xbd, 0xc3, 0xd1, 0x22, 0xc2, 0xa8, 0x95, 0x92, 0x06, 0x7f, \ - 0x43, 0x02, 0x91, 0xbc, 0xdd, 0x23, 0x01, 0x89, 0x94, 0x20, 0x44, 0x64, \ - 0xf5, 0x1d, 0x67, 0xd2, 0x8f, 0xe8, 0x69, 0xa5, 0x29, 0x25, 0xe6, 0x50, \ - 0x9c, 0xe3, 0xe9, 0xcb, 0x75, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x29, 0x3e, \ - 0xaa, 0x6b, 0xd5, 0x59, 0x1e, 0x9c, 0xe6, 0x47, 0xd5, 0xb6, 0xd7, 0xe3, \ - 0xf1, 0x8e, 0x9e, 0xe9, 0x83, 0x5f, 0x10, 0x9f, 0x63, 0xec, 0x04, 0x44, \ - 0xcc, 0x3f, 0xf8, 0xd9, 0x3a, 0x17, 0xe0, 0x4f, 0xfe, 0xd8, 0x4d, 0xcd, \ - 0x46, 0x54, 0x74, 0xbf, 0x0a, 0xc4, 0x67, 0x9c, 0xa7, 0xd8, 0x89, 0x65, \ - 0x4c, 0xfd, 0x58, 0x2a, 0x47, 0x0f, 0xf4, 0x37, 0xb6, 0x55, 0xb0, 0x1d, \ - 0xed, 0xa7, 0x39, 0xfc, 0x4f, 0xa3, 0xc4, 0x75, 0x3a, 0xa3, 0x98, 0xa7, \ - 0x45, 0xf5, 0x66, 0xcb, 0x7c, 0x65, 0xfb, 0x80, 0x23, 0xe6, 0xff, 0xfd, \ - 0x99, 0x1f, 0x8e, 0x6b, 0xff, 0x5e, 0x93, 0x66, 0xdf, 0x6c, 0x6f, 0xc3, \ - 0xf6, 0x38, 0x2e, 0xff, 0x69, 0xb5, 0xac, 0xae, 0xbb, 0xc6, 0x71, 0x16, \ - 0x6b, 0xd0, 0xf8, 0x22, 0xd9, 0xf8, 0xa2, 0x72, 0x20, 0xd2, 0xe2, 0x3a, \ - 0x70, 0x4b, 0xde, 0xab, 0x2f, 0x02, 0x81, 0x81, 0x00, 0xda, 0x51, 0x9b, \ - 0xb8, 0xb2, 0x2a, 0x14, 0x75, 0x58, 0x40, 0x8d, 0x27, 0x70, 0xfa, 0x31, \ - 0x48, 0xb0, 0x20, 0x21, 0x34, 0xfa, 0x4c, 0x57, 0xa8, 0x11, 0x88, 0xf3, \ - 0xa7, 0xae, 0x21, 0xe9, 0xb6, 0x2b, 0xd1, 0xcd, 0xa7, 0xf8, 0xd8, 0x0c, \ - 0x8a, 0x76, 0x22, 0x35, 0x44, 0xce, 0x3f, 0x25, 0x29, 0x83, 0x7d, 0x79, \ - 0xa7, 0x31, 0xd6, 0xec, 0xb2, 0xbf, 0xda, 0x34, 0xb6, 0xf6, 0xb2, 0x3b, \ - 0xf3, 0x78, 0x5a, 0x04, 0x83, 0x33, 0x3e, 0xa2, 0xe2, 0x81, 0x82, 0x13, \ - 0xd4, 0x35, 0x17, 0x63, 0x9b, 0x9e, 0xc4, 0x8d, 0x91, 0x4c, 0x03, 0x77, \ - 0xc7, 0x71, 0x5b, 0xee, 0x83, 0x6d, 0xd5, 0x78, 0x88, 0xf6, 0x2c, 0x79, \ - 0xc2, 0x4a, 0xb4, 0x79, 0x90, 0x70, 0xbf, 0xdf, 0x34, 0x56, 0x96, 0x71, \ - 0xe3, 0x0e, 0x68, 0x91, 0xbc, 0xea, 0xcb, 0x33, 0xc0, 0xbe, 0x45, 0xd7, \ - 0xfc, 0x30, 0xfd, 0x01, 0x3b, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x9f, 0x2a, \ - 0xb7, 0x38, 0x19, 0xc7, 0x17, 0x95, 0x73, 0x78, 0xae, 0xf5, 0xcb, 0x75, \ - 0x83, 0x7f, 0x19, 0x4b, 0xcb, 0x86, 0xfb, 0x4a, 0x15, 0x9a, 0xb6, 0x17, \ - 0x04, 0x49, 0x07, 0x8d, 0xf6, 0x66, 0x4a, 0x06, 0xf6, 0x05, 0xa7, 0xdf, \ - 0x66, 0x82, 0x3c, 0xff, 0xb6, 0x1d, 0x57, 0x89, 0x33, 0x5f, 0x9c, 0x05, \ - 0x75, 0x7f, 0xf3, 0x5d, 0xdc, 0x34, 0x65, 0x72, 0x85, 0x22, 0xa4, 0x14, \ - 0x1b, 0x41, 0xc3, 0xe4, 0xd0, 0x9e, 0x69, 0xd5, 0xeb, 0x38, 0x74, 0x70, \ - 0x43, 0xdc, 0xd9, 0x50, 0xe4, 0x97, 0x6d, 0x73, 0xd6, 0xfb, 0xc8, 0xa7, \ - 0xfa, 0xb4, 0xc2, 0xc4, 0x9d, 0x5d, 0x0c, 0xd5, 0x9f, 0x79, 0xb3, 0x54, \ - 0xc2, 0xb7, 0x6c, 0x3d, 0x7d, 0xcb, 0x2d, 0xf8, 0xc4, 0xf3, 0x78, 0x5a, \ - 0x33, 0x2a, 0xb8, 0x0c, 0x6d, 0x06, 0xfa, 0xf2, 0x62, 0xd3, 0x42, 0xd0, \ - 0xbd, 0xc8, 0x4a, 0xa5, 0x0d, 0x02, 0x81, 0x81, 0x00, 0xd4, 0xa9, 0x90, \ - 0x15, 0xde, 0xbf, 0x2c, 0xc4, 0x8d, 0x9d, 0xfb, 0xa1, 0xc2, 0xe4, 0x83, \ - 0xe3, 0x79, 0x65, 0x22, 0xd3, 0xb7, 0x49, 0x6c, 0x4d, 0x94, 0x1f, 0x22, \ - 0xb1, 0x60, 0xe7, 0x3a, 0x00, 0xb1, 0x38, 0xa2, 0xab, 0x0f, 0xb4, 0x6c, \ - 0xaa, 0xe7, 0x9e, 0x34, 0xe3, 0x7c, 0x40, 0x78, 0x53, 0xb2, 0xf9, 0x23, \ - 0xea, 0xa0, 0x9a, 0xea, 0x60, 0xc8, 0x8f, 0xa6, 0xaf, 0xdf, 0x29, 0x09, \ - 0x4b, 0x06, 0x1e, 0x31, 0xad, 0x17, 0xda, 0xd8, 0xd1, 0xe9, 0x33, 0xab, \ - 0x5b, 0x18, 0x08, 0x5b, 0x87, 0xf8, 0xa5, 0x1f, 0xfd, 0xbb, 0xdc, 0xd8, \ - 0xed, 0x97, 0x57, 0xe4, 0xc3, 0x73, 0xd6, 0xf0, 0x9e, 0x01, 0xa6, 0x9b, \ - 0x48, 0x8e, 0x7a, 0xb4, 0xbb, 0xe5, 0x88, 0x91, 0xc5, 0x2a, 0xdf, 0x4b, \ - 0xba, 0xd0, 0x8b, 0x3e, 0x03, 0x97, 0x77, 0x2f, 0x47, 0x7e, 0x51, 0x0c, \ - 0xae, 0x65, 0x8d, 0xde, 0x87, 0x02, 0x81, 0x80, 0x20, 0x24, 0x0f, 0xd2, \ - 0xaf, 0xc2, 0x28, 0x3b, 0x97, 0x20, 0xb2, 0x92, 0x49, 0xeb, 0x09, 0x68, \ - 0x40, 0xb2, 0xbe, 0xd1, 0xc3, 0x83, 0x94, 0x34, 0x38, 0xd6, 0xc9, 0xec, \ - 0x34, 0x09, 0xf9, 0x41, 0x6d, 0x5c, 0x42, 0x94, 0xf7, 0x04, 0xfc, 0x32, \ - 0x39, 0x69, 0xbc, 0x1c, 0xfb, 0x3e, 0x61, 0x98, 0xc0, 0x80, 0xd8, 0x36, \ - 0x47, 0xc3, 0x6d, 0xc2, 0x2e, 0xe7, 0x81, 0x2a, 0x17, 0x34, 0x64, 0x30, \ - 0x4e, 0x96, 0xbb, 0x26, 0x16, 0xb9, 0x41, 0x36, 0xfe, 0x8a, 0xd6, 0x53, \ - 0x7c, 0xaa, 0xec, 0x39, 0x42, 0x50, 0xef, 0xe3, 0xb3, 0x01, 0x28, 0x32, \ - 0xca, 0x6d, 0xf5, 0x9a, 0x1e, 0x9f, 0x37, 0xbe, 0xfe, 0x38, 0x20, 0x22, \ - 0x91, 0x8c, 0xcd, 0x95, 0x02, 0xf2, 0x4d, 0x6f, 0x1a, 0xb4, 0x43, 0xf0, \ - 0x19, 0xdf, 0x65, 0xc0, 0x92, 0xe7, 0x9d, 0x2f, 0x09, 0xe7, 0xec, 0x69, \ - 0xa8, 0xc2, 0x8f, 0x0d \ -} -/* END FILE */ - -/* - * Test server Certificates - * - * Test server certificates are defined for each choice - * of the following parameters: - * - PEM or DER encoding - * - SHA-1 or SHA-256 hash - * - RSA or EC key - * - * Things to add: - * - multiple EC curve types - */ - -/* This is taken from tests/data_files/server5.crt. */ -/* BEGIN FILE string macro TEST_SRV_CRT_EC_PEM tests/data_files/server5.crt */ -#define TEST_SRV_CRT_EC_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" \ - "MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" \ - "CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" \ - "2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" \ - "BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" \ - "PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" \ - "clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" \ - "CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" \ - "C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" \ - "fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/server5.crt.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_SRV_CRT_EC_DER tests/data_files/server5.crt.der */ -#define TEST_SRV_CRT_EC_DER { \ - 0x30, 0x82, 0x02, 0x1f, 0x30, 0x82, 0x01, 0xa5, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x09, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ - 0x3d, 0x04, 0x03, 0x02, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ - 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, \ - 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x33, 0x30, 0x39, 0x32, 0x34, 0x31, 0x35, 0x35, 0x32, 0x30, 0x34, \ - 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x39, 0x32, 0x32, 0x31, 0x35, 0x35, \ - 0x32, 0x30, 0x34, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x59, \ - 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, \ - 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, \ - 0x04, 0x37, 0xcc, 0x56, 0xd9, 0x76, 0x09, 0x1e, 0x5a, 0x72, 0x3e, 0xc7, \ - 0x59, 0x2d, 0xff, 0x20, 0x6e, 0xee, 0x7c, 0xf9, 0x06, 0x91, 0x74, 0xd0, \ - 0xad, 0x14, 0xb5, 0xf7, 0x68, 0x22, 0x59, 0x62, 0x92, 0x4e, 0xe5, 0x00, \ - 0xd8, 0x23, 0x11, 0xff, 0xea, 0x2f, 0xd2, 0x34, 0x5d, 0x5d, 0x16, 0xbd, \ - 0x8a, 0x88, 0xc2, 0x6b, 0x77, 0x0d, 0x55, 0xcd, 0x8a, 0x2a, 0x0e, 0xfa, \ - 0x01, 0xc8, 0xb4, 0xed, 0xff, 0xa3, 0x81, 0x9d, 0x30, 0x81, 0x9a, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, \ - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x50, 0x61, 0xa5, \ - 0x8f, 0xd4, 0x07, 0xd9, 0xd7, 0x82, 0x01, 0x0c, 0xe5, 0x65, 0x7f, 0x8c, \ - 0x63, 0x46, 0xa7, 0x13, 0xbe, 0x30, 0x6e, 0x06, 0x03, 0x55, 0x1d, 0x23, \ - 0x04, 0x67, 0x30, 0x65, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, 0x01, \ - 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, 0xfb, \ - 0x36, 0x7c, 0xa1, 0x42, 0xa4, 0x40, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \ - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ - 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \ - 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, \ - 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x82, 0x09, \ - 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, 0x30, 0x0a, 0x06, \ - 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x68, 0x00, \ - 0x30, 0x65, 0x02, 0x31, 0x00, 0x9a, 0x2c, 0x5c, 0xd7, 0xa6, 0xdb, 0xa2, \ - 0xe5, 0x64, 0x0d, 0xf0, 0xb9, 0x4e, 0xdd, 0xd7, 0x61, 0xd6, 0x13, 0x31, \ - 0xc7, 0xab, 0x73, 0x80, 0xbb, 0xd3, 0xd3, 0x73, 0x13, 0x54, 0xad, 0x92, \ - 0x0b, 0x5d, 0xab, 0xd0, 0xbc, 0xf7, 0xae, 0x2f, 0xe6, 0xa1, 0x21, 0x29, \ - 0x35, 0x95, 0xaa, 0x3e, 0x39, 0x02, 0x30, 0x21, 0x36, 0x7f, 0x9d, 0xc6, \ - 0x5d, 0xc6, 0x0b, 0xab, 0x27, 0xf2, 0x25, 0x1d, 0x3b, 0xf1, 0xcf, 0xf1, \ - 0x35, 0x25, 0x14, 0xe7, 0xe5, 0xf1, 0x97, 0xb5, 0x59, 0xe3, 0x5e, 0x15, \ - 0x7c, 0x66, 0xb9, 0x90, 0x7b, 0xc7, 0x01, 0x10, 0x4f, 0x73, 0xc6, 0x00, \ - 0x21, 0x52, 0x2a, 0x0e, 0xf1, 0xc7, 0xd5 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/server5.key. */ -/* BEGIN FILE string macro TEST_SRV_KEY_EC_PEM tests/data_files/server5.key */ -#define TEST_SRV_KEY_EC_PEM \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" \ - "AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" \ - "6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/server5.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_SRV_KEY_EC_DER tests/data_files/server5.key.der */ -#define TEST_SRV_KEY_EC_DER { \ - 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xf1, 0x2a, 0x13, 0x20, 0x76, \ - 0x02, 0x70, 0xa8, 0x3c, 0xbf, 0xfd, 0x53, 0xf6, 0x03, 0x1e, 0xf7, 0x6a, \ - 0x5d, 0x86, 0xc8, 0xa2, 0x04, 0xf2, 0xc3, 0x0c, 0xa9, 0xeb, 0xf5, 0x1f, \ - 0x0f, 0x0e, 0xa7, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x37, 0xcc, 0x56, \ - 0xd9, 0x76, 0x09, 0x1e, 0x5a, 0x72, 0x3e, 0xc7, 0x59, 0x2d, 0xff, 0x20, \ - 0x6e, 0xee, 0x7c, 0xf9, 0x06, 0x91, 0x74, 0xd0, 0xad, 0x14, 0xb5, 0xf7, \ - 0x68, 0x22, 0x59, 0x62, 0x92, 0x4e, 0xe5, 0x00, 0xd8, 0x23, 0x11, 0xff, \ - 0xea, 0x2f, 0xd2, 0x34, 0x5d, 0x5d, 0x16, 0xbd, 0x8a, 0x88, 0xc2, 0x6b, \ - 0x77, 0x0d, 0x55, 0xcd, 0x8a, 0x2a, 0x0e, 0xfa, 0x01, 0xc8, 0xb4, 0xed, \ - 0xff \ -} -/* END FILE */ - -/* This is taken from tests/data_files/server2-sha256.crt. */ -/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA256_PEM tests/data_files/server2-sha256.crt */ -#define TEST_SRV_CRT_RSA_SHA256_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ - "AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ - "owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ - "NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ - "tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ - "hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ - "HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ - "VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ - "FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJh\r\n" \ - "Pqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6U\r\n" \ - "HoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq9\r\n" \ - "1C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sv\r\n" \ - "a1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0\r\n" \ - "e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbo\r\n" \ - "pMZqLmbBm/7WPLc=\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is taken from tests/data_files/server2-sha256.crt.der. */ -/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA256_DER tests/data_files/server2-sha256.crt.der */ -#define TEST_SRV_CRT_RSA_SHA256_DER { \ - 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \ - 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \ - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \ - 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \ - 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \ - 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \ - 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \ - 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \ - 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \ - 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \ - 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \ - 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \ - 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \ - 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \ - 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \ - 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \ - 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \ - 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \ - 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \ - 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \ - 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \ - 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \ - 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \ - 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \ - 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \ - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \ - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \ - 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \ - 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \ - 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \ - 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \ - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, \ - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x2e, 0x3a, 0xe4, 0x52, 0x61, \ - 0x3e, 0xa7, 0xa5, 0xef, 0x32, 0x67, 0x80, 0x72, 0x07, 0x26, 0xba, 0xa3, \ - 0xff, 0x05, 0x40, 0xc4, 0x60, 0x05, 0x39, 0x31, 0x77, 0xf7, 0xa5, 0xca, \ - 0x01, 0x31, 0x80, 0xa7, 0xe1, 0xd1, 0x0a, 0xa2, 0x7c, 0xd5, 0x1c, 0xba, \ - 0xd0, 0x23, 0x4a, 0xd6, 0x30, 0xf3, 0x93, 0xc7, 0x6f, 0xe8, 0xce, 0x94, \ - 0x1e, 0x84, 0xbb, 0x44, 0x81, 0x62, 0x33, 0xff, 0x6b, 0x5d, 0x00, 0x9b, \ - 0x25, 0xf8, 0x8f, 0x0f, 0x9c, 0x4c, 0x4d, 0xe8, 0xd9, 0xa7, 0x99, 0xf9, \ - 0x51, 0x81, 0xc0, 0x9b, 0x1b, 0x31, 0x0d, 0xa6, 0xb3, 0x7c, 0x0e, 0x45, \ - 0xb8, 0x18, 0x64, 0x7e, 0x89, 0x0a, 0x2b, 0xa8, 0xc3, 0xe0, 0x4a, 0xbd, \ - 0xd4, 0x2f, 0x78, 0xc4, 0x62, 0x9b, 0xe9, 0x7e, 0x3f, 0x56, 0x46, 0x8f, \ - 0x17, 0xb7, 0x2a, 0xa0, 0x10, 0x70, 0xfd, 0xb1, 0xf1, 0x6b, 0x05, 0xdc, \ - 0xd1, 0x41, 0x0f, 0x8e, 0xa6, 0xb2, 0x88, 0x1a, 0x42, 0x61, 0x4f, 0xeb, \ - 0x26, 0x85, 0x59, 0x80, 0xba, 0x85, 0x54, 0xfe, 0xcf, 0xc7, 0x7b, 0x2f, \ - 0x6b, 0x59, 0xce, 0xac, 0xdc, 0x7c, 0xac, 0xf3, 0xc8, 0xd6, 0x12, 0x7e, \ - 0x64, 0xe8, 0x3c, 0x99, 0xa8, 0x8f, 0x4f, 0x11, 0xd9, 0x9c, 0x15, 0x4b, \ - 0x6a, 0x44, 0x92, 0x2d, 0x0c, 0xbf, 0xb1, 0x67, 0x96, 0xc9, 0xac, 0xce, \ - 0xd5, 0x19, 0xeb, 0x6f, 0x18, 0xeb, 0x6e, 0x04, 0x2d, 0x60, 0xac, 0xf4, \ - 0x7b, 0x79, 0xf0, 0x1a, 0x9b, 0xb5, 0xc3, 0x5d, 0xef, 0x7d, 0xc9, 0x05, \ - 0x99, 0x44, 0x81, 0x84, 0x75, 0xc7, 0xec, 0x00, 0x12, 0xfc, 0x7a, 0x4a, \ - 0x0b, 0x82, 0x07, 0xec, 0x6d, 0x86, 0x02, 0x4d, 0xfe, 0x9f, 0xc8, 0x92, \ - 0x48, 0xde, 0xf5, 0xb1, 0x9c, 0xe9, 0xc6, 0x89, 0xd0, 0xc1, 0x56, 0xe8, \ - 0xa4, 0xc6, 0x6a, 0x2e, 0x66, 0xc1, 0x9b, 0xfe, 0xd6, 0x3c, 0xb7 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/server2.crt. */ -/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA1_PEM tests/data_files/server2.crt */ -#define TEST_SRV_CRT_RSA_SHA1_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ - "AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ - "owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ - "NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ - "tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ - "hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ - "HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ - "VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ - "FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJklg3Q4\r\n" \ - "cB7v7BzsxM/vLyKccO6op0/gZzM4ghuLq2Y32kl0sM6kSNUUmduuq3u/+GmUZN2A\r\n" \ - "O/7c+Hw7hDFEIvZk98aBGjCLqn3DmgHIv8ToQ67nellQxx2Uj309PdgjNi/r9HOc\r\n" \ - "KNAYPbBcg6MJGWWj2TI6vNaceios/DhOYx5V0j5nfqSJ/pnU0g9Ign2LAhgYpGJE\r\n" \ - "iEM9wW7hEMkwmk0h/sqZsrJsGH5YsF/VThSq/JVO1e2mZH2vruyZKJVBq+8tDNYp\r\n" \ - "HkK6tSyVYQhzIt3StMJWKMl/o5k2AYz6tSC164+1oG+ML3LWg8XrGKa91H4UOKap\r\n" \ - "Awgk0+4m0T25cNs=\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is taken from tests/data_files/server2.crt.der. */ -/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA1_DER tests/data_files/server2.crt.der */ -#define TEST_SRV_CRT_RSA_SHA1_DER { \ - 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \ - 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \ - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \ - 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \ - 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \ - 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \ - 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \ - 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \ - 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \ - 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \ - 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \ - 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \ - 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \ - 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \ - 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \ - 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \ - 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \ - 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \ - 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \ - 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \ - 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \ - 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \ - 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \ - 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \ - 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \ - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \ - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \ - 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \ - 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \ - 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \ - 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \ - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, \ - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x99, 0x25, 0x83, 0x74, 0x38, \ - 0x70, 0x1e, 0xef, 0xec, 0x1c, 0xec, 0xc4, 0xcf, 0xef, 0x2f, 0x22, 0x9c, \ - 0x70, 0xee, 0xa8, 0xa7, 0x4f, 0xe0, 0x67, 0x33, 0x38, 0x82, 0x1b, 0x8b, \ - 0xab, 0x66, 0x37, 0xda, 0x49, 0x74, 0xb0, 0xce, 0xa4, 0x48, 0xd5, 0x14, \ - 0x99, 0xdb, 0xae, 0xab, 0x7b, 0xbf, 0xf8, 0x69, 0x94, 0x64, 0xdd, 0x80, \ - 0x3b, 0xfe, 0xdc, 0xf8, 0x7c, 0x3b, 0x84, 0x31, 0x44, 0x22, 0xf6, 0x64, \ - 0xf7, 0xc6, 0x81, 0x1a, 0x30, 0x8b, 0xaa, 0x7d, 0xc3, 0x9a, 0x01, 0xc8, \ - 0xbf, 0xc4, 0xe8, 0x43, 0xae, 0xe7, 0x7a, 0x59, 0x50, 0xc7, 0x1d, 0x94, \ - 0x8f, 0x7d, 0x3d, 0x3d, 0xd8, 0x23, 0x36, 0x2f, 0xeb, 0xf4, 0x73, 0x9c, \ - 0x28, 0xd0, 0x18, 0x3d, 0xb0, 0x5c, 0x83, 0xa3, 0x09, 0x19, 0x65, 0xa3, \ - 0xd9, 0x32, 0x3a, 0xbc, 0xd6, 0x9c, 0x7a, 0x2a, 0x2c, 0xfc, 0x38, 0x4e, \ - 0x63, 0x1e, 0x55, 0xd2, 0x3e, 0x67, 0x7e, 0xa4, 0x89, 0xfe, 0x99, 0xd4, \ - 0xd2, 0x0f, 0x48, 0x82, 0x7d, 0x8b, 0x02, 0x18, 0x18, 0xa4, 0x62, 0x44, \ - 0x88, 0x43, 0x3d, 0xc1, 0x6e, 0xe1, 0x10, 0xc9, 0x30, 0x9a, 0x4d, 0x21, \ - 0xfe, 0xca, 0x99, 0xb2, 0xb2, 0x6c, 0x18, 0x7e, 0x58, 0xb0, 0x5f, 0xd5, \ - 0x4e, 0x14, 0xaa, 0xfc, 0x95, 0x4e, 0xd5, 0xed, 0xa6, 0x64, 0x7d, 0xaf, \ - 0xae, 0xec, 0x99, 0x28, 0x95, 0x41, 0xab, 0xef, 0x2d, 0x0c, 0xd6, 0x29, \ - 0x1e, 0x42, 0xba, 0xb5, 0x2c, 0x95, 0x61, 0x08, 0x73, 0x22, 0xdd, 0xd2, \ - 0xb4, 0xc2, 0x56, 0x28, 0xc9, 0x7f, 0xa3, 0x99, 0x36, 0x01, 0x8c, 0xfa, \ - 0xb5, 0x20, 0xb5, 0xeb, 0x8f, 0xb5, 0xa0, 0x6f, 0x8c, 0x2f, 0x72, 0xd6, \ - 0x83, 0xc5, 0xeb, 0x18, 0xa6, 0xbd, 0xd4, 0x7e, 0x14, 0x38, 0xa6, 0xa9, \ - 0x03, 0x08, 0x24, 0xd3, 0xee, 0x26, 0xd1, 0x3d, 0xb9, 0x70, 0xdb \ -} -/* END FILE */ - -/* This is taken from tests/data_files/server2.key. */ -/* BEGIN FILE string macro TEST_SRV_KEY_RSA_PEM tests/data_files/server2.key */ -#define TEST_SRV_KEY_RSA_PEM \ - "-----BEGIN RSA PRIVATE KEY-----\r\n" \ - "MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" \ - "lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" \ - "2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" \ - "Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" \ - "GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" \ - "y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" \ - "++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" \ - "Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" \ - "/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" \ - "WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" \ - "GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" \ - "TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" \ - "CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" \ - "nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" \ - "AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" \ - "sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" \ - "mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" \ - "BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" \ - "whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" \ - "vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" \ - "3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" \ - "3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" \ - "ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" \ - "4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" \ - "TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" \ - "-----END RSA PRIVATE KEY-----\r\n" -/* END FILE */ - -/* This was generated from tests/data_files/server2.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_SRV_KEY_RSA_DER tests/data_files/server2.key.der */ -#define TEST_SRV_KEY_RSA_DER { \ - 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ - 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, \ - 0xb8, 0x99, 0xac, 0x0e, 0x78, 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, \ - 0x16, 0xd0, 0x5a, 0xe4, 0xcd, 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, \ - 0x96, 0xa7, 0x52, 0xb4, 0x90, 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, \ - 0xfc, 0xb6, 0x34, 0xac, 0x24, 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, \ - 0xb0, 0x28, 0x7d, 0xa1, 0xda, 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, \ - 0xfe, 0xc1, 0x04, 0x52, 0xb3, 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, \ - 0xd8, 0x90, 0xc1, 0x61, 0xb4, 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, \ - 0xab, 0x74, 0x5e, 0x07, 0x7d, 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, \ - 0xd9, 0x0d, 0x1c, 0x2d, 0x49, 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, \ - 0x0b, 0x8a, 0x4f, 0x69, 0x0c, 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, \ - 0x66, 0x7d, 0xae, 0x54, 0x2b, 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, \ - 0xc3, 0xcd, 0x40, 0x49, 0x08, 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, \ - 0x46, 0xbf, 0xd0, 0xb8, 0xaa, 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, \ - 0x1e, 0x44, 0x18, 0x0f, 0x0f, 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, \ - 0x18, 0xc6, 0x62, 0x2f, 0xc7, 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, \ - 0x27, 0x89, 0x29, 0x01, 0xc5, 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, \ - 0x4a, 0x0e, 0xef, 0xd6, 0xde, 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, \ - 0x7a, 0xc4, 0x02, 0x3c, 0x9a, 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, \ - 0xcb, 0x73, 0x4b, 0x52, 0x96, 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, \ - 0x39, 0x5a, 0xd3, 0x0f, 0xb0, 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, \ - 0x12, 0x01, 0x30, 0x97, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ - 0x01, 0x00, 0x97, 0x47, 0x44, 0xbc, 0x10, 0x81, 0xc5, 0x18, 0xe4, 0x59, \ - 0xfb, 0xe0, 0x2d, 0x3a, 0x0e, 0x9e, 0x10, 0xdc, 0x43, 0xfb, 0x15, 0x6c, \ - 0xd1, 0xfd, 0x48, 0x78, 0x6c, 0xf9, 0xed, 0x38, 0xe8, 0xdd, 0x09, 0xd7, \ - 0x5f, 0xb5, 0x41, 0x64, 0xd7, 0x63, 0xfa, 0x9d, 0x44, 0x0a, 0xf8, 0x42, \ - 0x13, 0xf1, 0xbb, 0x5e, 0x79, 0x20, 0x53, 0x98, 0x4b, 0x65, 0x7f, 0x86, \ - 0x67, 0x48, 0xe4, 0xcf, 0xfb, 0x6a, 0x24, 0xe2, 0x34, 0xbd, 0x14, 0x9d, \ - 0x2c, 0x16, 0xe2, 0xa4, 0x79, 0xd6, 0xa2, 0xec, 0x81, 0x43, 0x87, 0xbf, \ - 0x03, 0x5c, 0x88, 0x25, 0xd9, 0x41, 0xb6, 0xa5, 0xf1, 0x27, 0x52, 0x84, \ - 0xfe, 0x2b, 0x6e, 0x1d, 0x16, 0xcd, 0x73, 0x88, 0xf8, 0x90, 0xbf, 0x19, \ - 0xfe, 0xbe, 0xa9, 0xbf, 0x09, 0xd3, 0x23, 0x43, 0xd2, 0xc7, 0x61, 0x2a, \ - 0xb3, 0x4e, 0x3c, 0x61, 0xd4, 0xbd, 0xd8, 0xb4, 0xfa, 0xa8, 0x0b, 0xf8, \ - 0x7e, 0x56, 0xcd, 0x0f, 0x13, 0x27, 0xda, 0xe6, 0x3b, 0xb3, 0x8c, 0x9c, \ - 0x4b, 0x84, 0x3c, 0xc3, 0x52, 0x57, 0x9c, 0x27, 0x9a, 0x02, 0x76, 0x26, \ - 0x59, 0x82, 0x39, 0xc3, 0x13, 0xbe, 0x6e, 0xf4, 0x44, 0x2d, 0x1d, 0x8c, \ - 0x73, 0x3e, 0x43, 0x99, 0x59, 0xcb, 0xf2, 0x34, 0x72, 0x9a, 0x5e, 0xa5, \ - 0xeb, 0x9f, 0x36, 0x6d, 0x2b, 0xf9, 0xa2, 0xe7, 0xd1, 0x78, 0x52, 0x1b, \ - 0xc8, 0xf6, 0x5b, 0x41, 0x69, 0x57, 0x81, 0x89, 0xe9, 0xbb, 0xa1, 0xde, \ - 0x19, 0x37, 0x3b, 0x13, 0x5c, 0xca, 0x61, 0x01, 0x86, 0xff, 0xdf, 0x83, \ - 0x41, 0x49, 0x7f, 0xd6, 0xf4, 0x2e, 0x08, 0xfa, 0x90, 0xc2, 0x7c, 0xb4, \ - 0xb5, 0x0a, 0x17, 0xdb, 0x0e, 0x6d, 0x75, 0x8a, 0x5d, 0x31, 0xd5, 0x66, \ - 0xfb, 0x39, 0x0b, 0xb5, 0xb6, 0xa3, 0xcd, 0xd4, 0xef, 0x88, 0x92, 0x5a, \ - 0x4d, 0x6c, 0xcb, 0xea, 0x5b, 0x79, 0x02, 0x81, 0x81, 0x00, 0xdf, 0x3a, \ - 0xf9, 0x25, 0x5e, 0x24, 0x37, 0x26, 0x40, 0x97, 0x2f, 0xe0, 0x4a, 0xba, \ - 0x52, 0x1b, 0x51, 0xaf, 0x84, 0x06, 0x32, 0x24, 0x0c, 0xcf, 0x44, 0xa8, \ - 0x77, 0xa7, 0xad, 0xb5, 0x8c, 0x58, 0xcc, 0xc8, 0x31, 0xb7, 0x0d, 0xbc, \ - 0x08, 0x8a, 0xe0, 0xa6, 0x8c, 0xc2, 0x73, 0xe5, 0x1a, 0x64, 0x92, 0xe8, \ - 0xed, 0x4c, 0x6f, 0x0b, 0xa6, 0xa7, 0xf3, 0x9a, 0xf5, 0x6f, 0x69, 0xca, \ - 0x3c, 0x22, 0xd0, 0x15, 0xa8, 0x20, 0x27, 0x41, 0xf8, 0x43, 0x42, 0x7f, \ - 0xb1, 0x93, 0xa1, 0x04, 0x85, 0xda, 0xa0, 0x1c, 0xd6, 0xc6, 0xf7, 0x8a, \ - 0x9e, 0xea, 0x5c, 0x78, 0xa7, 0x55, 0xc4, 0x6b, 0x05, 0x8b, 0xc0, 0x83, \ - 0xcb, 0xce, 0x83, 0x05, 0xf8, 0xb2, 0x16, 0x2b, 0xdf, 0x06, 0x3f, 0xb8, \ - 0xec, 0x16, 0xda, 0x43, 0x33, 0xc1, 0x8f, 0xb0, 0xb8, 0xac, 0xae, 0xd4, \ - 0x94, 0xb8, 0xda, 0x6f, 0x6a, 0xc3, 0x02, 0x81, 0x81, 0x00, 0xdd, 0xae, \ - 0x00, 0xcd, 0xa0, 0x72, 0x1a, 0x05, 0x8a, 0xee, 0x2f, 0xd4, 0x71, 0x4b, \ - 0xf0, 0x3e, 0xe5, 0xc1, 0xe1, 0x29, 0x8b, 0xa6, 0x67, 0x30, 0x98, 0xe7, \ - 0x12, 0xef, 0xdd, 0x12, 0x01, 0x90, 0x24, 0x58, 0xf0, 0x76, 0x92, 0xe7, \ - 0x3d, 0xbb, 0x23, 0xe1, 0xce, 0xf9, 0xa1, 0xd4, 0x38, 0x1b, 0x3f, 0x20, \ - 0xb3, 0x0f, 0x65, 0x6a, 0x8f, 0x55, 0x57, 0x36, 0xee, 0xb2, 0x84, 0x44, \ - 0xfc, 0x91, 0x88, 0xe1, 0xa4, 0xdd, 0x3b, 0x4a, 0x40, 0x4d, 0x7c, 0x86, \ - 0xed, 0xe1, 0xb5, 0x42, 0xef, 0xb9, 0x61, 0xcd, 0x58, 0x19, 0x77, 0x02, \ - 0xae, 0x58, 0x80, 0xdb, 0x13, 0x3d, 0xc7, 0x1f, 0x9d, 0xed, 0xff, 0xac, \ - 0x98, 0xfc, 0xcd, 0xf9, 0x62, 0x04, 0x83, 0x91, 0x89, 0x0d, 0x86, 0x43, \ - 0x8c, 0x0c, 0xc7, 0x1b, 0x90, 0x4d, 0xbe, 0x2f, 0xc5, 0x7c, 0xcd, 0x42, \ - 0xf5, 0xd3, 0xad, 0x8e, 0xfd, 0x9d, 0x02, 0x81, 0x80, 0x17, 0x4b, 0x79, \ - 0x2a, 0x6c, 0x1b, 0x8d, 0x61, 0xc1, 0x85, 0xc5, 0x6a, 0x3b, 0x82, 0x1c, \ - 0x05, 0x5b, 0xcd, 0xdc, 0x12, 0x25, 0x73, 0x5b, 0x9e, 0xd9, 0x84, 0x57, \ - 0x10, 0x39, 0x71, 0x63, 0x96, 0xf4, 0xaf, 0xc3, 0x78, 0x5d, 0xc7, 0x8c, \ - 0x80, 0xa9, 0x96, 0xd7, 0xc3, 0x87, 0x02, 0x96, 0x71, 0x7e, 0x5f, 0x2e, \ - 0x3c, 0x36, 0xae, 0x59, 0x92, 0xd7, 0x3a, 0x09, 0x78, 0xb9, 0xea, 0x6f, \ - 0xc2, 0x16, 0x42, 0xdc, 0x4b, 0x96, 0xad, 0x2c, 0xb2, 0x20, 0x23, 0x61, \ - 0x2d, 0x8d, 0xb5, 0x02, 0x1e, 0xe1, 0x6c, 0x81, 0x01, 0x3c, 0x5d, 0xcb, \ - 0xdd, 0x9b, 0x0e, 0xc0, 0x2f, 0x94, 0x12, 0xb2, 0xfe, 0x75, 0x75, 0x8b, \ - 0x74, 0x1e, 0x7a, 0x26, 0x0c, 0xb7, 0x81, 0x96, 0x81, 0x79, 0x6e, 0xdb, \ - 0xbc, 0x3a, 0xc4, 0x9e, 0x87, 0x09, 0x6e, 0xa0, 0xa6, 0xec, 0x8b, 0xa4, \ - 0x85, 0x71, 0xce, 0x04, 0xaf, 0x02, 0x81, 0x81, 0x00, 0xc2, 0xa7, 0x47, \ - 0x07, 0x48, 0x6a, 0xc8, 0xd4, 0xb3, 0x20, 0xe1, 0x98, 0xee, 0xff, 0x5a, \ - 0x6f, 0x30, 0x7a, 0xa5, 0x47, 0x40, 0xdc, 0x16, 0x62, 0x42, 0xf1, 0x2c, \ - 0xdc, 0xb8, 0xc7, 0x55, 0xde, 0x07, 0x3c, 0x9d, 0xb1, 0xd0, 0xdf, 0x02, \ - 0x82, 0xb0, 0x48, 0x58, 0xe1, 0x34, 0xab, 0xcf, 0xb4, 0x85, 0x23, 0x26, \ - 0x78, 0x4f, 0x7a, 0x59, 0x6f, 0xfb, 0x8c, 0x3d, 0xdf, 0x3d, 0x6c, 0x02, \ - 0x47, 0x9c, 0xe5, 0x5e, 0x49, 0xf1, 0x05, 0x0b, 0x1f, 0xbf, 0x48, 0x0f, \ - 0xdc, 0x10, 0xb9, 0x3d, 0x1d, 0x10, 0x77, 0x2a, 0x73, 0xf9, 0xdf, 0xbd, \ - 0xcd, 0xf3, 0x1f, 0xeb, 0x6e, 0x64, 0xca, 0x2b, 0x78, 0x4f, 0xf8, 0x73, \ - 0xc2, 0x10, 0xef, 0x79, 0x95, 0x33, 0x1e, 0x79, 0x35, 0x09, 0xff, 0x88, \ - 0x1b, 0xb4, 0x3e, 0x4c, 0xe1, 0x27, 0x2e, 0x75, 0x80, 0x58, 0x11, 0x03, \ - 0x21, 0x23, 0x96, 0x9a, 0xb5, 0x02, 0x81, 0x80, 0x05, 0x12, 0x64, 0x71, \ - 0x83, 0x00, 0x1c, 0xfe, 0xef, 0x83, 0xea, 0xdd, 0x2c, 0xc8, 0x2c, 0x00, \ - 0x62, 0x1e, 0x8f, 0x3a, 0xdb, 0x1c, 0xab, 0xd6, 0x34, 0x8b, 0xd1, 0xb2, \ - 0x5a, 0x4f, 0x3d, 0x37, 0x38, 0x02, 0xe0, 0xd7, 0x70, 0xc1, 0xb0, 0x47, \ - 0xe0, 0x08, 0x1a, 0x84, 0xec, 0x48, 0xc5, 0x7c, 0x76, 0x83, 0x12, 0x67, \ - 0xab, 0x7c, 0x9f, 0x90, 0x97, 0xc8, 0x8f, 0x07, 0xf4, 0xb3, 0x60, 0xf2, \ - 0x3f, 0x49, 0x18, 0xdb, 0x2e, 0x94, 0x6b, 0x53, 0x9e, 0xa2, 0x63, 0xde, \ - 0x63, 0xd9, 0xab, 0x21, 0x2e, 0x2d, 0x0a, 0xe0, 0xd0, 0xe8, 0xba, 0xc4, \ - 0x4c, 0x1e, 0xa5, 0xf5, 0x51, 0xa8, 0xc4, 0x92, 0xf8, 0x7f, 0x21, 0xe7, \ - 0x65, 0xbf, 0x0b, 0xe6, 0x01, 0xaf, 0x9c, 0x1d, 0x5b, 0x6c, 0x3f, 0x1c, \ - 0x2f, 0xa6, 0x0f, 0x68, 0x38, 0x8e, 0x85, 0xc4, 0x6c, 0x78, 0x2f, 0x6f, \ - 0x06, 0x21, 0x2e, 0x56 \ -} -/* END FILE */ - -/* - * Test client Certificates - * - * Test client certificates are defined for each choice - * of the following parameters: - * - PEM or DER encoding - * - RSA or EC key - * - * Things to add: - * - hash type - * - multiple EC curve types - */ - -/* This is taken from tests/data_files/cli2.crt. */ -/* BEGIN FILE string macro TEST_CLI_CRT_EC_PEM tests/data_files/cli2.crt */ -#define TEST_CLI_CRT_EC_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIB3zCCAWOgAwIBAgIBDTAMBggqhkjOPQQDAgUAMD4xCzAJBgNVBAYTAk5MMREw\r\n" \ - "DwYDVQQKDAhQb2xhclNTTDEcMBoGA1UEAwwTUG9sYXJTU0wgVGVzdCBFQyBDQTAe\r\n" \ - "Fw0xOTAyMTAxNDQ0MDBaFw0yOTAyMTAxNDQ0MDBaMEExCzAJBgNVBAYTAk5MMREw\r\n" \ - "DwYDVQQKDAhQb2xhclNTTDEfMB0GA1UEAwwWUG9sYXJTU0wgVGVzdCBDbGllbnQg\r\n" \ - "MjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFflrrFz39Osu5O4gf8Sru7mU6zO\r\n" \ - "VVP2NA7MLuNjJQvfmOLzXGA2lsDVGBRw5X+f1UtFGOWwbNVc+JaPh3Cj5MejTTBL\r\n" \ - "MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMB8GA1Ud\r\n" \ - "IwQYMBaAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8MAwGCCqGSM49BAMCBQADaAAwZQIx\r\n" \ - "AMqme4DKMldUlplDET9Q6Eptre7uUWKhsLOF+zPkKDlfzpIkJYEFgcloDHGYw80u\r\n" \ - "IgIwNftyPXsabTqMM7iEHgVpX/GRozKklY9yQI/5eoA6gGW7Y+imuGR/oao5ySOb\r\n" \ - "a9Vk\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/cli2.crt.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CLI_CRT_EC_DER tests/data_files/cli2.crt.der */ -#define TEST_CLI_CRT_EC_DER { \ - 0x30, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01, 0x63, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x0d, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ - 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \ - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ - 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \ - 0x03, 0x0c, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \ - 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, \ - 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, \ - 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, \ - 0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, 0x09, \ - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ - 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, \ - 0x03, 0x0c, 0x16, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \ - 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, \ - 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, \ - 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, 0xb1, 0x73, 0xdf, 0xd3, 0xac, \ - 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, 0xee, 0xe6, 0x53, 0xac, 0xce, \ - 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, 0xe3, 0x63, 0x25, 0x0b, 0xdf, \ - 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, 0xc0, 0xd5, 0x18, 0x14, 0x70, \ - 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, \ - 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, 0xc7, 0xa3, 0x4d, 0x30, 0x4b, \ - 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, \ - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7a, 0x00, \ - 0x5f, 0x86, 0x64, 0xfc, 0xe0, 0x5d, 0xe5, 0x11, 0x10, 0x3b, 0xb2, 0xe6, \ - 0x3b, 0xc4, 0x26, 0x3f, 0xcf, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, \ - 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, \ - 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, \ - 0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x31, \ - 0x00, 0xca, 0xa6, 0x7b, 0x80, 0xca, 0x32, 0x57, 0x54, 0x96, 0x99, 0x43, \ - 0x11, 0x3f, 0x50, 0xe8, 0x4a, 0x6d, 0xad, 0xee, 0xee, 0x51, 0x62, 0xa1, \ - 0xb0, 0xb3, 0x85, 0xfb, 0x33, 0xe4, 0x28, 0x39, 0x5f, 0xce, 0x92, 0x24, \ - 0x25, 0x81, 0x05, 0x81, 0xc9, 0x68, 0x0c, 0x71, 0x98, 0xc3, 0xcd, 0x2e, \ - 0x22, 0x02, 0x30, 0x35, 0xfb, 0x72, 0x3d, 0x7b, 0x1a, 0x6d, 0x3a, 0x8c, \ - 0x33, 0xb8, 0x84, 0x1e, 0x05, 0x69, 0x5f, 0xf1, 0x91, 0xa3, 0x32, 0xa4, \ - 0x95, 0x8f, 0x72, 0x40, 0x8f, 0xf9, 0x7a, 0x80, 0x3a, 0x80, 0x65, 0xbb, \ - 0x63, 0xe8, 0xa6, 0xb8, 0x64, 0x7f, 0xa1, 0xaa, 0x39, 0xc9, 0x23, 0x9b, \ - 0x6b, 0xd5, 0x64 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/cli2.key. */ -/* BEGIN FILE string macro TEST_CLI_KEY_EC_PEM tests/data_files/cli2.key */ -#define TEST_CLI_KEY_EC_PEM \ - "-----BEGIN EC PRIVATE KEY-----\r\n" \ - "MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n" \ - "AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" \ - "wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" \ - "-----END EC PRIVATE KEY-----\r\n" -/* END FILE */ - -/* This is generated from tests/data_files/cli2.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CLI_KEY_EC_DER tests/data_files/cli2.key.der */ -#define TEST_CLI_KEY_EC_DER { \ - 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xf6, 0xf7, 0x86, 0x64, 0xf1, \ - 0x67, 0x7f, 0xe6, 0x64, 0x8d, 0xef, 0xca, 0x4e, 0xe9, 0xdd, 0x4d, 0xf0, \ - 0x05, 0xff, 0x96, 0x22, 0x8a, 0x7a, 0x84, 0x38, 0x64, 0x17, 0x32, 0x61, \ - 0x98, 0xb7, 0x2a, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ - 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, \ - 0xb1, 0x73, 0xdf, 0xd3, 0xac, 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, \ - 0xee, 0xe6, 0x53, 0xac, 0xce, 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, \ - 0xe3, 0x63, 0x25, 0x0b, 0xdf, 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, \ - 0xc0, 0xd5, 0x18, 0x14, 0x70, 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, \ - 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, \ - 0xc7 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/cli-rsa-sha256.crt. */ -/* BEGIN FILE string macro TEST_CLI_CRT_RSA_PEM tests/data_files/cli-rsa-sha256.crt */ -#define TEST_CLI_CRT_RSA_PEM \ - "-----BEGIN CERTIFICATE-----\r\n" \ - "MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ - "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ - "MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" \ - "A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" \ - "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" \ - "M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" \ - "1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" \ - "MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" \ - "4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" \ - "/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" \ - "o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n" \ - "BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQsFAAOC\r\n" \ - "AQEAXidv1d4pLlBiKWED95rMycBdgDcgyNqJxakFkRfRyA2y1mlyTn7uBXRkNLY5\r\n" \ - "ZFzK82GCjk2Q2OD4RZSCPAJJqLpHHU34t71ciffvy2KK81YvrxczRhMAE64i+qna\r\n" \ - "yP3Td2XuWJR05PVPoSemsNELs9gWttdnYy3ce+EY2Y0n7Rsi7982EeLIAA7H6ca4\r\n" \ - "2Es/NUH//JZJT32OP0doMxeDRA+vplkKqTLLWf7dX26LIriBkBaRCgR5Yv9LBPFc\r\n" \ - "NOtpzu/LbrY7QFXKJMI+JXDudCsOn8KCmiA4d6Emisqfh3V3485l7HEQNcvLTxlD\r\n" \ - "6zDQyi0/ykYUYZkwQTK1N2Nvlw==\r\n" \ - "-----END CERTIFICATE-----\r\n" -/* END FILE */ - -/* This was generated from tests/data_files/cli-rsa-sha256.crt.der - using `xxd -i.` */ -/* BEGIN FILE binary macro TEST_CLI_CRT_RSA_DER tests/data_files/cli-rsa-sha256.crt.der */ -#define TEST_CLI_CRT_RSA_DER { \ - 0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0x27, 0xa0, 0x03, 0x02, 0x01, \ - 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ - 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ - 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ - 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ - 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ - 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ - 0x34, 0x30, 0x36, 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ - 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ - 0x53, 0x4c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ - 0x11, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x6c, \ - 0x69, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, \ - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, \ - 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, \ - 0x01, 0x01, 0x00, 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, \ - 0x45, 0xd9, 0x14, 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, \ - 0x33, 0xad, 0x0d, 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, \ - 0xcc, 0x66, 0x85, 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, \ - 0x9e, 0x0a, 0x6e, 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, \ - 0x93, 0x86, 0x49, 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, \ - 0xd4, 0x2f, 0x77, 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, \ - 0x48, 0x70, 0xf5, 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, \ - 0xe6, 0x43, 0xea, 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, \ - 0x57, 0x4e, 0xa9, 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, \ - 0x32, 0x30, 0xd5, 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, \ - 0x5f, 0xf9, 0x3d, 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, \ - 0xfb, 0xe5, 0x0c, 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, \ - 0x7f, 0xca, 0xad, 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, \ - 0xe0, 0x9b, 0xf8, 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, \ - 0x04, 0x66, 0xc7, 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, \ - 0x06, 0x67, 0xf4, 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, \ - 0x3c, 0x8b, 0x35, 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, \ - 0xfc, 0x36, 0x6b, 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, \ - 0x00, 0xcf, 0xaf, 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, \ - 0xe7, 0x50, 0x71, 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, \ - 0xe4, 0xc4, 0xfd, 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, \ - 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, \ - 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, \ - 0x04, 0x14, 0x71, 0xa1, 0x00, 0x73, 0x72, 0x40, 0x2f, 0x54, 0x76, 0x5e, \ - 0x33, 0xfc, 0x52, 0x8f, 0xbc, 0xf1, 0xdd, 0x6b, 0x46, 0x21, 0x30, 0x1f, \ - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb4, \ - 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, 0xa6, 0x95, \ - 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, \ - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, \ - 0x01, 0x01, 0x00, 0x5e, 0x27, 0x6f, 0xd5, 0xde, 0x29, 0x2e, 0x50, 0x62, \ - 0x29, 0x61, 0x03, 0xf7, 0x9a, 0xcc, 0xc9, 0xc0, 0x5d, 0x80, 0x37, 0x20, \ - 0xc8, 0xda, 0x89, 0xc5, 0xa9, 0x05, 0x91, 0x17, 0xd1, 0xc8, 0x0d, 0xb2, \ - 0xd6, 0x69, 0x72, 0x4e, 0x7e, 0xee, 0x05, 0x74, 0x64, 0x34, 0xb6, 0x39, \ - 0x64, 0x5c, 0xca, 0xf3, 0x61, 0x82, 0x8e, 0x4d, 0x90, 0xd8, 0xe0, 0xf8, \ - 0x45, 0x94, 0x82, 0x3c, 0x02, 0x49, 0xa8, 0xba, 0x47, 0x1d, 0x4d, 0xf8, \ - 0xb7, 0xbd, 0x5c, 0x89, 0xf7, 0xef, 0xcb, 0x62, 0x8a, 0xf3, 0x56, 0x2f, \ - 0xaf, 0x17, 0x33, 0x46, 0x13, 0x00, 0x13, 0xae, 0x22, 0xfa, 0xa9, 0xda, \ - 0xc8, 0xfd, 0xd3, 0x77, 0x65, 0xee, 0x58, 0x94, 0x74, 0xe4, 0xf5, 0x4f, \ - 0xa1, 0x27, 0xa6, 0xb0, 0xd1, 0x0b, 0xb3, 0xd8, 0x16, 0xb6, 0xd7, 0x67, \ - 0x63, 0x2d, 0xdc, 0x7b, 0xe1, 0x18, 0xd9, 0x8d, 0x27, 0xed, 0x1b, 0x22, \ - 0xef, 0xdf, 0x36, 0x11, 0xe2, 0xc8, 0x00, 0x0e, 0xc7, 0xe9, 0xc6, 0xb8, \ - 0xd8, 0x4b, 0x3f, 0x35, 0x41, 0xff, 0xfc, 0x96, 0x49, 0x4f, 0x7d, 0x8e, \ - 0x3f, 0x47, 0x68, 0x33, 0x17, 0x83, 0x44, 0x0f, 0xaf, 0xa6, 0x59, 0x0a, \ - 0xa9, 0x32, 0xcb, 0x59, 0xfe, 0xdd, 0x5f, 0x6e, 0x8b, 0x22, 0xb8, 0x81, \ - 0x90, 0x16, 0x91, 0x0a, 0x04, 0x79, 0x62, 0xff, 0x4b, 0x04, 0xf1, 0x5c, \ - 0x34, 0xeb, 0x69, 0xce, 0xef, 0xcb, 0x6e, 0xb6, 0x3b, 0x40, 0x55, 0xca, \ - 0x24, 0xc2, 0x3e, 0x25, 0x70, 0xee, 0x74, 0x2b, 0x0e, 0x9f, 0xc2, 0x82, \ - 0x9a, 0x20, 0x38, 0x77, 0xa1, 0x26, 0x8a, 0xca, 0x9f, 0x87, 0x75, 0x77, \ - 0xe3, 0xce, 0x65, 0xec, 0x71, 0x10, 0x35, 0xcb, 0xcb, 0x4f, 0x19, 0x43, \ - 0xeb, 0x30, 0xd0, 0xca, 0x2d, 0x3f, 0xca, 0x46, 0x14, 0x61, 0x99, 0x30, \ - 0x41, 0x32, 0xb5, 0x37, 0x63, 0x6f, 0x97 \ -} -/* END FILE */ - -/* This is taken from tests/data_files/cli-rsa.key. */ -/* BEGIN FILE string macro TEST_CLI_KEY_RSA_PEM tests/data_files/cli-rsa.key */ -#define TEST_CLI_KEY_RSA_PEM \ - "-----BEGIN RSA PRIVATE KEY-----\r\n" \ - "MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n" \ - "B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n" \ - "bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n" \ - "Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n" \ - "7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n" \ - "dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n" \ - "yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n" \ - "4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n" \ - "ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n" \ - "zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n" \ - "l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n" \ - "DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" \ - "VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" \ - "Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" \ - "wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" \ - "c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" \ - "33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" \ - "ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" \ - "BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" \ - "KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" \ - "UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" \ - "7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" \ - "gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" \ - "bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" \ - "8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" \ - "-----END RSA PRIVATE KEY-----\r\n"/* END FILE */ - -/* This was generated from tests/data_files/cli-rsa.key.der using `xxd -i`. */ -/* BEGIN FILE binary macro TEST_CLI_KEY_RSA_DER tests/data_files/cli-rsa.key.der */ -#define TEST_CLI_KEY_RSA_DER { \ - 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ - 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, 0x45, 0xd9, 0x14, \ - 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, 0x33, 0xad, 0x0d, \ - 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, 0xcc, 0x66, 0x85, \ - 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, 0x9e, 0x0a, 0x6e, \ - 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, 0x93, 0x86, 0x49, \ - 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, 0xd4, 0x2f, 0x77, \ - 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, 0x48, 0x70, 0xf5, \ - 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, 0xe6, 0x43, 0xea, \ - 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, 0x57, 0x4e, 0xa9, \ - 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, 0x32, 0x30, 0xd5, \ - 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, 0x5f, 0xf9, 0x3d, \ - 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, 0xfb, 0xe5, 0x0c, \ - 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, 0x7f, 0xca, 0xad, \ - 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, 0xe0, 0x9b, 0xf8, \ - 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, 0x04, 0x66, 0xc7, \ - 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, 0x06, 0x67, 0xf4, \ - 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, 0x3c, 0x8b, 0x35, \ - 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, 0xfc, 0x36, 0x6b, \ - 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, 0x00, 0xcf, 0xaf, \ - 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, 0xe7, 0x50, 0x71, \ - 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, 0xe4, 0xc4, 0xfd, \ - 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ - 0x00, 0x67, 0x4d, 0xb5, 0xf6, 0x03, 0x89, 0xaa, 0x7a, 0x6f, 0x3b, 0x2d, \ - 0xca, 0x10, 0xa2, 0x23, 0xc9, 0xbd, 0x4e, 0xda, 0xe1, 0x67, 0x0e, 0x0c, \ - 0x8a, 0xc6, 0x84, 0x68, 0xdf, 0xe5, 0x97, 0x75, 0xd2, 0x8d, 0xa3, 0x86, \ - 0xd9, 0xdb, 0xd5, 0xeb, 0x13, 0x19, 0x08, 0xc5, 0x7e, 0xe5, 0x37, 0x97, \ - 0x0c, 0x73, 0x80, 0x66, 0x76, 0x35, 0xf1, 0x88, 0xb5, 0xf2, 0xfc, 0xf3, \ - 0xe1, 0x4b, 0x76, 0x4e, 0x73, 0x45, 0xce, 0x2c, 0xc2, 0x10, 0x26, 0x0d, \ - 0x68, 0x0d, 0x9f, 0x49, 0x3d, 0xd6, 0x80, 0x89, 0xe7, 0xc5, 0x49, 0x15, \ - 0xdd, 0x85, 0xc0, 0xc8, 0xfe, 0x82, 0x37, 0x12, 0x5a, 0x0a, 0x6b, 0xf6, \ - 0x68, 0x0d, 0x32, 0x16, 0xbd, 0xa4, 0x15, 0x54, 0x9e, 0x68, 0xa1, 0xad, \ - 0xca, 0x6b, 0xe5, 0x8c, 0xda, 0x76, 0x35, 0x59, 0x2f, 0x9b, 0xb4, 0xe1, \ - 0xf1, 0xf0, 0x50, 0x04, 0xee, 0xc8, 0xec, 0x05, 0xe1, 0xcf, 0x8d, 0xe4, \ - 0xd2, 0x64, 0x7b, 0x5e, 0x63, 0xe0, 0x7b, 0x07, 0xbc, 0x02, 0x96, 0x4e, \ - 0x1b, 0x78, 0x6c, 0xb6, 0x43, 0x9a, 0x32, 0xf6, 0xd6, 0x02, 0xf5, 0x80, \ - 0xcc, 0x26, 0x6e, 0xa5, 0xd0, 0xe3, 0x65, 0x88, 0xce, 0x26, 0xa9, 0x40, \ - 0xe1, 0xe1, 0x00, 0xe0, 0x7f, 0x3f, 0xc3, 0xb1, 0x7c, 0xde, 0xbe, 0x42, \ - 0xba, 0x07, 0x81, 0x13, 0xc2, 0xe0, 0x11, 0x11, 0x23, 0x2c, 0xf8, 0xb2, \ - 0x7a, 0x3a, 0xd4, 0xe4, 0x7d, 0x5f, 0xb9, 0xb1, 0x18, 0xfa, 0x1d, 0x1d, \ - 0x97, 0x91, 0xd9, 0x04, 0x9e, 0xbc, 0xc9, 0xb4, 0xd7, 0x7d, 0x0e, 0x54, \ - 0xf6, 0x8f, 0xd0, 0x28, 0x0d, 0xdd, 0x77, 0x4b, 0x68, 0x04, 0x48, 0x61, \ - 0x75, 0x15, 0x03, 0x1b, 0x35, 0xad, 0x8e, 0xfc, 0x24, 0x11, 0x07, 0xea, \ - 0x17, 0x5a, 0xde, 0x19, 0x68, 0xff, 0xb6, 0x87, 0x7f, 0x80, 0x2a, 0x5f, \ - 0x0c, 0x58, 0xba, 0x5f, 0x41, 0x02, 0x81, 0x81, 0x00, 0xe3, 0x03, 0xaf, \ - 0xfe, 0x98, 0xd2, 0x0b, 0x7b, 0x72, 0xe9, 0x3b, 0x8e, 0xbc, 0xa5, 0xf6, \ - 0xac, 0xe5, 0x22, 0x06, 0xb2, 0xd7, 0x5e, 0xfd, 0x89, 0x4b, 0x16, 0x67, \ - 0x32, 0x83, 0x22, 0x58, 0x8e, 0x62, 0xa4, 0xb4, 0x2d, 0xf9, 0x16, 0x13, \ - 0x54, 0xf6, 0x9f, 0x2f, 0xf9, 0xbb, 0x0e, 0x7e, 0x8c, 0x6f, 0x08, 0xda, \ - 0xc8, 0xe9, 0x1c, 0x66, 0x10, 0x70, 0x93, 0x90, 0x8d, 0xcf, 0x90, 0x3a, \ - 0x43, 0x89, 0x49, 0xeb, 0x83, 0x2a, 0xfe, 0x5a, 0x87, 0xce, 0x74, 0x42, \ - 0x41, 0x0d, 0x8c, 0x73, 0x51, 0xbc, 0x7b, 0x20, 0xc5, 0xfd, 0xf6, 0x0b, \ - 0x65, 0xed, 0xa9, 0x2e, 0xfc, 0x0f, 0xf5, 0x50, 0xf9, 0x8d, 0x37, 0x36, \ - 0x9a, 0x20, 0xdf, 0xc3, 0xe3, 0x27, 0xbc, 0x98, 0x72, 0xc1, 0x14, 0x4b, \ - 0x71, 0xe9, 0x83, 0x14, 0xff, 0x24, 0xe2, 0x14, 0x15, 0xb6, 0x6f, 0x0f, \ - 0x32, 0x9d, 0xd9, 0x98, 0xd1, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x0c, 0xfb, \ - 0xc3, 0x33, 0x9b, 0x47, 0x88, 0x27, 0xf2, 0x26, 0xde, 0xeb, 0x5e, 0xee, \ - 0x40, 0xf6, 0x63, 0x5b, 0x35, 0x23, 0xf5, 0xd5, 0x07, 0x61, 0xdf, 0xa2, \ - 0x9f, 0x58, 0x30, 0x04, 0x22, 0x2b, 0xb4, 0xd9, 0xda, 0x46, 0x7f, 0x48, \ - 0xf5, 0x4f, 0xd0, 0xea, 0xd7, 0xa0, 0x45, 0x8a, 0x62, 0x8b, 0x8c, 0xac, \ - 0x73, 0x5e, 0xfa, 0x36, 0x65, 0x3e, 0xba, 0x6c, 0xba, 0x5e, 0x6b, 0x92, \ - 0x29, 0x5e, 0x6a, 0x0f, 0xd6, 0xd2, 0xa5, 0x95, 0x86, 0xda, 0x72, 0xc5, \ - 0x9e, 0xc9, 0x6b, 0x37, 0x5e, 0x4b, 0x9b, 0x77, 0xe1, 0x67, 0x1a, 0x1e, \ - 0x30, 0xd8, 0x41, 0x68, 0x40, 0xd3, 0x9c, 0xb4, 0xf6, 0xeb, 0x2a, 0x22, \ - 0xdf, 0x78, 0x29, 0xd2, 0x64, 0x92, 0x5b, 0x2f, 0x78, 0x64, 0x4a, 0xa2, \ - 0xa6, 0x6b, 0x3e, 0x50, 0xb1, 0x7a, 0xb1, 0x8d, 0x59, 0xb4, 0x55, 0xba, \ - 0xb6, 0x91, 0x85, 0xa3, 0x2f, 0x02, 0x81, 0x80, 0x10, 0x1e, 0x19, 0xe7, \ - 0xbc, 0x97, 0xe5, 0x22, 0xcd, 0xa4, 0xcb, 0x8a, 0xb5, 0xd0, 0x1e, 0xb4, \ - 0x65, 0xcc, 0x45, 0xa7, 0x7a, 0xed, 0x0e, 0x99, 0x29, 0xd0, 0x9c, 0x61, \ - 0x14, 0xb8, 0x62, 0x8b, 0x31, 0x6b, 0xba, 0x33, 0x2d, 0x65, 0x28, 0xd8, \ - 0x36, 0x6e, 0x54, 0xec, 0xa9, 0x20, 0x3d, 0x51, 0xe1, 0x2c, 0x42, 0xc4, \ - 0x52, 0xf0, 0xa6, 0x3a, 0x72, 0x93, 0xb7, 0x86, 0xa9, 0xfe, 0xf6, 0x74, \ - 0x07, 0x12, 0x4d, 0x7b, 0x51, 0x99, 0x1f, 0x7a, 0x56, 0xe9, 0x20, 0x2f, \ - 0x18, 0x34, 0x29, 0x97, 0xdb, 0x06, 0xee, 0xeb, 0xbf, 0xbd, 0x31, 0x4f, \ - 0xfa, 0x50, 0xb1, 0xba, 0x49, 0xb3, 0xc4, 0x1d, 0x03, 0xae, 0xb0, 0xdc, \ - 0xbe, 0x8a, 0xc4, 0x90, 0xa3, 0x28, 0x9b, 0xb6, 0x42, 0x09, 0x1b, 0xd6, \ - 0x29, 0x9b, 0x19, 0xe9, 0x87, 0x87, 0xd9, 0x9f, 0x35, 0x05, 0xab, 0x91, \ - 0x8f, 0x6d, 0x7c, 0x91, 0x02, 0x81, 0x81, 0x00, 0x94, 0x57, 0xf0, 0xe0, \ - 0x28, 0xfd, 0xbd, 0xf3, 0x9c, 0x43, 0x4d, 0x3e, 0xfd, 0x37, 0x4f, 0x23, \ - 0x52, 0x8d, 0xe1, 0x4c, 0xfe, 0x4c, 0x55, 0x80, 0x82, 0xba, 0x3f, 0xfe, \ - 0x51, 0xe1, 0x30, 0xd5, 0x3b, 0xd9, 0x73, 0x1d, 0xcb, 0x25, 0xbc, 0xbb, \ - 0x3f, 0xa5, 0xda, 0x77, 0xa6, 0xb5, 0xfc, 0x1a, 0xaf, 0x79, 0xa1, 0xb2, \ - 0x14, 0xa2, 0x1f, 0x10, 0x52, 0x1a, 0x05, 0x40, 0x48, 0xb6, 0x4f, 0x34, \ - 0xd6, 0xc0, 0xc3, 0xa4, 0x36, 0x98, 0x73, 0x88, 0x0b, 0xd3, 0x45, 0xdc, \ - 0xee, 0x51, 0x6e, 0x04, 0x73, 0x99, 0x93, 0x12, 0x58, 0x96, 0xcb, 0x39, \ - 0x42, 0xb1, 0xa9, 0xb8, 0xe1, 0x25, 0xf5, 0x9c, 0x14, 0xb7, 0x92, 0x2b, \ - 0x14, 0xb0, 0x5d, 0x61, 0xa2, 0xaa, 0x34, 0x7c, 0xcd, 0x54, 0x2d, 0x69, \ - 0x08, 0xf7, 0xdb, 0xfc, 0x9c, 0x87, 0xe8, 0x3a, 0xf6, 0x1d, 0x4c, 0x6a, \ - 0x83, 0x15, 0x30, 0x01, 0x02, 0x81, 0x81, 0x00, 0x9c, 0x53, 0xa1, 0xb6, \ - 0x2f, 0xc0, 0x06, 0xf5, 0xdf, 0x5c, 0xd1, 0x4a, 0x4e, 0xc8, 0xbd, 0x6d, \ - 0x32, 0xf1, 0x5e, 0xe5, 0x3b, 0x70, 0xd0, 0xa8, 0xe5, 0x41, 0x57, 0x6c, \ - 0x87, 0x53, 0x0f, 0xeb, 0x28, 0xa0, 0x62, 0x8f, 0x43, 0x62, 0xec, 0x2e, \ - 0x6c, 0x71, 0x55, 0x5b, 0x6a, 0xf4, 0x74, 0x14, 0xea, 0x7a, 0x03, 0xf6, \ - 0xfc, 0xa4, 0xce, 0xc4, 0xac, 0xda, 0x1d, 0xf0, 0xb5, 0xa9, 0xfd, 0x11, \ - 0x18, 0x3b, 0x14, 0xa0, 0x90, 0x8d, 0x26, 0xb7, 0x75, 0x73, 0x0a, 0x02, \ - 0x2c, 0x6f, 0x0f, 0xd8, 0x41, 0x78, 0xc3, 0x73, 0x81, 0xac, 0xaa, 0xaf, \ - 0xf2, 0xee, 0x32, 0xb5, 0x8d, 0x05, 0xf9, 0x59, 0x5a, 0x9e, 0x3e, 0x65, \ - 0x9b, 0x74, 0xda, 0xa0, 0x74, 0x95, 0x17, 0x5f, 0x8d, 0x58, 0xfc, 0x8e, \ - 0x4e, 0x2c, 0x1e, 0xbc, 0x81, 0x02, 0x18, 0xac, 0x12, 0xc6, 0xf9, 0x64, \ - 0x8b, 0x87, 0xc3, 0x00 \ -} -/* END FILE */ - -/* - * - * Test certificates and keys as C variables - * - */ - -/* - * CA - */ - -const char mbedtls_test_ca_crt_ec_pem[] = TEST_CA_CRT_EC_PEM; -const char mbedtls_test_ca_key_ec_pem[] = TEST_CA_KEY_EC_PEM; -const char mbedtls_test_ca_pwd_ec_pem[] = TEST_CA_PWD_EC_PEM; -const char mbedtls_test_ca_key_rsa_pem[] = TEST_CA_KEY_RSA_PEM; -const char mbedtls_test_ca_pwd_rsa_pem[] = TEST_CA_PWD_RSA_PEM; -const char mbedtls_test_ca_crt_rsa_sha1_pem[] = TEST_CA_CRT_RSA_SHA1_PEM; -const char mbedtls_test_ca_crt_rsa_sha256_pem[] = TEST_CA_CRT_RSA_SHA256_PEM; - -const unsigned char mbedtls_test_ca_crt_ec_der[] = TEST_CA_CRT_EC_DER; -const unsigned char mbedtls_test_ca_key_ec_der[] = TEST_CA_KEY_EC_DER; -const unsigned char mbedtls_test_ca_key_rsa_der[] = TEST_CA_KEY_RSA_DER; -const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[] = - TEST_CA_CRT_RSA_SHA1_DER; -const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[] = - TEST_CA_CRT_RSA_SHA256_DER; - -const size_t mbedtls_test_ca_crt_ec_pem_len = - sizeof( mbedtls_test_ca_crt_ec_pem ); -const size_t mbedtls_test_ca_key_ec_pem_len = - sizeof( mbedtls_test_ca_key_ec_pem ); -const size_t mbedtls_test_ca_pwd_ec_pem_len = - sizeof( mbedtls_test_ca_pwd_ec_pem ) - 1; -const size_t mbedtls_test_ca_key_rsa_pem_len = - sizeof( mbedtls_test_ca_key_rsa_pem ); -const size_t mbedtls_test_ca_pwd_rsa_pem_len = - sizeof( mbedtls_test_ca_pwd_rsa_pem ) - 1; -const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len = - sizeof( mbedtls_test_ca_crt_rsa_sha1_pem ); -const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len = - sizeof( mbedtls_test_ca_crt_rsa_sha256_pem ); - -const size_t mbedtls_test_ca_crt_ec_der_len = - sizeof( mbedtls_test_ca_crt_ec_der ); -const size_t mbedtls_test_ca_key_ec_der_len = - sizeof( mbedtls_test_ca_key_ec_der ); -const size_t mbedtls_test_ca_pwd_ec_der_len = 0; -const size_t mbedtls_test_ca_key_rsa_der_len = - sizeof( mbedtls_test_ca_key_rsa_der ); -const size_t mbedtls_test_ca_pwd_rsa_der_len = 0; -const size_t mbedtls_test_ca_crt_rsa_sha1_der_len = - sizeof( mbedtls_test_ca_crt_rsa_sha1_der ); -const size_t mbedtls_test_ca_crt_rsa_sha256_der_len = - sizeof( mbedtls_test_ca_crt_rsa_sha256_der ); - -/* - * Server - */ - -const char mbedtls_test_srv_crt_ec_pem[] = TEST_SRV_CRT_EC_PEM; -const char mbedtls_test_srv_key_ec_pem[] = TEST_SRV_KEY_EC_PEM; -const char mbedtls_test_srv_pwd_ec_pem[] = ""; -const char mbedtls_test_srv_key_rsa_pem[] = TEST_SRV_KEY_RSA_PEM; -const char mbedtls_test_srv_pwd_rsa_pem[] = ""; -const char mbedtls_test_srv_crt_rsa_sha1_pem[] = TEST_SRV_CRT_RSA_SHA1_PEM; -const char mbedtls_test_srv_crt_rsa_sha256_pem[] = TEST_SRV_CRT_RSA_SHA256_PEM; - -const unsigned char mbedtls_test_srv_crt_ec_der[] = TEST_SRV_CRT_EC_DER; -const unsigned char mbedtls_test_srv_key_ec_der[] = TEST_SRV_KEY_EC_DER; -const unsigned char mbedtls_test_srv_key_rsa_der[] = TEST_SRV_KEY_RSA_DER; -const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[] = - TEST_SRV_CRT_RSA_SHA1_DER; -const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[] = - TEST_SRV_CRT_RSA_SHA256_DER; - -const size_t mbedtls_test_srv_crt_ec_pem_len = - sizeof( mbedtls_test_srv_crt_ec_pem ); -const size_t mbedtls_test_srv_key_ec_pem_len = - sizeof( mbedtls_test_srv_key_ec_pem ); -const size_t mbedtls_test_srv_pwd_ec_pem_len = - sizeof( mbedtls_test_srv_pwd_ec_pem ) - 1; -const size_t mbedtls_test_srv_key_rsa_pem_len = - sizeof( mbedtls_test_srv_key_rsa_pem ); -const size_t mbedtls_test_srv_pwd_rsa_pem_len = - sizeof( mbedtls_test_srv_pwd_rsa_pem ) - 1; -const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len = - sizeof( mbedtls_test_srv_crt_rsa_sha1_pem ); -const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len = - sizeof( mbedtls_test_srv_crt_rsa_sha256_pem ); - -const size_t mbedtls_test_srv_crt_ec_der_len = - sizeof( mbedtls_test_srv_crt_ec_der ); -const size_t mbedtls_test_srv_key_ec_der_len = - sizeof( mbedtls_test_srv_key_ec_der ); -const size_t mbedtls_test_srv_pwd_ec_der_len = 0; -const size_t mbedtls_test_srv_key_rsa_der_len = - sizeof( mbedtls_test_srv_key_rsa_der ); -const size_t mbedtls_test_srv_pwd_rsa_der_len = 0; -const size_t mbedtls_test_srv_crt_rsa_sha1_der_len = - sizeof( mbedtls_test_srv_crt_rsa_sha1_der ); -const size_t mbedtls_test_srv_crt_rsa_sha256_der_len = - sizeof( mbedtls_test_srv_crt_rsa_sha256_der ); - -/* - * Client - */ - -const char mbedtls_test_cli_crt_ec_pem[] = TEST_CLI_CRT_EC_PEM; -const char mbedtls_test_cli_key_ec_pem[] = TEST_CLI_KEY_EC_PEM; -const char mbedtls_test_cli_pwd_ec_pem[] = ""; -const char mbedtls_test_cli_key_rsa_pem[] = TEST_CLI_KEY_RSA_PEM; -const char mbedtls_test_cli_pwd_rsa_pem[] = ""; -const char mbedtls_test_cli_crt_rsa_pem[] = TEST_CLI_CRT_RSA_PEM; - -const unsigned char mbedtls_test_cli_crt_ec_der[] = TEST_CLI_CRT_EC_DER; -const unsigned char mbedtls_test_cli_key_ec_der[] = TEST_CLI_KEY_EC_DER; -const unsigned char mbedtls_test_cli_key_rsa_der[] = TEST_CLI_KEY_RSA_DER; -const unsigned char mbedtls_test_cli_crt_rsa_der[] = TEST_CLI_CRT_RSA_DER; - -const size_t mbedtls_test_cli_crt_ec_pem_len = - sizeof( mbedtls_test_cli_crt_ec_pem ); -const size_t mbedtls_test_cli_key_ec_pem_len = - sizeof( mbedtls_test_cli_key_ec_pem ); -const size_t mbedtls_test_cli_pwd_ec_pem_len = - sizeof( mbedtls_test_cli_pwd_ec_pem ) - 1; -const size_t mbedtls_test_cli_key_rsa_pem_len = - sizeof( mbedtls_test_cli_key_rsa_pem ); -const size_t mbedtls_test_cli_pwd_rsa_pem_len = - sizeof( mbedtls_test_cli_pwd_rsa_pem ) - 1; -const size_t mbedtls_test_cli_crt_rsa_pem_len = - sizeof( mbedtls_test_cli_crt_rsa_pem ); - -const size_t mbedtls_test_cli_crt_ec_der_len = - sizeof( mbedtls_test_cli_crt_ec_der ); -const size_t mbedtls_test_cli_key_ec_der_len = - sizeof( mbedtls_test_cli_key_ec_der ); -const size_t mbedtls_test_cli_key_rsa_der_len = - sizeof( mbedtls_test_cli_key_rsa_der ); -const size_t mbedtls_test_cli_crt_rsa_der_len = - sizeof( mbedtls_test_cli_crt_rsa_der ); - -/* - * - * Definitions of test CRTs without specification of all parameters, choosing - * them automatically according to the config. For example, mbedtls_test_ca_crt - * is one of mbedtls_test_ca_crt_{rsa|ec}_{sha1|sha256}_{pem|der}. - * - */ - -/* - * Dispatch between PEM and DER according to config - */ - -#if defined(MBEDTLS_PEM_PARSE_C) - -/* PEM encoded test CA certificates and keys */ - -#define TEST_CA_KEY_RSA TEST_CA_KEY_RSA_PEM -#define TEST_CA_PWD_RSA TEST_CA_PWD_RSA_PEM -#define TEST_CA_CRT_RSA_SHA256 TEST_CA_CRT_RSA_SHA256_PEM -#define TEST_CA_CRT_RSA_SHA1 TEST_CA_CRT_RSA_SHA1_PEM -#define TEST_CA_KEY_EC TEST_CA_KEY_EC_PEM -#define TEST_CA_PWD_EC TEST_CA_PWD_EC_PEM -#define TEST_CA_CRT_EC TEST_CA_CRT_EC_PEM - -/* PEM encoded test server certificates and keys */ - -#define TEST_SRV_KEY_RSA TEST_SRV_KEY_RSA_PEM -#define TEST_SRV_PWD_RSA "" -#define TEST_SRV_CRT_RSA_SHA256 TEST_SRV_CRT_RSA_SHA256_PEM -#define TEST_SRV_CRT_RSA_SHA1 TEST_SRV_CRT_RSA_SHA1_PEM -#define TEST_SRV_KEY_EC TEST_SRV_KEY_EC_PEM -#define TEST_SRV_PWD_EC "" -#define TEST_SRV_CRT_EC TEST_SRV_CRT_EC_PEM - -/* PEM encoded test client certificates and keys */ - -#define TEST_CLI_KEY_RSA TEST_CLI_KEY_RSA_PEM -#define TEST_CLI_PWD_RSA "" -#define TEST_CLI_CRT_RSA TEST_CLI_CRT_RSA_PEM -#define TEST_CLI_KEY_EC TEST_CLI_KEY_EC_PEM -#define TEST_CLI_PWD_EC "" -#define TEST_CLI_CRT_EC TEST_CLI_CRT_EC_PEM - -#else /* MBEDTLS_PEM_PARSE_C */ - -/* DER encoded test CA certificates and keys */ - -#define TEST_CA_KEY_RSA TEST_CA_KEY_RSA_DER -#define TEST_CA_PWD_RSA "" -#define TEST_CA_CRT_RSA_SHA256 TEST_CA_CRT_RSA_SHA256_DER -#define TEST_CA_CRT_RSA_SHA1 TEST_CA_CRT_RSA_SHA1_DER -#define TEST_CA_KEY_EC TEST_CA_KEY_EC_DER -#define TEST_CA_PWD_EC "" -#define TEST_CA_CRT_EC TEST_CA_CRT_EC_DER - -/* DER encoded test server certificates and keys */ - -#define TEST_SRV_KEY_RSA TEST_SRV_KEY_RSA_DER -#define TEST_SRV_PWD_RSA "" -#define TEST_SRV_CRT_RSA_SHA256 TEST_SRV_CRT_RSA_SHA256_DER -#define TEST_SRV_CRT_RSA_SHA1 TEST_SRV_CRT_RSA_SHA1_DER -#define TEST_SRV_KEY_EC TEST_SRV_KEY_EC_DER -#define TEST_SRV_PWD_EC "" -#define TEST_SRV_CRT_EC TEST_SRV_CRT_EC_DER - -/* DER encoded test client certificates and keys */ - -#define TEST_CLI_KEY_RSA TEST_CLI_KEY_RSA_DER -#define TEST_CLI_PWD_RSA "" -#define TEST_CLI_CRT_RSA TEST_CLI_CRT_RSA_DER -#define TEST_CLI_KEY_EC TEST_CLI_KEY_EC_DER -#define TEST_CLI_PWD_EC "" -#define TEST_CLI_CRT_EC TEST_CLI_CRT_EC_DER - -#endif /* MBEDTLS_PEM_PARSE_C */ - -const char mbedtls_test_ca_key_rsa[] = TEST_CA_KEY_RSA; -const char mbedtls_test_ca_pwd_rsa[] = TEST_CA_PWD_RSA; -const char mbedtls_test_ca_crt_rsa_sha256[] = TEST_CA_CRT_RSA_SHA256; -const char mbedtls_test_ca_crt_rsa_sha1[] = TEST_CA_CRT_RSA_SHA1; -const char mbedtls_test_ca_key_ec[] = TEST_CA_KEY_EC; -const char mbedtls_test_ca_pwd_ec[] = TEST_CA_PWD_EC; -const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC; - -const char mbedtls_test_srv_key_rsa[] = TEST_SRV_KEY_RSA; -const char mbedtls_test_srv_pwd_rsa[] = TEST_SRV_PWD_RSA; -const char mbedtls_test_srv_crt_rsa_sha256[] = TEST_SRV_CRT_RSA_SHA256; -const char mbedtls_test_srv_crt_rsa_sha1[] = TEST_SRV_CRT_RSA_SHA1; -const char mbedtls_test_srv_key_ec[] = TEST_SRV_KEY_EC; -const char mbedtls_test_srv_pwd_ec[] = TEST_SRV_PWD_EC; -const char mbedtls_test_srv_crt_ec[] = TEST_SRV_CRT_EC; - -const char mbedtls_test_cli_key_rsa[] = TEST_CLI_KEY_RSA; -const char mbedtls_test_cli_pwd_rsa[] = TEST_CLI_PWD_RSA; -const char mbedtls_test_cli_crt_rsa[] = TEST_CLI_CRT_RSA; -const char mbedtls_test_cli_key_ec[] = TEST_CLI_KEY_EC; -const char mbedtls_test_cli_pwd_ec[] = TEST_CLI_PWD_EC; -const char mbedtls_test_cli_crt_ec[] = TEST_CLI_CRT_EC; - -const size_t mbedtls_test_ca_key_rsa_len = - sizeof( mbedtls_test_ca_key_rsa ); -const size_t mbedtls_test_ca_pwd_rsa_len = - sizeof( mbedtls_test_ca_pwd_rsa ) - 1; -const size_t mbedtls_test_ca_crt_rsa_sha256_len = - sizeof( mbedtls_test_ca_crt_rsa_sha256 ); -const size_t mbedtls_test_ca_crt_rsa_sha1_len = - sizeof( mbedtls_test_ca_crt_rsa_sha1 ); -const size_t mbedtls_test_ca_key_ec_len = - sizeof( mbedtls_test_ca_key_ec ); -const size_t mbedtls_test_ca_pwd_ec_len = - sizeof( mbedtls_test_ca_pwd_ec ) - 1; -const size_t mbedtls_test_ca_crt_ec_len = - sizeof( mbedtls_test_ca_crt_ec ); - -const size_t mbedtls_test_srv_key_rsa_len = - sizeof( mbedtls_test_srv_key_rsa ); -const size_t mbedtls_test_srv_pwd_rsa_len = - sizeof( mbedtls_test_srv_pwd_rsa ) -1; -const size_t mbedtls_test_srv_crt_rsa_sha256_len = - sizeof( mbedtls_test_srv_crt_rsa_sha256 ); -const size_t mbedtls_test_srv_crt_rsa_sha1_len = - sizeof( mbedtls_test_srv_crt_rsa_sha1 ); -const size_t mbedtls_test_srv_key_ec_len = - sizeof( mbedtls_test_srv_key_ec ); -const size_t mbedtls_test_srv_pwd_ec_len = - sizeof( mbedtls_test_srv_pwd_ec ) - 1; -const size_t mbedtls_test_srv_crt_ec_len = - sizeof( mbedtls_test_srv_crt_ec ); - -const size_t mbedtls_test_cli_key_rsa_len = - sizeof( mbedtls_test_cli_key_rsa ); -const size_t mbedtls_test_cli_pwd_rsa_len = - sizeof( mbedtls_test_cli_pwd_rsa ) - 1; -const size_t mbedtls_test_cli_crt_rsa_len = - sizeof( mbedtls_test_cli_crt_rsa ); -const size_t mbedtls_test_cli_key_ec_len = - sizeof( mbedtls_test_cli_key_ec ); -const size_t mbedtls_test_cli_pwd_ec_len = - sizeof( mbedtls_test_cli_pwd_ec ) - 1; -const size_t mbedtls_test_cli_crt_ec_len = - sizeof( mbedtls_test_cli_crt_ec ); - -/* - * Dispatch between SHA-1 and SHA-256 - */ - -#if defined(MBEDTLS_SHA256_C) -#define TEST_CA_CRT_RSA TEST_CA_CRT_RSA_SHA256 -#define TEST_SRV_CRT_RSA TEST_SRV_CRT_RSA_SHA256 -#else -#define TEST_CA_CRT_RSA TEST_CA_CRT_RSA_SHA1 -#define TEST_SRV_CRT_RSA TEST_SRV_CRT_RSA_SHA1 -#endif /* MBEDTLS_SHA256_C */ - -const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA; -const char mbedtls_test_srv_crt_rsa[] = TEST_SRV_CRT_RSA; - -const size_t mbedtls_test_ca_crt_rsa_len = - sizeof( mbedtls_test_ca_crt_rsa ); -const size_t mbedtls_test_srv_crt_rsa_len = - sizeof( mbedtls_test_srv_crt_rsa ); - -/* - * Dispatch between RSA and EC - */ - -#if defined(MBEDTLS_RSA_C) - -#define TEST_CA_KEY TEST_CA_KEY_RSA -#define TEST_CA_PWD TEST_CA_PWD_RSA -#define TEST_CA_CRT TEST_CA_CRT_RSA - -#define TEST_SRV_KEY TEST_SRV_KEY_RSA -#define TEST_SRV_PWD TEST_SRV_PWD_RSA -#define TEST_SRV_CRT TEST_SRV_CRT_RSA - -#define TEST_CLI_KEY TEST_CLI_KEY_RSA -#define TEST_CLI_PWD TEST_CLI_PWD_RSA -#define TEST_CLI_CRT TEST_CLI_CRT_RSA - -#else /* no RSA, so assume ECDSA */ - -#define TEST_CA_KEY TEST_CA_KEY_EC -#define TEST_CA_PWD TEST_CA_PWD_EC -#define TEST_CA_CRT TEST_CA_CRT_EC - -#define TEST_SRV_KEY TEST_SRV_KEY_EC -#define TEST_SRV_PWD TEST_SRV_PWD_EC -#define TEST_SRV_CRT TEST_SRV_CRT_EC - -#define TEST_CLI_KEY TEST_CLI_KEY_EC -#define TEST_CLI_PWD TEST_CLI_PWD_EC -#define TEST_CLI_CRT TEST_CLI_CRT_EC - -#endif /* MBEDTLS_RSA_C */ - -/* API stability forces us to declare - * mbedtls_test_{ca|srv|cli}_{key|pwd|crt} - * as pointers. */ -static const char test_ca_key[] = TEST_CA_KEY; -static const char test_ca_pwd[] = TEST_CA_PWD; -static const char test_ca_crt[] = TEST_CA_CRT; - -static const char test_srv_key[] = TEST_SRV_KEY; -static const char test_srv_pwd[] = TEST_SRV_PWD; -static const char test_srv_crt[] = TEST_SRV_CRT; - -static const char test_cli_key[] = TEST_CLI_KEY; -static const char test_cli_pwd[] = TEST_CLI_PWD; -static const char test_cli_crt[] = TEST_CLI_CRT; - -const char *mbedtls_test_ca_key = test_ca_key; -const char *mbedtls_test_ca_pwd = test_ca_pwd; -const char *mbedtls_test_ca_crt = test_ca_crt; - -const char *mbedtls_test_srv_key = test_srv_key; -const char *mbedtls_test_srv_pwd = test_srv_pwd; -const char *mbedtls_test_srv_crt = test_srv_crt; - -const char *mbedtls_test_cli_key = test_cli_key; -const char *mbedtls_test_cli_pwd = test_cli_pwd; -const char *mbedtls_test_cli_crt = test_cli_crt; - -const size_t mbedtls_test_ca_key_len = - sizeof( test_ca_key ); -const size_t mbedtls_test_ca_pwd_len = - sizeof( test_ca_pwd ) - 1; -const size_t mbedtls_test_ca_crt_len = - sizeof( test_ca_crt ); - -const size_t mbedtls_test_srv_key_len = - sizeof( test_srv_key ); -const size_t mbedtls_test_srv_pwd_len = - sizeof( test_srv_pwd ) - 1; -const size_t mbedtls_test_srv_crt_len = - sizeof( test_srv_crt ); - -const size_t mbedtls_test_cli_key_len = - sizeof( test_cli_key ); -const size_t mbedtls_test_cli_pwd_len = - sizeof( test_cli_pwd ) - 1; -const size_t mbedtls_test_cli_crt_len = - sizeof( test_cli_crt ); - -/* - * - * Lists of certificates - * - */ - -/* List of CAs in PEM or DER, depending on config */ -const char * mbedtls_test_cas[] = { -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA1_C) - mbedtls_test_ca_crt_rsa_sha1, -#endif -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) - mbedtls_test_ca_crt_rsa_sha256, -#endif -#if defined(MBEDTLS_ECDSA_C) - mbedtls_test_ca_crt_ec, -#endif - NULL -}; -const size_t mbedtls_test_cas_len[] = { -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA1_C) - sizeof( mbedtls_test_ca_crt_rsa_sha1 ), -#endif -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) - sizeof( mbedtls_test_ca_crt_rsa_sha256 ), -#endif -#if defined(MBEDTLS_ECDSA_C) - sizeof( mbedtls_test_ca_crt_ec ), -#endif - 0 -}; - -/* List of all available CA certificates in DER format */ -const unsigned char * mbedtls_test_cas_der[] = { -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_SHA256_C) - mbedtls_test_ca_crt_rsa_sha256_der, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA1_C) - mbedtls_test_ca_crt_rsa_sha1_der, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECDSA_C) - mbedtls_test_ca_crt_ec_der, -#endif /* MBEDTLS_ECDSA_C */ - NULL -}; - -const size_t mbedtls_test_cas_der_len[] = { -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_SHA256_C) - sizeof( mbedtls_test_ca_crt_rsa_sha256_der ), -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA1_C) - sizeof( mbedtls_test_ca_crt_rsa_sha1_der ), -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECDSA_C) - sizeof( mbedtls_test_ca_crt_ec_der ), -#endif /* MBEDTLS_ECDSA_C */ - 0 -}; - -/* Concatenation of all available CA certificates in PEM format */ -#if defined(MBEDTLS_PEM_PARSE_C) -const char mbedtls_test_cas_pem[] = -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_SHA256_C) - TEST_CA_CRT_RSA_SHA256_PEM -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA1_C) - TEST_CA_CRT_RSA_SHA1_PEM -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECDSA_C) - TEST_CA_CRT_EC_PEM -#endif /* MBEDTLS_ECDSA_C */ - ""; -const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); -#endif /* MBEDTLS_PEM_PARSE_C */ - -#endif /* MBEDTLS_CERTS_C */ diff --git a/mbedtls/certs.h b/mbedtls/certs.h deleted file mode 100644 index 1021af7c6..000000000 --- a/mbedtls/certs.h +++ /dev/null @@ -1,278 +0,0 @@ -#pragma GCC system_header -/** - * \file certs.h - * - * \brief Sample certificates and DHM parameters for testing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_CERTS_H -#define MBEDTLS_CERTS_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* List of all PEM-encoded CA certificates, terminated by NULL; - * PEM encoded if MBEDTLS_PEM_PARSE_C is enabled, DER encoded - * otherwise. */ -extern const char * mbedtls_test_cas[]; -extern const size_t mbedtls_test_cas_len[]; - -/* List of all DER-encoded CA certificates, terminated by NULL */ -extern const unsigned char * mbedtls_test_cas_der[]; -extern const size_t mbedtls_test_cas_der_len[]; - -#if defined(MBEDTLS_PEM_PARSE_C) -/* Concatenation of all CA certificates in PEM format if available */ -extern const char mbedtls_test_cas_pem[]; -extern const size_t mbedtls_test_cas_pem_len; -#endif /* MBEDTLS_PEM_PARSE_C */ - -/* - * CA test certificates - */ - -extern const char mbedtls_test_ca_crt_ec_pem[]; -extern const char mbedtls_test_ca_key_ec_pem[]; -extern const char mbedtls_test_ca_pwd_ec_pem[]; -extern const char mbedtls_test_ca_key_rsa_pem[]; -extern const char mbedtls_test_ca_pwd_rsa_pem[]; -extern const char mbedtls_test_ca_crt_rsa_sha1_pem[]; -extern const char mbedtls_test_ca_crt_rsa_sha256_pem[]; - -extern const unsigned char mbedtls_test_ca_crt_ec_der[]; -extern const unsigned char mbedtls_test_ca_key_ec_der[]; -extern const unsigned char mbedtls_test_ca_key_rsa_der[]; -extern const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[]; -extern const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[]; - -extern const size_t mbedtls_test_ca_crt_ec_pem_len; -extern const size_t mbedtls_test_ca_key_ec_pem_len; -extern const size_t mbedtls_test_ca_pwd_ec_pem_len; -extern const size_t mbedtls_test_ca_key_rsa_pem_len; -extern const size_t mbedtls_test_ca_pwd_rsa_pem_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len; - -extern const size_t mbedtls_test_ca_crt_ec_der_len; -extern const size_t mbedtls_test_ca_key_ec_der_len; -extern const size_t mbedtls_test_ca_pwd_ec_der_len; -extern const size_t mbedtls_test_ca_key_rsa_der_len; -extern const size_t mbedtls_test_ca_pwd_rsa_der_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha1_der_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha256_der_len; - -/* Config-dependent dispatch between PEM and DER encoding - * (PEM if enabled, otherwise DER) */ - -extern const char mbedtls_test_ca_crt_ec[]; -extern const char mbedtls_test_ca_key_ec[]; -extern const char mbedtls_test_ca_pwd_ec[]; -extern const char mbedtls_test_ca_key_rsa[]; -extern const char mbedtls_test_ca_pwd_rsa[]; -extern const char mbedtls_test_ca_crt_rsa_sha1[]; -extern const char mbedtls_test_ca_crt_rsa_sha256[]; - -extern const size_t mbedtls_test_ca_crt_ec_len; -extern const size_t mbedtls_test_ca_key_ec_len; -extern const size_t mbedtls_test_ca_pwd_ec_len; -extern const size_t mbedtls_test_ca_key_rsa_len; -extern const size_t mbedtls_test_ca_pwd_rsa_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha1_len; -extern const size_t mbedtls_test_ca_crt_rsa_sha256_len; - -/* Config-dependent dispatch between SHA-1 and SHA-256 - * (SHA-256 if enabled, otherwise SHA-1) */ - -extern const char mbedtls_test_ca_crt_rsa[]; -extern const size_t mbedtls_test_ca_crt_rsa_len; - -/* Config-dependent dispatch between EC and RSA - * (RSA if enabled, otherwise EC) */ - -extern const char * mbedtls_test_ca_crt; -extern const char * mbedtls_test_ca_key; -extern const char * mbedtls_test_ca_pwd; -extern const size_t mbedtls_test_ca_crt_len; -extern const size_t mbedtls_test_ca_key_len; -extern const size_t mbedtls_test_ca_pwd_len; - -/* - * Server test certificates - */ - -extern const char mbedtls_test_srv_crt_ec_pem[]; -extern const char mbedtls_test_srv_key_ec_pem[]; -extern const char mbedtls_test_srv_pwd_ec_pem[]; -extern const char mbedtls_test_srv_key_rsa_pem[]; -extern const char mbedtls_test_srv_pwd_rsa_pem[]; -extern const char mbedtls_test_srv_crt_rsa_sha1_pem[]; -extern const char mbedtls_test_srv_crt_rsa_sha256_pem[]; - -extern const unsigned char mbedtls_test_srv_crt_ec_der[]; -extern const unsigned char mbedtls_test_srv_key_ec_der[]; -extern const unsigned char mbedtls_test_srv_key_rsa_der[]; -extern const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[]; -extern const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[]; - -extern const size_t mbedtls_test_srv_crt_ec_pem_len; -extern const size_t mbedtls_test_srv_key_ec_pem_len; -extern const size_t mbedtls_test_srv_pwd_ec_pem_len; -extern const size_t mbedtls_test_srv_key_rsa_pem_len; -extern const size_t mbedtls_test_srv_pwd_rsa_pem_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len; - -extern const size_t mbedtls_test_srv_crt_ec_der_len; -extern const size_t mbedtls_test_srv_key_ec_der_len; -extern const size_t mbedtls_test_srv_pwd_ec_der_len; -extern const size_t mbedtls_test_srv_key_rsa_der_len; -extern const size_t mbedtls_test_srv_pwd_rsa_der_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha1_der_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha256_der_len; - -/* Config-dependent dispatch between PEM and DER encoding - * (PEM if enabled, otherwise DER) */ - -extern const char mbedtls_test_srv_crt_ec[]; -extern const char mbedtls_test_srv_key_ec[]; -extern const char mbedtls_test_srv_pwd_ec[]; -extern const char mbedtls_test_srv_key_rsa[]; -extern const char mbedtls_test_srv_pwd_rsa[]; -extern const char mbedtls_test_srv_crt_rsa_sha1[]; -extern const char mbedtls_test_srv_crt_rsa_sha256[]; - -extern const size_t mbedtls_test_srv_crt_ec_len; -extern const size_t mbedtls_test_srv_key_ec_len; -extern const size_t mbedtls_test_srv_pwd_ec_len; -extern const size_t mbedtls_test_srv_key_rsa_len; -extern const size_t mbedtls_test_srv_pwd_rsa_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha1_len; -extern const size_t mbedtls_test_srv_crt_rsa_sha256_len; - -/* Config-dependent dispatch between SHA-1 and SHA-256 - * (SHA-256 if enabled, otherwise SHA-1) */ - -extern const char mbedtls_test_srv_crt_rsa[]; -extern const size_t mbedtls_test_srv_crt_rsa_len; - -/* Config-dependent dispatch between EC and RSA - * (RSA if enabled, otherwise EC) */ - -extern const char * mbedtls_test_srv_crt; -extern const char * mbedtls_test_srv_key; -extern const char * mbedtls_test_srv_pwd; -extern const size_t mbedtls_test_srv_crt_len; -extern const size_t mbedtls_test_srv_key_len; -extern const size_t mbedtls_test_srv_pwd_len; - -/* - * Client test certificates - */ - -extern const char mbedtls_test_cli_crt_ec_pem[]; -extern const char mbedtls_test_cli_key_ec_pem[]; -extern const char mbedtls_test_cli_pwd_ec_pem[]; -extern const char mbedtls_test_cli_key_rsa_pem[]; -extern const char mbedtls_test_cli_pwd_rsa_pem[]; -extern const char mbedtls_test_cli_crt_rsa_pem[]; - -extern const unsigned char mbedtls_test_cli_crt_ec_der[]; -extern const unsigned char mbedtls_test_cli_key_ec_der[]; -extern const unsigned char mbedtls_test_cli_key_rsa_der[]; -extern const unsigned char mbedtls_test_cli_crt_rsa_der[]; - -extern const size_t mbedtls_test_cli_crt_ec_pem_len; -extern const size_t mbedtls_test_cli_key_ec_pem_len; -extern const size_t mbedtls_test_cli_pwd_ec_pem_len; -extern const size_t mbedtls_test_cli_key_rsa_pem_len; -extern const size_t mbedtls_test_cli_pwd_rsa_pem_len; -extern const size_t mbedtls_test_cli_crt_rsa_pem_len; - -extern const size_t mbedtls_test_cli_crt_ec_der_len; -extern const size_t mbedtls_test_cli_key_ec_der_len; -extern const size_t mbedtls_test_cli_key_rsa_der_len; -extern const size_t mbedtls_test_cli_crt_rsa_der_len; - -/* Config-dependent dispatch between PEM and DER encoding - * (PEM if enabled, otherwise DER) */ - -extern const char mbedtls_test_cli_crt_ec[]; -extern const char mbedtls_test_cli_key_ec[]; -extern const char mbedtls_test_cli_pwd_ec[]; -extern const char mbedtls_test_cli_key_rsa[]; -extern const char mbedtls_test_cli_pwd_rsa[]; -extern const char mbedtls_test_cli_crt_rsa[]; - -extern const size_t mbedtls_test_cli_crt_ec_len; -extern const size_t mbedtls_test_cli_key_ec_len; -extern const size_t mbedtls_test_cli_pwd_ec_len; -extern const size_t mbedtls_test_cli_key_rsa_len; -extern const size_t mbedtls_test_cli_pwd_rsa_len; -extern const size_t mbedtls_test_cli_crt_rsa_len; - -/* Config-dependent dispatch between EC and RSA - * (RSA if enabled, otherwise EC) */ - -extern const char * mbedtls_test_cli_crt; -extern const char * mbedtls_test_cli_key; -extern const char * mbedtls_test_cli_pwd; -extern const size_t mbedtls_test_cli_crt_len; -extern const size_t mbedtls_test_cli_key_len; -extern const size_t mbedtls_test_cli_pwd_len; - -#ifdef __cplusplus -} -#endif - -#endif /* certs.h */ diff --git a/mbedtls/chacha20.c b/mbedtls/chacha20.c deleted file mode 100644 index 48f657211..000000000 --- a/mbedtls/chacha20.c +++ /dev/null @@ -1,608 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file chacha20.c - * - * \brief ChaCha20 cipher. - * - * \author Daniel King - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CHACHA20_C) - -#include "mbedtls/chacha20.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_CHACHA20_ALT) - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* Parameter validation macros */ -#define CHACHA20_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) -#define CHACHA20_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define BYTES_TO_U32_LE( data, offset ) \ - ( (uint32_t) (data)[offset] \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \ - ) - -#define ROTL32( value, amount ) \ - ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) ) - -#define CHACHA20_CTR_INDEX ( 12U ) - -#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U ) - -/** - * \brief ChaCha20 quarter round operation. - * - * The quarter round is defined as follows (from RFC 7539): - * 1. a += b; d ^= a; d <<<= 16; - * 2. c += d; b ^= c; b <<<= 12; - * 3. a += b; d ^= a; d <<<= 8; - * 4. c += d; b ^= c; b <<<= 7; - * - * \param state ChaCha20 state to modify. - * \param a The index of 'a' in the state. - * \param b The index of 'b' in the state. - * \param c The index of 'c' in the state. - * \param d The index of 'd' in the state. - */ -static inline void chacha20_quarter_round( uint32_t state[16], - size_t a, - size_t b, - size_t c, - size_t d ) -{ - /* a += b; d ^= a; d <<<= 16; */ - state[a] += state[b]; - state[d] ^= state[a]; - state[d] = ROTL32( state[d], 16 ); - - /* c += d; b ^= c; b <<<= 12 */ - state[c] += state[d]; - state[b] ^= state[c]; - state[b] = ROTL32( state[b], 12 ); - - /* a += b; d ^= a; d <<<= 8; */ - state[a] += state[b]; - state[d] ^= state[a]; - state[d] = ROTL32( state[d], 8 ); - - /* c += d; b ^= c; b <<<= 7; */ - state[c] += state[d]; - state[b] ^= state[c]; - state[b] = ROTL32( state[b], 7 ); -} - -/** - * \brief Perform the ChaCha20 inner block operation. - * - * This function performs two rounds: the column round and the - * diagonal round. - * - * \param state The ChaCha20 state to update. - */ -static void chacha20_inner_block( uint32_t state[16] ) -{ - chacha20_quarter_round( state, 0, 4, 8, 12 ); - chacha20_quarter_round( state, 1, 5, 9, 13 ); - chacha20_quarter_round( state, 2, 6, 10, 14 ); - chacha20_quarter_round( state, 3, 7, 11, 15 ); - - chacha20_quarter_round( state, 0, 5, 10, 15 ); - chacha20_quarter_round( state, 1, 6, 11, 12 ); - chacha20_quarter_round( state, 2, 7, 8, 13 ); - chacha20_quarter_round( state, 3, 4, 9, 14 ); -} - -/** - * \brief Generates a keystream block. - * - * \param initial_state The initial ChaCha20 state (key, nonce, counter). - * \param keystream Generated keystream bytes are written to this buffer. - */ -static void chacha20_block( const uint32_t initial_state[16], - unsigned char keystream[64] ) -{ - uint32_t working_state[16]; - size_t i; - - memcpy( working_state, - initial_state, - CHACHA20_BLOCK_SIZE_BYTES ); - - for( i = 0U; i < 10U; i++ ) - chacha20_inner_block( working_state ); - - working_state[ 0] += initial_state[ 0]; - working_state[ 1] += initial_state[ 1]; - working_state[ 2] += initial_state[ 2]; - working_state[ 3] += initial_state[ 3]; - working_state[ 4] += initial_state[ 4]; - working_state[ 5] += initial_state[ 5]; - working_state[ 6] += initial_state[ 6]; - working_state[ 7] += initial_state[ 7]; - working_state[ 8] += initial_state[ 8]; - working_state[ 9] += initial_state[ 9]; - working_state[10] += initial_state[10]; - working_state[11] += initial_state[11]; - working_state[12] += initial_state[12]; - working_state[13] += initial_state[13]; - working_state[14] += initial_state[14]; - working_state[15] += initial_state[15]; - - for( i = 0U; i < 16; i++ ) - { - size_t offset = i * 4U; - - keystream[offset ] = (unsigned char)( working_state[i] ); - keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 ); - keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 ); - keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 ); - } - - mbedtls_platform_zeroize( working_state, sizeof( working_state ) ); -} - -void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ) -{ - CHACHA20_VALIDATE( ctx != NULL ); - - mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) ); - mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); - - /* Initially, there's no keystream bytes available */ - ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; -} - -void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ) -{ - if( ctx != NULL ) - { - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) ); - } -} - -int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, - const unsigned char key[32] ) -{ - CHACHA20_VALIDATE_RET( ctx != NULL ); - CHACHA20_VALIDATE_RET( key != NULL ); - - /* ChaCha20 constants - the string "expand 32-byte k" */ - ctx->state[0] = 0x61707865; - ctx->state[1] = 0x3320646e; - ctx->state[2] = 0x79622d32; - ctx->state[3] = 0x6b206574; - - /* Set key */ - ctx->state[4] = BYTES_TO_U32_LE( key, 0 ); - ctx->state[5] = BYTES_TO_U32_LE( key, 4 ); - ctx->state[6] = BYTES_TO_U32_LE( key, 8 ); - ctx->state[7] = BYTES_TO_U32_LE( key, 12 ); - ctx->state[8] = BYTES_TO_U32_LE( key, 16 ); - ctx->state[9] = BYTES_TO_U32_LE( key, 20 ); - ctx->state[10] = BYTES_TO_U32_LE( key, 24 ); - ctx->state[11] = BYTES_TO_U32_LE( key, 28 ); - - return( 0 ); -} - -int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, - const unsigned char nonce[12], - uint32_t counter ) -{ - CHACHA20_VALIDATE_RET( ctx != NULL ); - CHACHA20_VALIDATE_RET( nonce != NULL ); - - /* Counter */ - ctx->state[12] = counter; - - /* Nonce */ - ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 ); - ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 ); - ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 ); - - mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); - - /* Initially, there's no keystream bytes available */ - ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; - - return( 0 ); -} - -int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, - size_t size, - const unsigned char *input, - unsigned char *output ) -{ - size_t offset = 0U; - size_t i; - - CHACHA20_VALIDATE_RET( ctx != NULL ); - CHACHA20_VALIDATE_RET( size == 0 || input != NULL ); - CHACHA20_VALIDATE_RET( size == 0 || output != NULL ); - - /* Use leftover keystream bytes, if available */ - while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES ) - { - output[offset] = input[offset] - ^ ctx->keystream8[ctx->keystream_bytes_used]; - - ctx->keystream_bytes_used++; - offset++; - size--; - } - - /* Process full blocks */ - while( size >= CHACHA20_BLOCK_SIZE_BYTES ) - { - /* Generate new keystream block and increment counter */ - chacha20_block( ctx->state, ctx->keystream8 ); - ctx->state[CHACHA20_CTR_INDEX]++; - - for( i = 0U; i < 64U; i += 8U ) - { - output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ]; - output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1]; - output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2]; - output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3]; - output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4]; - output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5]; - output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6]; - output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7]; - } - - offset += CHACHA20_BLOCK_SIZE_BYTES; - size -= CHACHA20_BLOCK_SIZE_BYTES; - } - - /* Last (partial) block */ - if( size > 0U ) - { - /* Generate new keystream block and increment counter */ - chacha20_block( ctx->state, ctx->keystream8 ); - ctx->state[CHACHA20_CTR_INDEX]++; - - for( i = 0U; i < size; i++) - { - output[offset + i] = input[offset + i] ^ ctx->keystream8[i]; - } - - ctx->keystream_bytes_used = size; - - } - - return( 0 ); -} - -int mbedtls_chacha20_crypt( const unsigned char key[32], - const unsigned char nonce[12], - uint32_t counter, - size_t data_len, - const unsigned char* input, - unsigned char* output ) -{ - mbedtls_chacha20_context ctx; - int ret; - - CHACHA20_VALIDATE_RET( key != NULL ); - CHACHA20_VALIDATE_RET( nonce != NULL ); - CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL ); - CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL ); - - mbedtls_chacha20_init( &ctx ); - - ret = mbedtls_chacha20_setkey( &ctx, key ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chacha20_starts( &ctx, nonce, counter ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chacha20_update( &ctx, data_len, input, output ); - -cleanup: - mbedtls_chacha20_free( &ctx ); - return( ret ); -} - -#endif /* !MBEDTLS_CHACHA20_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_keys[2][32] = -{ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 - } -}; - -static const unsigned char test_nonces[2][12] = -{ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02 - } -}; - -static const uint32_t test_counters[2] = -{ - 0U, - 1U -}; - -static const unsigned char test_input[2][375] = -{ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, - 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45, - 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, - 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, - 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, - 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, - 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, - 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20, - 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69, - 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49, - 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, - 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, - 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49, - 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, - 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, - 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, - 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63, - 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61, - 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, - 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, - 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, - 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, - 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f - } -}; - -static const unsigned char test_output[2][375] = -{ - { - 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, - 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, - 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a, - 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, - 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, - 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, - 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, - 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86 - }, - { - 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde, - 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70, - 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd, - 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec, - 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15, - 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05, - 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f, - 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d, - 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa, - 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e, - 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7, - 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50, - 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05, - 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c, - 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05, - 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a, - 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0, - 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66, - 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4, - 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d, - 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91, - 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28, - 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87, - 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b, - 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2, - 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f, - 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76, - 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c, - 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b, - 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84, - 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd, - 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b, - 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe, - 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0, - 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80, - 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f, - 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3, - 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62, - 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91, - 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6, - 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64, - 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85, - 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41, - 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab, - 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba, - 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd, - 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21 - } -}; - -static const size_t test_lengths[2] = -{ - 64U, - 375U -}; - -#define ASSERT( cond, args ) \ - do \ - { \ - if( ! ( cond ) ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf args; \ - \ - return( -1 ); \ - } \ - } \ - while( 0 ) - -int mbedtls_chacha20_self_test( int verbose ) -{ - unsigned char output[381]; - unsigned i; - int ret; - - for( i = 0U; i < 2U; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " ChaCha20 test %u ", i ); - - ret = mbedtls_chacha20_crypt( test_keys[i], - test_nonces[i], - test_counters[i], - test_lengths[i], - test_input[i], - output ); - - ASSERT( 0 == ret, ( "error code: %i\n", ret ) ); - - ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ), - ( "failed (output)\n" ) ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* !MBEDTLS_CHACHA20_C */ diff --git a/mbedtls/chacha20.h b/mbedtls/chacha20.h deleted file mode 100644 index d17fe1772..000000000 --- a/mbedtls/chacha20.h +++ /dev/null @@ -1,253 +0,0 @@ -#pragma GCC system_header -/** - * \file chacha20.h - * - * \brief This file contains ChaCha20 definitions and functions. - * - * ChaCha20 is a stream cipher that can encrypt and decrypt - * information. ChaCha was created by Daniel Bernstein as a variant of - * its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf - * ChaCha20 is the variant with 20 rounds, that was also standardized - * in RFC 7539. - * - * \author Daniel King - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_CHACHA20_H -#define MBEDTLS_CHACHA20_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x0051 /**< Invalid input parameter(s). */ - -/* MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE is deprecated and should not be - * used. */ -#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */ - -/* MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED is deprecated and should not be used. - */ -#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED -0x0055 /**< Chacha20 hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_CHACHA20_ALT) - -typedef struct mbedtls_chacha20_context -{ - uint32_t state[16]; /*! The state (before round operations). */ - uint8_t keystream8[64]; /*! Leftover keystream bytes. */ - size_t keystream_bytes_used; /*! Number of keystream bytes already used. */ -} -mbedtls_chacha20_context; - -#else /* MBEDTLS_CHACHA20_ALT */ -#include "chacha20_alt.h" -#endif /* MBEDTLS_CHACHA20_ALT */ - -/** - * \brief This function initializes the specified ChaCha20 context. - * - * It must be the first API called before using - * the context. - * - * It is usually followed by calls to - * \c mbedtls_chacha20_setkey() and - * \c mbedtls_chacha20_starts(), then one or more calls to - * to \c mbedtls_chacha20_update(), and finally to - * \c mbedtls_chacha20_free(). - * - * \param ctx The ChaCha20 context to initialize. - * This must not be \c NULL. - */ -void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ); - -/** - * \brief This function releases and clears the specified - * ChaCha20 context. - * - * \param ctx The ChaCha20 context to clear. This may be \c NULL, - * in which case this function is a no-op. If it is not - * \c NULL, it must point to an initialized context. - * - */ -void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ); - -/** - * \brief This function sets the encryption/decryption key. - * - * \note After using this function, you must also call - * \c mbedtls_chacha20_starts() to set a nonce before you - * start encrypting/decrypting data with - * \c mbedtls_chacha_update(). - * - * \param ctx The ChaCha20 context to which the key should be bound. - * It must be initialized. - * \param key The encryption/decryption key. This must be \c 32 Bytes - * in length. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL. - */ -int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, - const unsigned char key[32] ); - -/** - * \brief This function sets the nonce and initial counter value. - * - * \note A ChaCha20 context can be re-used with the same key by - * calling this function to change the nonce. - * - * \warning You must never use the same nonce twice with the same key. - * This would void any confidentiality guarantees for the - * messages encrypted with the same nonce and key. - * - * \param ctx The ChaCha20 context to which the nonce should be bound. - * It must be initialized and bound to a key. - * \param nonce The nonce. This must be \c 12 Bytes in size. - * \param counter The initial counter value. This is usually \c 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is - * NULL. - */ -int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, - const unsigned char nonce[12], - uint32_t counter ); - -/** - * \brief This function encrypts or decrypts data. - * - * Since ChaCha20 is a stream cipher, the same operation is - * used for encrypting and decrypting data. - * - * \note The \p input and \p output pointers must either be equal or - * point to non-overlapping buffers. - * - * \note \c mbedtls_chacha20_setkey() and - * \c mbedtls_chacha20_starts() must be called at least once - * to setup the context before this function can be called. - * - * \note This function can be called multiple times in a row in - * order to encrypt of decrypt data piecewise with the same - * key and nonce. - * - * \param ctx The ChaCha20 context to use for encryption or decryption. - * It must be initialized and bound to a key and nonce. - * \param size The length of the input data in Bytes. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `size == 0`. - * \param output The buffer holding the output data. - * This must be able to hold \p size Bytes. - * This pointer can be \c NULL if `size == 0`. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, - size_t size, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function encrypts or decrypts data with ChaCha20 and - * the given key and nonce. - * - * Since ChaCha20 is a stream cipher, the same operation is - * used for encrypting and decrypting data. - * - * \warning You must never use the same (key, nonce) pair more than - * once. This would void any confidentiality guarantees for - * the messages encrypted with the same nonce and key. - * - * \note The \p input and \p output pointers must either be equal or - * point to non-overlapping buffers. - * - * \param key The encryption/decryption key. - * This must be \c 32 Bytes in length. - * \param nonce The nonce. This must be \c 12 Bytes in size. - * \param counter The initial counter value. This is usually \c 0. - * \param size The length of the input data in Bytes. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `size == 0`. - * \param output The buffer holding the output data. - * This must be able to hold \p size Bytes. - * This pointer can be \c NULL if `size == 0`. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chacha20_crypt( const unsigned char key[32], - const unsigned char nonce[12], - uint32_t counter, - size_t size, - const unsigned char* input, - unsigned char* output ); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The ChaCha20 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_chacha20_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CHACHA20_H */ diff --git a/mbedtls/chachapoly.c b/mbedtls/chachapoly.c deleted file mode 100644 index 8815fb62c..000000000 --- a/mbedtls/chachapoly.c +++ /dev/null @@ -1,578 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file chachapoly.c - * - * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - -#include "mbedtls/chachapoly.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_CHACHAPOLY_ALT) - -/* Parameter validation macros */ -#define CHACHAPOLY_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ) -#define CHACHAPOLY_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define CHACHAPOLY_STATE_INIT ( 0 ) -#define CHACHAPOLY_STATE_AAD ( 1 ) -#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */ -#define CHACHAPOLY_STATE_FINISHED ( 3 ) - -/** - * \brief Adds nul bytes to pad the AAD for Poly1305. - * - * \param ctx The ChaCha20-Poly1305 context. - */ -static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) -{ - uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U ); - unsigned char zeroes[15]; - - if( partial_block_len == 0U ) - return( 0 ); - - memset( zeroes, 0, sizeof( zeroes ) ); - - return( mbedtls_poly1305_update( &ctx->poly1305_ctx, - zeroes, - 16U - partial_block_len ) ); -} - -/** - * \brief Adds nul bytes to pad the ciphertext for Poly1305. - * - * \param ctx The ChaCha20-Poly1305 context. - */ -static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) -{ - uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U ); - unsigned char zeroes[15]; - - if( partial_block_len == 0U ) - return( 0 ); - - memset( zeroes, 0, sizeof( zeroes ) ); - return( mbedtls_poly1305_update( &ctx->poly1305_ctx, - zeroes, - 16U - partial_block_len ) ); -} - -void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ) -{ - CHACHAPOLY_VALIDATE( ctx != NULL ); - - mbedtls_chacha20_init( &ctx->chacha20_ctx ); - mbedtls_poly1305_init( &ctx->poly1305_ctx ); - ctx->aad_len = 0U; - ctx->ciphertext_len = 0U; - ctx->state = CHACHAPOLY_STATE_INIT; - ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; -} - -void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_chacha20_free( &ctx->chacha20_ctx ); - mbedtls_poly1305_free( &ctx->poly1305_ctx ); - ctx->aad_len = 0U; - ctx->ciphertext_len = 0U; - ctx->state = CHACHAPOLY_STATE_INIT; - ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; -} - -int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, - const unsigned char key[32] ) -{ - int ret; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( key != NULL ); - - ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key ); - - return( ret ); -} - -int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, - const unsigned char nonce[12], - mbedtls_chachapoly_mode_t mode ) -{ - int ret; - unsigned char poly1305_key[64]; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( nonce != NULL ); - - /* Set counter = 0, will be update to 1 when generating Poly1305 key */ - ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U ); - if( ret != 0 ) - goto cleanup; - - /* Generate the Poly1305 key by getting the ChaCha20 keystream output with - * counter = 0. This is the same as encrypting a buffer of zeroes. - * Only the first 256-bits (32 bytes) of the key is used for Poly1305. - * The other 256 bits are discarded. - */ - memset( poly1305_key, 0, sizeof( poly1305_key ) ); - ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ), - poly1305_key, poly1305_key ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key ); - - if( ret == 0 ) - { - ctx->aad_len = 0U; - ctx->ciphertext_len = 0U; - ctx->state = CHACHAPOLY_STATE_AAD; - ctx->mode = mode; - } - -cleanup: - mbedtls_platform_zeroize( poly1305_key, 64U ); - return( ret ); -} - -int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, - const unsigned char *aad, - size_t aad_len ) -{ - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL ); - - if( ctx->state != CHACHAPOLY_STATE_AAD ) - return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); - - ctx->aad_len += aad_len; - - return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) ); -} - -int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, - size_t len, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL ); - CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL ); - - if( ( ctx->state != CHACHAPOLY_STATE_AAD ) && - ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) ) - { - return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); - } - - if( ctx->state == CHACHAPOLY_STATE_AAD ) - { - ctx->state = CHACHAPOLY_STATE_CIPHERTEXT; - - ret = chachapoly_pad_aad( ctx ); - if( ret != 0 ) - return( ret ); - } - - ctx->ciphertext_len += len; - - if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT ) - { - ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len ); - if( ret != 0 ) - return( ret ); - } - else /* DECRYPT */ - { - ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); - if( ret != 0 ) - return( ret ); - } - - return( 0 ); -} - -int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, - unsigned char mac[16] ) -{ - int ret; - unsigned char len_block[16]; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( mac != NULL ); - - if( ctx->state == CHACHAPOLY_STATE_INIT ) - { - return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); - } - - if( ctx->state == CHACHAPOLY_STATE_AAD ) - { - ret = chachapoly_pad_aad( ctx ); - if( ret != 0 ) - return( ret ); - } - else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT ) - { - ret = chachapoly_pad_ciphertext( ctx ); - if( ret != 0 ) - return( ret ); - } - - ctx->state = CHACHAPOLY_STATE_FINISHED; - - /* The lengths of the AAD and ciphertext are processed by - * Poly1305 as the final 128-bit block, encoded as little-endian integers. - */ - len_block[ 0] = (unsigned char)( ctx->aad_len ); - len_block[ 1] = (unsigned char)( ctx->aad_len >> 8 ); - len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 ); - len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 ); - len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 ); - len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 ); - len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 ); - len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 ); - len_block[ 8] = (unsigned char)( ctx->ciphertext_len ); - len_block[ 9] = (unsigned char)( ctx->ciphertext_len >> 8 ); - len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 ); - len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 ); - len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 ); - len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 ); - len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 ); - len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 ); - - ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); - - return( ret ); -} - -static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, - mbedtls_chachapoly_mode_t mode, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char *input, - unsigned char *output, - unsigned char tag[16] ) -{ - int ret; - - ret = mbedtls_chachapoly_starts( ctx, nonce, mode ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chachapoly_update( ctx, length, input, output ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_chachapoly_finish( ctx, tag ); - -cleanup: - return( ret ); -} - -int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char *input, - unsigned char *output, - unsigned char tag[16] ) -{ - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( nonce != NULL ); - CHACHAPOLY_VALIDATE_RET( tag != NULL ); - CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL ); - CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL ); - CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL ); - - return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, - length, nonce, aad, aad_len, - input, output, tag ) ); -} - -int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char tag[16], - const unsigned char *input, - unsigned char *output ) -{ - int ret; - unsigned char check_tag[16]; - size_t i; - int diff; - CHACHAPOLY_VALIDATE_RET( ctx != NULL ); - CHACHAPOLY_VALIDATE_RET( nonce != NULL ); - CHACHAPOLY_VALIDATE_RET( tag != NULL ); - CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL ); - CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL ); - CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL ); - - if( ( ret = chachapoly_crypt_and_tag( ctx, - MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce, - aad, aad_len, input, output, check_tag ) ) != 0 ) - { - return( ret ); - } - - /* Check tag in "constant-time" */ - for( diff = 0, i = 0; i < sizeof( check_tag ); i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) - { - mbedtls_platform_zeroize( output, length ); - return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ); - } - - return( 0 ); -} - -#endif /* MBEDTLS_CHACHAPOLY_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_key[1][32] = -{ - { - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f - } -}; - -static const unsigned char test_nonce[1][12] = -{ - { - 0x07, 0x00, 0x00, 0x00, /* 32-bit common part */ - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */ - } -}; - -static const unsigned char test_aad[1][12] = -{ - { - 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7 - } -}; - -static const size_t test_aad_len[1] = -{ - 12U -}; - -static const unsigned char test_input[1][114] = -{ - { - 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, - 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, - 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, - 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, - 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, - 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, - 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, - 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, - 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, - 0x74, 0x2e - } -}; - -static const unsigned char test_output[1][114] = -{ - { - 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, - 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, - 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, - 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, - 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, - 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, - 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, - 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, - 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, - 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, - 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, - 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, - 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, - 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, - 0x61, 0x16 - } -}; - -static const size_t test_input_len[1] = -{ - 114U -}; - -static const unsigned char test_mac[1][16] = -{ - { - 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, - 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91 - } -}; - -#define ASSERT( cond, args ) \ - do \ - { \ - if( ! ( cond ) ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf args; \ - \ - return( -1 ); \ - } \ - } \ - while( 0 ) - -int mbedtls_chachapoly_self_test( int verbose ) -{ - mbedtls_chachapoly_context ctx; - unsigned i; - int ret; - unsigned char output[200]; - unsigned char mac[16]; - - for( i = 0U; i < 1U; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " ChaCha20-Poly1305 test %u ", i ); - - mbedtls_chachapoly_init( &ctx ); - - ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] ); - ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) ); - - ret = mbedtls_chachapoly_encrypt_and_tag( &ctx, - test_input_len[i], - test_nonce[i], - test_aad[i], - test_aad_len[i], - test_input[i], - output, - mac ); - - ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) ); - - ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ), - ( "failure (wrong output)\n" ) ); - - ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), - ( "failure (wrong MAC)\n" ) ); - - mbedtls_chachapoly_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CHACHAPOLY_C */ diff --git a/mbedtls/chachapoly.h b/mbedtls/chachapoly.h deleted file mode 100644 index 1898bcd4d..000000000 --- a/mbedtls/chachapoly.h +++ /dev/null @@ -1,385 +0,0 @@ -#pragma GCC system_header -/** - * \file chachapoly.h - * - * \brief This file contains the AEAD-ChaCha20-Poly1305 definitions and - * functions. - * - * ChaCha20-Poly1305 is an algorithm for Authenticated Encryption - * with Associated Data (AEAD) that can be used to encrypt and - * authenticate data. It is based on ChaCha20 and Poly1305 by Daniel - * Bernstein and was standardized in RFC 7539. - * - * \author Daniel King - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_CHACHAPOLY_H -#define MBEDTLS_CHACHAPOLY_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -/* for shared error codes */ -#include "poly1305.h" - -#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054 /**< The requested operation is not permitted in the current state. */ -#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056 /**< Authenticated decryption failed: data was not authentic. */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum -{ - MBEDTLS_CHACHAPOLY_ENCRYPT, /**< The mode value for performing encryption. */ - MBEDTLS_CHACHAPOLY_DECRYPT /**< The mode value for performing decryption. */ -} -mbedtls_chachapoly_mode_t; - -#if !defined(MBEDTLS_CHACHAPOLY_ALT) - -#include "chacha20.h" - -typedef struct mbedtls_chachapoly_context -{ - mbedtls_chacha20_context chacha20_ctx; /**< The ChaCha20 context. */ - mbedtls_poly1305_context poly1305_ctx; /**< The Poly1305 context. */ - uint64_t aad_len; /**< The length (bytes) of the Additional Authenticated Data. */ - uint64_t ciphertext_len; /**< The length (bytes) of the ciphertext. */ - int state; /**< The current state of the context. */ - mbedtls_chachapoly_mode_t mode; /**< Cipher mode (encrypt or decrypt). */ -} -mbedtls_chachapoly_context; - -#else /* !MBEDTLS_CHACHAPOLY_ALT */ -#include "chachapoly_alt.h" -#endif /* !MBEDTLS_CHACHAPOLY_ALT */ - -/** - * \brief This function initializes the specified ChaCha20-Poly1305 context. - * - * It must be the first API called before using - * the context. It must be followed by a call to - * \c mbedtls_chachapoly_setkey() before any operation can be - * done, and to \c mbedtls_chachapoly_free() once all - * operations with that context have been finished. - * - * In order to encrypt or decrypt full messages at once, for - * each message you should make a single call to - * \c mbedtls_chachapoly_crypt_and_tag() or - * \c mbedtls_chachapoly_auth_decrypt(). - * - * In order to encrypt messages piecewise, for each - * message you should make a call to - * \c mbedtls_chachapoly_starts(), then 0 or more calls to - * \c mbedtls_chachapoly_update_aad(), then 0 or more calls to - * \c mbedtls_chachapoly_update(), then one call to - * \c mbedtls_chachapoly_finish(). - * - * \warning Decryption with the piecewise API is discouraged! Always - * use \c mbedtls_chachapoly_auth_decrypt() when possible! - * - * If however this is not possible because the data is too - * large to fit in memory, you need to: - * - * - call \c mbedtls_chachapoly_starts() and (if needed) - * \c mbedtls_chachapoly_update_aad() as above, - * - call \c mbedtls_chachapoly_update() multiple times and - * ensure its output (the plaintext) is NOT used in any other - * way than placing it in temporary storage at this point, - * - call \c mbedtls_chachapoly_finish() to compute the - * authentication tag and compared it in constant time to the - * tag received with the ciphertext. - * - * If the tags are not equal, you must immediately discard - * all previous outputs of \c mbedtls_chachapoly_update(), - * otherwise you can now safely use the plaintext. - * - * \param ctx The ChachaPoly context to initialize. Must not be \c NULL. - */ -void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ); - -/** - * \brief This function releases and clears the specified - * ChaCha20-Poly1305 context. - * - * \param ctx The ChachaPoly context to clear. This may be \c NULL, in which - * case this function is a no-op. - */ -void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ); - -/** - * \brief This function sets the ChaCha20-Poly1305 - * symmetric encryption key. - * - * \param ctx The ChaCha20-Poly1305 context to which the key should be - * bound. This must be initialized. - * \param key The \c 256 Bit (\c 32 Bytes) key. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, - const unsigned char key[32] ); - -/** - * \brief This function starts a ChaCha20-Poly1305 encryption or - * decryption operation. - * - * \warning You must never use the same nonce twice with the same key. - * This would void any confidentiality and authenticity - * guarantees for the messages encrypted with the same nonce - * and key. - * - * \note If the context is being used for AAD only (no data to - * encrypt or decrypt) then \p mode can be set to any value. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \param ctx The ChaCha20-Poly1305 context. This must be initialized - * and bound to a key. - * \param nonce The nonce/IV to use for the message. - * This must be a redable buffer of length \c 12 Bytes. - * \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or - * #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning). - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, - const unsigned char nonce[12], - mbedtls_chachapoly_mode_t mode ); - -/** - * \brief This function feeds additional data to be authenticated - * into an ongoing ChaCha20-Poly1305 operation. - * - * The Additional Authenticated Data (AAD), also called - * Associated Data (AD) is only authenticated but not - * encrypted nor included in the encrypted output. It is - * usually transmitted separately from the ciphertext or - * computed locally by each party. - * - * \note This function is called before data is encrypted/decrypted. - * I.e. call this function to process the AAD before calling - * \c mbedtls_chachapoly_update(). - * - * You may call this function multiple times to process - * an arbitrary amount of AAD. It is permitted to call - * this function 0 times, if no AAD is used. - * - * This function cannot be called any more if data has - * been processed by \c mbedtls_chachapoly_update(), - * or if the context has been finished. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \param ctx The ChaCha20-Poly1305 context. This must be initialized - * and bound to a key. - * \param aad_len The length in Bytes of the AAD. The length has no - * restrictions. - * \param aad Buffer containing the AAD. - * This pointer can be \c NULL if `aad_len == 0`. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA - * if \p ctx or \p aad are NULL. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE - * if the operations has not been started or has been - * finished, or if the AAD has been finished. - */ -int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, - const unsigned char *aad, - size_t aad_len ); - -/** - * \brief Thus function feeds data to be encrypted or decrypted - * into an on-going ChaCha20-Poly1305 - * operation. - * - * The direction (encryption or decryption) depends on the - * mode that was given when calling - * \c mbedtls_chachapoly_starts(). - * - * You may call this function multiple times to process - * an arbitrary amount of data. It is permitted to call - * this function 0 times, if no data is to be encrypted - * or decrypted. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \param ctx The ChaCha20-Poly1305 context to use. This must be initialized. - * \param len The length (in bytes) of the data to encrypt or decrypt. - * \param input The buffer containing the data to encrypt or decrypt. - * This pointer can be \c NULL if `len == 0`. - * \param output The buffer to where the encrypted or decrypted data is - * written. This must be able to hold \p len bytes. - * This pointer can be \c NULL if `len == 0`. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE - * if the operation has not been started or has been - * finished. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, - size_t len, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function finished the ChaCha20-Poly1305 operation and - * generates the MAC (authentication tag). - * - * \param ctx The ChaCha20-Poly1305 context to use. This must be initialized. - * \param mac The buffer to where the 128-bit (16 bytes) MAC is written. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE - * if the operation has not been started or has been - * finished. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, - unsigned char mac[16] ); - -/** - * \brief This function performs a complete ChaCha20-Poly1305 - * authenticated encryption with the previously-set key. - * - * \note Before using this function, you must set the key with - * \c mbedtls_chachapoly_setkey(). - * - * \warning You must never use the same nonce twice with the same key. - * This would void any confidentiality and authenticity - * guarantees for the messages encrypted with the same nonce - * and key. - * - * \param ctx The ChaCha20-Poly1305 context to use (holds the key). - * This must be initialized. - * \param length The length (in bytes) of the data to encrypt or decrypt. - * \param nonce The 96-bit (12 bytes) nonce/IV to use. - * \param aad The buffer containing the additional authenticated - * data (AAD). This pointer can be \c NULL if `aad_len == 0`. - * \param aad_len The length (in bytes) of the AAD data to process. - * \param input The buffer containing the data to encrypt or decrypt. - * This pointer can be \c NULL if `ilen == 0`. - * \param output The buffer to where the encrypted or decrypted data - * is written. This pointer can be \c NULL if `ilen == 0`. - * \param tag The buffer to where the computed 128-bit (16 bytes) MAC - * is written. This must not be \c NULL. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char *input, - unsigned char *output, - unsigned char tag[16] ); - -/** - * \brief This function performs a complete ChaCha20-Poly1305 - * authenticated decryption with the previously-set key. - * - * \note Before using this function, you must set the key with - * \c mbedtls_chachapoly_setkey(). - * - * \param ctx The ChaCha20-Poly1305 context to use (holds the key). - * \param length The length (in Bytes) of the data to decrypt. - * \param nonce The \c 96 Bit (\c 12 bytes) nonce/IV to use. - * \param aad The buffer containing the additional authenticated data (AAD). - * This pointer can be \c NULL if `aad_len == 0`. - * \param aad_len The length (in bytes) of the AAD data to process. - * \param tag The buffer holding the authentication tag. - * This must be a readable buffer of length \c 16 Bytes. - * \param input The buffer containing the data to decrypt. - * This pointer can be \c NULL if `ilen == 0`. - * \param output The buffer to where the decrypted data is written. - * This pointer can be \c NULL if `ilen == 0`. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED - * if the data was not authentic. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char tag[16], - const unsigned char *input, - unsigned char *output ); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The ChaCha20-Poly1305 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_chachapoly_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CHACHAPOLY_H */ diff --git a/mbedtls/check_config.h b/mbedtls/check_config.h deleted file mode 100644 index 5b18ec95d..000000000 --- a/mbedtls/check_config.h +++ /dev/null @@ -1,775 +0,0 @@ -#pragma GCC system_header -/** - * \file check_config.h - * - * \brief Consistency checks for configuration options - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * It is recommended to include this file from your config.h - * in order to catch dependency issues early. - */ - -#ifndef MBEDTLS_CHECK_CONFIG_H -#define MBEDTLS_CHECK_CONFIG_H - -/* - * We assume CHAR_BIT is 8 in many places. In practice, this is true on our - * target platforms, so not an issue, but let's just be extra sure. - */ -#include -#if CHAR_BIT != 8 -#error "mbed TLS requires a platform with 8-bit chars" -#endif - -#if defined(_WIN32) -#if !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_C is required on Windows" -#endif - -/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as - * it would confuse config.pl. */ -#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \ - !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) -#define MBEDTLS_PLATFORM_SNPRINTF_ALT -#endif -#endif /* _WIN32 */ - -#if defined(TARGET_LIKE_MBED) && \ - ( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) ) -#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS" -#endif - -#if defined(MBEDTLS_DEPRECATED_WARNING) && \ - !defined(__GNUC__) && !defined(__clang__) -#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" -#endif - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME) -#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" -#endif - -#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_AESNI_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) -#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) -#error "MBEDTLS_DHM_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDTLS_SSL_TRUNCATED_HMAC) -#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_CMAC_C) && \ - !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) -#error "MBEDTLS_CMAC_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_NIST_KW_C) && \ - ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) ) -#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) -#error "MBEDTLS_ECDH_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDSA_C) && \ - ( !defined(MBEDTLS_ECP_C) || \ - !defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_ASN1_WRITE_C) ) -#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECJPAKE_C) && \ - ( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) ) -#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) && \ - ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \ - defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \ - defined(MBEDTLS_ECDSA_SIGN_ALT) || \ - defined(MBEDTLS_ECDSA_VERIFY_ALT) || \ - defined(MBEDTLS_ECDSA_GENKEY_ALT) || \ - defined(MBEDTLS_ECP_INTERNAL_ALT) || \ - defined(MBEDTLS_ECP_ALT) ) -#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation" -#endif - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) -#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ - !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) ) -#error "MBEDTLS_ECP_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_C) && !( \ - defined(MBEDTLS_ECP_ALT) || \ - defined(MBEDTLS_CTR_DRBG_C) || \ - defined(MBEDTLS_HMAC_DRBG_C) || \ - defined(MBEDTLS_SHA512_C) || \ - defined(MBEDTLS_SHA256_C) || \ - defined(MBEDTLS_ECP_NO_INTERNAL_RNG)) -#error "MBEDTLS_ECP_C requires a DRBG or SHA-2 module unless MBEDTLS_ECP_NO_INTERNAL_RNG is defined or an alternative implementation is used" -#endif - -#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C) -#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites" -#endif - -#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \ - !defined(MBEDTLS_SHA256_C)) -#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites" -#endif -#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \ - defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64) -#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" -#endif -#if defined(MBEDTLS_ENTROPY_C) && \ - ( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \ - && defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32) -#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" -#endif -#if defined(MBEDTLS_ENTROPY_C) && \ - defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C) -#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" -#endif - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) -#define MBEDTLS_HAS_MEMSAN -#endif -#endif -#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN) -#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer" -#endif -#undef MBEDTLS_HAS_MEMSAN - -#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ - ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) ) -#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites" -#endif -#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ - ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ - defined(MBEDTLS_HAVEGE_C) ) -#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too" -#endif - -#if defined(MBEDTLS_GCM_C) && ( \ - !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) ) -#error "MBEDTLS_GCM_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C) -#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C) -#error "MBEDTLS_HKDF_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) -#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C) -#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ - !defined(MBEDTLS_ECDH_C) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ - ( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \ - !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ) -#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites" -#endif - -#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites" -#endif - -#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C) -#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C) -#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_C) && \ - ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) ) -#error "MBEDTLS_PK_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C) -#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C) -#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C) -#error "MBEDTLS_PKCS11_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\ - defined(MBEDTLS_PLATFORM_EXIT_ALT) ) -#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ - ( !defined(MBEDTLS_PLATFORM_C) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ - defined(MBEDTLS_PLATFORM_TIME_ALT) ) -#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ - defined(MBEDTLS_PLATFORM_TIME_ALT) ) -#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\ - defined(MBEDTLS_PLATFORM_FPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ - defined(MBEDTLS_PLATFORM_STD_FREE) -#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ - defined(MBEDTLS_PLATFORM_STD_CALLOC) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO) -#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is" -#endif - -#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\ - defined(MBEDTLS_PLATFORM_PRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ - defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ - !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) -#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\ - !defined(MBEDTLS_PLATFORM_EXIT_ALT) -#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ - ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ - !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\ - !defined(MBEDTLS_PLATFORM_PRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\ - !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) ) -#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\ - !defined(MBEDTLS_ENTROPY_NV_SEED) -#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\ - !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\ - !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\ - defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) -#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\ - defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) -#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) ) -#error "MBEDTLS_RSA_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled" -#endif - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) -#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \ - !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) ) -#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" -#endif - -#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ - !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ) -#error "One or more versions of the TLS protocol are enabled " \ - "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx" -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C) -#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \ - !defined(MBEDTLS_MD_C) ) -#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C) -#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2)) -#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1)) -#error "Illegal protocol selection" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1)) -#error "Illegal protocol selection" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1))) -#error "Illegal protocol selection" -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS) -#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ - !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ - ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ - ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites" -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites" -#endif - -#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C) -#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \ - !defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1) -#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ - !defined(MBEDTLS_X509_CRT_PARSE_C) -#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_THREADING_PTHREAD) -#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" -#endif -#define MBEDTLS_THREADING_IMPL -#endif - -#if defined(MBEDTLS_THREADING_ALT) -#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" -#endif -#define MBEDTLS_THREADING_IMPL -#endif - -#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_C defined, single threading implementation required" -#endif -#undef MBEDTLS_THREADING_IMPL - -#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C) -#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_PK_PARSE_C) ) -#error "MBEDTLS_X509_USE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \ - !defined(MBEDTLS_PK_WRITE_C) ) -#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C) -#error "MBEDTLS_CERTS_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) -#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) -#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64) -#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously" -#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */ - -#if ( defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64) ) && \ - defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously" -#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */ - -/* - * Avoid warning from -pedantic. This is a convenient place for this - * workaround since this is included by every single file before the - * #if defined(MBEDTLS_xxx_C) that results in empty translation units. - */ -typedef int mbedtls_iso_c_forbids_empty_translation_units; - -#endif /* MBEDTLS_CHECK_CONFIG_H */ diff --git a/mbedtls/cipher.c b/mbedtls/cipher.c deleted file mode 100644 index 8bd1d8a8a..000000000 --- a/mbedtls/cipher.c +++ /dev/null @@ -1,1196 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file cipher.c - * - * \brief Generic cipher wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CIPHER_C) - -#include "mbedtls/cipher.h" -#include "mbedtls/cipher_internal.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_CMAC_C) -#include "mbedtls/cmac.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#define CIPHER_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ) -#define CIPHER_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/* Compare the contents of two buffers in constant time. - * Returns 0 if the contents are bitwise identical, otherwise returns - * a non-zero value. - * This is currently only used by GCM and ChaCha20+Poly1305. - */ -static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len ) -{ - const unsigned char *p1 = (const unsigned char*) v1; - const unsigned char *p2 = (const unsigned char*) v2; - size_t i; - unsigned char diff; - - for( diff = 0, i = 0; i < len; i++ ) - diff |= p1[i] ^ p2[i]; - - return( (int)diff ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -static int supported_init = 0; - -const int *mbedtls_cipher_list( void ) -{ - const mbedtls_cipher_definition_t *def; - int *type; - - if( ! supported_init ) - { - def = mbedtls_cipher_definitions; - type = mbedtls_cipher_supported; - - while( def->type != 0 ) - *type++ = (*def++).type; - - *type = 0; - - supported_init = 1; - } - - return( mbedtls_cipher_supported ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ) -{ - const mbedtls_cipher_definition_t *def; - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( def->type == cipher_type ) - return( def->info ); - - return( NULL ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ) -{ - const mbedtls_cipher_definition_t *def; - - if( NULL == cipher_name ) - return( NULL ); - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( ! strcmp( def->info->name, cipher_name ) ) - return( def->info ); - - return( NULL ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, - int key_bitlen, - const mbedtls_cipher_mode_t mode ) -{ - const mbedtls_cipher_definition_t *def; - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( def->info->base->cipher == cipher_id && - def->info->key_bitlen == (unsigned) key_bitlen && - def->info->mode == mode ) - return( def->info ); - - return( NULL ); -} - -void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) -{ - CIPHER_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); -} - -void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_CMAC_C) - if( ctx->cmac_ctx ) - { - mbedtls_platform_zeroize( ctx->cmac_ctx, - sizeof( mbedtls_cmac_context_t ) ); - mbedtls_free( ctx->cmac_ctx ); - } -#endif - - if( ctx->cipher_ctx ) - ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); - - mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); -} - -int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); - - if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) - return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); - - ctx->cipher_info = cipher_info; - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - /* - * Ignore possible errors caused by a cipher mode that doesn't use padding - */ -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); -#else - (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); -#endif -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - - return( 0 ); -} - -int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, - const unsigned char *key, - int key_bitlen, - const mbedtls_operation_t operation ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( key != NULL ); - CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT || - operation == MBEDTLS_DECRYPT ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && - (int) ctx->cipher_info->key_bitlen != key_bitlen ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - ctx->key_bitlen = key_bitlen; - ctx->operation = operation; - - /* - * For OFB, CFB and CTR mode always use the encryption key schedule - */ - if( MBEDTLS_ENCRYPT == operation || - MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_OFB == ctx->cipher_info->mode || - MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) - { - return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, - ctx->key_bitlen ) ); - } - - if( MBEDTLS_DECRYPT == operation ) - return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, - ctx->key_bitlen ) ); - - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -} - -int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, - size_t iv_len ) -{ - size_t actual_iv_size; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* avoid buffer overflow in ctx->iv */ - if( iv_len > MBEDTLS_MAX_IV_LENGTH ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) - actual_iv_size = iv_len; - else - { - actual_iv_size = ctx->cipher_info->iv_size; - - /* avoid reading past the end of input buffer */ - if( actual_iv_size > iv_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_CHACHA20_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) - { - if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, - iv, - 0U ) ) /* Initial counter value */ - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - } -#endif - - if ( actual_iv_size != 0 ) - { - memcpy( ctx->iv, iv, actual_iv_size ); - ctx->iv_size = actual_iv_size; - } - - return( 0 ); -} - -int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - ctx->unprocessed_len = 0; - - return( 0 ); -} - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, - const unsigned char *ad, size_t ad_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, - ctx->iv, ctx->iv_size, ad, ad_len ) ); - } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - int result; - mbedtls_chachapoly_mode_t mode; - - mode = ( ctx->operation == MBEDTLS_ENCRYPT ) - ? MBEDTLS_CHACHAPOLY_ENCRYPT - : MBEDTLS_CHACHAPOLY_DECRYPT; - - result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ctx->iv, - mode ); - if ( result != 0 ) - return( result ); - - return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ad, ad_len ) ); - } -#endif - - return( 0 ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, - size_t ilen, unsigned char *output, size_t *olen ) -{ - int ret; - size_t block_size; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *olen = 0; - block_size = mbedtls_cipher_get_block_size( ctx ); - if ( 0 == block_size ) - { - return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); - } - - if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) - { - if( ilen != block_size ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - *olen = ilen; - - if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, - ctx->operation, input, output ) ) ) - { - return( ret ); - } - - return( 0 ); - } - -#if defined(MBEDTLS_GCM_C) - if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) - { - *olen = ilen; - return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, - output ) ); - } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) - { - *olen = ilen; - return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ilen, input, output ) ); - } -#endif - - if( input == output && - ( ctx->unprocessed_len != 0 || ilen % block_size ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) - { - size_t copy_len = 0; - - /* - * If there is not enough data for a full block, cache it. - */ - if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding && - ilen <= block_size - ctx->unprocessed_len ) || - ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding && - ilen < block_size - ctx->unprocessed_len ) || - ( ctx->operation == MBEDTLS_ENCRYPT && - ilen < block_size - ctx->unprocessed_len ) ) - { - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, - ilen ); - - ctx->unprocessed_len += ilen; - return( 0 ); - } - - /* - * Process cached data first - */ - if( 0 != ctx->unprocessed_len ) - { - copy_len = block_size - ctx->unprocessed_len; - - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, - copy_len ); - - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, block_size, ctx->iv, - ctx->unprocessed_data, output ) ) ) - { - return( ret ); - } - - *olen += block_size; - output += block_size; - ctx->unprocessed_len = 0; - - input += copy_len; - ilen -= copy_len; - } - - /* - * Cache final, incomplete block - */ - if( 0 != ilen ) - { - /* Encryption: only cache partial blocks - * Decryption w/ padding: always keep at least one whole block - * Decryption w/o padding: only cache partial blocks - */ - copy_len = ilen % block_size; - if( copy_len == 0 && - ctx->operation == MBEDTLS_DECRYPT && - NULL != ctx->add_padding) - { - copy_len = block_size; - } - - memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), - copy_len ); - - ctx->unprocessed_len += copy_len; - ilen -= copy_len; - } - - /* - * Process remaining full blocks - */ - if( ilen ) - { - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, ilen, ctx->iv, input, output ) ) ) - { - return( ret ); - } - - *olen += ilen; - } - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) - { - if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, - ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, - input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB ) - { - if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx, - ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) - { - if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, - ilen, &ctx->unprocessed_len, ctx->iv, - ctx->unprocessed_data, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) - { - if( ctx->unprocessed_len > 0 ) { - /* We can only process an entire data unit at a time. */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, - ctx->operation, ilen, ctx->iv, input, output ); - if( ret != 0 ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) - { - if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, - ilen, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_STREAM */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) -/* - * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len - */ -static void add_pkcs_padding( unsigned char *output, size_t output_len, - size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i; - - for( i = 0; i < padding_len; i++ ) - output[data_len + i] = (unsigned char) padding_len; -} - -static int get_pkcs_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i, pad_idx; - unsigned char padding_len, bad = 0; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - padding_len = input[input_len - 1]; - *data_len = input_len - padding_len; - - /* Avoid logical || since it results in a branch */ - bad |= padding_len > input_len; - bad |= padding_len == 0; - - /* The number of bytes checked must be independent of padding_len, - * so pick input_len, which is usually 8 or 16 (one block) */ - pad_idx = input_len - padding_len; - for( i = 0; i < input_len; i++ ) - bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); -} -#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ - -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) -/* - * One and zeros padding: fill with 80 00 ... 00 - */ -static void add_one_and_zeros_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - output[data_len] = 0x80; - for( i = 1; i < padding_len; i++ ) - output[data_len + i] = 0x00; -} - -static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i; - unsigned char done = 0, prev_done, bad; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - bad = 0x80; - *data_len = 0; - for( i = input_len; i > 0; i-- ) - { - prev_done = done; - done |= ( input[i - 1] != 0 ); - *data_len |= ( i - 1 ) * ( done != prev_done ); - bad ^= input[i - 1] * ( done != prev_done ); - } - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); - -} -#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) -/* - * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length - */ -static void add_zeros_and_len_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - for( i = 1; i < padding_len; i++ ) - output[data_len + i - 1] = 0x00; - output[output_len - 1] = (unsigned char) padding_len; -} - -static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i, pad_idx; - unsigned char padding_len, bad = 0; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - padding_len = input[input_len - 1]; - *data_len = input_len - padding_len; - - /* Avoid logical || since it results in a branch */ - bad |= padding_len > input_len; - bad |= padding_len == 0; - - /* The number of bytes checked must be independent of padding_len */ - pad_idx = input_len - padding_len; - for( i = 0; i < input_len - 1; i++ ) - bad |= input[i] * ( i >= pad_idx ); - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) -/* - * Zero padding: fill with 00 ... 00 - */ -static void add_zeros_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t i; - - for( i = data_len; i < output_len; i++ ) - output[i] = 0x00; -} - -static int get_zeros_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i; - unsigned char done = 0, prev_done; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *data_len = 0; - for( i = input_len; i > 0; i-- ) - { - prev_done = done; - done |= ( input[i-1] != 0 ); - *data_len |= i * ( done != prev_done ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ - -/* - * No padding: don't pad :) - * - * There is no add_padding function (check for NULL in mbedtls_cipher_finish) - * but a trivial get_padding function - */ -static int get_no_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *data_len = input_len; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *olen = 0; - - if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_OFB == ctx->cipher_info->mode || - MBEDTLS_MODE_CTR == ctx->cipher_info->mode || - MBEDTLS_MODE_GCM == ctx->cipher_info->mode || - MBEDTLS_MODE_XTS == ctx->cipher_info->mode || - MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) - { - return( 0 ); - } - - if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || - ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) - { - return( 0 ); - } - - if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) - { - if( ctx->unprocessed_len != 0 ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - return( 0 ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) - { - int ret = 0; - - if( MBEDTLS_ENCRYPT == ctx->operation ) - { - /* check for 'no padding' mode */ - if( NULL == ctx->add_padding ) - { - if( 0 != ctx->unprocessed_len ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - return( 0 ); - } - - ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), - ctx->unprocessed_len ); - } - else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) - { - /* - * For decrypt operations, expect a full block, - * or an empty block if no padding - */ - if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) - return( 0 ); - - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - } - - /* cipher block */ - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, - ctx->unprocessed_data, output ) ) ) - { - return( ret ); - } - - /* Set output size for decryption */ - if( MBEDTLS_DECRYPT == ctx->operation ) - return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), - olen ) ); - - /* Set output size for encryption */ - *olen = mbedtls_cipher_get_block_size( ctx ); - return( 0 ); - } -#else - ((void) output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, - mbedtls_cipher_padding_t mode ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - - if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - switch( mode ) - { -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - case MBEDTLS_PADDING_PKCS7: - ctx->add_padding = add_pkcs_padding; - ctx->get_padding = get_pkcs_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) - case MBEDTLS_PADDING_ONE_AND_ZEROS: - ctx->add_padding = add_one_and_zeros_padding; - ctx->get_padding = get_one_and_zeros_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) - case MBEDTLS_PADDING_ZEROS_AND_LEN: - ctx->add_padding = add_zeros_and_len_padding; - ctx->get_padding = get_zeros_and_len_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) - case MBEDTLS_PADDING_ZEROS: - ctx->add_padding = add_zeros_padding; - ctx->get_padding = get_zeros_padding; - break; -#endif - case MBEDTLS_PADDING_NONE: - ctx->add_padding = NULL; - ctx->get_padding = get_no_padding; - break; - - default: - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, - unsigned char *tag, size_t tag_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_ENCRYPT != ctx->operation ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, - tag, tag_len ) ); -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* Don't allow truncated MAC for Poly1305 */ - if ( tag_len != 16U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - tag ) ); - } -#endif - - return( 0 ); -} - -int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, - const unsigned char *tag, size_t tag_len ) -{ - unsigned char check_tag[16]; - int ret; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - if( ctx->cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_DECRYPT != ctx->operation ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - if( tag_len > sizeof( check_tag ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, - check_tag, tag_len ) ) ) - { - return( ret ); - } - - /* Check the tag in "constant-time" */ - if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - - return( 0 ); - } -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* Don't allow truncated MAC for Poly1305 */ - if ( tag_len != sizeof( check_tag ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - check_tag ); - if ( ret != 0 ) - { - return( ret ); - } - - /* Check the tag in "constant-time" */ - if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - - return( 0 ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ - - return( 0 ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/* - * Packet-oriented wrapper for non-AEAD modes - */ -int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen ) -{ - int ret; - size_t finish_olen; - - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - - if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) - return( ret ); - - *olen += finish_olen; - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) -/* - * Packet-oriented encryption for AEAD modes - */ -int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - unsigned char *tag, size_t tag_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - *olen = ilen; - return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, - iv, iv_len, ad, ad_len, input, output, - tag_len, tag ) ); - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) - { - *olen = ilen; - return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, input, output, - tag, tag_len ) ); - } -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - *olen = ilen; - return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, - ilen, iv, ad, ad_len, input, output, tag ) ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -/* - * Packet-oriented decryption for AEAD modes - */ -int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - const unsigned char *tag, size_t tag_len ) -{ - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - int ret; - - *olen = ilen; - ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - tag, tag_len, input, output ); - - if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) - { - int ret; - - *olen = ilen; - ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - input, output, tag, tag_len ); - - if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) - { - int ret; - - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - *olen = ilen; - ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, - iv, ad, ad_len, tag, input, output ); - - if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ - -#endif /* MBEDTLS_CIPHER_C */ diff --git a/mbedtls/cipher.h b/mbedtls/cipher.h deleted file mode 100644 index 24d1ecd66..000000000 --- a/mbedtls/cipher.h +++ /dev/null @@ -1,898 +0,0 @@ -#pragma GCC system_header -/** - * \file cipher.h - * - * \brief This file contains an abstraction interface for use with the cipher - * primitives provided by the library. It provides a common interface to all of - * the available cipher operations. - * - * \author Adriaan de Jong - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_CIPHER_H -#define MBEDTLS_CIPHER_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include "platform_util.h" - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -#define MBEDTLS_CIPHER_MODE_AEAD -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define MBEDTLS_CIPHER_MODE_WITH_PADDING -#endif - -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ - defined(MBEDTLS_CHACHA20_C) -#define MBEDTLS_CIPHER_MODE_STREAM -#endif - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */ -#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */ -#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */ -#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ -#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ -#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ -#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */ - -/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */ - -#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */ -#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Supported cipher types. - * - * \warning RC4 and DES are considered weak ciphers and their use - * constitutes a security risk. Arm recommends considering stronger - * ciphers instead. - */ -typedef enum { - MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */ - MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */ - MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */ - MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */ - MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */ - MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ - MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */ - MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */ - MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */ - MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ -} mbedtls_cipher_id_t; - -/** - * \brief Supported {cipher type, cipher mode} pairs. - * - * \warning RC4 and DES are considered weak ciphers and their use - * constitutes a security risk. Arm recommends considering stronger - * ciphers instead. - */ -typedef enum { - MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */ - MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */ - MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */ - MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */ - MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */ - MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */ - MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */ - MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */ - MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */ - MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */ - MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */ - MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */ - MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */ - MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */ - MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */ - MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */ - MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */ - MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */ - MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */ - MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */ - MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */ - MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */ - MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */ - MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */ - MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */ - MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */ - MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */ - MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ - MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */ - MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */ - MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */ - MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ - MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ - MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ - MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ -} mbedtls_cipher_type_t; - -/** Supported cipher modes. */ -typedef enum { - MBEDTLS_MODE_NONE = 0, /**< None. */ - MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */ - MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */ - MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */ - MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */ - MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */ - MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ - MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ - MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ - MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ - MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */ -} mbedtls_cipher_mode_t; - -/** Supported cipher padding types. */ -typedef enum { - MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */ - MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */ - MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */ - MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */ - MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */ -} mbedtls_cipher_padding_t; - -/** Type of operation. */ -typedef enum { - MBEDTLS_OPERATION_NONE = -1, - MBEDTLS_DECRYPT = 0, - MBEDTLS_ENCRYPT, -} mbedtls_operation_t; - -enum { - /** Undefined key length. */ - MBEDTLS_KEY_LENGTH_NONE = 0, - /** Key length, in bits (including parity), for DES keys. */ - MBEDTLS_KEY_LENGTH_DES = 64, - /** Key length in bits, including parity, for DES in two-key EDE. */ - MBEDTLS_KEY_LENGTH_DES_EDE = 128, - /** Key length in bits, including parity, for DES in three-key EDE. */ - MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, -}; - -/** Maximum length of any IV, in Bytes. */ -#define MBEDTLS_MAX_IV_LENGTH 16 -/** Maximum block size of any cipher, in Bytes. */ -#define MBEDTLS_MAX_BLOCK_LENGTH 16 - -/** - * Base cipher information (opaque struct). - */ -typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; - -/** - * CMAC context (opaque struct). - */ -typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; - -/** - * Cipher information. Allows calling cipher functions - * in a generic way. - */ -typedef struct mbedtls_cipher_info_t -{ - /** Full cipher identifier. For example, - * MBEDTLS_CIPHER_AES_256_CBC. - */ - mbedtls_cipher_type_t type; - - /** The cipher mode. For example, MBEDTLS_MODE_CBC. */ - mbedtls_cipher_mode_t mode; - - /** The cipher key length, in bits. This is the - * default length for variable sized ciphers. - * Includes parity bits for ciphers like DES. - */ - unsigned int key_bitlen; - - /** Name of the cipher. */ - const char * name; - - /** IV or nonce size, in Bytes. - * For ciphers that accept variable IV sizes, - * this is the recommended size. - */ - unsigned int iv_size; - - /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and - * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the - * cipher supports variable IV or variable key sizes, respectively. - */ - int flags; - - /** The block size, in Bytes. */ - unsigned int block_size; - - /** Struct for base cipher information and functions. */ - const mbedtls_cipher_base_t *base; - -} mbedtls_cipher_info_t; - -/** - * Generic cipher context. - */ -typedef struct mbedtls_cipher_context_t -{ - /** Information about the associated cipher. */ - const mbedtls_cipher_info_t *cipher_info; - - /** Key length to use. */ - int key_bitlen; - - /** Operation that the key of the context has been - * initialized for. - */ - mbedtls_operation_t operation; - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - /** Padding functions to use, if relevant for - * the specific cipher mode. - */ - void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); - int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); -#endif - - /** Buffer for input that has not been processed yet. */ - unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; - - /** Number of Bytes that have not been processed yet. */ - size_t unprocessed_len; - - /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number - * for XTS-mode. */ - unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; - - /** IV size in Bytes, for ciphers with variable-length IVs. */ - size_t iv_size; - - /** The cipher-specific context. */ - void *cipher_ctx; - -#if defined(MBEDTLS_CMAC_C) - /** CMAC-specific context. */ - mbedtls_cmac_context_t *cmac_ctx; -#endif -} mbedtls_cipher_context_t; - -/** - * \brief This function retrieves the list of ciphers supported by the generic - * cipher module. - * - * \return A statically-allocated array of ciphers. The last entry - * is zero. - */ -const int *mbedtls_cipher_list( void ); - -/** - * \brief This function retrieves the cipher-information - * structure associated with the given cipher name. - * - * \param cipher_name Name of the cipher to search for. This must not be - * \c NULL. - * - * \return The cipher information structure associated with the - * given \p cipher_name. - * \return \c NULL if the associated cipher information is not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ); - -/** - * \brief This function retrieves the cipher-information - * structure associated with the given cipher type. - * - * \param cipher_type Type of the cipher to search for. - * - * \return The cipher information structure associated with the - * given \p cipher_type. - * \return \c NULL if the associated cipher information is not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ); - -/** - * \brief This function retrieves the cipher-information - * structure associated with the given cipher ID, - * key size and mode. - * - * \param cipher_id The ID of the cipher to search for. For example, - * #MBEDTLS_CIPHER_ID_AES. - * \param key_bitlen The length of the key in bits. - * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC. - * - * \return The cipher information structure associated with the - * given \p cipher_id. - * \return \c NULL if the associated cipher information is not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, - int key_bitlen, - const mbedtls_cipher_mode_t mode ); - -/** - * \brief This function initializes a \p cipher_context as NONE. - * - * \param ctx The context to be initialized. This must not be \c NULL. - */ -void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); - -/** - * \brief This function frees and clears the cipher-specific - * context of \p ctx. Freeing \p ctx itself remains the - * responsibility of the caller. - * - * \param ctx The context to be freed. If this is \c NULL, the - * function has no effect, otherwise this must point to an - * initialized context. - */ -void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); - - -/** - * \brief This function initializes and fills the cipher-context - * structure with the appropriate values. It also clears - * the structure. - * - * \param ctx The context to initialize. This must be initialized. - * \param cipher_info The cipher to use. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the - * cipher-specific context fails. - * - * \internal Currently, the function also clears the structure. - * In future versions, the caller will be required to call - * mbedtls_cipher_init() on the structure first. - */ -int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info ); - -/** - * \brief This function returns the block size of the given cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The block size of the underlying cipher. - * \return \c 0 if \p ctx has not been initialized. - */ -static inline unsigned int mbedtls_cipher_get_block_size( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); - if( ctx->cipher_info == NULL ) - return 0; - - return ctx->cipher_info->block_size; -} - -/** - * \brief This function returns the mode of operation for - * the cipher. For example, MBEDTLS_MODE_CBC. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The mode of operation. - * \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized. - */ -static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE ); - if( ctx->cipher_info == NULL ) - return MBEDTLS_MODE_NONE; - - return ctx->cipher_info->mode; -} - -/** - * \brief This function returns the size of the IV or nonce - * of the cipher, in Bytes. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The recommended IV size if no IV has been set. - * \return \c 0 for ciphers not using an IV or a nonce. - * \return The actual size if an IV has been set. - */ -static inline int mbedtls_cipher_get_iv_size( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); - if( ctx->cipher_info == NULL ) - return 0; - - if( ctx->iv_size != 0 ) - return (int) ctx->iv_size; - - return (int) ctx->cipher_info->iv_size; -} - -/** - * \brief This function returns the type of the given cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The type of the cipher. - * \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized. - */ -static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( - ctx != NULL, MBEDTLS_CIPHER_NONE ); - if( ctx->cipher_info == NULL ) - return MBEDTLS_CIPHER_NONE; - - return ctx->cipher_info->type; -} - -/** - * \brief This function returns the name of the given cipher - * as a string. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The name of the cipher. - * \return NULL if \p ctx has not been not initialized. - */ -static inline const char *mbedtls_cipher_get_name( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); - if( ctx->cipher_info == NULL ) - return 0; - - return ctx->cipher_info->name; -} - -/** - * \brief This function returns the key length of the cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The key length of the cipher in bits. - * \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been - * initialized. - */ -static inline int mbedtls_cipher_get_key_bitlen( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( - ctx != NULL, MBEDTLS_KEY_LENGTH_NONE ); - if( ctx->cipher_info == NULL ) - return MBEDTLS_KEY_LENGTH_NONE; - - return (int) ctx->cipher_info->key_bitlen; -} - -/** - * \brief This function returns the operation of the given cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. - * \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized. - */ -static inline mbedtls_operation_t mbedtls_cipher_get_operation( - const mbedtls_cipher_context_t *ctx ) -{ - MBEDTLS_INTERNAL_VALIDATE_RET( - ctx != NULL, MBEDTLS_OPERATION_NONE ); - if( ctx->cipher_info == NULL ) - return MBEDTLS_OPERATION_NONE; - - return ctx->operation; -} - -/** - * \brief This function sets the key to use with the given context. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param key The key to use. This must be a readable buffer of at - * least \p key_bitlen Bits. - * \param key_bitlen The key length to use, in Bits. - * \param operation The operation that the key will be used for: - * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, - const unsigned char *key, - int key_bitlen, - const mbedtls_operation_t operation ); - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -/** - * \brief This function sets the padding mode, for cipher modes - * that use padding. - * - * The default passing mode is PKCS7 padding. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param mode The padding mode. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE - * if the selected padding mode is not supported. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode - * does not support padding. - */ -int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, - mbedtls_cipher_padding_t mode ); -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -/** - * \brief This function sets the initialization vector (IV) - * or nonce. - * - * \note Some ciphers do not use IVs nor nonce. For these - * ciphers, this function has no effect. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This - * must be a readable buffer of at least \p iv_len Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - */ -int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, - size_t iv_len ); - -/** - * \brief This function resets the cipher state. - * - * \param ctx The generic cipher context. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - */ -int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/** - * \brief This function adds additional data for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called exactly once, after - * mbedtls_cipher_reset(). - * - * \param ctx The generic cipher context. This must be initialized. - * \param ad The additional data to use. This must be a readable - * buffer of at least \p ad_len Bytes. - * \param ad_len the Length of \p ad Bytes. - * - * \return \c 0 on success. - * \return A specific error code on failure. - */ -int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, - const unsigned char *ad, size_t ad_len ); -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/** - * \brief The generic cipher update function. It encrypts or - * decrypts using the given cipher context. Writes as - * many block-sized blocks of data as possible to output. - * Any data that cannot be written immediately is either - * added to the next block, or flushed when - * mbedtls_cipher_finish() is called. - * Exception: For MBEDTLS_MODE_ECB, expects a single block - * in size. For example, 16 Bytes for AES. - * - * \note If the underlying cipher is used in GCM mode, all calls - * to this function, except for the last one before - * mbedtls_cipher_finish(), must have \p ilen as a - * multiple of the block size of the cipher. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data. - * \param output The buffer for the output data. This must be able to - * hold at least `ilen + block_size`. This must not be the - * same buffer as \p input. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an - * unsupported mode for a cipher. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, - size_t ilen, unsigned char *output, size_t *olen ); - -/** - * \brief The generic cipher finalization function. If data still - * needs to be flushed from an incomplete block, the data - * contained in it is padded to the size of - * the last block, and written to the \p output buffer. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param output The buffer to write data to. This needs to be a writable - * buffer of at least \p block_size Bytes. - * \param olen The length of the data written to the \p output buffer. - * This may not be \c NULL. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption - * expecting a full block but not receiving one. - * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen ); - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/** - * \brief This function writes a tag for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called after mbedtls_cipher_finish(). - * - * \param ctx The generic cipher context. This must be initialized, - * bound to a key, and have just completed a cipher - * operation through mbedtls_cipher_finish() the tag for - * which should be written. - * \param tag The buffer to write the tag to. This must be a writable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to write. - * - * \return \c 0 on success. - * \return A specific error code on failure. - */ -int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, - unsigned char *tag, size_t tag_len ); - -/** - * \brief This function checks the tag for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called after mbedtls_cipher_finish(). - * - * \param ctx The generic cipher context. This must be initialized. - * \param tag The buffer holding the tag. This must be a readable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to check. - * - * \return \c 0 on success. - * \return A specific error code on failure. - */ -int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, - const unsigned char *tag, size_t tag_len ); -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/** - * \brief The generic all-in-one encryption/decryption function, - * for all ciphers except AEAD constructs. - * - * \param ctx The generic cipher context. This must be initialized. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size - * IV. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The buffer for the output data. This must be able to - * hold at least `ilen + block_size`. This must not be the - * same buffer as \p input. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * - * \note Some ciphers do not use IVs nor nonce. For these - * ciphers, use \p iv = NULL and \p iv_len = 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption - * expecting a full block but not receiving one. - * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen ); - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) -/** - * \brief The generic autenticated encryption (AEAD) function. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. - * \param ad The additional data to authenticate. This must be a - * readable buffer of at least \p ad_len Bytes. - * \param ad_len The length of \p ad. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data. - * \param output The buffer for the output data. This must be able to - * hold at least \p ilen Bytes. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * \param tag The buffer for the authentication tag. This must be a - * writable buffer of at least \p tag_len Bytes. - * \param tag_len The desired length of the authentication tag. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - unsigned char *tag, size_t tag_len ); - -/** - * \brief The generic autenticated decryption (AEAD) function. - * - * \note If the data is not authentic, then the output buffer - * is zeroed out to prevent the unauthentic plaintext being - * used, making this interface safer. - * - * \param ctx The generic cipher context. This must be initialized and - * and bound to a key. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. - * \param ad The additional data to be authenticated. This must be a - * readable buffer of at least \p ad_len Bytes. - * \param ad_len The length of \p ad. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data. - * \param output The buffer for the output data. - * This must be able to hold at least \p ilen Bytes. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * \param tag The buffer holding the authentication tag. This must be - * a readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication tag. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - const unsigned char *tag, size_t tag_len ); -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CIPHER_H */ diff --git a/mbedtls/cipher_internal.h b/mbedtls/cipher_internal.h deleted file mode 100644 index fd1b9511b..000000000 --- a/mbedtls/cipher_internal.h +++ /dev/null @@ -1,151 +0,0 @@ -#pragma GCC system_header -/** - * \file cipher_internal.h - * - * \brief Cipher wrappers. - * - * \author Adriaan de Jong - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_CIPHER_WRAP_H -#define MBEDTLS_CIPHER_WRAP_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "cipher.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Base cipher information. The non-mode specific functions and values. - */ -struct mbedtls_cipher_base_t -{ - /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ - mbedtls_cipher_id_t cipher; - - /** Encrypt using ECB */ - int (*ecb_func)( void *ctx, mbedtls_operation_t mode, - const unsigned char *input, unsigned char *output ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /** Encrypt using CBC */ - int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length, - unsigned char *iv, const unsigned char *input, - unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - /** Encrypt using CFB (Full length) */ - int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, - unsigned char *iv, const unsigned char *input, - unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - /** Encrypt using OFB (Full length) */ - int (*ofb_func)( void *ctx, size_t length, size_t *iv_off, - unsigned char *iv, - const unsigned char *input, - unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /** Encrypt using CTR */ - int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - /** Encrypt or decrypt using XTS. */ - int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length, - const unsigned char data_unit[16], - const unsigned char *input, unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - /** Encrypt using STREAM */ - int (*stream_func)( void *ctx, size_t length, - const unsigned char *input, unsigned char *output ); -#endif - - /** Set key for encryption purposes */ - int (*setkey_enc_func)( void *ctx, const unsigned char *key, - unsigned int key_bitlen ); - - /** Set key for decryption purposes */ - int (*setkey_dec_func)( void *ctx, const unsigned char *key, - unsigned int key_bitlen); - - /** Allocate a new context */ - void * (*ctx_alloc_func)( void ); - - /** Free the given context */ - void (*ctx_free_func)( void *ctx ); - -}; - -typedef struct -{ - mbedtls_cipher_type_t type; - const mbedtls_cipher_info_t *info; -} mbedtls_cipher_definition_t; - -extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; - -extern int mbedtls_cipher_supported[]; - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CIPHER_WRAP_H */ diff --git a/mbedtls/cipher_wrap.c b/mbedtls/cipher_wrap.c deleted file mode 100644 index 6e909a4f5..000000000 --- a/mbedtls/cipher_wrap.c +++ /dev/null @@ -1,2310 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file cipher_wrap.c - * - * \brief Generic cipher wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CIPHER_C) - -#include "mbedtls/cipher_internal.h" - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#endif - -#if defined(MBEDTLS_ARC4_C) -#include "mbedtls/arc4.h" -#endif - -#if defined(MBEDTLS_CAMELLIA_C) -#include "mbedtls/camellia.h" -#endif - -#if defined(MBEDTLS_ARIA_C) -#include "mbedtls/aria.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_BLOWFISH_C) -#include "mbedtls/blowfish.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#include -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_GCM_C) -/* shared by all GCM ciphers */ -static void *gcm_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); - - if( ctx != NULL ) - mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); - - return( ctx ); -} - -static void gcm_ctx_free( void *ctx ) -{ - mbedtls_gcm_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -/* shared by all CCM ciphers */ -static void *ccm_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); - - if( ctx != NULL ) - mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); - - return( ctx ); -} - -static void ccm_ctx_free( void *ctx ) -{ - mbedtls_ccm_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_CCM_C */ - -#if defined(MBEDTLS_AES_C) - -static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off, - iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, - stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - int mode; - - switch( operation ) - { - case MBEDTLS_ENCRYPT: - mode = MBEDTLS_AES_ENCRYPT; - break; - case MBEDTLS_DECRYPT: - mode = MBEDTLS_AES_DECRYPT; - break; - default: - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return mbedtls_aes_crypt_xts( xts_ctx, mode, length, - data_unit, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); -} - -static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); -} - -static void * aes_ctx_alloc( void ) -{ - mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); - - if( aes == NULL ) - return( NULL ); - - mbedtls_aes_init( aes ); - - return( aes ); -} - -static void aes_ctx_free( void *ctx ) -{ - mbedtls_aes_free( (mbedtls_aes_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t aes_info = { - MBEDTLS_CIPHER_ID_AES, - aes_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - aes_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - aes_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - aes_crypt_ofb_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - aes_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - aes_setkey_enc_wrap, - aes_setkey_dec_wrap, - aes_ctx_alloc, - aes_ctx_free -}; - -static const mbedtls_cipher_info_t aes_128_ecb_info = { - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "AES-128-ECB", - 0, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ecb_info = { - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "AES-192-ECB", - 0, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ecb_info = { - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "AES-256-ECB", - 0, - 0, - 16, - &aes_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aes_128_cbc_info = { - MBEDTLS_CIPHER_AES_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "AES-128-CBC", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_cbc_info = { - MBEDTLS_CIPHER_AES_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "AES-192-CBC", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_cbc_info = { - MBEDTLS_CIPHER_AES_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "AES-256-CBC", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aes_128_cfb128_info = { - MBEDTLS_CIPHER_AES_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "AES-128-CFB128", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_cfb128_info = { - MBEDTLS_CIPHER_AES_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "AES-192-CFB128", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_cfb128_info = { - MBEDTLS_CIPHER_AES_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "AES-256-CFB128", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -static const mbedtls_cipher_info_t aes_128_ofb_info = { - MBEDTLS_CIPHER_AES_128_OFB, - MBEDTLS_MODE_OFB, - 128, - "AES-128-OFB", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ofb_info = { - MBEDTLS_CIPHER_AES_192_OFB, - MBEDTLS_MODE_OFB, - 192, - "AES-192-OFB", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ofb_info = { - MBEDTLS_CIPHER_AES_256_OFB, - MBEDTLS_MODE_OFB, - 256, - "AES-256-OFB", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aes_128_ctr_info = { - MBEDTLS_CIPHER_AES_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "AES-128-CTR", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ctr_info = { - MBEDTLS_CIPHER_AES_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "AES-192-CTR", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ctr_info = { - MBEDTLS_CIPHER_AES_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "AES-256-CTR", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) ); -} - -static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) ); -} - -static void *xts_aes_ctx_alloc( void ) -{ - mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) ); - - if( xts_ctx != NULL ) - mbedtls_aes_xts_init( xts_ctx ); - - return( xts_ctx ); -} - -static void xts_aes_ctx_free( void *ctx ) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - - if( xts_ctx == NULL ) - return; - - mbedtls_aes_xts_free( xts_ctx ); - mbedtls_free( xts_ctx ); -} - -static const mbedtls_cipher_base_t xts_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - aes_crypt_xts_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - xts_aes_setkey_enc_wrap, - xts_aes_setkey_dec_wrap, - xts_aes_ctx_alloc, - xts_aes_ctx_free -}; - -static const mbedtls_cipher_info_t aes_128_xts_info = { - MBEDTLS_CIPHER_AES_128_XTS, - MBEDTLS_MODE_XTS, - 256, - "AES-128-XTS", - 16, - 0, - 16, - &xts_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_xts_info = { - MBEDTLS_CIPHER_AES_256_XTS, - MBEDTLS_MODE_XTS, - 512, - "AES-256-XTS", - 16, - 0, - 16, - &xts_aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_aes_setkey_wrap, - gcm_aes_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_gcm_info = { - MBEDTLS_CIPHER_AES_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "AES-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_gcm_info = { - MBEDTLS_CIPHER_AES_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "AES-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_gcm_info = { - MBEDTLS_CIPHER_AES_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "AES-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_aes_setkey_wrap, - ccm_aes_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_ccm_info = { - MBEDTLS_CIPHER_AES_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "AES-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ccm_info = { - MBEDTLS_CIPHER_AES_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "AES-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ccm_info = { - MBEDTLS_CIPHER_AES_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "AES-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - -static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); -} - -static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); -} - -static void * camellia_ctx_alloc( void ) -{ - mbedtls_camellia_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_camellia_init( ctx ); - - return( ctx ); -} - -static void camellia_ctx_free( void *ctx ) -{ - mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - camellia_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - camellia_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - camellia_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - camellia_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - camellia_setkey_enc_wrap, - camellia_setkey_dec_wrap, - camellia_ctx_alloc, - camellia_ctx_free -}; - -static const mbedtls_cipher_info_t camellia_128_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "CAMELLIA-128-ECB", - 0, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "CAMELLIA-192-ECB", - 0, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "CAMELLIA-256-ECB", - 0, - 0, - 16, - &camellia_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t camellia_128_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "CAMELLIA-128-CBC", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "CAMELLIA-192-CBC", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "CAMELLIA-256-CBC", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t camellia_128_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "CAMELLIA-128-CFB128", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "CAMELLIA-192-CFB128", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "CAMELLIA-256-CFB128", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t camellia_128_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "CAMELLIA-128-CTR", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "CAMELLIA-192-CTR", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "CAMELLIA-256-CTR", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_camellia_setkey_wrap, - gcm_camellia_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "CAMELLIA-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "CAMELLIA-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "CAMELLIA-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_camellia_setkey_wrap, - ccm_camellia_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "CAMELLIA-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "CAMELLIA-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "CAMELLIA-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_ARIA_C) - -static int aria_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - (void) operation; - return mbedtls_aria_crypt_ecb( (mbedtls_aria_context *) ctx, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int aria_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aria_crypt_cbc( (mbedtls_aria_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int aria_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aria_crypt_cfb128( (mbedtls_aria_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int aria_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aria_crypt_ctr( (mbedtls_aria_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int aria_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aria_setkey_dec( (mbedtls_aria_context *) ctx, key, key_bitlen ); -} - -static int aria_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aria_setkey_enc( (mbedtls_aria_context *) ctx, key, key_bitlen ); -} - -static void * aria_ctx_alloc( void ) -{ - mbedtls_aria_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_aria_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_aria_init( ctx ); - - return( ctx ); -} - -static void aria_ctx_free( void *ctx ) -{ - mbedtls_aria_free( (mbedtls_aria_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - aria_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - aria_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - aria_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - aria_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - aria_setkey_enc_wrap, - aria_setkey_dec_wrap, - aria_ctx_alloc, - aria_ctx_free -}; - -static const mbedtls_cipher_info_t aria_128_ecb_info = { - MBEDTLS_CIPHER_ARIA_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "ARIA-128-ECB", - 0, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_ecb_info = { - MBEDTLS_CIPHER_ARIA_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "ARIA-192-ECB", - 0, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_ecb_info = { - MBEDTLS_CIPHER_ARIA_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "ARIA-256-ECB", - 0, - 0, - 16, - &aria_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aria_128_cbc_info = { - MBEDTLS_CIPHER_ARIA_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "ARIA-128-CBC", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_cbc_info = { - MBEDTLS_CIPHER_ARIA_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "ARIA-192-CBC", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_cbc_info = { - MBEDTLS_CIPHER_ARIA_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "ARIA-256-CBC", - 16, - 0, - 16, - &aria_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aria_128_cfb128_info = { - MBEDTLS_CIPHER_ARIA_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "ARIA-128-CFB128", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_cfb128_info = { - MBEDTLS_CIPHER_ARIA_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "ARIA-192-CFB128", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_cfb128_info = { - MBEDTLS_CIPHER_ARIA_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "ARIA-256-CFB128", - 16, - 0, - 16, - &aria_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aria_128_ctr_info = { - MBEDTLS_CIPHER_ARIA_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "ARIA-128-CTR", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_192_ctr_info = { - MBEDTLS_CIPHER_ARIA_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "ARIA-192-CTR", - 16, - 0, - 16, - &aria_info -}; - -static const mbedtls_cipher_info_t aria_256_ctr_info = { - MBEDTLS_CIPHER_ARIA_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "ARIA-256-CTR", - 16, - 0, - 16, - &aria_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_aria_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_aria_setkey_wrap, - gcm_aria_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t aria_128_gcm_info = { - MBEDTLS_CIPHER_ARIA_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "ARIA-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aria_info -}; - -static const mbedtls_cipher_info_t aria_192_gcm_info = { - MBEDTLS_CIPHER_ARIA_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "ARIA-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aria_info -}; - -static const mbedtls_cipher_info_t aria_256_gcm_info = { - MBEDTLS_CIPHER_ARIA_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "ARIA-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aria_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_aria_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_aria_setkey_wrap, - ccm_aria_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t aria_128_ccm_info = { - MBEDTLS_CIPHER_ARIA_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "ARIA-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aria_info -}; - -static const mbedtls_cipher_info_t aria_192_ccm_info = { - MBEDTLS_CIPHER_ARIA_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "ARIA-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aria_info -}; - -static const mbedtls_cipher_info_t aria_256_ccm_info = { - MBEDTLS_CIPHER_ARIA_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "ARIA-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aria_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_DES_C) - -static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - ((void) operation); - return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); -} - -static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - ((void) operation); - return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); -} - -static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); -} - -static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); -} - -static void * des_ctx_alloc( void ) -{ - mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); - - if( des == NULL ) - return( NULL ); - - mbedtls_des_init( des ); - - return( des ); -} - -static void des_ctx_free( void *ctx ) -{ - mbedtls_des_free( (mbedtls_des_context *) ctx ); - mbedtls_free( ctx ); -} - -static void * des3_ctx_alloc( void ) -{ - mbedtls_des3_context *des3; - des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); - - if( des3 == NULL ) - return( NULL ); - - mbedtls_des3_init( des3 ); - - return( des3 ); -} - -static void des3_ctx_free( void *ctx ) -{ - mbedtls_des3_free( (mbedtls_des3_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t des_info = { - MBEDTLS_CIPHER_ID_DES, - des_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des_setkey_enc_wrap, - des_setkey_dec_wrap, - des_ctx_alloc, - des_ctx_free -}; - -static const mbedtls_cipher_info_t des_ecb_info = { - MBEDTLS_CIPHER_DES_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES, - "DES-ECB", - 0, - 0, - 8, - &des_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_cbc_info = { - MBEDTLS_CIPHER_DES_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES, - "DES-CBC", - 8, - 0, - 8, - &des_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede_info = { - MBEDTLS_CIPHER_ID_DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set2key_enc_wrap, - des3_set2key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede_ecb_info = { - MBEDTLS_CIPHER_DES_EDE_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES_EDE, - "DES-EDE-ECB", - 0, - 0, - 8, - &des_ede_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede_cbc_info = { - MBEDTLS_CIPHER_DES_EDE_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES_EDE, - "DES-EDE-CBC", - 8, - 0, - 8, - &des_ede_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede3_info = { - MBEDTLS_CIPHER_ID_3DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set3key_enc_wrap, - des3_set3key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede3_ecb_info = { - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES_EDE3, - "DES-EDE3-ECB", - 0, - 0, - 8, - &des_ede3_info -}; -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede3_cbc_info = { - MBEDTLS_CIPHER_DES_EDE3_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES_EDE3, - "DES-EDE3-CBC", - 8, - 0, - 8, - &des_ede3_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_BLOWFISH_C) - -static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, const unsigned char *input, - unsigned char *output ) -{ - return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); -} - -static void * blowfish_ctx_alloc( void ) -{ - mbedtls_blowfish_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_blowfish_init( ctx ); - - return( ctx ); -} - -static void blowfish_ctx_free( void *ctx ) -{ - mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t blowfish_info = { - MBEDTLS_CIPHER_ID_BLOWFISH, - blowfish_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - blowfish_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - blowfish_crypt_cfb64_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - blowfish_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - blowfish_setkey_wrap, - blowfish_setkey_wrap, - blowfish_ctx_alloc, - blowfish_ctx_free -}; - -static const mbedtls_cipher_info_t blowfish_ecb_info = { - MBEDTLS_CIPHER_BLOWFISH_ECB, - MBEDTLS_MODE_ECB, - 128, - "BLOWFISH-ECB", - 0, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t blowfish_cbc_info = { - MBEDTLS_CIPHER_BLOWFISH_CBC, - MBEDTLS_MODE_CBC, - 128, - "BLOWFISH-CBC", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t blowfish_cfb64_info = { - MBEDTLS_CIPHER_BLOWFISH_CFB64, - MBEDTLS_MODE_CFB, - 128, - "BLOWFISH-CFB64", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t blowfish_ctr_info = { - MBEDTLS_CIPHER_BLOWFISH_CTR, - MBEDTLS_MODE_CTR, - 128, - "BLOWFISH-CTR", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* MBEDTLS_BLOWFISH_C */ - -#if defined(MBEDTLS_ARC4_C) -static int arc4_crypt_stream_wrap( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); -} - -static int arc4_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - /* we get key_bitlen in bits, arc4 expects it in bytes */ - if( key_bitlen % 8 != 0 ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); - return( 0 ); -} - -static void * arc4_ctx_alloc( void ) -{ - mbedtls_arc4_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_arc4_init( ctx ); - - return( ctx ); -} - -static void arc4_ctx_free( void *ctx ) -{ - mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t arc4_base_info = { - MBEDTLS_CIPHER_ID_ARC4, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - arc4_crypt_stream_wrap, -#endif - arc4_setkey_wrap, - arc4_setkey_wrap, - arc4_ctx_alloc, - arc4_ctx_free -}; - -static const mbedtls_cipher_info_t arc4_128_info = { - MBEDTLS_CIPHER_ARC4_128, - MBEDTLS_MODE_STREAM, - 128, - "ARC4-128", - 0, - 0, - 1, - &arc4_base_info -}; -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CHACHA20_C) - -static int chacha20_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - if( key_bitlen != 256U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( 0 ); -} - -static int chacha20_stream_wrap( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - - ret = mbedtls_chacha20_update( ctx, length, input, output ); - if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( ret ); -} - -static void * chacha20_ctx_alloc( void ) -{ - mbedtls_chacha20_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_chacha20_init( ctx ); - - return( ctx ); -} - -static void chacha20_ctx_free( void *ctx ) -{ - mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t chacha20_base_info = { - MBEDTLS_CIPHER_ID_CHACHA20, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - chacha20_stream_wrap, -#endif - chacha20_setkey_wrap, - chacha20_setkey_wrap, - chacha20_ctx_alloc, - chacha20_ctx_free -}; -static const mbedtls_cipher_info_t chacha20_info = { - MBEDTLS_CIPHER_CHACHA20, - MBEDTLS_MODE_STREAM, - 256, - "CHACHA20", - 12, - 0, - 1, - &chacha20_base_info -}; -#endif /* MBEDTLS_CHACHA20_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - -static int chachapoly_setkey_wrap( void *ctx, - const unsigned char *key, - unsigned int key_bitlen ) -{ - if( key_bitlen != 256U ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - return( 0 ); -} - -static void * chachapoly_ctx_alloc( void ) -{ - mbedtls_chachapoly_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_chachapoly_init( ctx ); - - return( ctx ); -} - -static void chachapoly_ctx_free( void *ctx ) -{ - mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t chachapoly_base_info = { - MBEDTLS_CIPHER_ID_CHACHA20, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - chachapoly_setkey_wrap, - chachapoly_setkey_wrap, - chachapoly_ctx_alloc, - chachapoly_ctx_free -}; -static const mbedtls_cipher_info_t chachapoly_info = { - MBEDTLS_CIPHER_CHACHA20_POLY1305, - MBEDTLS_MODE_CHACHAPOLY, - 256, - "CHACHA20-POLY1305", - 12, - 0, - 1, - &chachapoly_base_info -}; -#endif /* MBEDTLS_CHACHAPOLY_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -static int null_crypt_stream( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - ((void) ctx); - memmove( output, input, length ); - return( 0 ); -} - -static int null_setkey( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) ctx); - ((void) key); - ((void) key_bitlen); - - return( 0 ); -} - -static void * null_ctx_alloc( void ) -{ - return( (void *) 1 ); -} - -static void null_ctx_free( void *ctx ) -{ - ((void) ctx); -} - -static const mbedtls_cipher_base_t null_base_info = { - MBEDTLS_CIPHER_ID_NULL, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - null_crypt_stream, -#endif - null_setkey, - null_setkey, - null_ctx_alloc, - null_ctx_free -}; - -static const mbedtls_cipher_info_t null_cipher_info = { - MBEDTLS_CIPHER_NULL, - MBEDTLS_MODE_STREAM, - 0, - "NULL", - 0, - 0, - 1, - &null_base_info -}; -#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ - -const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = -{ -#if defined(MBEDTLS_AES_C) - { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, - { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, - { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, - { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, - { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, - { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, - { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - { MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info }, - { MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info }, - { MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, - { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, - { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info }, - { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, - { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, - { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, - { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, - { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, -#endif -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_ARC4_C) - { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, -#endif - -#if defined(MBEDTLS_BLOWFISH_C) - { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, -#endif -#endif /* MBEDTLS_BLOWFISH_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, -#endif -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_ARIA_C) - { MBEDTLS_CIPHER_ARIA_128_ECB, &aria_128_ecb_info }, - { MBEDTLS_CIPHER_ARIA_192_ECB, &aria_192_ecb_info }, - { MBEDTLS_CIPHER_ARIA_256_ECB, &aria_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_ARIA_128_CBC, &aria_128_cbc_info }, - { MBEDTLS_CIPHER_ARIA_192_CBC, &aria_192_cbc_info }, - { MBEDTLS_CIPHER_ARIA_256_CBC, &aria_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_ARIA_128_CFB128, &aria_128_cfb128_info }, - { MBEDTLS_CIPHER_ARIA_192_CFB128, &aria_192_cfb128_info }, - { MBEDTLS_CIPHER_ARIA_256_CFB128, &aria_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_ARIA_128_CTR, &aria_128_ctr_info }, - { MBEDTLS_CIPHER_ARIA_192_CTR, &aria_192_ctr_info }, - { MBEDTLS_CIPHER_ARIA_256_CTR, &aria_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_ARIA_128_GCM, &aria_128_gcm_info }, - { MBEDTLS_CIPHER_ARIA_192_GCM, &aria_192_gcm_info }, - { MBEDTLS_CIPHER_ARIA_256_GCM, &aria_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_ARIA_128_CCM, &aria_128_ccm_info }, - { MBEDTLS_CIPHER_ARIA_192_CCM, &aria_192_ccm_info }, - { MBEDTLS_CIPHER_ARIA_256_CCM, &aria_256_ccm_info }, -#endif -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_DES_C) - { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, -#endif -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_CHACHA20_C) - { MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info }, -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) - { MBEDTLS_CIPHER_NULL, &null_cipher_info }, -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ - - { MBEDTLS_CIPHER_NONE, NULL } -}; - -#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0] -int mbedtls_cipher_supported[NUM_CIPHERS]; - -#endif /* MBEDTLS_CIPHER_C */ diff --git a/mbedtls/cmac.c b/mbedtls/cmac.c deleted file mode 100644 index 4e09e8cbb..000000000 --- a/mbedtls/cmac.c +++ /dev/null @@ -1,1116 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file cmac.c - * - * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * References: - * - * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The - * CMAC Mode for Authentication - * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf - * - * - RFC 4493 - The AES-CMAC Algorithm - * https://tools.ietf.org/html/rfc4493 - * - * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message - * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) - * Algorithm for the Internet Key Exchange Protocol (IKE) - * https://tools.ietf.org/html/rfc4615 - * - * Additional test vectors: ISO/IEC 9797-1 - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CMAC_C) - -#include "mbedtls/cmac.h" -#include "mbedtls/platform_util.h" - -#include - - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#if defined(MBEDTLS_SELF_TEST) -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_SELF_TEST */ -#endif /* MBEDTLS_PLATFORM_C */ - -#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) - -/* - * Multiplication by u in the Galois field of GF(2^n) - * - * As explained in NIST SP 800-38B, this can be computed: - * - * If MSB(p) = 0, then p = (p << 1) - * If MSB(p) = 1, then p = (p << 1) ^ R_n - * with R_64 = 0x1B and R_128 = 0x87 - * - * Input and output MUST NOT point to the same buffer - * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES. - */ -static int cmac_multiply_by_u( unsigned char *output, - const unsigned char *input, - size_t blocksize ) -{ - const unsigned char R_128 = 0x87; - const unsigned char R_64 = 0x1B; - unsigned char R_n, mask; - unsigned char overflow = 0x00; - int i; - - if( blocksize == MBEDTLS_AES_BLOCK_SIZE ) - { - R_n = R_128; - } - else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE ) - { - R_n = R_64; - } - else - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - for( i = (int)blocksize - 1; i >= 0; i-- ) - { - output[i] = input[i] << 1 | overflow; - overflow = input[i] >> 7; - } - - /* mask = ( input[0] >> 7 ) ? 0xff : 0x00 - * using bit operations to avoid branches */ - - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - mask = - ( input[0] >> 7 ); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - output[ blocksize - 1 ] ^= R_n & mask; - - return( 0 ); -} - -/* - * Generate subkeys - * - * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm - */ -static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx, - unsigned char* K1, unsigned char* K2 ) -{ - int ret; - unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX]; - size_t olen, block_size; - - mbedtls_platform_zeroize( L, sizeof( L ) ); - - block_size = ctx->cipher_info->block_size; - - /* Calculate Ek(0) */ - if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 ) - goto exit; - - /* - * Generate K1 and K2 - */ - if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 ) - goto exit; - - if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 ) - goto exit; - -exit: - mbedtls_platform_zeroize( L, sizeof( L ) ); - - return( ret ); -} -#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */ - -#if !defined(MBEDTLS_CMAC_ALT) -static void cmac_xor_block( unsigned char *output, const unsigned char *input1, - const unsigned char *input2, - const size_t block_size ) -{ - size_t idx; - - for( idx = 0; idx < block_size; idx++ ) - output[ idx ] = input1[ idx ] ^ input2[ idx ]; -} - -/* - * Create padded last block from (partial) last block. - * - * We can't use the padding option from the cipher layer, as it only works for - * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition. - */ -static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX], - size_t padded_block_len, - const unsigned char *last_block, - size_t last_block_len ) -{ - size_t j; - - for( j = 0; j < padded_block_len; j++ ) - { - if( j < last_block_len ) - padded_block[j] = last_block[j]; - else if( j == last_block_len ) - padded_block[j] = 0x80; - else - padded_block[j] = 0x00; - } -} - -int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, - const unsigned char *key, size_t keybits ) -{ - mbedtls_cipher_type_t type; - mbedtls_cmac_context_t *cmac_ctx; - int retval; - - if( ctx == NULL || ctx->cipher_info == NULL || key == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - return( retval ); - - type = ctx->cipher_info->type; - - switch( type ) - { - case MBEDTLS_CIPHER_AES_128_ECB: - case MBEDTLS_CIPHER_AES_192_ECB: - case MBEDTLS_CIPHER_AES_256_ECB: - case MBEDTLS_CIPHER_DES_EDE3_ECB: - break; - default: - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - /* Allocated and initialise in the cipher context memory for the CMAC - * context */ - cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) ); - if( cmac_ctx == NULL ) - return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); - - ctx->cmac_ctx = cmac_ctx; - - mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) ); - - return 0; -} - -int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, - const unsigned char *input, size_t ilen ) -{ - mbedtls_cmac_context_t* cmac_ctx; - unsigned char *state; - int ret = 0; - size_t n, j, olen, block_size; - - if( ctx == NULL || ctx->cipher_info == NULL || input == NULL || - ctx->cmac_ctx == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - cmac_ctx = ctx->cmac_ctx; - block_size = ctx->cipher_info->block_size; - state = ctx->cmac_ctx->state; - - /* Is there data still to process from the last call, that's greater in - * size than a block? */ - if( cmac_ctx->unprocessed_len > 0 && - ilen > block_size - cmac_ctx->unprocessed_len ) - { - memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], - input, - block_size - cmac_ctx->unprocessed_len ); - - cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size ); - - if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, - &olen ) ) != 0 ) - { - goto exit; - } - - input += block_size - cmac_ctx->unprocessed_len; - ilen -= block_size - cmac_ctx->unprocessed_len; - cmac_ctx->unprocessed_len = 0; - } - - /* n is the number of blocks including any final partial block */ - n = ( ilen + block_size - 1 ) / block_size; - - /* Iterate across the input data in block sized chunks, excluding any - * final partial or complete block */ - for( j = 1; j < n; j++ ) - { - cmac_xor_block( state, input, state, block_size ); - - if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, - &olen ) ) != 0 ) - goto exit; - - ilen -= block_size; - input += block_size; - } - - /* If there is data left over that wasn't aligned to a block */ - if( ilen > 0 ) - { - memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], - input, - ilen ); - cmac_ctx->unprocessed_len += ilen; - } - -exit: - return( ret ); -} - -int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output ) -{ - mbedtls_cmac_context_t* cmac_ctx; - unsigned char *state, *last_block; - unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; - unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; - unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX]; - int ret; - size_t olen, block_size; - - if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL || - output == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - cmac_ctx = ctx->cmac_ctx; - block_size = ctx->cipher_info->block_size; - state = cmac_ctx->state; - - mbedtls_platform_zeroize( K1, sizeof( K1 ) ); - mbedtls_platform_zeroize( K2, sizeof( K2 ) ); - cmac_generate_subkeys( ctx, K1, K2 ); - - last_block = cmac_ctx->unprocessed_block; - - /* Calculate last block */ - if( cmac_ctx->unprocessed_len < block_size ) - { - cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len ); - cmac_xor_block( M_last, M_last, K2, block_size ); - } - else - { - /* Last block is complete block */ - cmac_xor_block( M_last, last_block, K1, block_size ); - } - - - cmac_xor_block( state, M_last, state, block_size ); - if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, - &olen ) ) != 0 ) - { - goto exit; - } - - memcpy( output, state, block_size ); - -exit: - /* Wipe the generated keys on the stack, and any other transients to avoid - * side channel leakage */ - mbedtls_platform_zeroize( K1, sizeof( K1 ) ); - mbedtls_platform_zeroize( K2, sizeof( K2 ) ); - - cmac_ctx->unprocessed_len = 0; - mbedtls_platform_zeroize( cmac_ctx->unprocessed_block, - sizeof( cmac_ctx->unprocessed_block ) ); - - mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX ); - return( ret ); -} - -int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ) -{ - mbedtls_cmac_context_t* cmac_ctx; - - if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - cmac_ctx = ctx->cmac_ctx; - - /* Reset the internal state */ - cmac_ctx->unprocessed_len = 0; - mbedtls_platform_zeroize( cmac_ctx->unprocessed_block, - sizeof( cmac_ctx->unprocessed_block ) ); - mbedtls_platform_zeroize( cmac_ctx->state, - sizeof( cmac_ctx->state ) ); - - return( 0 ); -} - -int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, - const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - mbedtls_cipher_context_t ctx; - int ret; - - if( cipher_info == NULL || key == NULL || input == NULL || output == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - mbedtls_cipher_init( &ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) - goto exit; - - ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_cipher_cmac_update( &ctx, input, ilen ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_cipher_cmac_finish( &ctx, output ); - -exit: - mbedtls_cipher_free( &ctx ); - - return( ret ); -} - -#if defined(MBEDTLS_AES_C) -/* - * Implementation of AES-CMAC-PRF-128 defined in RFC 4615 - */ -int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length, - const unsigned char *input, size_t in_len, - unsigned char output[16] ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE]; - unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE]; - - if( key == NULL || input == NULL || output == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB ); - if( cipher_info == NULL ) - { - /* Failing at this point must be due to a build issue */ - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto exit; - } - - if( key_length == MBEDTLS_AES_BLOCK_SIZE ) - { - /* Use key as is */ - memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE ); - } - else - { - memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE ); - - ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key, - key_length, int_key ); - if( ret != 0 ) - goto exit; - } - - ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len, - output ); - -exit: - mbedtls_platform_zeroize( int_key, sizeof( int_key ) ); - - return( ret ); -} -#endif /* MBEDTLS_AES_C */ - -#endif /* !MBEDTLS_CMAC_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * CMAC test data for SP800-38B - * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf - * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf - * - * AES-CMAC-PRF-128 test data from RFC 4615 - * https://tools.ietf.org/html/rfc4615#page-4 - */ - -#define NB_CMAC_TESTS_PER_KEY 4 -#define NB_PRF_TESTS 3 - -#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) -/* All CMAC test inputs are truncated from the same 64 byte buffer. */ -static const unsigned char test_message[] = { - /* PT */ - 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, - 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, - 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, - 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, - 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 -}; -#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) -/* Truncation point of message for AES CMAC tests */ -static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { - /* Mlen */ - 0, - 16, - 20, - 64 -}; - -/* CMAC-AES128 Test Data */ -static const unsigned char aes_128_key[16] = { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c -}; -static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* K1 */ - 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66, - 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde - }, - { - /* K2 */ - 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc, - 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b - } -}; -static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* Example #1 */ - 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, - 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 - }, - { - /* Example #2 */ - 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, - 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c - }, - { - /* Example #3 */ - 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8, - 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde - }, - { - /* Example #4 */ - 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, - 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe - } -}; - -/* CMAC-AES192 Test Data */ -static const unsigned char aes_192_key[24] = { - 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, - 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, - 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b -}; -static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* K1 */ - 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27, - 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96 - }, - { - /* K2 */ - 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e, - 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c - } -}; -static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* Example #1 */ - 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, - 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67 - }, - { - /* Example #2 */ - 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, - 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 - }, - { - /* Example #3 */ - 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04, - 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8 - }, - { - /* Example #4 */ - 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, - 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11 - } -}; - -/* CMAC-AES256 Test Data */ -static const unsigned char aes_256_key[32] = { - 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, - 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, - 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, - 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 -}; -static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* K1 */ - 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac, - 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f - }, - { - /* K2 */ - 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58, - 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9 - } -}; -static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* Example #1 */ - 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, - 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83 - }, - { - /* Example #2 */ - 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, - 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c - }, - { - /* Example #3 */ - 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a, - 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93 - }, - { - /* Example #4 */ - 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, - 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10 - } -}; -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_DES_C) -/* Truncation point of message for 3DES CMAC tests */ -static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { - 0, - 16, - 20, - 32 -}; - -/* CMAC-TDES (Generation) - 2 Key Test Data */ -static const unsigned char des3_2key_key[24] = { - /* Key1 */ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - /* Key2 */ - 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01, - /* Key3 */ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef -}; -static const unsigned char des3_2key_subkeys[2][8] = { - { - /* K1 */ - 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9 - }, - { - /* K2 */ - 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2 - } -}; -static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { - { - /* Sample #1 */ - 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60 - }, - { - /* Sample #2 */ - 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b - }, - { - /* Sample #3 */ - 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69 - }, - { - /* Sample #4 */ - 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb - } -}; - -/* CMAC-TDES (Generation) - 3 Key Test Data */ -static const unsigned char des3_3key_key[24] = { - /* Key1 */ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef, - /* Key2 */ - 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, - /* Key3 */ - 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 -}; -static const unsigned char des3_3key_subkeys[2][8] = { - { - /* K1 */ - 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0 - }, - { - /* K2 */ - 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b - } -}; -static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { - { - /* Sample #1 */ - 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50 - }, - { - /* Sample #2 */ - 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09 - }, - { - /* Sample #3 */ - 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2 - }, - { - /* Sample #4 */ - 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5 - } -}; - -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) -/* AES AES-CMAC-PRF-128 Test Data */ -static const unsigned char PRFK[] = { - /* Key */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0xed, 0xcb -}; - -/* Sizes in bytes */ -static const size_t PRFKlen[NB_PRF_TESTS] = { - 18, - 16, - 10 -}; - -/* Message */ -static const unsigned char PRFM[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13 -}; - -static const unsigned char PRFT[NB_PRF_TESTS][16] = { - { - 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b, - 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a - }, - { - 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52, - 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d - }, - { - 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee, - 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d - } -}; -#endif /* MBEDTLS_AES_C */ - -static int cmac_test_subkeys( int verbose, - const char* testname, - const unsigned char* key, - int keybits, - const unsigned char* subkeys, - mbedtls_cipher_type_t cipher_type, - int block_size, - int num_tests ) -{ - int i, ret = 0; - mbedtls_cipher_context_t ctx; - const mbedtls_cipher_info_t *cipher_info; - unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; - unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; - - cipher_info = mbedtls_cipher_info_from_type( cipher_type ); - if( cipher_info == NULL ) - { - /* Failing at this point must be due to a build issue */ - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - for( i = 0; i < num_tests; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 ); - - mbedtls_cipher_init( &ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "test execution failed\n" ); - - goto cleanup; - } - - if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "test execution failed\n" ); - - goto cleanup; - } - - ret = cmac_generate_subkeys( &ctx, K1, K2 ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 || - ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_cipher_free( &ctx ); - } - - ret = 0; - goto exit; - -cleanup: - mbedtls_cipher_free( &ctx ); - -exit: - return( ret ); -} - -static int cmac_test_wth_cipher( int verbose, - const char* testname, - const unsigned char* key, - int keybits, - const unsigned char* messages, - const unsigned int message_lengths[4], - const unsigned char* expected_result, - mbedtls_cipher_type_t cipher_type, - int block_size, - int num_tests ) -{ - const mbedtls_cipher_info_t *cipher_info; - int i, ret = 0; - unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX]; - - cipher_info = mbedtls_cipher_info_from_type( cipher_type ); - if( cipher_info == NULL ) - { - /* Failing at this point must be due to a build issue */ - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto exit; - } - - for( i = 0; i < num_tests; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 ); - - if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages, - message_lengths[i], output ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - goto exit; - } - - if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - ret = 0; - -exit: - return( ret ); -} - -#if defined(MBEDTLS_AES_C) -static int test_aes128_cmac_prf( int verbose ) -{ - int i; - int ret; - unsigned char output[MBEDTLS_AES_BLOCK_SIZE]; - - for( i = 0; i < NB_PRF_TESTS; i++ ) - { - mbedtls_printf( " AES CMAC 128 PRF #%u: ", i ); - ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output ); - if( ret != 0 || - memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 ) - { - - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); - } - else if( verbose != 0 ) - { - mbedtls_printf( "passed\n" ); - } - } - return( ret ); -} -#endif /* MBEDTLS_AES_C */ - -int mbedtls_cmac_self_test( int verbose ) -{ - int ret; - -#if defined(MBEDTLS_AES_C) - /* AES-128 */ - if( ( ret = cmac_test_subkeys( verbose, - "AES 128", - aes_128_key, - 128, - (const unsigned char*)aes_128_subkeys, - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher( verbose, - "AES 128", - aes_128_key, - 128, - test_message, - aes_message_lengths, - (const unsigned char*)aes_128_expected_result, - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - /* AES-192 */ - if( ( ret = cmac_test_subkeys( verbose, - "AES 192", - aes_192_key, - 192, - (const unsigned char*)aes_192_subkeys, - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher( verbose, - "AES 192", - aes_192_key, - 192, - test_message, - aes_message_lengths, - (const unsigned char*)aes_192_expected_result, - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - /* AES-256 */ - if( ( ret = cmac_test_subkeys( verbose, - "AES 256", - aes_256_key, - 256, - (const unsigned char*)aes_256_subkeys, - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher ( verbose, - "AES 256", - aes_256_key, - 256, - test_message, - aes_message_lengths, - (const unsigned char*)aes_256_expected_result, - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_DES_C) - /* 3DES 2 key */ - if( ( ret = cmac_test_subkeys( verbose, - "3DES 2 key", - des3_2key_key, - 192, - (const unsigned char*)des3_2key_subkeys, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher( verbose, - "3DES 2 key", - des3_2key_key, - 192, - test_message, - des3_message_lengths, - (const unsigned char*)des3_2key_expected_result, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - /* 3DES 3 key */ - if( ( ret = cmac_test_subkeys( verbose, - "3DES 3 key", - des3_3key_key, - 192, - (const unsigned char*)des3_3key_subkeys, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = cmac_test_wth_cipher( verbose, - "3DES 3 key", - des3_3key_key, - 192, - test_message, - des3_message_lengths, - (const unsigned char*)des3_3key_expected_result, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY ) ) != 0 ) - { - return( ret ); - } -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) - if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 ) - return( ret ); -#endif /* MBEDTLS_AES_C */ - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CMAC_C */ diff --git a/mbedtls/cmac.h b/mbedtls/cmac.h deleted file mode 100644 index 526be4b4f..000000000 --- a/mbedtls/cmac.h +++ /dev/null @@ -1,239 +0,0 @@ -#pragma GCC system_header -/** - * \file cmac.h - * - * \brief This file contains CMAC definitions and functions. - * - * The Cipher-based Message Authentication Code (CMAC) Mode for - * Authentication is defined in RFC-4493: The AES-CMAC Algorithm. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_CMAC_H -#define MBEDTLS_CMAC_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "cipher.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A /**< CMAC hardware accelerator failed. */ - -#define MBEDTLS_AES_BLOCK_SIZE 16 -#define MBEDTLS_DES3_BLOCK_SIZE 8 - -#if defined(MBEDTLS_AES_C) -#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /**< The longest block used by CMAC is that of AES. */ -#else -#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /**< The longest block used by CMAC is that of 3DES. */ -#endif - -#if !defined(MBEDTLS_CMAC_ALT) - -/** - * The CMAC context structure. - */ -struct mbedtls_cmac_context_t -{ - /** The internal state of the CMAC algorithm. */ - unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX]; - - /** Unprocessed data - either data that was not block aligned and is still - * pending processing, or the final block. */ - unsigned char unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX]; - - /** The length of data pending processing. */ - size_t unprocessed_len; -}; - -#else /* !MBEDTLS_CMAC_ALT */ -#include "cmac_alt.h" -#endif /* !MBEDTLS_CMAC_ALT */ - -/** - * \brief This function sets the CMAC key, and prepares to authenticate - * the input data. - * Must be called with an initialized cipher context. - * - * \param ctx The cipher context used for the CMAC operation, initialized - * as one of the following types: MBEDTLS_CIPHER_AES_128_ECB, - * MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB, - * or MBEDTLS_CIPHER_DES_EDE3_ECB. - * \param key The CMAC key. - * \param keybits The length of the CMAC key in bits. - * Must be supported by the cipher. - * - * \return \c 0 on success. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, - const unsigned char *key, size_t keybits ); - -/** - * \brief This function feeds an input buffer into an ongoing CMAC - * computation. - * - * It is called between mbedtls_cipher_cmac_starts() or - * mbedtls_cipher_cmac_reset(), and mbedtls_cipher_cmac_finish(). - * Can be called repeatedly. - * - * \param ctx The cipher context used for the CMAC operation. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA - * if parameter verification fails. - */ -int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, - const unsigned char *input, size_t ilen ); - -/** - * \brief This function finishes the CMAC operation, and writes - * the result to the output buffer. - * - * It is called after mbedtls_cipher_cmac_update(). - * It can be followed by mbedtls_cipher_cmac_reset() and - * mbedtls_cipher_cmac_update(), or mbedtls_cipher_free(). - * - * \param ctx The cipher context used for the CMAC operation. - * \param output The output buffer for the CMAC checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA - * if parameter verification fails. - */ -int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output ); - -/** - * \brief This function prepares the authentication of another - * message with the same key as the previous CMAC - * operation. - * - * It is called after mbedtls_cipher_cmac_finish() - * and before mbedtls_cipher_cmac_update(). - * - * \param ctx The cipher context used for the CMAC operation. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA - * if parameter verification fails. - */ -int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ); - -/** - * \brief This function calculates the full generic CMAC - * on the input buffer with the provided key. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The CMAC result is calculated as - * output = generic CMAC(cmac key, input buffer). - * - * - * \param cipher_info The cipher information. - * \param key The CMAC key. - * \param keylen The length of the CMAC key in bits. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * \param output The buffer for the generic CMAC result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA - * if parameter verification fails. - */ -int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, - const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output ); - -#if defined(MBEDTLS_AES_C) -/** - * \brief This function implements the AES-CMAC-PRF-128 pseudorandom - * function, as defined in - * RFC-4615: The Advanced Encryption Standard-Cipher-based - * Message Authentication Code-Pseudo-Random Function-128 - * (AES-CMAC-PRF-128) Algorithm for the Internet Key - * Exchange Protocol (IKE). - * - * \param key The key to use. - * \param key_len The key length in Bytes. - * \param input The buffer holding the input data. - * \param in_len The length of the input data in Bytes. - * \param output The buffer holding the generated 16 Bytes of - * pseudorandom output. - * - * \return \c 0 on success. - */ -int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len, - const unsigned char *input, size_t in_len, - unsigned char output[16] ); -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) ) -/** - * \brief The CMAC checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_cmac_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CMAC_H */ diff --git a/mbedtls/compat-1.3.h b/mbedtls/compat-1.3.h deleted file mode 100644 index 66a76c68f..000000000 --- a/mbedtls/compat-1.3.h +++ /dev/null @@ -1,2557 +0,0 @@ -#pragma GCC system_header -/** - * \file compat-1.3.h - * - * \brief Compatibility definitions for using mbed TLS with client code written - * for the PolarSSL naming conventions. - * - * \disabled_deprecated Use the new names directly instead - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if ! defined(MBEDTLS_DEPRECATED_REMOVED) - -#if defined(MBEDTLS_DEPRECATED_WARNING) -#warning "Including compat-1.3.h is deprecated" -#endif - -#ifndef MBEDTLS_COMPAT13_H -#define MBEDTLS_COMPAT13_H - -/* - * config.h options - */ -#if defined MBEDTLS_AESNI_C -#define POLARSSL_AESNI_C MBEDTLS_AESNI_C -#endif -#if defined MBEDTLS_AES_ALT -#define POLARSSL_AES_ALT MBEDTLS_AES_ALT -#endif -#if defined MBEDTLS_AES_C -#define POLARSSL_AES_C MBEDTLS_AES_C -#endif -#if defined MBEDTLS_AES_ROM_TABLES -#define POLARSSL_AES_ROM_TABLES MBEDTLS_AES_ROM_TABLES -#endif -#if defined MBEDTLS_ARC4_ALT -#define POLARSSL_ARC4_ALT MBEDTLS_ARC4_ALT -#endif -#if defined MBEDTLS_ARC4_C -#define POLARSSL_ARC4_C MBEDTLS_ARC4_C -#endif -#if defined MBEDTLS_ASN1_PARSE_C -#define POLARSSL_ASN1_PARSE_C MBEDTLS_ASN1_PARSE_C -#endif -#if defined MBEDTLS_ASN1_WRITE_C -#define POLARSSL_ASN1_WRITE_C MBEDTLS_ASN1_WRITE_C -#endif -#if defined MBEDTLS_BASE64_C -#define POLARSSL_BASE64_C MBEDTLS_BASE64_C -#endif -#if defined MBEDTLS_BIGNUM_C -#define POLARSSL_BIGNUM_C MBEDTLS_BIGNUM_C -#endif -#if defined MBEDTLS_BLOWFISH_ALT -#define POLARSSL_BLOWFISH_ALT MBEDTLS_BLOWFISH_ALT -#endif -#if defined MBEDTLS_BLOWFISH_C -#define POLARSSL_BLOWFISH_C MBEDTLS_BLOWFISH_C -#endif -#if defined MBEDTLS_CAMELLIA_ALT -#define POLARSSL_CAMELLIA_ALT MBEDTLS_CAMELLIA_ALT -#endif -#if defined MBEDTLS_CAMELLIA_C -#define POLARSSL_CAMELLIA_C MBEDTLS_CAMELLIA_C -#endif -#if defined MBEDTLS_CAMELLIA_SMALL_MEMORY -#define POLARSSL_CAMELLIA_SMALL_MEMORY MBEDTLS_CAMELLIA_SMALL_MEMORY -#endif -#if defined MBEDTLS_CCM_C -#define POLARSSL_CCM_C MBEDTLS_CCM_C -#endif -#if defined MBEDTLS_CERTS_C -#define POLARSSL_CERTS_C MBEDTLS_CERTS_C -#endif -#if defined MBEDTLS_CIPHER_C -#define POLARSSL_CIPHER_C MBEDTLS_CIPHER_C -#endif -#if defined MBEDTLS_CIPHER_MODE_CBC -#define POLARSSL_CIPHER_MODE_CBC MBEDTLS_CIPHER_MODE_CBC -#endif -#if defined MBEDTLS_CIPHER_MODE_CFB -#define POLARSSL_CIPHER_MODE_CFB MBEDTLS_CIPHER_MODE_CFB -#endif -#if defined MBEDTLS_CIPHER_MODE_CTR -#define POLARSSL_CIPHER_MODE_CTR MBEDTLS_CIPHER_MODE_CTR -#endif -#if defined MBEDTLS_CIPHER_NULL_CIPHER -#define POLARSSL_CIPHER_NULL_CIPHER MBEDTLS_CIPHER_NULL_CIPHER -#endif -#if defined MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#define POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#endif -#if defined MBEDTLS_CIPHER_PADDING_PKCS7 -#define POLARSSL_CIPHER_PADDING_PKCS7 MBEDTLS_CIPHER_PADDING_PKCS7 -#endif -#if defined MBEDTLS_CIPHER_PADDING_ZEROS -#define POLARSSL_CIPHER_PADDING_ZEROS MBEDTLS_CIPHER_PADDING_ZEROS -#endif -#if defined MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#define POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#endif -#if defined MBEDTLS_CTR_DRBG_C -#define POLARSSL_CTR_DRBG_C MBEDTLS_CTR_DRBG_C -#endif -#if defined MBEDTLS_DEBUG_C -#define POLARSSL_DEBUG_C MBEDTLS_DEBUG_C -#endif -#if defined MBEDTLS_DEPRECATED_REMOVED -#define POLARSSL_DEPRECATED_REMOVED MBEDTLS_DEPRECATED_REMOVED -#endif -#if defined MBEDTLS_DEPRECATED_WARNING -#define POLARSSL_DEPRECATED_WARNING MBEDTLS_DEPRECATED_WARNING -#endif -#if defined MBEDTLS_DES_ALT -#define POLARSSL_DES_ALT MBEDTLS_DES_ALT -#endif -#if defined MBEDTLS_DES_C -#define POLARSSL_DES_C MBEDTLS_DES_C -#endif -#if defined MBEDTLS_DHM_C -#define POLARSSL_DHM_C MBEDTLS_DHM_C -#endif -#if defined MBEDTLS_ECDH_C -#define POLARSSL_ECDH_C MBEDTLS_ECDH_C -#endif -#if defined MBEDTLS_ECDSA_C -#define POLARSSL_ECDSA_C MBEDTLS_ECDSA_C -#endif -#if defined MBEDTLS_ECDSA_DETERMINISTIC -#define POLARSSL_ECDSA_DETERMINISTIC MBEDTLS_ECDSA_DETERMINISTIC -#endif -#if defined MBEDTLS_ECP_C -#define POLARSSL_ECP_C MBEDTLS_ECP_C -#endif -#if defined MBEDTLS_ECP_DP_BP256R1_ENABLED -#define POLARSSL_ECP_DP_BP256R1_ENABLED MBEDTLS_ECP_DP_BP256R1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_BP384R1_ENABLED -#define POLARSSL_ECP_DP_BP384R1_ENABLED MBEDTLS_ECP_DP_BP384R1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_BP512R1_ENABLED -#define POLARSSL_ECP_DP_BP512R1_ENABLED MBEDTLS_ECP_DP_BP512R1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define POLARSSL_ECP_DP_M255_ENABLED MBEDTLS_ECP_DP_CURVE25519_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define POLARSSL_ECP_DP_SECP192K1_ENABLED MBEDTLS_ECP_DP_SECP192K1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define POLARSSL_ECP_DP_SECP192R1_ENABLED MBEDTLS_ECP_DP_SECP192R1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define POLARSSL_ECP_DP_SECP224K1_ENABLED MBEDTLS_ECP_DP_SECP224K1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define POLARSSL_ECP_DP_SECP224R1_ENABLED MBEDTLS_ECP_DP_SECP224R1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define POLARSSL_ECP_DP_SECP256K1_ENABLED MBEDTLS_ECP_DP_SECP256K1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define POLARSSL_ECP_DP_SECP256R1_ENABLED MBEDTLS_ECP_DP_SECP256R1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define POLARSSL_ECP_DP_SECP384R1_ENABLED MBEDTLS_ECP_DP_SECP384R1_ENABLED -#endif -#if defined MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define POLARSSL_ECP_DP_SECP521R1_ENABLED MBEDTLS_ECP_DP_SECP521R1_ENABLED -#endif -#if defined MBEDTLS_ECP_FIXED_POINT_OPTIM -#define POLARSSL_ECP_FIXED_POINT_OPTIM MBEDTLS_ECP_FIXED_POINT_OPTIM -#endif -#if defined MBEDTLS_ECP_MAX_BITS -#define POLARSSL_ECP_MAX_BITS MBEDTLS_ECP_MAX_BITS -#endif -#if defined MBEDTLS_ECP_NIST_OPTIM -#define POLARSSL_ECP_NIST_OPTIM MBEDTLS_ECP_NIST_OPTIM -#endif -#if defined MBEDTLS_ECP_WINDOW_SIZE -#define POLARSSL_ECP_WINDOW_SIZE MBEDTLS_ECP_WINDOW_SIZE -#endif -#if defined MBEDTLS_ENABLE_WEAK_CIPHERSUITES -#define POLARSSL_ENABLE_WEAK_CIPHERSUITES MBEDTLS_ENABLE_WEAK_CIPHERSUITES -#endif -#if defined MBEDTLS_ENTROPY_C -#define POLARSSL_ENTROPY_C MBEDTLS_ENTROPY_C -#endif -#if defined MBEDTLS_ENTROPY_FORCE_SHA256 -#define POLARSSL_ENTROPY_FORCE_SHA256 MBEDTLS_ENTROPY_FORCE_SHA256 -#endif -#if defined MBEDTLS_ERROR_C -#define POLARSSL_ERROR_C MBEDTLS_ERROR_C -#endif -#if defined MBEDTLS_ERROR_STRERROR_DUMMY -#define POLARSSL_ERROR_STRERROR_DUMMY MBEDTLS_ERROR_STRERROR_DUMMY -#endif -#if defined MBEDTLS_FS_IO -#define POLARSSL_FS_IO MBEDTLS_FS_IO -#endif -#if defined MBEDTLS_GCM_C -#define POLARSSL_GCM_C MBEDTLS_GCM_C -#endif -#if defined MBEDTLS_GENPRIME -#define POLARSSL_GENPRIME MBEDTLS_GENPRIME -#endif -#if defined MBEDTLS_HAVEGE_C -#define POLARSSL_HAVEGE_C MBEDTLS_HAVEGE_C -#endif -#if defined MBEDTLS_HAVE_ASM -#define POLARSSL_HAVE_ASM MBEDTLS_HAVE_ASM -#endif -#if defined MBEDTLS_HAVE_SSE2 -#define POLARSSL_HAVE_SSE2 MBEDTLS_HAVE_SSE2 -#endif -#if defined MBEDTLS_HAVE_TIME -#define POLARSSL_HAVE_TIME MBEDTLS_HAVE_TIME -#endif -#if defined MBEDTLS_HMAC_DRBG_C -#define POLARSSL_HMAC_DRBG_C MBEDTLS_HMAC_DRBG_C -#endif -#if defined MBEDTLS_HMAC_DRBG_MAX_INPUT -#define POLARSSL_HMAC_DRBG_MAX_INPUT MBEDTLS_HMAC_DRBG_MAX_INPUT -#endif -#if defined MBEDTLS_HMAC_DRBG_MAX_REQUEST -#define POLARSSL_HMAC_DRBG_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST -#endif -#if defined MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT -#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT -#endif -#if defined MBEDTLS_HMAC_DRBG_RESEED_INTERVAL -#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL MBEDTLS_HMAC_DRBG_RESEED_INTERVAL -#endif -#if defined MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED -#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED -#endif -#if defined MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED -#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED -#endif -#if defined MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED -#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED -#endif -#if defined MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED -#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED -#endif -#if defined MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -#endif -#if defined MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED -#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED -#endif -#if defined MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED -#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED -#endif -#if defined MBEDTLS_KEY_EXCHANGE_PSK_ENABLED -#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_PSK_ENABLED -#endif -#if defined MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#endif -#if defined MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED -#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED -#endif -#if defined MBEDTLS_MD2_ALT -#define POLARSSL_MD2_ALT MBEDTLS_MD2_ALT -#endif -#if defined MBEDTLS_MD2_C -#define POLARSSL_MD2_C MBEDTLS_MD2_C -#endif -#if defined MBEDTLS_MD2_PROCESS_ALT -#define POLARSSL_MD2_PROCESS_ALT MBEDTLS_MD2_PROCESS_ALT -#endif -#if defined MBEDTLS_MD4_ALT -#define POLARSSL_MD4_ALT MBEDTLS_MD4_ALT -#endif -#if defined MBEDTLS_MD4_C -#define POLARSSL_MD4_C MBEDTLS_MD4_C -#endif -#if defined MBEDTLS_MD4_PROCESS_ALT -#define POLARSSL_MD4_PROCESS_ALT MBEDTLS_MD4_PROCESS_ALT -#endif -#if defined MBEDTLS_MD5_ALT -#define POLARSSL_MD5_ALT MBEDTLS_MD5_ALT -#endif -#if defined MBEDTLS_MD5_C -#define POLARSSL_MD5_C MBEDTLS_MD5_C -#endif -#if defined MBEDTLS_MD5_PROCESS_ALT -#define POLARSSL_MD5_PROCESS_ALT MBEDTLS_MD5_PROCESS_ALT -#endif -#if defined MBEDTLS_MD_C -#define POLARSSL_MD_C MBEDTLS_MD_C -#endif -#if defined MBEDTLS_MEMORY_ALIGN_MULTIPLE -#define POLARSSL_MEMORY_ALIGN_MULTIPLE MBEDTLS_MEMORY_ALIGN_MULTIPLE -#endif -#if defined MBEDTLS_MEMORY_BACKTRACE -#define POLARSSL_MEMORY_BACKTRACE MBEDTLS_MEMORY_BACKTRACE -#endif -#if defined MBEDTLS_MEMORY_BUFFER_ALLOC_C -#define POLARSSL_MEMORY_BUFFER_ALLOC_C MBEDTLS_MEMORY_BUFFER_ALLOC_C -#endif -#if defined MBEDTLS_MEMORY_DEBUG -#define POLARSSL_MEMORY_DEBUG MBEDTLS_MEMORY_DEBUG -#endif -#if defined MBEDTLS_MPI_MAX_SIZE -#define POLARSSL_MPI_MAX_SIZE MBEDTLS_MPI_MAX_SIZE -#endif -#if defined MBEDTLS_MPI_WINDOW_SIZE -#define POLARSSL_MPI_WINDOW_SIZE MBEDTLS_MPI_WINDOW_SIZE -#endif -#if defined MBEDTLS_NET_C -#define POLARSSL_NET_C MBEDTLS_NET_C -#endif -#if defined MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES -#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES -#endif -#if defined MBEDTLS_NO_PLATFORM_ENTROPY -#define POLARSSL_NO_PLATFORM_ENTROPY MBEDTLS_NO_PLATFORM_ENTROPY -#endif -#if defined MBEDTLS_OID_C -#define POLARSSL_OID_C MBEDTLS_OID_C -#endif -#if defined MBEDTLS_PADLOCK_C -#define POLARSSL_PADLOCK_C MBEDTLS_PADLOCK_C -#endif -#if defined MBEDTLS_PEM_PARSE_C -#define POLARSSL_PEM_PARSE_C MBEDTLS_PEM_PARSE_C -#endif -#if defined MBEDTLS_PEM_WRITE_C -#define POLARSSL_PEM_WRITE_C MBEDTLS_PEM_WRITE_C -#endif -#if defined MBEDTLS_PKCS11_C -#define POLARSSL_PKCS11_C MBEDTLS_PKCS11_C -#endif -#if defined MBEDTLS_PKCS12_C -#define POLARSSL_PKCS12_C MBEDTLS_PKCS12_C -#endif -#if defined MBEDTLS_PKCS1_V15 -#define POLARSSL_PKCS1_V15 MBEDTLS_PKCS1_V15 -#endif -#if defined MBEDTLS_PKCS1_V21 -#define POLARSSL_PKCS1_V21 MBEDTLS_PKCS1_V21 -#endif -#if defined MBEDTLS_PKCS5_C -#define POLARSSL_PKCS5_C MBEDTLS_PKCS5_C -#endif -#if defined MBEDTLS_PK_C -#define POLARSSL_PK_C MBEDTLS_PK_C -#endif -#if defined MBEDTLS_PK_PARSE_C -#define POLARSSL_PK_PARSE_C MBEDTLS_PK_PARSE_C -#endif -#if defined MBEDTLS_PK_PARSE_EC_EXTENDED -#define POLARSSL_PK_PARSE_EC_EXTENDED MBEDTLS_PK_PARSE_EC_EXTENDED -#endif -#if defined MBEDTLS_PK_RSA_ALT_SUPPORT -#define POLARSSL_PK_RSA_ALT_SUPPORT MBEDTLS_PK_RSA_ALT_SUPPORT -#endif -#if defined MBEDTLS_PK_WRITE_C -#define POLARSSL_PK_WRITE_C MBEDTLS_PK_WRITE_C -#endif -#if defined MBEDTLS_PLATFORM_C -#define POLARSSL_PLATFORM_C MBEDTLS_PLATFORM_C -#endif -#if defined MBEDTLS_PLATFORM_EXIT_ALT -#define POLARSSL_PLATFORM_EXIT_ALT MBEDTLS_PLATFORM_EXIT_ALT -#endif -#if defined MBEDTLS_PLATFORM_EXIT_MACRO -#define POLARSSL_PLATFORM_EXIT_MACRO MBEDTLS_PLATFORM_EXIT_MACRO -#endif -#if defined MBEDTLS_PLATFORM_FPRINTF_ALT -#define POLARSSL_PLATFORM_FPRINTF_ALT MBEDTLS_PLATFORM_FPRINTF_ALT -#endif -#if defined MBEDTLS_PLATFORM_FPRINTF_MACRO -#define POLARSSL_PLATFORM_FPRINTF_MACRO MBEDTLS_PLATFORM_FPRINTF_MACRO -#endif -#if defined MBEDTLS_PLATFORM_FREE_MACRO -#define POLARSSL_PLATFORM_FREE_MACRO MBEDTLS_PLATFORM_FREE_MACRO -#endif -#if defined MBEDTLS_PLATFORM_MEMORY -#define POLARSSL_PLATFORM_MEMORY MBEDTLS_PLATFORM_MEMORY -#endif -#if defined MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#endif -#if defined MBEDTLS_PLATFORM_PRINTF_ALT -#define POLARSSL_PLATFORM_PRINTF_ALT MBEDTLS_PLATFORM_PRINTF_ALT -#endif -#if defined MBEDTLS_PLATFORM_PRINTF_MACRO -#define POLARSSL_PLATFORM_PRINTF_MACRO MBEDTLS_PLATFORM_PRINTF_MACRO -#endif -#if defined MBEDTLS_PLATFORM_SNPRINTF_ALT -#define POLARSSL_PLATFORM_SNPRINTF_ALT MBEDTLS_PLATFORM_SNPRINTF_ALT -#endif -#if defined MBEDTLS_PLATFORM_SNPRINTF_MACRO -#define POLARSSL_PLATFORM_SNPRINTF_MACRO MBEDTLS_PLATFORM_SNPRINTF_MACRO -#endif -#if defined MBEDTLS_PLATFORM_STD_EXIT -#define POLARSSL_PLATFORM_STD_EXIT MBEDTLS_PLATFORM_STD_EXIT -#endif -#if defined MBEDTLS_PLATFORM_STD_FPRINTF -#define POLARSSL_PLATFORM_STD_FPRINTF MBEDTLS_PLATFORM_STD_FPRINTF -#endif -#if defined MBEDTLS_PLATFORM_STD_FREE -#define POLARSSL_PLATFORM_STD_FREE MBEDTLS_PLATFORM_STD_FREE -#endif -#if defined MBEDTLS_PLATFORM_STD_MEM_HDR -#define POLARSSL_PLATFORM_STD_MEM_HDR MBEDTLS_PLATFORM_STD_MEM_HDR -#endif -#if defined MBEDTLS_PLATFORM_STD_PRINTF -#define POLARSSL_PLATFORM_STD_PRINTF MBEDTLS_PLATFORM_STD_PRINTF -#endif -#if defined MBEDTLS_PLATFORM_STD_SNPRINTF -#define POLARSSL_PLATFORM_STD_SNPRINTF MBEDTLS_PLATFORM_STD_SNPRINTF -#endif -#if defined MBEDTLS_PSK_MAX_LEN -#define POLARSSL_PSK_MAX_LEN MBEDTLS_PSK_MAX_LEN -#endif -#if defined MBEDTLS_REMOVE_ARC4_CIPHERSUITES -#define POLARSSL_REMOVE_ARC4_CIPHERSUITES MBEDTLS_REMOVE_ARC4_CIPHERSUITES -#endif -#if defined MBEDTLS_RIPEMD160_ALT -#define POLARSSL_RIPEMD160_ALT MBEDTLS_RIPEMD160_ALT -#endif -#if defined MBEDTLS_RIPEMD160_C -#define POLARSSL_RIPEMD160_C MBEDTLS_RIPEMD160_C -#endif -#if defined MBEDTLS_RIPEMD160_PROCESS_ALT -#define POLARSSL_RIPEMD160_PROCESS_ALT MBEDTLS_RIPEMD160_PROCESS_ALT -#endif -#if defined MBEDTLS_RSA_C -#define POLARSSL_RSA_C MBEDTLS_RSA_C -#endif -#if defined MBEDTLS_RSA_NO_CRT -#define POLARSSL_RSA_NO_CRT MBEDTLS_RSA_NO_CRT -#endif -#if defined MBEDTLS_SELF_TEST -#define POLARSSL_SELF_TEST MBEDTLS_SELF_TEST -#endif -#if defined MBEDTLS_SHA1_ALT -#define POLARSSL_SHA1_ALT MBEDTLS_SHA1_ALT -#endif -#if defined MBEDTLS_SHA1_C -#define POLARSSL_SHA1_C MBEDTLS_SHA1_C -#endif -#if defined MBEDTLS_SHA1_PROCESS_ALT -#define POLARSSL_SHA1_PROCESS_ALT MBEDTLS_SHA1_PROCESS_ALT -#endif -#if defined MBEDTLS_SHA256_ALT -#define POLARSSL_SHA256_ALT MBEDTLS_SHA256_ALT -#endif -#if defined MBEDTLS_SHA256_C -#define POLARSSL_SHA256_C MBEDTLS_SHA256_C -#endif -#if defined MBEDTLS_SHA256_PROCESS_ALT -#define POLARSSL_SHA256_PROCESS_ALT MBEDTLS_SHA256_PROCESS_ALT -#endif -#if defined MBEDTLS_SHA512_ALT -#define POLARSSL_SHA512_ALT MBEDTLS_SHA512_ALT -#endif -#if defined MBEDTLS_SHA512_C -#define POLARSSL_SHA512_C MBEDTLS_SHA512_C -#endif -#if defined MBEDTLS_SHA512_PROCESS_ALT -#define POLARSSL_SHA512_PROCESS_ALT MBEDTLS_SHA512_PROCESS_ALT -#endif -#if defined MBEDTLS_SSL_ALL_ALERT_MESSAGES -#define POLARSSL_SSL_ALL_ALERT_MESSAGES MBEDTLS_SSL_ALL_ALERT_MESSAGES -#endif -#if defined MBEDTLS_SSL_ALPN -#define POLARSSL_SSL_ALPN MBEDTLS_SSL_ALPN -#endif -#if defined MBEDTLS_SSL_CACHE_C -#define POLARSSL_SSL_CACHE_C MBEDTLS_SSL_CACHE_C -#endif -#if defined MBEDTLS_SSL_CBC_RECORD_SPLITTING -#define POLARSSL_SSL_CBC_RECORD_SPLITTING MBEDTLS_SSL_CBC_RECORD_SPLITTING -#endif -#if defined MBEDTLS_SSL_CLI_C -#define POLARSSL_SSL_CLI_C MBEDTLS_SSL_CLI_C -#endif -#if defined MBEDTLS_SSL_COOKIE_C -#define POLARSSL_SSL_COOKIE_C MBEDTLS_SSL_COOKIE_C -#endif -#if defined MBEDTLS_SSL_COOKIE_TIMEOUT -#define POLARSSL_SSL_COOKIE_TIMEOUT MBEDTLS_SSL_COOKIE_TIMEOUT -#endif -#if defined MBEDTLS_SSL_DEBUG_ALL -#define POLARSSL_SSL_DEBUG_ALL MBEDTLS_SSL_DEBUG_ALL -#endif -#if defined MBEDTLS_SSL_DTLS_ANTI_REPLAY -#define POLARSSL_SSL_DTLS_ANTI_REPLAY MBEDTLS_SSL_DTLS_ANTI_REPLAY -#endif -#if defined MBEDTLS_SSL_DTLS_BADMAC_LIMIT -#define POLARSSL_SSL_DTLS_BADMAC_LIMIT MBEDTLS_SSL_DTLS_BADMAC_LIMIT -#endif -#if defined MBEDTLS_SSL_DTLS_HELLO_VERIFY -#define POLARSSL_SSL_DTLS_HELLO_VERIFY MBEDTLS_SSL_DTLS_HELLO_VERIFY -#endif -#if defined MBEDTLS_SSL_ENCRYPT_THEN_MAC -#define POLARSSL_SSL_ENCRYPT_THEN_MAC MBEDTLS_SSL_ENCRYPT_THEN_MAC -#endif -#if defined MBEDTLS_SSL_EXTENDED_MASTER_SECRET -#define POLARSSL_SSL_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MASTER_SECRET -#endif -#if defined MBEDTLS_SSL_FALLBACK_SCSV -#define POLARSSL_SSL_FALLBACK_SCSV MBEDTLS_SSL_FALLBACK_SCSV -#endif -#if defined MBEDTLS_SSL_HW_RECORD_ACCEL -#define POLARSSL_SSL_HW_RECORD_ACCEL MBEDTLS_SSL_HW_RECORD_ACCEL -#endif -#if defined MBEDTLS_SSL_MAX_FRAGMENT_LENGTH -#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH MBEDTLS_SSL_MAX_FRAGMENT_LENGTH -#endif -#if defined MBEDTLS_SSL_PROTO_DTLS -#define POLARSSL_SSL_PROTO_DTLS MBEDTLS_SSL_PROTO_DTLS -#endif -#if defined MBEDTLS_SSL_PROTO_SSL3 -#define POLARSSL_SSL_PROTO_SSL3 MBEDTLS_SSL_PROTO_SSL3 -#endif -#if defined MBEDTLS_SSL_PROTO_TLS1 -#define POLARSSL_SSL_PROTO_TLS1 MBEDTLS_SSL_PROTO_TLS1 -#endif -#if defined MBEDTLS_SSL_PROTO_TLS1_1 -#define POLARSSL_SSL_PROTO_TLS1_1 MBEDTLS_SSL_PROTO_TLS1_1 -#endif -#if defined MBEDTLS_SSL_PROTO_TLS1_2 -#define POLARSSL_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_2 -#endif -#if defined MBEDTLS_SSL_RENEGOTIATION -#define POLARSSL_SSL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION -#endif -#if defined MBEDTLS_SSL_SERVER_NAME_INDICATION -#define POLARSSL_SSL_SERVER_NAME_INDICATION MBEDTLS_SSL_SERVER_NAME_INDICATION -#endif -#if defined MBEDTLS_SSL_SESSION_TICKETS -#define POLARSSL_SSL_SESSION_TICKETS MBEDTLS_SSL_SESSION_TICKETS -#endif -#if defined MBEDTLS_SSL_SRV_C -#define POLARSSL_SSL_SRV_C MBEDTLS_SSL_SRV_C -#endif -#if defined MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE -#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE -#endif -#if defined MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO -#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO -#endif -#if defined MBEDTLS_SSL_TLS_C -#define POLARSSL_SSL_TLS_C MBEDTLS_SSL_TLS_C -#endif -#if defined MBEDTLS_SSL_TRUNCATED_HMAC -#define POLARSSL_SSL_TRUNCATED_HMAC MBEDTLS_SSL_TRUNCATED_HMAC -#endif -#if defined MBEDTLS_THREADING_ALT -#define POLARSSL_THREADING_ALT MBEDTLS_THREADING_ALT -#endif -#if defined MBEDTLS_THREADING_C -#define POLARSSL_THREADING_C MBEDTLS_THREADING_C -#endif -#if defined MBEDTLS_THREADING_PTHREAD -#define POLARSSL_THREADING_PTHREAD MBEDTLS_THREADING_PTHREAD -#endif -#if defined MBEDTLS_TIMING_ALT -#define POLARSSL_TIMING_ALT MBEDTLS_TIMING_ALT -#endif -#if defined MBEDTLS_TIMING_C -#define POLARSSL_TIMING_C MBEDTLS_TIMING_C -#endif -#if defined MBEDTLS_VERSION_C -#define POLARSSL_VERSION_C MBEDTLS_VERSION_C -#endif -#if defined MBEDTLS_VERSION_FEATURES -#define POLARSSL_VERSION_FEATURES MBEDTLS_VERSION_FEATURES -#endif -#if defined MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 -#define POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 -#endif -#if defined MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION -#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION -#endif -#if defined MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE -#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE -#endif -#if defined MBEDTLS_X509_CHECK_KEY_USAGE -#define POLARSSL_X509_CHECK_KEY_USAGE MBEDTLS_X509_CHECK_KEY_USAGE -#endif -#if defined MBEDTLS_X509_CREATE_C -#define POLARSSL_X509_CREATE_C MBEDTLS_X509_CREATE_C -#endif -#if defined MBEDTLS_X509_CRL_PARSE_C -#define POLARSSL_X509_CRL_PARSE_C MBEDTLS_X509_CRL_PARSE_C -#endif -#if defined MBEDTLS_X509_CRT_PARSE_C -#define POLARSSL_X509_CRT_PARSE_C MBEDTLS_X509_CRT_PARSE_C -#endif -#if defined MBEDTLS_X509_CRT_WRITE_C -#define POLARSSL_X509_CRT_WRITE_C MBEDTLS_X509_CRT_WRITE_C -#endif -#if defined MBEDTLS_X509_CSR_PARSE_C -#define POLARSSL_X509_CSR_PARSE_C MBEDTLS_X509_CSR_PARSE_C -#endif -#if defined MBEDTLS_X509_CSR_WRITE_C -#define POLARSSL_X509_CSR_WRITE_C MBEDTLS_X509_CSR_WRITE_C -#endif -#if defined MBEDTLS_X509_MAX_INTERMEDIATE_CA -#define POLARSSL_X509_MAX_INTERMEDIATE_CA MBEDTLS_X509_MAX_INTERMEDIATE_CA -#endif -#if defined MBEDTLS_X509_RSASSA_PSS_SUPPORT -#define POLARSSL_X509_RSASSA_PSS_SUPPORT MBEDTLS_X509_RSASSA_PSS_SUPPORT -#endif -#if defined MBEDTLS_X509_USE_C -#define POLARSSL_X509_USE_C MBEDTLS_X509_USE_C -#endif -#if defined MBEDTLS_XTEA_ALT -#define POLARSSL_XTEA_ALT MBEDTLS_XTEA_ALT -#endif -#if defined MBEDTLS_XTEA_C -#define POLARSSL_XTEA_C MBEDTLS_XTEA_C -#endif -#if defined MBEDTLS_ZLIB_SUPPORT -#define POLARSSL_ZLIB_SUPPORT MBEDTLS_ZLIB_SUPPORT -#endif - -/* - * Misc names (macros, types, functions, enum constants...) - */ -#define AES_DECRYPT MBEDTLS_AES_DECRYPT -#define AES_ENCRYPT MBEDTLS_AES_ENCRYPT -#define ASN1_BIT_STRING MBEDTLS_ASN1_BIT_STRING -#define ASN1_BMP_STRING MBEDTLS_ASN1_BMP_STRING -#define ASN1_BOOLEAN MBEDTLS_ASN1_BOOLEAN -#define ASN1_CHK_ADD MBEDTLS_ASN1_CHK_ADD -#define ASN1_CONSTRUCTED MBEDTLS_ASN1_CONSTRUCTED -#define ASN1_CONTEXT_SPECIFIC MBEDTLS_ASN1_CONTEXT_SPECIFIC -#define ASN1_GENERALIZED_TIME MBEDTLS_ASN1_GENERALIZED_TIME -#define ASN1_IA5_STRING MBEDTLS_ASN1_IA5_STRING -#define ASN1_INTEGER MBEDTLS_ASN1_INTEGER -#define ASN1_NULL MBEDTLS_ASN1_NULL -#define ASN1_OCTET_STRING MBEDTLS_ASN1_OCTET_STRING -#define ASN1_OID MBEDTLS_ASN1_OID -#define ASN1_PRIMITIVE MBEDTLS_ASN1_PRIMITIVE -#define ASN1_PRINTABLE_STRING MBEDTLS_ASN1_PRINTABLE_STRING -#define ASN1_SEQUENCE MBEDTLS_ASN1_SEQUENCE -#define ASN1_SET MBEDTLS_ASN1_SET -#define ASN1_T61_STRING MBEDTLS_ASN1_T61_STRING -#define ASN1_UNIVERSAL_STRING MBEDTLS_ASN1_UNIVERSAL_STRING -#define ASN1_UTC_TIME MBEDTLS_ASN1_UTC_TIME -#define ASN1_UTF8_STRING MBEDTLS_ASN1_UTF8_STRING -#define BADCERT_CN_MISMATCH MBEDTLS_X509_BADCERT_CN_MISMATCH -#define BADCERT_EXPIRED MBEDTLS_X509_BADCERT_EXPIRED -#define BADCERT_FUTURE MBEDTLS_X509_BADCERT_FUTURE -#define BADCERT_MISSING MBEDTLS_X509_BADCERT_MISSING -#define BADCERT_NOT_TRUSTED MBEDTLS_X509_BADCERT_NOT_TRUSTED -#define BADCERT_OTHER MBEDTLS_X509_BADCERT_OTHER -#define BADCERT_REVOKED MBEDTLS_X509_BADCERT_REVOKED -#define BADCERT_SKIP_VERIFY MBEDTLS_X509_BADCERT_SKIP_VERIFY -#define BADCRL_EXPIRED MBEDTLS_X509_BADCRL_EXPIRED -#define BADCRL_FUTURE MBEDTLS_X509_BADCRL_FUTURE -#define BADCRL_NOT_TRUSTED MBEDTLS_X509_BADCRL_NOT_TRUSTED -#define BLOWFISH_BLOCKSIZE MBEDTLS_BLOWFISH_BLOCKSIZE -#define BLOWFISH_DECRYPT MBEDTLS_BLOWFISH_DECRYPT -#define BLOWFISH_ENCRYPT MBEDTLS_BLOWFISH_ENCRYPT -#define BLOWFISH_MAX_KEY MBEDTLS_BLOWFISH_MAX_KEY_BITS -#define BLOWFISH_MIN_KEY MBEDTLS_BLOWFISH_MIN_KEY_BITS -#define BLOWFISH_ROUNDS MBEDTLS_BLOWFISH_ROUNDS -#define CAMELLIA_DECRYPT MBEDTLS_CAMELLIA_DECRYPT -#define CAMELLIA_ENCRYPT MBEDTLS_CAMELLIA_ENCRYPT -#define COLLECT_SIZE MBEDTLS_HAVEGE_COLLECT_SIZE -#define CTR_DRBG_BLOCKSIZE MBEDTLS_CTR_DRBG_BLOCKSIZE -#define CTR_DRBG_ENTROPY_LEN MBEDTLS_CTR_DRBG_ENTROPY_LEN -#define CTR_DRBG_KEYBITS MBEDTLS_CTR_DRBG_KEYBITS -#define CTR_DRBG_KEYSIZE MBEDTLS_CTR_DRBG_KEYSIZE -#define CTR_DRBG_MAX_INPUT MBEDTLS_CTR_DRBG_MAX_INPUT -#define CTR_DRBG_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST -#define CTR_DRBG_MAX_SEED_INPUT MBEDTLS_CTR_DRBG_MAX_SEED_INPUT -#define CTR_DRBG_PR_OFF MBEDTLS_CTR_DRBG_PR_OFF -#define CTR_DRBG_PR_ON MBEDTLS_CTR_DRBG_PR_ON -#define CTR_DRBG_RESEED_INTERVAL MBEDTLS_CTR_DRBG_RESEED_INTERVAL -#define CTR_DRBG_SEEDLEN MBEDTLS_CTR_DRBG_SEEDLEN -#define DEPRECATED MBEDTLS_DEPRECATED -#define DES_DECRYPT MBEDTLS_DES_DECRYPT -#define DES_ENCRYPT MBEDTLS_DES_ENCRYPT -#define DES_KEY_SIZE MBEDTLS_DES_KEY_SIZE -#define ENTROPY_BLOCK_SIZE MBEDTLS_ENTROPY_BLOCK_SIZE -#define ENTROPY_MAX_GATHER MBEDTLS_ENTROPY_MAX_GATHER -#define ENTROPY_MAX_SEED_SIZE MBEDTLS_ENTROPY_MAX_SEED_SIZE -#define ENTROPY_MAX_SOURCES MBEDTLS_ENTROPY_MAX_SOURCES -#define ENTROPY_MIN_HARDCLOCK MBEDTLS_ENTROPY_MIN_HARDCLOCK -#define ENTROPY_MIN_HAVEGE MBEDTLS_ENTROPY_MIN_HAVEGE -#define ENTROPY_MIN_PLATFORM MBEDTLS_ENTROPY_MIN_PLATFORM -#define ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_SOURCE_MANUAL -#define EXT_AUTHORITY_KEY_IDENTIFIER MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER -#define EXT_BASIC_CONSTRAINTS MBEDTLS_X509_EXT_BASIC_CONSTRAINTS -#define EXT_CERTIFICATE_POLICIES MBEDTLS_X509_EXT_CERTIFICATE_POLICIES -#define EXT_CRL_DISTRIBUTION_POINTS MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS -#define EXT_EXTENDED_KEY_USAGE MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE -#define EXT_FRESHEST_CRL MBEDTLS_X509_EXT_FRESHEST_CRL -#define EXT_INIHIBIT_ANYPOLICY MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY -#define EXT_ISSUER_ALT_NAME MBEDTLS_X509_EXT_ISSUER_ALT_NAME -#define EXT_KEY_USAGE MBEDTLS_X509_EXT_KEY_USAGE -#define EXT_NAME_CONSTRAINTS MBEDTLS_X509_EXT_NAME_CONSTRAINTS -#define EXT_NS_CERT_TYPE MBEDTLS_X509_EXT_NS_CERT_TYPE -#define EXT_POLICY_CONSTRAINTS MBEDTLS_X509_EXT_POLICY_CONSTRAINTS -#define EXT_POLICY_MAPPINGS MBEDTLS_X509_EXT_POLICY_MAPPINGS -#define EXT_SUBJECT_ALT_NAME MBEDTLS_X509_EXT_SUBJECT_ALT_NAME -#define EXT_SUBJECT_DIRECTORY_ATTRS MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS -#define EXT_SUBJECT_KEY_IDENTIFIER MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER -#define GCM_DECRYPT MBEDTLS_GCM_DECRYPT -#define GCM_ENCRYPT MBEDTLS_GCM_ENCRYPT -#define KU_CRL_SIGN MBEDTLS_X509_KU_CRL_SIGN -#define KU_DATA_ENCIPHERMENT MBEDTLS_X509_KU_DATA_ENCIPHERMENT -#define KU_DIGITAL_SIGNATURE MBEDTLS_X509_KU_DIGITAL_SIGNATURE -#define KU_KEY_AGREEMENT MBEDTLS_X509_KU_KEY_AGREEMENT -#define KU_KEY_CERT_SIGN MBEDTLS_X509_KU_KEY_CERT_SIGN -#define KU_KEY_ENCIPHERMENT MBEDTLS_X509_KU_KEY_ENCIPHERMENT -#define KU_NON_REPUDIATION MBEDTLS_X509_KU_NON_REPUDIATION -#define LN_2_DIV_LN_10_SCALE100 MBEDTLS_LN_2_DIV_LN_10_SCALE100 -#define MEMORY_VERIFY_ALLOC MBEDTLS_MEMORY_VERIFY_ALLOC -#define MEMORY_VERIFY_ALWAYS MBEDTLS_MEMORY_VERIFY_ALWAYS -#define MEMORY_VERIFY_FREE MBEDTLS_MEMORY_VERIFY_FREE -#define MEMORY_VERIFY_NONE MBEDTLS_MEMORY_VERIFY_NONE -#define MPI_CHK MBEDTLS_MPI_CHK -#define NET_PROTO_TCP MBEDTLS_NET_PROTO_TCP -#define NET_PROTO_UDP MBEDTLS_NET_PROTO_UDP -#define NS_CERT_TYPE_EMAIL MBEDTLS_X509_NS_CERT_TYPE_EMAIL -#define NS_CERT_TYPE_EMAIL_CA MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA -#define NS_CERT_TYPE_OBJECT_SIGNING MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING -#define NS_CERT_TYPE_OBJECT_SIGNING_CA MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA -#define NS_CERT_TYPE_RESERVED MBEDTLS_X509_NS_CERT_TYPE_RESERVED -#define NS_CERT_TYPE_SSL_CA MBEDTLS_X509_NS_CERT_TYPE_SSL_CA -#define NS_CERT_TYPE_SSL_CLIENT MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT -#define NS_CERT_TYPE_SSL_SERVER MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER -#define OID_ANSI_X9_62 MBEDTLS_OID_ANSI_X9_62 -#define OID_ANSI_X9_62_FIELD_TYPE MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE -#define OID_ANSI_X9_62_PRIME_FIELD MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD -#define OID_ANSI_X9_62_SIG MBEDTLS_OID_ANSI_X9_62_SIG -#define OID_ANSI_X9_62_SIG_SHA2 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 -#define OID_ANY_EXTENDED_KEY_USAGE MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE -#define OID_AT MBEDTLS_OID_AT -#define OID_AT_CN MBEDTLS_OID_AT_CN -#define OID_AT_COUNTRY MBEDTLS_OID_AT_COUNTRY -#define OID_AT_DN_QUALIFIER MBEDTLS_OID_AT_DN_QUALIFIER -#define OID_AT_GENERATION_QUALIFIER MBEDTLS_OID_AT_GENERATION_QUALIFIER -#define OID_AT_GIVEN_NAME MBEDTLS_OID_AT_GIVEN_NAME -#define OID_AT_INITIALS MBEDTLS_OID_AT_INITIALS -#define OID_AT_LOCALITY MBEDTLS_OID_AT_LOCALITY -#define OID_AT_ORGANIZATION MBEDTLS_OID_AT_ORGANIZATION -#define OID_AT_ORG_UNIT MBEDTLS_OID_AT_ORG_UNIT -#define OID_AT_POSTAL_ADDRESS MBEDTLS_OID_AT_POSTAL_ADDRESS -#define OID_AT_POSTAL_CODE MBEDTLS_OID_AT_POSTAL_CODE -#define OID_AT_PSEUDONYM MBEDTLS_OID_AT_PSEUDONYM -#define OID_AT_SERIAL_NUMBER MBEDTLS_OID_AT_SERIAL_NUMBER -#define OID_AT_STATE MBEDTLS_OID_AT_STATE -#define OID_AT_SUR_NAME MBEDTLS_OID_AT_SUR_NAME -#define OID_AT_TITLE MBEDTLS_OID_AT_TITLE -#define OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT_UNIQUE_IDENTIFIER -#define OID_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER -#define OID_BASIC_CONSTRAINTS MBEDTLS_OID_BASIC_CONSTRAINTS -#define OID_CERTICOM MBEDTLS_OID_CERTICOM -#define OID_CERTIFICATE_POLICIES MBEDTLS_OID_CERTIFICATE_POLICIES -#define OID_CLIENT_AUTH MBEDTLS_OID_CLIENT_AUTH -#define OID_CMP MBEDTLS_OID_CMP -#define OID_CODE_SIGNING MBEDTLS_OID_CODE_SIGNING -#define OID_COUNTRY_US MBEDTLS_OID_COUNTRY_US -#define OID_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_CRL_DISTRIBUTION_POINTS -#define OID_CRL_NUMBER MBEDTLS_OID_CRL_NUMBER -#define OID_DES_CBC MBEDTLS_OID_DES_CBC -#define OID_DES_EDE3_CBC MBEDTLS_OID_DES_EDE3_CBC -#define OID_DIGEST_ALG_MD2 MBEDTLS_OID_DIGEST_ALG_MD2 -#define OID_DIGEST_ALG_MD4 MBEDTLS_OID_DIGEST_ALG_MD4 -#define OID_DIGEST_ALG_MD5 MBEDTLS_OID_DIGEST_ALG_MD5 -#define OID_DIGEST_ALG_SHA1 MBEDTLS_OID_DIGEST_ALG_SHA1 -#define OID_DIGEST_ALG_SHA224 MBEDTLS_OID_DIGEST_ALG_SHA224 -#define OID_DIGEST_ALG_SHA256 MBEDTLS_OID_DIGEST_ALG_SHA256 -#define OID_DIGEST_ALG_SHA384 MBEDTLS_OID_DIGEST_ALG_SHA384 -#define OID_DIGEST_ALG_SHA512 MBEDTLS_OID_DIGEST_ALG_SHA512 -#define OID_DOMAIN_COMPONENT MBEDTLS_OID_DOMAIN_COMPONENT -#define OID_ECDSA_SHA1 MBEDTLS_OID_ECDSA_SHA1 -#define OID_ECDSA_SHA224 MBEDTLS_OID_ECDSA_SHA224 -#define OID_ECDSA_SHA256 MBEDTLS_OID_ECDSA_SHA256 -#define OID_ECDSA_SHA384 MBEDTLS_OID_ECDSA_SHA384 -#define OID_ECDSA_SHA512 MBEDTLS_OID_ECDSA_SHA512 -#define OID_EC_ALG_ECDH MBEDTLS_OID_EC_ALG_ECDH -#define OID_EC_ALG_UNRESTRICTED MBEDTLS_OID_EC_ALG_UNRESTRICTED -#define OID_EC_BRAINPOOL_V1 MBEDTLS_OID_EC_BRAINPOOL_V1 -#define OID_EC_GRP_BP256R1 MBEDTLS_OID_EC_GRP_BP256R1 -#define OID_EC_GRP_BP384R1 MBEDTLS_OID_EC_GRP_BP384R1 -#define OID_EC_GRP_BP512R1 MBEDTLS_OID_EC_GRP_BP512R1 -#define OID_EC_GRP_SECP192K1 MBEDTLS_OID_EC_GRP_SECP192K1 -#define OID_EC_GRP_SECP192R1 MBEDTLS_OID_EC_GRP_SECP192R1 -#define OID_EC_GRP_SECP224K1 MBEDTLS_OID_EC_GRP_SECP224K1 -#define OID_EC_GRP_SECP224R1 MBEDTLS_OID_EC_GRP_SECP224R1 -#define OID_EC_GRP_SECP256K1 MBEDTLS_OID_EC_GRP_SECP256K1 -#define OID_EC_GRP_SECP256R1 MBEDTLS_OID_EC_GRP_SECP256R1 -#define OID_EC_GRP_SECP384R1 MBEDTLS_OID_EC_GRP_SECP384R1 -#define OID_EC_GRP_SECP521R1 MBEDTLS_OID_EC_GRP_SECP521R1 -#define OID_EMAIL_PROTECTION MBEDTLS_OID_EMAIL_PROTECTION -#define OID_EXTENDED_KEY_USAGE MBEDTLS_OID_EXTENDED_KEY_USAGE -#define OID_FRESHEST_CRL MBEDTLS_OID_FRESHEST_CRL -#define OID_GOV MBEDTLS_OID_GOV -#define OID_HMAC_SHA1 MBEDTLS_OID_HMAC_SHA1 -#define OID_ID_CE MBEDTLS_OID_ID_CE -#define OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_INIHIBIT_ANYPOLICY -#define OID_ISO_CCITT_DS MBEDTLS_OID_ISO_CCITT_DS -#define OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ISO_IDENTIFIED_ORG -#define OID_ISO_ITU_COUNTRY MBEDTLS_OID_ISO_ITU_COUNTRY -#define OID_ISO_ITU_US_ORG MBEDTLS_OID_ISO_ITU_US_ORG -#define OID_ISO_MEMBER_BODIES MBEDTLS_OID_ISO_MEMBER_BODIES -#define OID_ISSUER_ALT_NAME MBEDTLS_OID_ISSUER_ALT_NAME -#define OID_KEY_USAGE MBEDTLS_OID_KEY_USAGE -#define OID_KP MBEDTLS_OID_KP -#define OID_MGF1 MBEDTLS_OID_MGF1 -#define OID_NAME_CONSTRAINTS MBEDTLS_OID_NAME_CONSTRAINTS -#define OID_NETSCAPE MBEDTLS_OID_NETSCAPE -#define OID_NS_BASE_URL MBEDTLS_OID_NS_BASE_URL -#define OID_NS_CA_POLICY_URL MBEDTLS_OID_NS_CA_POLICY_URL -#define OID_NS_CA_REVOCATION_URL MBEDTLS_OID_NS_CA_REVOCATION_URL -#define OID_NS_CERT MBEDTLS_OID_NS_CERT -#define OID_NS_CERT_SEQUENCE MBEDTLS_OID_NS_CERT_SEQUENCE -#define OID_NS_CERT_TYPE MBEDTLS_OID_NS_CERT_TYPE -#define OID_NS_COMMENT MBEDTLS_OID_NS_COMMENT -#define OID_NS_DATA_TYPE MBEDTLS_OID_NS_DATA_TYPE -#define OID_NS_RENEWAL_URL MBEDTLS_OID_NS_RENEWAL_URL -#define OID_NS_REVOCATION_URL MBEDTLS_OID_NS_REVOCATION_URL -#define OID_NS_SSL_SERVER_NAME MBEDTLS_OID_NS_SSL_SERVER_NAME -#define OID_OCSP_SIGNING MBEDTLS_OID_OCSP_SIGNING -#define OID_OIW_SECSIG MBEDTLS_OID_OIW_SECSIG -#define OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG_ALG -#define OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_SHA1 -#define OID_ORGANIZATION MBEDTLS_OID_ORGANIZATION -#define OID_ORG_ANSI_X9_62 MBEDTLS_OID_ORG_ANSI_X9_62 -#define OID_ORG_CERTICOM MBEDTLS_OID_ORG_CERTICOM -#define OID_ORG_DOD MBEDTLS_OID_ORG_DOD -#define OID_ORG_GOV MBEDTLS_OID_ORG_GOV -#define OID_ORG_NETSCAPE MBEDTLS_OID_ORG_NETSCAPE -#define OID_ORG_OIW MBEDTLS_OID_ORG_OIW -#define OID_ORG_RSA_DATA_SECURITY MBEDTLS_OID_ORG_RSA_DATA_SECURITY -#define OID_ORG_TELETRUST MBEDTLS_OID_ORG_TELETRUST -#define OID_PKCS MBEDTLS_OID_PKCS -#define OID_PKCS1 MBEDTLS_OID_PKCS1 -#define OID_PKCS12 MBEDTLS_OID_PKCS12 -#define OID_PKCS12_PBE MBEDTLS_OID_PKCS12_PBE -#define OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC -#define OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC -#define OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC -#define OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC -#define OID_PKCS12_PBE_SHA1_RC4_128 MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128 -#define OID_PKCS12_PBE_SHA1_RC4_40 MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_40 -#define OID_PKCS1_MD2 MBEDTLS_OID_PKCS1_MD2 -#define OID_PKCS1_MD4 MBEDTLS_OID_PKCS1_MD4 -#define OID_PKCS1_MD5 MBEDTLS_OID_PKCS1_MD5 -#define OID_PKCS1_RSA MBEDTLS_OID_PKCS1_RSA -#define OID_PKCS1_SHA1 MBEDTLS_OID_PKCS1_SHA1 -#define OID_PKCS1_SHA224 MBEDTLS_OID_PKCS1_SHA224 -#define OID_PKCS1_SHA256 MBEDTLS_OID_PKCS1_SHA256 -#define OID_PKCS1_SHA384 MBEDTLS_OID_PKCS1_SHA384 -#define OID_PKCS1_SHA512 MBEDTLS_OID_PKCS1_SHA512 -#define OID_PKCS5 MBEDTLS_OID_PKCS5 -#define OID_PKCS5_PBES2 MBEDTLS_OID_PKCS5_PBES2 -#define OID_PKCS5_PBE_MD2_DES_CBC MBEDTLS_OID_PKCS5_PBE_MD2_DES_CBC -#define OID_PKCS5_PBE_MD2_RC2_CBC MBEDTLS_OID_PKCS5_PBE_MD2_RC2_CBC -#define OID_PKCS5_PBE_MD5_DES_CBC MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC -#define OID_PKCS5_PBE_MD5_RC2_CBC MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC -#define OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC -#define OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC -#define OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5_PBKDF2 -#define OID_PKCS5_PBMAC1 MBEDTLS_OID_PKCS5_PBMAC1 -#define OID_PKCS9 MBEDTLS_OID_PKCS9 -#define OID_PKCS9_CSR_EXT_REQ MBEDTLS_OID_PKCS9_CSR_EXT_REQ -#define OID_PKCS9_EMAIL MBEDTLS_OID_PKCS9_EMAIL -#define OID_PKIX MBEDTLS_OID_PKIX -#define OID_POLICY_CONSTRAINTS MBEDTLS_OID_POLICY_CONSTRAINTS -#define OID_POLICY_MAPPINGS MBEDTLS_OID_POLICY_MAPPINGS -#define OID_PRIVATE_KEY_USAGE_PERIOD MBEDTLS_OID_PRIVATE_KEY_USAGE_PERIOD -#define OID_RSASSA_PSS MBEDTLS_OID_RSASSA_PSS -#define OID_RSA_COMPANY MBEDTLS_OID_RSA_COMPANY -#define OID_RSA_SHA_OBS MBEDTLS_OID_RSA_SHA_OBS -#define OID_SERVER_AUTH MBEDTLS_OID_SERVER_AUTH -#define OID_SIZE MBEDTLS_OID_SIZE -#define OID_SUBJECT_ALT_NAME MBEDTLS_OID_SUBJECT_ALT_NAME -#define OID_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS -#define OID_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER -#define OID_TELETRUST MBEDTLS_OID_TELETRUST -#define OID_TIME_STAMPING MBEDTLS_OID_TIME_STAMPING -#define PADLOCK_ACE MBEDTLS_PADLOCK_ACE -#define PADLOCK_ALIGN16 MBEDTLS_PADLOCK_ALIGN16 -#define PADLOCK_PHE MBEDTLS_PADLOCK_PHE -#define PADLOCK_PMM MBEDTLS_PADLOCK_PMM -#define PADLOCK_RNG MBEDTLS_PADLOCK_RNG -#define PKCS12_DERIVE_IV MBEDTLS_PKCS12_DERIVE_IV -#define PKCS12_DERIVE_KEY MBEDTLS_PKCS12_DERIVE_KEY -#define PKCS12_DERIVE_MAC_KEY MBEDTLS_PKCS12_DERIVE_MAC_KEY -#define PKCS12_PBE_DECRYPT MBEDTLS_PKCS12_PBE_DECRYPT -#define PKCS12_PBE_ENCRYPT MBEDTLS_PKCS12_PBE_ENCRYPT -#define PKCS5_DECRYPT MBEDTLS_PKCS5_DECRYPT -#define PKCS5_ENCRYPT MBEDTLS_PKCS5_ENCRYPT -#define POLARSSL_AESNI_AES MBEDTLS_AESNI_AES -#define POLARSSL_AESNI_CLMUL MBEDTLS_AESNI_CLMUL -#define POLARSSL_AESNI_H MBEDTLS_AESNI_H -#define POLARSSL_AES_H MBEDTLS_AES_H -#define POLARSSL_ARC4_H MBEDTLS_ARC4_H -#define POLARSSL_ASN1_H MBEDTLS_ASN1_H -#define POLARSSL_ASN1_WRITE_H MBEDTLS_ASN1_WRITE_H -#define POLARSSL_BASE64_H MBEDTLS_BASE64_H -#define POLARSSL_BIGNUM_H MBEDTLS_BIGNUM_H -#define POLARSSL_BLOWFISH_H MBEDTLS_BLOWFISH_H -#define POLARSSL_BN_MUL_H MBEDTLS_BN_MUL_H -#define POLARSSL_CAMELLIA_H MBEDTLS_CAMELLIA_H -#define POLARSSL_CCM_H MBEDTLS_CCM_H -#define POLARSSL_CERTS_H MBEDTLS_CERTS_H -#define POLARSSL_CHECK_CONFIG_H MBEDTLS_CHECK_CONFIG_H -#define POLARSSL_CIPHERSUITE_NODTLS MBEDTLS_CIPHERSUITE_NODTLS -#define POLARSSL_CIPHERSUITE_SHORT_TAG MBEDTLS_CIPHERSUITE_SHORT_TAG -#define POLARSSL_CIPHERSUITE_WEAK MBEDTLS_CIPHERSUITE_WEAK -#define POLARSSL_CIPHER_AES_128_CBC MBEDTLS_CIPHER_AES_128_CBC -#define POLARSSL_CIPHER_AES_128_CCM MBEDTLS_CIPHER_AES_128_CCM -#define POLARSSL_CIPHER_AES_128_CFB128 MBEDTLS_CIPHER_AES_128_CFB128 -#define POLARSSL_CIPHER_AES_128_CTR MBEDTLS_CIPHER_AES_128_CTR -#define POLARSSL_CIPHER_AES_128_ECB MBEDTLS_CIPHER_AES_128_ECB -#define POLARSSL_CIPHER_AES_128_GCM MBEDTLS_CIPHER_AES_128_GCM -#define POLARSSL_CIPHER_AES_192_CBC MBEDTLS_CIPHER_AES_192_CBC -#define POLARSSL_CIPHER_AES_192_CCM MBEDTLS_CIPHER_AES_192_CCM -#define POLARSSL_CIPHER_AES_192_CFB128 MBEDTLS_CIPHER_AES_192_CFB128 -#define POLARSSL_CIPHER_AES_192_CTR MBEDTLS_CIPHER_AES_192_CTR -#define POLARSSL_CIPHER_AES_192_ECB MBEDTLS_CIPHER_AES_192_ECB -#define POLARSSL_CIPHER_AES_192_GCM MBEDTLS_CIPHER_AES_192_GCM -#define POLARSSL_CIPHER_AES_256_CBC MBEDTLS_CIPHER_AES_256_CBC -#define POLARSSL_CIPHER_AES_256_CCM MBEDTLS_CIPHER_AES_256_CCM -#define POLARSSL_CIPHER_AES_256_CFB128 MBEDTLS_CIPHER_AES_256_CFB128 -#define POLARSSL_CIPHER_AES_256_CTR MBEDTLS_CIPHER_AES_256_CTR -#define POLARSSL_CIPHER_AES_256_ECB MBEDTLS_CIPHER_AES_256_ECB -#define POLARSSL_CIPHER_AES_256_GCM MBEDTLS_CIPHER_AES_256_GCM -#define POLARSSL_CIPHER_ARC4_128 MBEDTLS_CIPHER_ARC4_128 -#define POLARSSL_CIPHER_BLOWFISH_CBC MBEDTLS_CIPHER_BLOWFISH_CBC -#define POLARSSL_CIPHER_BLOWFISH_CFB64 MBEDTLS_CIPHER_BLOWFISH_CFB64 -#define POLARSSL_CIPHER_BLOWFISH_CTR MBEDTLS_CIPHER_BLOWFISH_CTR -#define POLARSSL_CIPHER_BLOWFISH_ECB MBEDTLS_CIPHER_BLOWFISH_ECB -#define POLARSSL_CIPHER_CAMELLIA_128_CBC MBEDTLS_CIPHER_CAMELLIA_128_CBC -#define POLARSSL_CIPHER_CAMELLIA_128_CCM MBEDTLS_CIPHER_CAMELLIA_128_CCM -#define POLARSSL_CIPHER_CAMELLIA_128_CFB128 MBEDTLS_CIPHER_CAMELLIA_128_CFB128 -#define POLARSSL_CIPHER_CAMELLIA_128_CTR MBEDTLS_CIPHER_CAMELLIA_128_CTR -#define POLARSSL_CIPHER_CAMELLIA_128_ECB MBEDTLS_CIPHER_CAMELLIA_128_ECB -#define POLARSSL_CIPHER_CAMELLIA_128_GCM MBEDTLS_CIPHER_CAMELLIA_128_GCM -#define POLARSSL_CIPHER_CAMELLIA_192_CBC MBEDTLS_CIPHER_CAMELLIA_192_CBC -#define POLARSSL_CIPHER_CAMELLIA_192_CCM MBEDTLS_CIPHER_CAMELLIA_192_CCM -#define POLARSSL_CIPHER_CAMELLIA_192_CFB128 MBEDTLS_CIPHER_CAMELLIA_192_CFB128 -#define POLARSSL_CIPHER_CAMELLIA_192_CTR MBEDTLS_CIPHER_CAMELLIA_192_CTR -#define POLARSSL_CIPHER_CAMELLIA_192_ECB MBEDTLS_CIPHER_CAMELLIA_192_ECB -#define POLARSSL_CIPHER_CAMELLIA_192_GCM MBEDTLS_CIPHER_CAMELLIA_192_GCM -#define POLARSSL_CIPHER_CAMELLIA_256_CBC MBEDTLS_CIPHER_CAMELLIA_256_CBC -#define POLARSSL_CIPHER_CAMELLIA_256_CCM MBEDTLS_CIPHER_CAMELLIA_256_CCM -#define POLARSSL_CIPHER_CAMELLIA_256_CFB128 MBEDTLS_CIPHER_CAMELLIA_256_CFB128 -#define POLARSSL_CIPHER_CAMELLIA_256_CTR MBEDTLS_CIPHER_CAMELLIA_256_CTR -#define POLARSSL_CIPHER_CAMELLIA_256_ECB MBEDTLS_CIPHER_CAMELLIA_256_ECB -#define POLARSSL_CIPHER_CAMELLIA_256_GCM MBEDTLS_CIPHER_CAMELLIA_256_GCM -#define POLARSSL_CIPHER_DES_CBC MBEDTLS_CIPHER_DES_CBC -#define POLARSSL_CIPHER_DES_ECB MBEDTLS_CIPHER_DES_ECB -#define POLARSSL_CIPHER_DES_EDE3_CBC MBEDTLS_CIPHER_DES_EDE3_CBC -#define POLARSSL_CIPHER_DES_EDE3_ECB MBEDTLS_CIPHER_DES_EDE3_ECB -#define POLARSSL_CIPHER_DES_EDE_CBC MBEDTLS_CIPHER_DES_EDE_CBC -#define POLARSSL_CIPHER_DES_EDE_ECB MBEDTLS_CIPHER_DES_EDE_ECB -#define POLARSSL_CIPHER_H MBEDTLS_CIPHER_H -#define POLARSSL_CIPHER_ID_3DES MBEDTLS_CIPHER_ID_3DES -#define POLARSSL_CIPHER_ID_AES MBEDTLS_CIPHER_ID_AES -#define POLARSSL_CIPHER_ID_ARC4 MBEDTLS_CIPHER_ID_ARC4 -#define POLARSSL_CIPHER_ID_BLOWFISH MBEDTLS_CIPHER_ID_BLOWFISH -#define POLARSSL_CIPHER_ID_CAMELLIA MBEDTLS_CIPHER_ID_CAMELLIA -#define POLARSSL_CIPHER_ID_DES MBEDTLS_CIPHER_ID_DES -#define POLARSSL_CIPHER_ID_NONE MBEDTLS_CIPHER_ID_NONE -#define POLARSSL_CIPHER_ID_NULL MBEDTLS_CIPHER_ID_NULL -#define POLARSSL_CIPHER_MODE_AEAD MBEDTLS_CIPHER_MODE_AEAD -#define POLARSSL_CIPHER_MODE_STREAM MBEDTLS_CIPHER_MODE_STREAM -#define POLARSSL_CIPHER_MODE_WITH_PADDING MBEDTLS_CIPHER_MODE_WITH_PADDING -#define POLARSSL_CIPHER_NONE MBEDTLS_CIPHER_NONE -#define POLARSSL_CIPHER_NULL MBEDTLS_CIPHER_NULL -#define POLARSSL_CIPHER_VARIABLE_IV_LEN MBEDTLS_CIPHER_VARIABLE_IV_LEN -#define POLARSSL_CIPHER_VARIABLE_KEY_LEN MBEDTLS_CIPHER_VARIABLE_KEY_LEN -#define POLARSSL_CIPHER_WRAP_H MBEDTLS_CIPHER_WRAP_H -#define POLARSSL_CONFIG_H MBEDTLS_CONFIG_H -#define POLARSSL_CTR_DRBG_H MBEDTLS_CTR_DRBG_H -#define POLARSSL_DEBUG_H MBEDTLS_DEBUG_H -#define POLARSSL_DECRYPT MBEDTLS_DECRYPT -#define POLARSSL_DES_H MBEDTLS_DES_H -#define POLARSSL_DHM_H MBEDTLS_DHM_H -#define POLARSSL_DHM_RFC3526_MODP_2048_G MBEDTLS_DHM_RFC3526_MODP_2048_G -#define POLARSSL_DHM_RFC3526_MODP_2048_P MBEDTLS_DHM_RFC3526_MODP_2048_P -#define POLARSSL_DHM_RFC3526_MODP_3072_G MBEDTLS_DHM_RFC3526_MODP_3072_G -#define POLARSSL_DHM_RFC3526_MODP_3072_P MBEDTLS_DHM_RFC3526_MODP_3072_P -#define POLARSSL_DHM_RFC5114_MODP_2048_G MBEDTLS_DHM_RFC5114_MODP_2048_G -#define POLARSSL_DHM_RFC5114_MODP_2048_P MBEDTLS_DHM_RFC5114_MODP_2048_P -#define POLARSSL_ECDH_H MBEDTLS_ECDH_H -#define POLARSSL_ECDH_OURS MBEDTLS_ECDH_OURS -#define POLARSSL_ECDH_THEIRS MBEDTLS_ECDH_THEIRS -#define POLARSSL_ECDSA_H MBEDTLS_ECDSA_H -#define POLARSSL_ECP_DP_BP256R1 MBEDTLS_ECP_DP_BP256R1 -#define POLARSSL_ECP_DP_BP384R1 MBEDTLS_ECP_DP_BP384R1 -#define POLARSSL_ECP_DP_BP512R1 MBEDTLS_ECP_DP_BP512R1 -#define POLARSSL_ECP_DP_M255 MBEDTLS_ECP_DP_CURVE25519 -#define POLARSSL_ECP_DP_MAX MBEDTLS_ECP_DP_MAX -#define POLARSSL_ECP_DP_NONE MBEDTLS_ECP_DP_NONE -#define POLARSSL_ECP_DP_SECP192K1 MBEDTLS_ECP_DP_SECP192K1 -#define POLARSSL_ECP_DP_SECP192R1 MBEDTLS_ECP_DP_SECP192R1 -#define POLARSSL_ECP_DP_SECP224K1 MBEDTLS_ECP_DP_SECP224K1 -#define POLARSSL_ECP_DP_SECP224R1 MBEDTLS_ECP_DP_SECP224R1 -#define POLARSSL_ECP_DP_SECP256K1 MBEDTLS_ECP_DP_SECP256K1 -#define POLARSSL_ECP_DP_SECP256R1 MBEDTLS_ECP_DP_SECP256R1 -#define POLARSSL_ECP_DP_SECP384R1 MBEDTLS_ECP_DP_SECP384R1 -#define POLARSSL_ECP_DP_SECP521R1 MBEDTLS_ECP_DP_SECP521R1 -#define POLARSSL_ECP_H MBEDTLS_ECP_H -#define POLARSSL_ECP_MAX_BYTES MBEDTLS_ECP_MAX_BYTES -#define POLARSSL_ECP_MAX_PT_LEN MBEDTLS_ECP_MAX_PT_LEN -#define POLARSSL_ECP_PF_COMPRESSED MBEDTLS_ECP_PF_COMPRESSED -#define POLARSSL_ECP_PF_UNCOMPRESSED MBEDTLS_ECP_PF_UNCOMPRESSED -#define POLARSSL_ECP_TLS_NAMED_CURVE MBEDTLS_ECP_TLS_NAMED_CURVE -#define POLARSSL_ENCRYPT MBEDTLS_ENCRYPT -#define POLARSSL_ENTROPY_H MBEDTLS_ENTROPY_H -#define POLARSSL_ENTROPY_POLL_H MBEDTLS_ENTROPY_POLL_H -#define POLARSSL_ENTROPY_SHA256_ACCUMULATOR MBEDTLS_ENTROPY_SHA256_ACCUMULATOR -#define POLARSSL_ENTROPY_SHA512_ACCUMULATOR MBEDTLS_ENTROPY_SHA512_ACCUMULATOR -#define POLARSSL_ERROR_H MBEDTLS_ERROR_H -#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -#define POLARSSL_ERR_ASN1_BUF_TOO_SMALL MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -#define POLARSSL_ERR_ASN1_INVALID_DATA MBEDTLS_ERR_ASN1_INVALID_DATA -#define POLARSSL_ERR_ASN1_INVALID_LENGTH MBEDTLS_ERR_ASN1_INVALID_LENGTH -#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -#define POLARSSL_ERR_ASN1_MALLOC_FAILED MBEDTLS_ERR_ASN1_ALLOC_FAILED -#define POLARSSL_ERR_ASN1_OUT_OF_DATA MBEDTLS_ERR_ASN1_OUT_OF_DATA -#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -#define POLARSSL_ERR_BASE64_INVALID_CHARACTER MBEDTLS_ERR_BASE64_INVALID_CHARACTER -#define POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -#define POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH -#define POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -#define POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH -#define POLARSSL_ERR_CCM_AUTH_FAILED MBEDTLS_ERR_CCM_AUTH_FAILED -#define POLARSSL_ERR_CCM_BAD_INPUT MBEDTLS_ERR_CCM_BAD_INPUT -#define POLARSSL_ERR_CIPHER_ALLOC_FAILED MBEDTLS_ERR_CIPHER_ALLOC_FAILED -#define POLARSSL_ERR_CIPHER_AUTH_FAILED MBEDTLS_ERR_CIPHER_AUTH_FAILED -#define POLARSSL_ERR_CIPHER_BAD_INPUT_DATA MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -#define POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -#define POLARSSL_ERR_CIPHER_INVALID_PADDING MBEDTLS_ERR_CIPHER_INVALID_PADDING -#define POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -#define POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -#define POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -#define POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -#define POLARSSL_ERR_DHM_BAD_INPUT_DATA MBEDTLS_ERR_DHM_BAD_INPUT_DATA -#define POLARSSL_ERR_DHM_CALC_SECRET_FAILED MBEDTLS_ERR_DHM_CALC_SECRET_FAILED -#define POLARSSL_ERR_DHM_FILE_IO_ERROR MBEDTLS_ERR_DHM_FILE_IO_ERROR -#define POLARSSL_ERR_DHM_INVALID_FORMAT MBEDTLS_ERR_DHM_INVALID_FORMAT -#define POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED -#define POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED -#define POLARSSL_ERR_DHM_MALLOC_FAILED MBEDTLS_ERR_DHM_ALLOC_FAILED -#define POLARSSL_ERR_DHM_READ_PARAMS_FAILED MBEDTLS_ERR_DHM_READ_PARAMS_FAILED -#define POLARSSL_ERR_DHM_READ_PUBLIC_FAILED MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED -#define POLARSSL_ERR_ECP_BAD_INPUT_DATA MBEDTLS_ERR_ECP_BAD_INPUT_DATA -#define POLARSSL_ERR_ECP_BUFFER_TOO_SMALL MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL -#define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_ECP_INVALID_KEY MBEDTLS_ERR_ECP_INVALID_KEY -#define POLARSSL_ERR_ECP_MALLOC_FAILED MBEDTLS_ERR_ECP_ALLOC_FAILED -#define POLARSSL_ERR_ECP_RANDOM_FAILED MBEDTLS_ERR_ECP_RANDOM_FAILED -#define POLARSSL_ERR_ECP_SIG_LEN_MISMATCH MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -#define POLARSSL_ERR_ECP_VERIFY_FAILED MBEDTLS_ERR_ECP_VERIFY_FAILED -#define POLARSSL_ERR_ENTROPY_FILE_IO_ERROR MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -#define POLARSSL_ERR_ENTROPY_MAX_SOURCES MBEDTLS_ERR_ENTROPY_MAX_SOURCES -#define POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -#define POLARSSL_ERR_ENTROPY_SOURCE_FAILED MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -#define POLARSSL_ERR_GCM_AUTH_FAILED MBEDTLS_ERR_GCM_AUTH_FAILED -#define POLARSSL_ERR_GCM_BAD_INPUT MBEDTLS_ERR_GCM_BAD_INPUT -#define POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -#define POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -#define POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -#define POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -#define POLARSSL_ERR_MD_ALLOC_FAILED MBEDTLS_ERR_MD_ALLOC_FAILED -#define POLARSSL_ERR_MD_BAD_INPUT_DATA MBEDTLS_ERR_MD_BAD_INPUT_DATA -#define POLARSSL_ERR_MD_FEATURE_UNAVAILABLE MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_MD_FILE_IO_ERROR MBEDTLS_ERR_MD_FILE_IO_ERROR -#define POLARSSL_ERR_MPI_BAD_INPUT_DATA MBEDTLS_ERR_MPI_BAD_INPUT_DATA -#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -#define POLARSSL_ERR_MPI_FILE_IO_ERROR MBEDTLS_ERR_MPI_FILE_IO_ERROR -#define POLARSSL_ERR_MPI_INVALID_CHARACTER MBEDTLS_ERR_MPI_INVALID_CHARACTER -#define POLARSSL_ERR_MPI_MALLOC_FAILED MBEDTLS_ERR_MPI_ALLOC_FAILED -#define POLARSSL_ERR_MPI_NEGATIVE_VALUE MBEDTLS_ERR_MPI_NEGATIVE_VALUE -#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -#define POLARSSL_ERR_NET_ACCEPT_FAILED MBEDTLS_ERR_NET_ACCEPT_FAILED -#define POLARSSL_ERR_NET_BIND_FAILED MBEDTLS_ERR_NET_BIND_FAILED -#define POLARSSL_ERR_NET_CONNECT_FAILED MBEDTLS_ERR_NET_CONNECT_FAILED -#define POLARSSL_ERR_NET_CONN_RESET MBEDTLS_ERR_NET_CONN_RESET -#define POLARSSL_ERR_NET_LISTEN_FAILED MBEDTLS_ERR_NET_LISTEN_FAILED -#define POLARSSL_ERR_NET_RECV_FAILED MBEDTLS_ERR_NET_RECV_FAILED -#define POLARSSL_ERR_NET_SEND_FAILED MBEDTLS_ERR_NET_SEND_FAILED -#define POLARSSL_ERR_NET_SOCKET_FAILED MBEDTLS_ERR_NET_SOCKET_FAILED -#define POLARSSL_ERR_NET_TIMEOUT MBEDTLS_ERR_SSL_TIMEOUT -#define POLARSSL_ERR_NET_UNKNOWN_HOST MBEDTLS_ERR_NET_UNKNOWN_HOST -#define POLARSSL_ERR_NET_WANT_READ MBEDTLS_ERR_SSL_WANT_READ -#define POLARSSL_ERR_NET_WANT_WRITE MBEDTLS_ERR_SSL_WANT_WRITE -#define POLARSSL_ERR_OID_BUF_TOO_SMALL MBEDTLS_ERR_OID_BUF_TOO_SMALL -#define POLARSSL_ERR_OID_NOT_FOUND MBEDTLS_ERR_OID_NOT_FOUND -#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -#define POLARSSL_ERR_PEM_BAD_INPUT_DATA MBEDTLS_ERR_PEM_BAD_INPUT_DATA -#define POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_PEM_INVALID_DATA MBEDTLS_ERR_PEM_INVALID_DATA -#define POLARSSL_ERR_PEM_INVALID_ENC_IV MBEDTLS_ERR_PEM_INVALID_ENC_IV -#define POLARSSL_ERR_PEM_MALLOC_FAILED MBEDTLS_ERR_PEM_ALLOC_FAILED -#define POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT -#define POLARSSL_ERR_PEM_PASSWORD_MISMATCH MBEDTLS_ERR_PEM_PASSWORD_MISMATCH -#define POLARSSL_ERR_PEM_PASSWORD_REQUIRED MBEDTLS_ERR_PEM_PASSWORD_REQUIRED -#define POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG -#define POLARSSL_ERR_PKCS12_BAD_INPUT_DATA MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA -#define POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH -#define POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT -#define POLARSSL_ERR_PKCS5_BAD_INPUT_DATA MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA -#define POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_PKCS5_INVALID_FORMAT MBEDTLS_ERR_PKCS5_INVALID_FORMAT -#define POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH -#define POLARSSL_ERR_PK_BAD_INPUT_DATA MBEDTLS_ERR_PK_BAD_INPUT_DATA -#define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_PK_FILE_IO_ERROR MBEDTLS_ERR_PK_FILE_IO_ERROR -#define POLARSSL_ERR_PK_INVALID_ALG MBEDTLS_ERR_PK_INVALID_ALG -#define POLARSSL_ERR_PK_INVALID_PUBKEY MBEDTLS_ERR_PK_INVALID_PUBKEY -#define POLARSSL_ERR_PK_KEY_INVALID_FORMAT MBEDTLS_ERR_PK_KEY_INVALID_FORMAT -#define POLARSSL_ERR_PK_KEY_INVALID_VERSION MBEDTLS_ERR_PK_KEY_INVALID_VERSION -#define POLARSSL_ERR_PK_MALLOC_FAILED MBEDTLS_ERR_PK_ALLOC_FAILED -#define POLARSSL_ERR_PK_PASSWORD_MISMATCH MBEDTLS_ERR_PK_PASSWORD_MISMATCH -#define POLARSSL_ERR_PK_PASSWORD_REQUIRED MBEDTLS_ERR_PK_PASSWORD_REQUIRED -#define POLARSSL_ERR_PK_SIG_LEN_MISMATCH MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -#define POLARSSL_ERR_PK_TYPE_MISMATCH MBEDTLS_ERR_PK_TYPE_MISMATCH -#define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -#define POLARSSL_ERR_PK_UNKNOWN_PK_ALG MBEDTLS_ERR_PK_UNKNOWN_PK_ALG -#define POLARSSL_ERR_RSA_BAD_INPUT_DATA MBEDTLS_ERR_RSA_BAD_INPUT_DATA -#define POLARSSL_ERR_RSA_INVALID_PADDING MBEDTLS_ERR_RSA_INVALID_PADDING -#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED MBEDTLS_ERR_RSA_KEY_CHECK_FAILED -#define POLARSSL_ERR_RSA_KEY_GEN_FAILED MBEDTLS_ERR_RSA_KEY_GEN_FAILED -#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE -#define POLARSSL_ERR_RSA_PRIVATE_FAILED MBEDTLS_ERR_RSA_PRIVATE_FAILED -#define POLARSSL_ERR_RSA_PUBLIC_FAILED MBEDTLS_ERR_RSA_PUBLIC_FAILED -#define POLARSSL_ERR_RSA_RNG_FAILED MBEDTLS_ERR_RSA_RNG_FAILED -#define POLARSSL_ERR_RSA_VERIFY_FAILED MBEDTLS_ERR_RSA_VERIFY_FAILED -#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE -#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST -#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY -#define POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO -#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE -#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS -#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP -#define POLARSSL_ERR_SSL_BAD_HS_FINISHED MBEDTLS_ERR_SSL_BAD_HS_FINISHED -#define POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET -#define POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION -#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO -#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE -#define POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE -#define POLARSSL_ERR_SSL_BAD_INPUT_DATA MBEDTLS_ERR_SSL_BAD_INPUT_DATA -#define POLARSSL_ERR_SSL_BUFFER_TOO_SMALL MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL -#define POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED -#define POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED -#define POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE -#define POLARSSL_ERR_SSL_COMPRESSION_FAILED MBEDTLS_ERR_SSL_COMPRESSION_FAILED -#define POLARSSL_ERR_SSL_CONN_EOF MBEDTLS_ERR_SSL_CONN_EOF -#define POLARSSL_ERR_SSL_COUNTER_WRAPPING MBEDTLS_ERR_SSL_COUNTER_WRAPPING -#define POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE -#define POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED -#define POLARSSL_ERR_SSL_HW_ACCEL_FAILED MBEDTLS_ERR_SSL_HW_ACCEL_FAILED -#define POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH -#define POLARSSL_ERR_SSL_INTERNAL_ERROR MBEDTLS_ERR_SSL_INTERNAL_ERROR -#define POLARSSL_ERR_SSL_INVALID_MAC MBEDTLS_ERR_SSL_INVALID_MAC -#define POLARSSL_ERR_SSL_INVALID_RECORD MBEDTLS_ERR_SSL_INVALID_RECORD -#define POLARSSL_ERR_SSL_MALLOC_FAILED MBEDTLS_ERR_SSL_ALLOC_FAILED -#define POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN -#define POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE -#define POLARSSL_ERR_SSL_NO_RNG MBEDTLS_ERR_SSL_NO_RNG -#define POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE -#define POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY -#define POLARSSL_ERR_SSL_PEER_VERIFY_FAILED MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED -#define POLARSSL_ERR_SSL_PK_TYPE_MISMATCH MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH -#define POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED -#define POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED -#define POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE -#define POLARSSL_ERR_SSL_UNKNOWN_CIPHER MBEDTLS_ERR_SSL_UNKNOWN_CIPHER -#define POLARSSL_ERR_SSL_UNKNOWN_IDENTITY MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY -#define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -#define POLARSSL_ERR_THREADING_BAD_INPUT_DATA MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -#define POLARSSL_ERR_THREADING_FEATURE_UNAVAILABLE MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_THREADING_MUTEX_ERROR MBEDTLS_ERR_THREADING_MUTEX_ERROR -#define POLARSSL_ERR_X509_BAD_INPUT_DATA MBEDTLS_ERR_X509_BAD_INPUT_DATA -#define POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT -#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED MBEDTLS_ERR_X509_CERT_VERIFY_FAILED -#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE -#define POLARSSL_ERR_X509_FILE_IO_ERROR MBEDTLS_ERR_X509_FILE_IO_ERROR -#define POLARSSL_ERR_X509_INVALID_ALG MBEDTLS_ERR_X509_INVALID_ALG -#define POLARSSL_ERR_X509_INVALID_DATE MBEDTLS_ERR_X509_INVALID_DATE -#define POLARSSL_ERR_X509_INVALID_EXTENSIONS MBEDTLS_ERR_X509_INVALID_EXTENSIONS -#define POLARSSL_ERR_X509_INVALID_FORMAT MBEDTLS_ERR_X509_INVALID_FORMAT -#define POLARSSL_ERR_X509_INVALID_NAME MBEDTLS_ERR_X509_INVALID_NAME -#define POLARSSL_ERR_X509_INVALID_SERIAL MBEDTLS_ERR_X509_INVALID_SERIAL -#define POLARSSL_ERR_X509_INVALID_SIGNATURE MBEDTLS_ERR_X509_INVALID_SIGNATURE -#define POLARSSL_ERR_X509_INVALID_VERSION MBEDTLS_ERR_X509_INVALID_VERSION -#define POLARSSL_ERR_X509_MALLOC_FAILED MBEDTLS_ERR_X509_ALLOC_FAILED -#define POLARSSL_ERR_X509_SIG_MISMATCH MBEDTLS_ERR_X509_SIG_MISMATCH -#define POLARSSL_ERR_X509_UNKNOWN_OID MBEDTLS_ERR_X509_UNKNOWN_OID -#define POLARSSL_ERR_X509_UNKNOWN_SIG_ALG MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG -#define POLARSSL_ERR_X509_UNKNOWN_VERSION MBEDTLS_ERR_X509_UNKNOWN_VERSION -#define POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH -#define POLARSSL_GCM_H MBEDTLS_GCM_H -#define POLARSSL_HAVEGE_H MBEDTLS_HAVEGE_H -#define POLARSSL_HAVE_INT32 MBEDTLS_HAVE_INT32 -#define POLARSSL_HAVE_INT64 MBEDTLS_HAVE_INT64 -#define POLARSSL_HAVE_UDBL MBEDTLS_HAVE_UDBL -#define POLARSSL_HAVE_X86 MBEDTLS_HAVE_X86 -#define POLARSSL_HAVE_X86_64 MBEDTLS_HAVE_X86_64 -#define POLARSSL_HMAC_DRBG_H MBEDTLS_HMAC_DRBG_H -#define POLARSSL_HMAC_DRBG_PR_OFF MBEDTLS_HMAC_DRBG_PR_OFF -#define POLARSSL_HMAC_DRBG_PR_ON MBEDTLS_HMAC_DRBG_PR_ON -#define POLARSSL_KEY_EXCHANGE_DHE_PSK MBEDTLS_KEY_EXCHANGE_DHE_PSK -#define POLARSSL_KEY_EXCHANGE_DHE_RSA MBEDTLS_KEY_EXCHANGE_DHE_RSA -#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA -#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK MBEDTLS_KEY_EXCHANGE_ECDHE_PSK -#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA MBEDTLS_KEY_EXCHANGE_ECDHE_RSA -#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA -#define POLARSSL_KEY_EXCHANGE_ECDH_RSA MBEDTLS_KEY_EXCHANGE_ECDH_RSA -#define POLARSSL_KEY_EXCHANGE_NONE MBEDTLS_KEY_EXCHANGE_NONE -#define POLARSSL_KEY_EXCHANGE_PSK MBEDTLS_KEY_EXCHANGE_PSK -#define POLARSSL_KEY_EXCHANGE_RSA MBEDTLS_KEY_EXCHANGE_RSA -#define POLARSSL_KEY_EXCHANGE_RSA_PSK MBEDTLS_KEY_EXCHANGE_RSA_PSK -#define POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED -#define POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED -#define POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED -#define POLARSSL_KEY_LENGTH_DES MBEDTLS_KEY_LENGTH_DES -#define POLARSSL_KEY_LENGTH_DES_EDE MBEDTLS_KEY_LENGTH_DES_EDE -#define POLARSSL_KEY_LENGTH_DES_EDE3 MBEDTLS_KEY_LENGTH_DES_EDE3 -#define POLARSSL_KEY_LENGTH_NONE MBEDTLS_KEY_LENGTH_NONE -#define POLARSSL_MAX_BLOCK_LENGTH MBEDTLS_MAX_BLOCK_LENGTH -#define POLARSSL_MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH -#define POLARSSL_MD2_H MBEDTLS_MD2_H -#define POLARSSL_MD4_H MBEDTLS_MD4_H -#define POLARSSL_MD5_H MBEDTLS_MD5_H -#define POLARSSL_MD_H MBEDTLS_MD_H -#define POLARSSL_MD_MAX_SIZE MBEDTLS_MD_MAX_SIZE -#define POLARSSL_MD_MD2 MBEDTLS_MD_MD2 -#define POLARSSL_MD_MD4 MBEDTLS_MD_MD4 -#define POLARSSL_MD_MD5 MBEDTLS_MD_MD5 -#define POLARSSL_MD_NONE MBEDTLS_MD_NONE -#define POLARSSL_MD_RIPEMD160 MBEDTLS_MD_RIPEMD160 -#define POLARSSL_MD_SHA1 MBEDTLS_MD_SHA1 -#define POLARSSL_MD_SHA224 MBEDTLS_MD_SHA224 -#define POLARSSL_MD_SHA256 MBEDTLS_MD_SHA256 -#define POLARSSL_MD_SHA384 MBEDTLS_MD_SHA384 -#define POLARSSL_MD_SHA512 MBEDTLS_MD_SHA512 -#define POLARSSL_MD_WRAP_H MBEDTLS_MD_WRAP_H -#define POLARSSL_MEMORY_BUFFER_ALLOC_H MBEDTLS_MEMORY_BUFFER_ALLOC_H -#define POLARSSL_MODE_CBC MBEDTLS_MODE_CBC -#define POLARSSL_MODE_CCM MBEDTLS_MODE_CCM -#define POLARSSL_MODE_CFB MBEDTLS_MODE_CFB -#define POLARSSL_MODE_CTR MBEDTLS_MODE_CTR -#define POLARSSL_MODE_ECB MBEDTLS_MODE_ECB -#define POLARSSL_MODE_GCM MBEDTLS_MODE_GCM -#define POLARSSL_MODE_NONE MBEDTLS_MODE_NONE -#define POLARSSL_MODE_OFB MBEDTLS_MODE_OFB -#define POLARSSL_MODE_STREAM MBEDTLS_MODE_STREAM -#define POLARSSL_MPI_MAX_BITS MBEDTLS_MPI_MAX_BITS -#define POLARSSL_MPI_MAX_BITS_SCALE100 MBEDTLS_MPI_MAX_BITS_SCALE100 -#define POLARSSL_MPI_MAX_LIMBS MBEDTLS_MPI_MAX_LIMBS -#define POLARSSL_MPI_RW_BUFFER_SIZE MBEDTLS_MPI_RW_BUFFER_SIZE -#define POLARSSL_NET_H MBEDTLS_NET_SOCKETS_H -#define POLARSSL_NET_LISTEN_BACKLOG MBEDTLS_NET_LISTEN_BACKLOG -#define POLARSSL_OID_H MBEDTLS_OID_H -#define POLARSSL_OPERATION_NONE MBEDTLS_OPERATION_NONE -#define POLARSSL_PADDING_NONE MBEDTLS_PADDING_NONE -#define POLARSSL_PADDING_ONE_AND_ZEROS MBEDTLS_PADDING_ONE_AND_ZEROS -#define POLARSSL_PADDING_PKCS7 MBEDTLS_PADDING_PKCS7 -#define POLARSSL_PADDING_ZEROS MBEDTLS_PADDING_ZEROS -#define POLARSSL_PADDING_ZEROS_AND_LEN MBEDTLS_PADDING_ZEROS_AND_LEN -#define POLARSSL_PADLOCK_H MBEDTLS_PADLOCK_H -#define POLARSSL_PEM_H MBEDTLS_PEM_H -#define POLARSSL_PKCS11_H MBEDTLS_PKCS11_H -#define POLARSSL_PKCS12_H MBEDTLS_PKCS12_H -#define POLARSSL_PKCS5_H MBEDTLS_PKCS5_H -#define POLARSSL_PK_DEBUG_ECP MBEDTLS_PK_DEBUG_ECP -#define POLARSSL_PK_DEBUG_MAX_ITEMS MBEDTLS_PK_DEBUG_MAX_ITEMS -#define POLARSSL_PK_DEBUG_MPI MBEDTLS_PK_DEBUG_MPI -#define POLARSSL_PK_DEBUG_NONE MBEDTLS_PK_DEBUG_NONE -#define POLARSSL_PK_ECDSA MBEDTLS_PK_ECDSA -#define POLARSSL_PK_ECKEY MBEDTLS_PK_ECKEY -#define POLARSSL_PK_ECKEY_DH MBEDTLS_PK_ECKEY_DH -#define POLARSSL_PK_H MBEDTLS_PK_H -#define POLARSSL_PK_NONE MBEDTLS_PK_NONE -#define POLARSSL_PK_RSA MBEDTLS_PK_RSA -#define POLARSSL_PK_RSASSA_PSS MBEDTLS_PK_RSASSA_PSS -#define POLARSSL_PK_RSA_ALT MBEDTLS_PK_RSA_ALT -#define POLARSSL_PK_WRAP_H MBEDTLS_PK_WRAP_H -#define POLARSSL_PLATFORM_H MBEDTLS_PLATFORM_H -#define POLARSSL_PREMASTER_SIZE MBEDTLS_PREMASTER_SIZE -#define POLARSSL_RIPEMD160_H MBEDTLS_RIPEMD160_H -#define POLARSSL_RSA_H MBEDTLS_RSA_H -#define POLARSSL_SHA1_H MBEDTLS_SHA1_H -#define POLARSSL_SHA256_H MBEDTLS_SHA256_H -#define POLARSSL_SHA512_H MBEDTLS_SHA512_H -#define POLARSSL_SSL_CACHE_H MBEDTLS_SSL_CACHE_H -#define POLARSSL_SSL_CIPHERSUITES_H MBEDTLS_SSL_CIPHERSUITES_H -#define POLARSSL_SSL_COOKIE_H MBEDTLS_SSL_COOKIE_H -#define POLARSSL_SSL_H MBEDTLS_SSL_H -#define POLARSSL_THREADING_H MBEDTLS_THREADING_H -#define POLARSSL_THREADING_IMPL MBEDTLS_THREADING_IMPL -#define POLARSSL_TIMING_H MBEDTLS_TIMING_H -#define POLARSSL_VERSION_H MBEDTLS_VERSION_H -#define POLARSSL_VERSION_MAJOR MBEDTLS_VERSION_MAJOR -#define POLARSSL_VERSION_MINOR MBEDTLS_VERSION_MINOR -#define POLARSSL_VERSION_NUMBER MBEDTLS_VERSION_NUMBER -#define POLARSSL_VERSION_PATCH MBEDTLS_VERSION_PATCH -#define POLARSSL_VERSION_STRING MBEDTLS_VERSION_STRING -#define POLARSSL_VERSION_STRING_FULL MBEDTLS_VERSION_STRING_FULL -#define POLARSSL_X509_CRL_H MBEDTLS_X509_CRL_H -#define POLARSSL_X509_CRT_H MBEDTLS_X509_CRT_H -#define POLARSSL_X509_CSR_H MBEDTLS_X509_CSR_H -#define POLARSSL_X509_H MBEDTLS_X509_H -#define POLARSSL_XTEA_H MBEDTLS_XTEA_H -#define RSA_CRYPT MBEDTLS_RSA_CRYPT -#define RSA_PKCS_V15 MBEDTLS_RSA_PKCS_V15 -#define RSA_PKCS_V21 MBEDTLS_RSA_PKCS_V21 -#define RSA_PRIVATE MBEDTLS_RSA_PRIVATE -#define RSA_PUBLIC MBEDTLS_RSA_PUBLIC -#define RSA_SALT_LEN_ANY MBEDTLS_RSA_SALT_LEN_ANY -#define RSA_SIGN MBEDTLS_RSA_SIGN -#define SSL_ALERT_LEVEL_FATAL MBEDTLS_SSL_ALERT_LEVEL_FATAL -#define SSL_ALERT_LEVEL_WARNING MBEDTLS_SSL_ALERT_LEVEL_WARNING -#define SSL_ALERT_MSG_ACCESS_DENIED MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED -#define SSL_ALERT_MSG_BAD_CERT MBEDTLS_SSL_ALERT_MSG_BAD_CERT -#define SSL_ALERT_MSG_BAD_RECORD_MAC MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC -#define SSL_ALERT_MSG_CERT_EXPIRED MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED -#define SSL_ALERT_MSG_CERT_REVOKED MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED -#define SSL_ALERT_MSG_CERT_UNKNOWN MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN -#define SSL_ALERT_MSG_CLOSE_NOTIFY MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY -#define SSL_ALERT_MSG_DECODE_ERROR MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR -#define SSL_ALERT_MSG_DECOMPRESSION_FAILURE MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE -#define SSL_ALERT_MSG_DECRYPTION_FAILED MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED -#define SSL_ALERT_MSG_DECRYPT_ERROR MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR -#define SSL_ALERT_MSG_EXPORT_RESTRICTION MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION -#define SSL_ALERT_MSG_HANDSHAKE_FAILURE MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE -#define SSL_ALERT_MSG_ILLEGAL_PARAMETER MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER -#define SSL_ALERT_MSG_INAPROPRIATE_FALLBACK MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK -#define SSL_ALERT_MSG_INSUFFICIENT_SECURITY MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY -#define SSL_ALERT_MSG_INTERNAL_ERROR MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR -#define SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL -#define SSL_ALERT_MSG_NO_CERT MBEDTLS_SSL_ALERT_MSG_NO_CERT -#define SSL_ALERT_MSG_NO_RENEGOTIATION MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION -#define SSL_ALERT_MSG_PROTOCOL_VERSION MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION -#define SSL_ALERT_MSG_RECORD_OVERFLOW MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW -#define SSL_ALERT_MSG_UNEXPECTED_MESSAGE MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE -#define SSL_ALERT_MSG_UNKNOWN_CA MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA -#define SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY -#define SSL_ALERT_MSG_UNRECOGNIZED_NAME MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME -#define SSL_ALERT_MSG_UNSUPPORTED_CERT MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT -#define SSL_ALERT_MSG_UNSUPPORTED_EXT MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT -#define SSL_ALERT_MSG_USER_CANCELED MBEDTLS_SSL_ALERT_MSG_USER_CANCELED -#define SSL_ANTI_REPLAY_DISABLED MBEDTLS_SSL_ANTI_REPLAY_DISABLED -#define SSL_ANTI_REPLAY_ENABLED MBEDTLS_SSL_ANTI_REPLAY_ENABLED -#define SSL_ARC4_DISABLED MBEDTLS_SSL_ARC4_DISABLED -#define SSL_ARC4_ENABLED MBEDTLS_SSL_ARC4_ENABLED -#define SSL_BUFFER_LEN ( ( ( MBEDTLS_SSL_IN_BUFFER_LEN ) < ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) \ - ? ( MBEDTLS_SSL_IN_BUFFER_LEN ) : ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) -#define SSL_CACHE_DEFAULT_MAX_ENTRIES MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES -#define SSL_CACHE_DEFAULT_TIMEOUT MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT -#define SSL_CBC_RECORD_SPLITTING_DISABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED -#define SSL_CBC_RECORD_SPLITTING_ENABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED -#define SSL_CERTIFICATE_REQUEST MBEDTLS_SSL_CERTIFICATE_REQUEST -#define SSL_CERTIFICATE_VERIFY MBEDTLS_SSL_CERTIFICATE_VERIFY -#define SSL_CERT_TYPE_ECDSA_SIGN MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN -#define SSL_CERT_TYPE_RSA_SIGN MBEDTLS_SSL_CERT_TYPE_RSA_SIGN -#define SSL_CHANNEL_INBOUND MBEDTLS_SSL_CHANNEL_INBOUND -#define SSL_CHANNEL_OUTBOUND MBEDTLS_SSL_CHANNEL_OUTBOUND -#define SSL_CIPHERSUITES MBEDTLS_SSL_CIPHERSUITES -#define SSL_CLIENT_CERTIFICATE MBEDTLS_SSL_CLIENT_CERTIFICATE -#define SSL_CLIENT_CHANGE_CIPHER_SPEC MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC -#define SSL_CLIENT_FINISHED MBEDTLS_SSL_CLIENT_FINISHED -#define SSL_CLIENT_HELLO MBEDTLS_SSL_CLIENT_HELLO -#define SSL_CLIENT_KEY_EXCHANGE MBEDTLS_SSL_CLIENT_KEY_EXCHANGE -#define SSL_COMPRESSION_ADD MBEDTLS_SSL_COMPRESSION_ADD -#define SSL_COMPRESS_DEFLATE MBEDTLS_SSL_COMPRESS_DEFLATE -#define SSL_COMPRESS_NULL MBEDTLS_SSL_COMPRESS_NULL -#define SSL_DEBUG_BUF MBEDTLS_SSL_DEBUG_BUF -#define SSL_DEBUG_CRT MBEDTLS_SSL_DEBUG_CRT -#define SSL_DEBUG_ECP MBEDTLS_SSL_DEBUG_ECP -#define SSL_DEBUG_MPI MBEDTLS_SSL_DEBUG_MPI -#define SSL_DEBUG_MSG MBEDTLS_SSL_DEBUG_MSG -#define SSL_DEBUG_RET MBEDTLS_SSL_DEBUG_RET -#define SSL_DEFAULT_TICKET_LIFETIME MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME -#define SSL_DTLS_TIMEOUT_DFL_MAX MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX -#define SSL_DTLS_TIMEOUT_DFL_MIN MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN -#define SSL_EMPTY_RENEGOTIATION_INFO MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO -#define SSL_ETM_DISABLED MBEDTLS_SSL_ETM_DISABLED -#define SSL_ETM_ENABLED MBEDTLS_SSL_ETM_ENABLED -#define SSL_EXTENDED_MS_DISABLED MBEDTLS_SSL_EXTENDED_MS_DISABLED -#define SSL_EXTENDED_MS_ENABLED MBEDTLS_SSL_EXTENDED_MS_ENABLED -#define SSL_FALLBACK_SCSV MBEDTLS_SSL_FALLBACK_SCSV -#define SSL_FLUSH_BUFFERS MBEDTLS_SSL_FLUSH_BUFFERS -#define SSL_HANDSHAKE_OVER MBEDTLS_SSL_HANDSHAKE_OVER -#define SSL_HANDSHAKE_WRAPUP MBEDTLS_SSL_HANDSHAKE_WRAPUP -#define SSL_HASH_MD5 MBEDTLS_SSL_HASH_MD5 -#define SSL_HASH_NONE MBEDTLS_SSL_HASH_NONE -#define SSL_HASH_SHA1 MBEDTLS_SSL_HASH_SHA1 -#define SSL_HASH_SHA224 MBEDTLS_SSL_HASH_SHA224 -#define SSL_HASH_SHA256 MBEDTLS_SSL_HASH_SHA256 -#define SSL_HASH_SHA384 MBEDTLS_SSL_HASH_SHA384 -#define SSL_HASH_SHA512 MBEDTLS_SSL_HASH_SHA512 -#define SSL_HELLO_REQUEST MBEDTLS_SSL_HELLO_REQUEST -#define SSL_HS_CERTIFICATE MBEDTLS_SSL_HS_CERTIFICATE -#define SSL_HS_CERTIFICATE_REQUEST MBEDTLS_SSL_HS_CERTIFICATE_REQUEST -#define SSL_HS_CERTIFICATE_VERIFY MBEDTLS_SSL_HS_CERTIFICATE_VERIFY -#define SSL_HS_CLIENT_HELLO MBEDTLS_SSL_HS_CLIENT_HELLO -#define SSL_HS_CLIENT_KEY_EXCHANGE MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE -#define SSL_HS_FINISHED MBEDTLS_SSL_HS_FINISHED -#define SSL_HS_HELLO_REQUEST MBEDTLS_SSL_HS_HELLO_REQUEST -#define SSL_HS_HELLO_VERIFY_REQUEST MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST -#define SSL_HS_NEW_SESSION_TICKET MBEDTLS_SSL_HS_NEW_SESSION_TICKET -#define SSL_HS_SERVER_HELLO MBEDTLS_SSL_HS_SERVER_HELLO -#define SSL_HS_SERVER_HELLO_DONE MBEDTLS_SSL_HS_SERVER_HELLO_DONE -#define SSL_HS_SERVER_KEY_EXCHANGE MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE -#define SSL_INITIAL_HANDSHAKE MBEDTLS_SSL_INITIAL_HANDSHAKE -#define SSL_IS_CLIENT MBEDTLS_SSL_IS_CLIENT -#define SSL_IS_FALLBACK MBEDTLS_SSL_IS_FALLBACK -#define SSL_IS_NOT_FALLBACK MBEDTLS_SSL_IS_NOT_FALLBACK -#define SSL_IS_SERVER MBEDTLS_SSL_IS_SERVER -#define SSL_LEGACY_ALLOW_RENEGOTIATION MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION -#define SSL_LEGACY_BREAK_HANDSHAKE MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE -#define SSL_LEGACY_NO_RENEGOTIATION MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION -#define SSL_LEGACY_RENEGOTIATION MBEDTLS_SSL_LEGACY_RENEGOTIATION -#define SSL_MAC_ADD MBEDTLS_SSL_MAC_ADD -#define SSL_MAJOR_VERSION_3 MBEDTLS_SSL_MAJOR_VERSION_3 -#define SSL_MAX_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN -#define SSL_MAX_FRAG_LEN_1024 MBEDTLS_SSL_MAX_FRAG_LEN_1024 -#define SSL_MAX_FRAG_LEN_2048 MBEDTLS_SSL_MAX_FRAG_LEN_2048 -#define SSL_MAX_FRAG_LEN_4096 MBEDTLS_SSL_MAX_FRAG_LEN_4096 -#define SSL_MAX_FRAG_LEN_512 MBEDTLS_SSL_MAX_FRAG_LEN_512 -#define SSL_MAX_FRAG_LEN_INVALID MBEDTLS_SSL_MAX_FRAG_LEN_INVALID -#define SSL_MAX_FRAG_LEN_NONE MBEDTLS_SSL_MAX_FRAG_LEN_NONE -#define SSL_MAX_MAJOR_VERSION MBEDTLS_SSL_MAX_MAJOR_VERSION -#define SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MAX_MINOR_VERSION -#define SSL_MINOR_VERSION_0 MBEDTLS_SSL_MINOR_VERSION_0 -#define SSL_MINOR_VERSION_1 MBEDTLS_SSL_MINOR_VERSION_1 -#define SSL_MINOR_VERSION_2 MBEDTLS_SSL_MINOR_VERSION_2 -#define SSL_MINOR_VERSION_3 MBEDTLS_SSL_MINOR_VERSION_3 -#define SSL_MIN_MAJOR_VERSION MBEDTLS_SSL_MIN_MAJOR_VERSION -#define SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MIN_MINOR_VERSION -#define SSL_MSG_ALERT MBEDTLS_SSL_MSG_ALERT -#define SSL_MSG_APPLICATION_DATA MBEDTLS_SSL_MSG_APPLICATION_DATA -#define SSL_MSG_CHANGE_CIPHER_SPEC MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC -#define SSL_MSG_HANDSHAKE MBEDTLS_SSL_MSG_HANDSHAKE -#define SSL_PADDING_ADD MBEDTLS_SSL_PADDING_ADD -#define SSL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION -#define SSL_RENEGOTIATION_DISABLED MBEDTLS_SSL_RENEGOTIATION_DISABLED -#define SSL_RENEGOTIATION_DONE MBEDTLS_SSL_RENEGOTIATION_DONE -#define SSL_RENEGOTIATION_ENABLED MBEDTLS_SSL_RENEGOTIATION_ENABLED -#define SSL_RENEGOTIATION_NOT_ENFORCED MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED -#define SSL_RENEGOTIATION_PENDING MBEDTLS_SSL_RENEGOTIATION_PENDING -#define SSL_RENEGO_MAX_RECORDS_DEFAULT MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT -#define SSL_RETRANS_FINISHED MBEDTLS_SSL_RETRANS_FINISHED -#define SSL_RETRANS_PREPARING MBEDTLS_SSL_RETRANS_PREPARING -#define SSL_RETRANS_SENDING MBEDTLS_SSL_RETRANS_SENDING -#define SSL_RETRANS_WAITING MBEDTLS_SSL_RETRANS_WAITING -#define SSL_SECURE_RENEGOTIATION MBEDTLS_SSL_SECURE_RENEGOTIATION -#define SSL_SERVER_CERTIFICATE MBEDTLS_SSL_SERVER_CERTIFICATE -#define SSL_SERVER_CHANGE_CIPHER_SPEC MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC -#define SSL_SERVER_FINISHED MBEDTLS_SSL_SERVER_FINISHED -#define SSL_SERVER_HELLO MBEDTLS_SSL_SERVER_HELLO -#define SSL_SERVER_HELLO_DONE MBEDTLS_SSL_SERVER_HELLO_DONE -#define SSL_SERVER_HELLO_VERIFY_REQUEST_SENT MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT -#define SSL_SERVER_KEY_EXCHANGE MBEDTLS_SSL_SERVER_KEY_EXCHANGE -#define SSL_SERVER_NEW_SESSION_TICKET MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET -#define SSL_SESSION_TICKETS_DISABLED MBEDTLS_SSL_SESSION_TICKETS_DISABLED -#define SSL_SESSION_TICKETS_ENABLED MBEDTLS_SSL_SESSION_TICKETS_ENABLED -#define SSL_SIG_ANON MBEDTLS_SSL_SIG_ANON -#define SSL_SIG_ECDSA MBEDTLS_SSL_SIG_ECDSA -#define SSL_SIG_RSA MBEDTLS_SSL_SIG_RSA -#define SSL_TRANSPORT_DATAGRAM MBEDTLS_SSL_TRANSPORT_DATAGRAM -#define SSL_TRANSPORT_STREAM MBEDTLS_SSL_TRANSPORT_STREAM -#define SSL_TRUNCATED_HMAC_LEN MBEDTLS_SSL_TRUNCATED_HMAC_LEN -#define SSL_TRUNC_HMAC_DISABLED MBEDTLS_SSL_TRUNC_HMAC_DISABLED -#define SSL_TRUNC_HMAC_ENABLED MBEDTLS_SSL_TRUNC_HMAC_ENABLED -#define SSL_VERIFY_DATA_MAX_LEN MBEDTLS_SSL_VERIFY_DATA_MAX_LEN -#define SSL_VERIFY_NONE MBEDTLS_SSL_VERIFY_NONE -#define SSL_VERIFY_OPTIONAL MBEDTLS_SSL_VERIFY_OPTIONAL -#define SSL_VERIFY_REQUIRED MBEDTLS_SSL_VERIFY_REQUIRED -#define TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA -#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA -#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 -#define TLS_DHE_PSK_WITH_AES_128_CCM MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM -#define TLS_DHE_PSK_WITH_AES_128_CCM_8 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8 -#define TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 -#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA -#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 -#define TLS_DHE_PSK_WITH_AES_256_CCM MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM -#define TLS_DHE_PSK_WITH_AES_256_CCM_8 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8 -#define TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 -#define TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 -#define TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 -#define TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 -#define TLS_DHE_PSK_WITH_NULL_SHA MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA -#define TLS_DHE_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 -#define TLS_DHE_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 -#define TLS_DHE_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA -#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA -#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA -#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 -#define TLS_DHE_RSA_WITH_AES_128_CCM MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM -#define TLS_DHE_RSA_WITH_AES_128_CCM_8 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 -#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 -#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA -#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 -#define TLS_DHE_RSA_WITH_AES_256_CCM MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM -#define TLS_DHE_RSA_WITH_AES_256_CCM_8 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 -#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 -#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA -#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 -#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA -#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 -#define TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 -#define TLS_DHE_RSA_WITH_DES_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA -#define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA -#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA -#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 -#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM -#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 -#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 -#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA -#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 -#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM -#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 -#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 -#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 -#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 -#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 -#define TLS_ECDHE_ECDSA_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA -#define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA -#define TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA -#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA -#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 -#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA -#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 -#define TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 -#define TLS_ECDHE_PSK_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA -#define TLS_ECDHE_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 -#define TLS_ECDHE_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 -#define TLS_ECDHE_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA -#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA -#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA -#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 -#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA -#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 -#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 -#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 -#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 -#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 -#define TLS_ECDHE_RSA_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA -#define TLS_ECDHE_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA -#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA -#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA -#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 -#define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 -#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA -#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 -#define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 -#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 -#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 -#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 -#define TLS_ECDH_ECDSA_WITH_NULL_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA -#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA -#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA -#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA -#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 -#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 -#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA -#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 -#define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 -#define TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 -#define TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 -#define TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 -#define TLS_ECDH_RSA_WITH_NULL_SHA MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA -#define TLS_ECDH_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA -#define TLS_EXT_ALPN MBEDTLS_TLS_EXT_ALPN -#define TLS_EXT_ENCRYPT_THEN_MAC MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC -#define TLS_EXT_EXTENDED_MASTER_SECRET MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET -#define TLS_EXT_MAX_FRAGMENT_LENGTH MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH -#define TLS_EXT_RENEGOTIATION_INFO MBEDTLS_TLS_EXT_RENEGOTIATION_INFO -#define TLS_EXT_SERVERNAME MBEDTLS_TLS_EXT_SERVERNAME -#define TLS_EXT_SERVERNAME_HOSTNAME MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME -#define TLS_EXT_SESSION_TICKET MBEDTLS_TLS_EXT_SESSION_TICKET -#define TLS_EXT_SIG_ALG MBEDTLS_TLS_EXT_SIG_ALG -#define TLS_EXT_SUPPORTED_ELLIPTIC_CURVES MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES -#define TLS_EXT_SUPPORTED_POINT_FORMATS MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS -#define TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT -#define TLS_EXT_TRUNCATED_HMAC MBEDTLS_TLS_EXT_TRUNCATED_HMAC -#define TLS_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA -#define TLS_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA -#define TLS_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 -#define TLS_PSK_WITH_AES_128_CCM MBEDTLS_TLS_PSK_WITH_AES_128_CCM -#define TLS_PSK_WITH_AES_128_CCM_8 MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8 -#define TLS_PSK_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 -#define TLS_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA -#define TLS_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 -#define TLS_PSK_WITH_AES_256_CCM MBEDTLS_TLS_PSK_WITH_AES_256_CCM -#define TLS_PSK_WITH_AES_256_CCM_8 MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8 -#define TLS_PSK_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 -#define TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 -#define TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 -#define TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 -#define TLS_PSK_WITH_NULL_SHA MBEDTLS_TLS_PSK_WITH_NULL_SHA -#define TLS_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_PSK_WITH_NULL_SHA256 -#define TLS_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_PSK_WITH_NULL_SHA384 -#define TLS_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_PSK_WITH_RC4_128_SHA -#define TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA -#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA -#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 -#define TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 -#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA -#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 -#define TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 -#define TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 -#define TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 -#define TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 -#define TLS_RSA_PSK_WITH_NULL_SHA MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA -#define TLS_RSA_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 -#define TLS_RSA_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 -#define TLS_RSA_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA -#define TLS_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA -#define TLS_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA -#define TLS_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 -#define TLS_RSA_WITH_AES_128_CCM MBEDTLS_TLS_RSA_WITH_AES_128_CCM -#define TLS_RSA_WITH_AES_128_CCM_8 MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8 -#define TLS_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 -#define TLS_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA -#define TLS_RSA_WITH_AES_256_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 -#define TLS_RSA_WITH_AES_256_CCM MBEDTLS_TLS_RSA_WITH_AES_256_CCM -#define TLS_RSA_WITH_AES_256_CCM_8 MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8 -#define TLS_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 -#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA -#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 -#define TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 -#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA -#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 -#define TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 -#define TLS_RSA_WITH_DES_CBC_SHA MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA -#define TLS_RSA_WITH_NULL_MD5 MBEDTLS_TLS_RSA_WITH_NULL_MD5 -#define TLS_RSA_WITH_NULL_SHA MBEDTLS_TLS_RSA_WITH_NULL_SHA -#define TLS_RSA_WITH_NULL_SHA256 MBEDTLS_TLS_RSA_WITH_NULL_SHA256 -#define TLS_RSA_WITH_RC4_128_MD5 MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 -#define TLS_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_RSA_WITH_RC4_128_SHA -#define X509_CRT_VERSION_1 MBEDTLS_X509_CRT_VERSION_1 -#define X509_CRT_VERSION_2 MBEDTLS_X509_CRT_VERSION_2 -#define X509_CRT_VERSION_3 MBEDTLS_X509_CRT_VERSION_3 -#define X509_FORMAT_DER MBEDTLS_X509_FORMAT_DER -#define X509_FORMAT_PEM MBEDTLS_X509_FORMAT_PEM -#define X509_MAX_DN_NAME_SIZE MBEDTLS_X509_MAX_DN_NAME_SIZE -#define X509_RFC5280_MAX_SERIAL_LEN MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN -#define X509_RFC5280_UTC_TIME_LEN MBEDTLS_X509_RFC5280_UTC_TIME_LEN -#define XTEA_DECRYPT MBEDTLS_XTEA_DECRYPT -#define XTEA_ENCRYPT MBEDTLS_XTEA_ENCRYPT -#define _asn1_bitstring mbedtls_asn1_bitstring -#define _asn1_buf mbedtls_asn1_buf -#define _asn1_named_data mbedtls_asn1_named_data -#define _asn1_sequence mbedtls_asn1_sequence -#define _ssl_cache_context mbedtls_ssl_cache_context -#define _ssl_cache_entry mbedtls_ssl_cache_entry -#define _ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t -#define _ssl_context mbedtls_ssl_context -#define _ssl_flight_item mbedtls_ssl_flight_item -#define _ssl_handshake_params mbedtls_ssl_handshake_params -#define _ssl_key_cert mbedtls_ssl_key_cert -#define _ssl_premaster_secret mbedtls_ssl_premaster_secret -#define _ssl_session mbedtls_ssl_session -#define _ssl_transform mbedtls_ssl_transform -#define _x509_crl mbedtls_x509_crl -#define _x509_crl_entry mbedtls_x509_crl_entry -#define _x509_crt mbedtls_x509_crt -#define _x509_csr mbedtls_x509_csr -#define _x509_time mbedtls_x509_time -#define _x509write_cert mbedtls_x509write_cert -#define _x509write_csr mbedtls_x509write_csr -#define aes_context mbedtls_aes_context -#define aes_crypt_cbc mbedtls_aes_crypt_cbc -#define aes_crypt_cfb128 mbedtls_aes_crypt_cfb128 -#define aes_crypt_cfb8 mbedtls_aes_crypt_cfb8 -#define aes_crypt_ctr mbedtls_aes_crypt_ctr -#define aes_crypt_ecb mbedtls_aes_crypt_ecb -#define aes_free mbedtls_aes_free -#define aes_init mbedtls_aes_init -#define aes_self_test mbedtls_aes_self_test -#define aes_setkey_dec mbedtls_aes_setkey_dec -#define aes_setkey_enc mbedtls_aes_setkey_enc -#define aesni_crypt_ecb mbedtls_aesni_crypt_ecb -#define aesni_gcm_mult mbedtls_aesni_gcm_mult -#define aesni_inverse_key mbedtls_aesni_inverse_key -#define aesni_setkey_enc mbedtls_aesni_setkey_enc -#define aesni_supports mbedtls_aesni_has_support -#define alarmed mbedtls_timing_alarmed -#define arc4_context mbedtls_arc4_context -#define arc4_crypt mbedtls_arc4_crypt -#define arc4_free mbedtls_arc4_free -#define arc4_init mbedtls_arc4_init -#define arc4_self_test mbedtls_arc4_self_test -#define arc4_setup mbedtls_arc4_setup -#define asn1_bitstring mbedtls_asn1_bitstring -#define asn1_buf mbedtls_asn1_buf -#define asn1_find_named_data mbedtls_asn1_find_named_data -#define asn1_free_named_data mbedtls_asn1_free_named_data -#define asn1_free_named_data_list mbedtls_asn1_free_named_data_list -#define asn1_get_alg mbedtls_asn1_get_alg -#define asn1_get_alg_null mbedtls_asn1_get_alg_null -#define asn1_get_bitstring mbedtls_asn1_get_bitstring -#define asn1_get_bitstring_null mbedtls_asn1_get_bitstring_null -#define asn1_get_bool mbedtls_asn1_get_bool -#define asn1_get_int mbedtls_asn1_get_int -#define asn1_get_len mbedtls_asn1_get_len -#define asn1_get_mpi mbedtls_asn1_get_mpi -#define asn1_get_sequence_of mbedtls_asn1_get_sequence_of -#define asn1_get_tag mbedtls_asn1_get_tag -#define asn1_named_data mbedtls_asn1_named_data -#define asn1_sequence mbedtls_asn1_sequence -#define asn1_store_named_data mbedtls_asn1_store_named_data -#define asn1_write_algorithm_identifier mbedtls_asn1_write_algorithm_identifier -#define asn1_write_bitstring mbedtls_asn1_write_bitstring -#define asn1_write_bool mbedtls_asn1_write_bool -#define asn1_write_ia5_string mbedtls_asn1_write_ia5_string -#define asn1_write_int mbedtls_asn1_write_int -#define asn1_write_len mbedtls_asn1_write_len -#define asn1_write_mpi mbedtls_asn1_write_mpi -#define asn1_write_null mbedtls_asn1_write_null -#define asn1_write_octet_string mbedtls_asn1_write_octet_string -#define asn1_write_oid mbedtls_asn1_write_oid -#define asn1_write_printable_string mbedtls_asn1_write_printable_string -#define asn1_write_raw_buffer mbedtls_asn1_write_raw_buffer -#define asn1_write_tag mbedtls_asn1_write_tag -#define base64_decode mbedtls_base64_decode -#define base64_encode mbedtls_base64_encode -#define base64_self_test mbedtls_base64_self_test -#define blowfish_context mbedtls_blowfish_context -#define blowfish_crypt_cbc mbedtls_blowfish_crypt_cbc -#define blowfish_crypt_cfb64 mbedtls_blowfish_crypt_cfb64 -#define blowfish_crypt_ctr mbedtls_blowfish_crypt_ctr -#define blowfish_crypt_ecb mbedtls_blowfish_crypt_ecb -#define blowfish_free mbedtls_blowfish_free -#define blowfish_init mbedtls_blowfish_init -#define blowfish_setkey mbedtls_blowfish_setkey -#define camellia_context mbedtls_camellia_context -#define camellia_crypt_cbc mbedtls_camellia_crypt_cbc -#define camellia_crypt_cfb128 mbedtls_camellia_crypt_cfb128 -#define camellia_crypt_ctr mbedtls_camellia_crypt_ctr -#define camellia_crypt_ecb mbedtls_camellia_crypt_ecb -#define camellia_free mbedtls_camellia_free -#define camellia_init mbedtls_camellia_init -#define camellia_self_test mbedtls_camellia_self_test -#define camellia_setkey_dec mbedtls_camellia_setkey_dec -#define camellia_setkey_enc mbedtls_camellia_setkey_enc -#define ccm_auth_decrypt mbedtls_ccm_auth_decrypt -#define ccm_context mbedtls_ccm_context -#define ccm_encrypt_and_tag mbedtls_ccm_encrypt_and_tag -#define ccm_free mbedtls_ccm_free -#define ccm_init mbedtls_ccm_init -#define ccm_self_test mbedtls_ccm_self_test -#define cipher_auth_decrypt mbedtls_cipher_auth_decrypt -#define cipher_auth_encrypt mbedtls_cipher_auth_encrypt -#define cipher_base_t mbedtls_cipher_base_t -#define cipher_check_tag mbedtls_cipher_check_tag -#define cipher_context_t mbedtls_cipher_context_t -#define cipher_crypt mbedtls_cipher_crypt -#define cipher_definition_t mbedtls_cipher_definition_t -#define cipher_definitions mbedtls_cipher_definitions -#define cipher_finish mbedtls_cipher_finish -#define cipher_free mbedtls_cipher_free -#define cipher_get_block_size mbedtls_cipher_get_block_size -#define cipher_get_cipher_mode mbedtls_cipher_get_cipher_mode -#define cipher_get_iv_size mbedtls_cipher_get_iv_size -#define cipher_get_key_size mbedtls_cipher_get_key_bitlen -#define cipher_get_name mbedtls_cipher_get_name -#define cipher_get_operation mbedtls_cipher_get_operation -#define cipher_get_type mbedtls_cipher_get_type -#define cipher_id_t mbedtls_cipher_id_t -#define cipher_info_from_string mbedtls_cipher_info_from_string -#define cipher_info_from_type mbedtls_cipher_info_from_type -#define cipher_info_from_values mbedtls_cipher_info_from_values -#define cipher_info_t mbedtls_cipher_info_t -#define cipher_init mbedtls_cipher_init -#define cipher_init_ctx mbedtls_cipher_setup -#define cipher_list mbedtls_cipher_list -#define cipher_mode_t mbedtls_cipher_mode_t -#define cipher_padding_t mbedtls_cipher_padding_t -#define cipher_reset mbedtls_cipher_reset -#define cipher_set_iv mbedtls_cipher_set_iv -#define cipher_set_padding_mode mbedtls_cipher_set_padding_mode -#define cipher_setkey mbedtls_cipher_setkey -#define cipher_type_t mbedtls_cipher_type_t -#define cipher_update mbedtls_cipher_update -#define cipher_update_ad mbedtls_cipher_update_ad -#define cipher_write_tag mbedtls_cipher_write_tag -#define ctr_drbg_context mbedtls_ctr_drbg_context -#define ctr_drbg_free mbedtls_ctr_drbg_free -#define ctr_drbg_init mbedtls_ctr_drbg_init -#define ctr_drbg_random mbedtls_ctr_drbg_random -#define ctr_drbg_random_with_add mbedtls_ctr_drbg_random_with_add -#define ctr_drbg_reseed mbedtls_ctr_drbg_reseed -#define ctr_drbg_self_test mbedtls_ctr_drbg_self_test -#define ctr_drbg_set_entropy_len mbedtls_ctr_drbg_set_entropy_len -#define ctr_drbg_set_prediction_resistance mbedtls_ctr_drbg_set_prediction_resistance -#define ctr_drbg_set_reseed_interval mbedtls_ctr_drbg_set_reseed_interval -#define ctr_drbg_update mbedtls_ctr_drbg_update -#define ctr_drbg_update_seed_file mbedtls_ctr_drbg_update_seed_file -#define ctr_drbg_write_seed_file mbedtls_ctr_drbg_write_seed_file -#define debug_print_buf mbedtls_debug_print_buf -#define debug_print_crt mbedtls_debug_print_crt -#define debug_print_ecp mbedtls_debug_print_ecp -#define debug_print_mpi mbedtls_debug_print_mpi -#define debug_print_msg mbedtls_debug_print_msg -#define debug_print_ret mbedtls_debug_print_ret -#define debug_set_threshold mbedtls_debug_set_threshold -#define des3_context mbedtls_des3_context -#define des3_crypt_cbc mbedtls_des3_crypt_cbc -#define des3_crypt_ecb mbedtls_des3_crypt_ecb -#define des3_free mbedtls_des3_free -#define des3_init mbedtls_des3_init -#define des3_set2key_dec mbedtls_des3_set2key_dec -#define des3_set2key_enc mbedtls_des3_set2key_enc -#define des3_set3key_dec mbedtls_des3_set3key_dec -#define des3_set3key_enc mbedtls_des3_set3key_enc -#define des_context mbedtls_des_context -#define des_crypt_cbc mbedtls_des_crypt_cbc -#define des_crypt_ecb mbedtls_des_crypt_ecb -#define des_free mbedtls_des_free -#define des_init mbedtls_des_init -#define des_key_check_key_parity mbedtls_des_key_check_key_parity -#define des_key_check_weak mbedtls_des_key_check_weak -#define des_key_set_parity mbedtls_des_key_set_parity -#define des_self_test mbedtls_des_self_test -#define des_setkey_dec mbedtls_des_setkey_dec -#define des_setkey_enc mbedtls_des_setkey_enc -#define dhm_calc_secret mbedtls_dhm_calc_secret -#define dhm_context mbedtls_dhm_context -#define dhm_free mbedtls_dhm_free -#define dhm_init mbedtls_dhm_init -#define dhm_make_params mbedtls_dhm_make_params -#define dhm_make_public mbedtls_dhm_make_public -#define dhm_parse_dhm mbedtls_dhm_parse_dhm -#define dhm_parse_dhmfile mbedtls_dhm_parse_dhmfile -#define dhm_read_params mbedtls_dhm_read_params -#define dhm_read_public mbedtls_dhm_read_public -#define dhm_self_test mbedtls_dhm_self_test -#define ecdh_calc_secret mbedtls_ecdh_calc_secret -#define ecdh_compute_shared mbedtls_ecdh_compute_shared -#define ecdh_context mbedtls_ecdh_context -#define ecdh_free mbedtls_ecdh_free -#define ecdh_gen_public mbedtls_ecdh_gen_public -#define ecdh_get_params mbedtls_ecdh_get_params -#define ecdh_init mbedtls_ecdh_init -#define ecdh_make_params mbedtls_ecdh_make_params -#define ecdh_make_public mbedtls_ecdh_make_public -#define ecdh_read_params mbedtls_ecdh_read_params -#define ecdh_read_public mbedtls_ecdh_read_public -#define ecdh_side mbedtls_ecdh_side -#define ecdsa_context mbedtls_ecdsa_context -#define ecdsa_free mbedtls_ecdsa_free -#define ecdsa_from_keypair mbedtls_ecdsa_from_keypair -#define ecdsa_genkey mbedtls_ecdsa_genkey -#define ecdsa_info mbedtls_ecdsa_info -#define ecdsa_init mbedtls_ecdsa_init -#define ecdsa_read_signature mbedtls_ecdsa_read_signature -#define ecdsa_sign mbedtls_ecdsa_sign -#define ecdsa_sign_det mbedtls_ecdsa_sign_det -#define ecdsa_verify mbedtls_ecdsa_verify -#define ecdsa_write_signature mbedtls_ecdsa_write_signature -#define ecdsa_write_signature_det mbedtls_ecdsa_write_signature_det -#define eckey_info mbedtls_eckey_info -#define eckeydh_info mbedtls_eckeydh_info -#define ecp_check_privkey mbedtls_ecp_check_privkey -#define ecp_check_pub_priv mbedtls_ecp_check_pub_priv -#define ecp_check_pubkey mbedtls_ecp_check_pubkey -#define ecp_copy mbedtls_ecp_copy -#define ecp_curve_info mbedtls_ecp_curve_info -#define ecp_curve_info_from_grp_id mbedtls_ecp_curve_info_from_grp_id -#define ecp_curve_info_from_name mbedtls_ecp_curve_info_from_name -#define ecp_curve_info_from_tls_id mbedtls_ecp_curve_info_from_tls_id -#define ecp_curve_list mbedtls_ecp_curve_list -#define ecp_gen_key mbedtls_ecp_gen_key -#define ecp_gen_keypair mbedtls_ecp_gen_keypair -#define ecp_group mbedtls_ecp_group -#define ecp_group_copy mbedtls_ecp_group_copy -#define ecp_group_free mbedtls_ecp_group_free -#define ecp_group_id mbedtls_ecp_group_id -#define ecp_group_init mbedtls_ecp_group_init -#define ecp_grp_id_list mbedtls_ecp_grp_id_list -#define ecp_is_zero mbedtls_ecp_is_zero -#define ecp_keypair mbedtls_ecp_keypair -#define ecp_keypair_free mbedtls_ecp_keypair_free -#define ecp_keypair_init mbedtls_ecp_keypair_init -#define ecp_mul mbedtls_ecp_mul -#define ecp_point mbedtls_ecp_point -#define ecp_point_free mbedtls_ecp_point_free -#define ecp_point_init mbedtls_ecp_point_init -#define ecp_point_read_binary mbedtls_ecp_point_read_binary -#define ecp_point_read_string mbedtls_ecp_point_read_string -#define ecp_point_write_binary mbedtls_ecp_point_write_binary -#define ecp_self_test mbedtls_ecp_self_test -#define ecp_set_zero mbedtls_ecp_set_zero -#define ecp_tls_read_group mbedtls_ecp_tls_read_group -#define ecp_tls_read_point mbedtls_ecp_tls_read_point -#define ecp_tls_write_group mbedtls_ecp_tls_write_group -#define ecp_tls_write_point mbedtls_ecp_tls_write_point -#define ecp_use_known_dp mbedtls_ecp_group_load -#define entropy_add_source mbedtls_entropy_add_source -#define entropy_context mbedtls_entropy_context -#define entropy_free mbedtls_entropy_free -#define entropy_func mbedtls_entropy_func -#define entropy_gather mbedtls_entropy_gather -#define entropy_init mbedtls_entropy_init -#define entropy_self_test mbedtls_entropy_self_test -#define entropy_update_manual mbedtls_entropy_update_manual -#define entropy_update_seed_file mbedtls_entropy_update_seed_file -#define entropy_write_seed_file mbedtls_entropy_write_seed_file -#define error_strerror mbedtls_strerror -#define f_source_ptr mbedtls_entropy_f_source_ptr -#define gcm_auth_decrypt mbedtls_gcm_auth_decrypt -#define gcm_context mbedtls_gcm_context -#define gcm_crypt_and_tag mbedtls_gcm_crypt_and_tag -#define gcm_finish mbedtls_gcm_finish -#define gcm_free mbedtls_gcm_free -#define gcm_init mbedtls_gcm_init -#define gcm_self_test mbedtls_gcm_self_test -#define gcm_starts mbedtls_gcm_starts -#define gcm_update mbedtls_gcm_update -#define get_timer mbedtls_timing_get_timer -#define hardclock mbedtls_timing_hardclock -#define hardclock_poll mbedtls_hardclock_poll -#define havege_free mbedtls_havege_free -#define havege_init mbedtls_havege_init -#define havege_poll mbedtls_havege_poll -#define havege_random mbedtls_havege_random -#define havege_state mbedtls_havege_state -#define hmac_drbg_context mbedtls_hmac_drbg_context -#define hmac_drbg_free mbedtls_hmac_drbg_free -#define hmac_drbg_init mbedtls_hmac_drbg_init -#define hmac_drbg_random mbedtls_hmac_drbg_random -#define hmac_drbg_random_with_add mbedtls_hmac_drbg_random_with_add -#define hmac_drbg_reseed mbedtls_hmac_drbg_reseed -#define hmac_drbg_self_test mbedtls_hmac_drbg_self_test -#define hmac_drbg_set_entropy_len mbedtls_hmac_drbg_set_entropy_len -#define hmac_drbg_set_prediction_resistance mbedtls_hmac_drbg_set_prediction_resistance -#define hmac_drbg_set_reseed_interval mbedtls_hmac_drbg_set_reseed_interval -#define hmac_drbg_update mbedtls_hmac_drbg_update -#define hmac_drbg_update_seed_file mbedtls_hmac_drbg_update_seed_file -#define hmac_drbg_write_seed_file mbedtls_hmac_drbg_write_seed_file -#define hr_time mbedtls_timing_hr_time -#define key_exchange_type_t mbedtls_key_exchange_type_t -#define md mbedtls_md -#define md2 mbedtls_md2 -#define md2_context mbedtls_md2_context -#define md2_finish mbedtls_md2_finish -#define md2_free mbedtls_md2_free -#define md2_info mbedtls_md2_info -#define md2_init mbedtls_md2_init -#define md2_process mbedtls_md2_process -#define md2_self_test mbedtls_md2_self_test -#define md2_starts mbedtls_md2_starts -#define md2_update mbedtls_md2_update -#define md4 mbedtls_md4 -#define md4_context mbedtls_md4_context -#define md4_finish mbedtls_md4_finish -#define md4_free mbedtls_md4_free -#define md4_info mbedtls_md4_info -#define md4_init mbedtls_md4_init -#define md4_process mbedtls_md4_process -#define md4_self_test mbedtls_md4_self_test -#define md4_starts mbedtls_md4_starts -#define md4_update mbedtls_md4_update -#define md5 mbedtls_md5 -#define md5_context mbedtls_md5_context -#define md5_finish mbedtls_md5_finish -#define md5_free mbedtls_md5_free -#define md5_info mbedtls_md5_info -#define md5_init mbedtls_md5_init -#define md5_process mbedtls_md5_process -#define md5_self_test mbedtls_md5_self_test -#define md5_starts mbedtls_md5_starts -#define md5_update mbedtls_md5_update -#define md_context_t mbedtls_md_context_t -#define md_file mbedtls_md_file -#define md_finish mbedtls_md_finish -#define md_free mbedtls_md_free -#define md_get_name mbedtls_md_get_name -#define md_get_size mbedtls_md_get_size -#define md_get_type mbedtls_md_get_type -#define md_hmac mbedtls_md_hmac -#define md_hmac_finish mbedtls_md_hmac_finish -#define md_hmac_reset mbedtls_md_hmac_reset -#define md_hmac_starts mbedtls_md_hmac_starts -#define md_hmac_update mbedtls_md_hmac_update -#define md_info_from_string mbedtls_md_info_from_string -#define md_info_from_type mbedtls_md_info_from_type -#define md_info_t mbedtls_md_info_t -#define md_init mbedtls_md_init -#define md_init_ctx mbedtls_md_init_ctx -#define md_list mbedtls_md_list -#define md_process mbedtls_md_process -#define md_starts mbedtls_md_starts -#define md_type_t mbedtls_md_type_t -#define md_update mbedtls_md_update -#define memory_buffer_alloc_cur_get mbedtls_memory_buffer_alloc_cur_get -#define memory_buffer_alloc_free mbedtls_memory_buffer_alloc_free -#define memory_buffer_alloc_init mbedtls_memory_buffer_alloc_init -#define memory_buffer_alloc_max_get mbedtls_memory_buffer_alloc_max_get -#define memory_buffer_alloc_max_reset mbedtls_memory_buffer_alloc_max_reset -#define memory_buffer_alloc_self_test mbedtls_memory_buffer_alloc_self_test -#define memory_buffer_alloc_status mbedtls_memory_buffer_alloc_status -#define memory_buffer_alloc_verify mbedtls_memory_buffer_alloc_verify -#define memory_buffer_set_verify mbedtls_memory_buffer_set_verify -#define mpi mbedtls_mpi -#define mpi_add_abs mbedtls_mpi_add_abs -#define mpi_add_int mbedtls_mpi_add_int -#define mpi_add_mpi mbedtls_mpi_add_mpi -#define mpi_cmp_abs mbedtls_mpi_cmp_abs -#define mpi_cmp_int mbedtls_mpi_cmp_int -#define mpi_cmp_mpi mbedtls_mpi_cmp_mpi -#define mpi_copy mbedtls_mpi_copy -#define mpi_div_int mbedtls_mpi_div_int -#define mpi_div_mpi mbedtls_mpi_div_mpi -#define mpi_exp_mod mbedtls_mpi_exp_mod -#define mpi_fill_random mbedtls_mpi_fill_random -#define mpi_free mbedtls_mpi_free -#define mpi_gcd mbedtls_mpi_gcd -#define mpi_gen_prime mbedtls_mpi_gen_prime -#define mpi_get_bit mbedtls_mpi_get_bit -#define mpi_grow mbedtls_mpi_grow -#define mpi_init mbedtls_mpi_init -#define mpi_inv_mod mbedtls_mpi_inv_mod -#define mpi_is_prime mbedtls_mpi_is_prime -#define mpi_lsb mbedtls_mpi_lsb -#define mpi_lset mbedtls_mpi_lset -#define mpi_mod_int mbedtls_mpi_mod_int -#define mpi_mod_mpi mbedtls_mpi_mod_mpi -#define mpi_msb mbedtls_mpi_bitlen -#define mpi_mul_int mbedtls_mpi_mul_int -#define mpi_mul_mpi mbedtls_mpi_mul_mpi -#define mpi_read_binary mbedtls_mpi_read_binary -#define mpi_read_file mbedtls_mpi_read_file -#define mpi_read_string mbedtls_mpi_read_string -#define mpi_safe_cond_assign mbedtls_mpi_safe_cond_assign -#define mpi_safe_cond_swap mbedtls_mpi_safe_cond_swap -#define mpi_self_test mbedtls_mpi_self_test -#define mpi_set_bit mbedtls_mpi_set_bit -#define mpi_shift_l mbedtls_mpi_shift_l -#define mpi_shift_r mbedtls_mpi_shift_r -#define mpi_shrink mbedtls_mpi_shrink -#define mpi_size mbedtls_mpi_size -#define mpi_sub_abs mbedtls_mpi_sub_abs -#define mpi_sub_int mbedtls_mpi_sub_int -#define mpi_sub_mpi mbedtls_mpi_sub_mpi -#define mpi_swap mbedtls_mpi_swap -#define mpi_write_binary mbedtls_mpi_write_binary -#define mpi_write_file mbedtls_mpi_write_file -#define mpi_write_string mbedtls_mpi_write_string -#define net_accept mbedtls_net_accept -#define net_bind mbedtls_net_bind -#define net_close mbedtls_net_free -#define net_connect mbedtls_net_connect -#define net_recv mbedtls_net_recv -#define net_recv_timeout mbedtls_net_recv_timeout -#define net_send mbedtls_net_send -#define net_set_block mbedtls_net_set_block -#define net_set_nonblock mbedtls_net_set_nonblock -#define net_usleep mbedtls_net_usleep -#define oid_descriptor_t mbedtls_oid_descriptor_t -#define oid_get_attr_short_name mbedtls_oid_get_attr_short_name -#define oid_get_cipher_alg mbedtls_oid_get_cipher_alg -#define oid_get_ec_grp mbedtls_oid_get_ec_grp -#define oid_get_extended_key_usage mbedtls_oid_get_extended_key_usage -#define oid_get_md_alg mbedtls_oid_get_md_alg -#define oid_get_numeric_string mbedtls_oid_get_numeric_string -#define oid_get_oid_by_ec_grp mbedtls_oid_get_oid_by_ec_grp -#define oid_get_oid_by_md mbedtls_oid_get_oid_by_md -#define oid_get_oid_by_pk_alg mbedtls_oid_get_oid_by_pk_alg -#define oid_get_oid_by_sig_alg mbedtls_oid_get_oid_by_sig_alg -#define oid_get_pk_alg mbedtls_oid_get_pk_alg -#define oid_get_pkcs12_pbe_alg mbedtls_oid_get_pkcs12_pbe_alg -#define oid_get_sig_alg mbedtls_oid_get_sig_alg -#define oid_get_sig_alg_desc mbedtls_oid_get_sig_alg_desc -#define oid_get_x509_ext_type mbedtls_oid_get_x509_ext_type -#define operation_t mbedtls_operation_t -#define padlock_supports mbedtls_padlock_has_support -#define padlock_xcryptcbc mbedtls_padlock_xcryptcbc -#define padlock_xcryptecb mbedtls_padlock_xcryptecb -#define pem_context mbedtls_pem_context -#define pem_free mbedtls_pem_free -#define pem_init mbedtls_pem_init -#define pem_read_buffer mbedtls_pem_read_buffer -#define pem_write_buffer mbedtls_pem_write_buffer -#define pk_can_do mbedtls_pk_can_do -#define pk_check_pair mbedtls_pk_check_pair -#define pk_context mbedtls_pk_context -#define pk_debug mbedtls_pk_debug -#define pk_debug_item mbedtls_pk_debug_item -#define pk_debug_type mbedtls_pk_debug_type -#define pk_decrypt mbedtls_pk_decrypt -#define pk_ec mbedtls_pk_ec -#define pk_encrypt mbedtls_pk_encrypt -#define pk_free mbedtls_pk_free -#define pk_get_len mbedtls_pk_get_len -#define pk_get_name mbedtls_pk_get_name -#define pk_get_size mbedtls_pk_get_bitlen -#define pk_get_type mbedtls_pk_get_type -#define pk_info_from_type mbedtls_pk_info_from_type -#define pk_info_t mbedtls_pk_info_t -#define pk_init mbedtls_pk_init -#define pk_init_ctx mbedtls_pk_setup -#define pk_init_ctx_rsa_alt mbedtls_pk_setup_rsa_alt -#define pk_load_file mbedtls_pk_load_file -#define pk_parse_key mbedtls_pk_parse_key -#define pk_parse_keyfile mbedtls_pk_parse_keyfile -#define pk_parse_public_key mbedtls_pk_parse_public_key -#define pk_parse_public_keyfile mbedtls_pk_parse_public_keyfile -#define pk_parse_subpubkey mbedtls_pk_parse_subpubkey -#define pk_rsa mbedtls_pk_rsa -#define pk_rsa_alt_decrypt_func mbedtls_pk_rsa_alt_decrypt_func -#define pk_rsa_alt_key_len_func mbedtls_pk_rsa_alt_key_len_func -#define pk_rsa_alt_sign_func mbedtls_pk_rsa_alt_sign_func -#define pk_rsassa_pss_options mbedtls_pk_rsassa_pss_options -#define pk_sign mbedtls_pk_sign -#define pk_type_t mbedtls_pk_type_t -#define pk_verify mbedtls_pk_verify -#define pk_verify_ext mbedtls_pk_verify_ext -#define pk_write_key_der mbedtls_pk_write_key_der -#define pk_write_key_pem mbedtls_pk_write_key_pem -#define pk_write_pubkey mbedtls_pk_write_pubkey -#define pk_write_pubkey_der mbedtls_pk_write_pubkey_der -#define pk_write_pubkey_pem mbedtls_pk_write_pubkey_pem -#define pkcs11_context mbedtls_pkcs11_context -#define pkcs11_decrypt mbedtls_pkcs11_decrypt -#define pkcs11_priv_key_free mbedtls_pkcs11_priv_key_free -#define pkcs11_priv_key_init mbedtls_pkcs11_priv_key_bind -#define pkcs11_sign mbedtls_pkcs11_sign -#define pkcs11_x509_cert_init mbedtls_pkcs11_x509_cert_bind -#define pkcs12_derivation mbedtls_pkcs12_derivation -#define pkcs12_pbe mbedtls_pkcs12_pbe -#define pkcs12_pbe_sha1_rc4_128 mbedtls_pkcs12_pbe_sha1_rc4_128 -#define pkcs5_pbes2 mbedtls_pkcs5_pbes2 -#define pkcs5_pbkdf2_hmac mbedtls_pkcs5_pbkdf2_hmac -#define pkcs5_self_test mbedtls_pkcs5_self_test -#define platform_entropy_poll mbedtls_platform_entropy_poll -#define platform_set_exit mbedtls_platform_set_exit -#define platform_set_fprintf mbedtls_platform_set_fprintf -#define platform_set_printf mbedtls_platform_set_printf -#define platform_set_snprintf mbedtls_platform_set_snprintf -#define polarssl_exit mbedtls_exit -#define polarssl_fprintf mbedtls_fprintf -#define polarssl_free mbedtls_free -#define polarssl_mutex_free mbedtls_mutex_free -#define polarssl_mutex_init mbedtls_mutex_init -#define polarssl_mutex_lock mbedtls_mutex_lock -#define polarssl_mutex_unlock mbedtls_mutex_unlock -#define polarssl_printf mbedtls_printf -#define polarssl_snprintf mbedtls_snprintf -#define polarssl_strerror mbedtls_strerror -#define ripemd160 mbedtls_ripemd160 -#define ripemd160_context mbedtls_ripemd160_context -#define ripemd160_finish mbedtls_ripemd160_finish -#define ripemd160_free mbedtls_ripemd160_free -#define ripemd160_info mbedtls_ripemd160_info -#define ripemd160_init mbedtls_ripemd160_init -#define ripemd160_process mbedtls_ripemd160_process -#define ripemd160_self_test mbedtls_ripemd160_self_test -#define ripemd160_starts mbedtls_ripemd160_starts -#define ripemd160_update mbedtls_ripemd160_update -#define rsa_alt_context mbedtls_rsa_alt_context -#define rsa_alt_info mbedtls_rsa_alt_info -#define rsa_check_privkey mbedtls_rsa_check_privkey -#define rsa_check_pub_priv mbedtls_rsa_check_pub_priv -#define rsa_check_pubkey mbedtls_rsa_check_pubkey -#define rsa_context mbedtls_rsa_context -#define rsa_copy mbedtls_rsa_copy -#define rsa_free mbedtls_rsa_free -#define rsa_gen_key mbedtls_rsa_gen_key -#define rsa_info mbedtls_rsa_info -#define rsa_init mbedtls_rsa_init -#define rsa_pkcs1_decrypt mbedtls_rsa_pkcs1_decrypt -#define rsa_pkcs1_encrypt mbedtls_rsa_pkcs1_encrypt -#define rsa_pkcs1_sign mbedtls_rsa_pkcs1_sign -#define rsa_pkcs1_verify mbedtls_rsa_pkcs1_verify -#define rsa_private mbedtls_rsa_private -#define rsa_public mbedtls_rsa_public -#define rsa_rsaes_oaep_decrypt mbedtls_rsa_rsaes_oaep_decrypt -#define rsa_rsaes_oaep_encrypt mbedtls_rsa_rsaes_oaep_encrypt -#define rsa_rsaes_pkcs1_v15_decrypt mbedtls_rsa_rsaes_pkcs1_v15_decrypt -#define rsa_rsaes_pkcs1_v15_encrypt mbedtls_rsa_rsaes_pkcs1_v15_encrypt -#define rsa_rsassa_pkcs1_v15_sign mbedtls_rsa_rsassa_pkcs1_v15_sign -#define rsa_rsassa_pkcs1_v15_verify mbedtls_rsa_rsassa_pkcs1_v15_verify -#define rsa_rsassa_pss_sign mbedtls_rsa_rsassa_pss_sign -#define rsa_rsassa_pss_verify mbedtls_rsa_rsassa_pss_verify -#define rsa_rsassa_pss_verify_ext mbedtls_rsa_rsassa_pss_verify_ext -#define rsa_self_test mbedtls_rsa_self_test -#define rsa_set_padding mbedtls_rsa_set_padding -#define safer_memcmp mbedtls_ssl_safer_memcmp -#define set_alarm mbedtls_set_alarm -#define sha1 mbedtls_sha1 -#define sha1_context mbedtls_sha1_context -#define sha1_finish mbedtls_sha1_finish -#define sha1_free mbedtls_sha1_free -#define sha1_info mbedtls_sha1_info -#define sha1_init mbedtls_sha1_init -#define sha1_process mbedtls_sha1_process -#define sha1_self_test mbedtls_sha1_self_test -#define sha1_starts mbedtls_sha1_starts -#define sha1_update mbedtls_sha1_update -#define sha224_info mbedtls_sha224_info -#define sha256 mbedtls_sha256 -#define sha256_context mbedtls_sha256_context -#define sha256_finish mbedtls_sha256_finish -#define sha256_free mbedtls_sha256_free -#define sha256_info mbedtls_sha256_info -#define sha256_init mbedtls_sha256_init -#define sha256_process mbedtls_sha256_process -#define sha256_self_test mbedtls_sha256_self_test -#define sha256_starts mbedtls_sha256_starts -#define sha256_update mbedtls_sha256_update -#define sha384_info mbedtls_sha384_info -#define sha512 mbedtls_sha512 -#define sha512_context mbedtls_sha512_context -#define sha512_finish mbedtls_sha512_finish -#define sha512_free mbedtls_sha512_free -#define sha512_info mbedtls_sha512_info -#define sha512_init mbedtls_sha512_init -#define sha512_process mbedtls_sha512_process -#define sha512_self_test mbedtls_sha512_self_test -#define sha512_starts mbedtls_sha512_starts -#define sha512_update mbedtls_sha512_update -#define source_state mbedtls_entropy_source_state -#define ssl_cache_context mbedtls_ssl_cache_context -#define ssl_cache_entry mbedtls_ssl_cache_entry -#define ssl_cache_free mbedtls_ssl_cache_free -#define ssl_cache_get mbedtls_ssl_cache_get -#define ssl_cache_init mbedtls_ssl_cache_init -#define ssl_cache_set mbedtls_ssl_cache_set -#define ssl_cache_set_max_entries mbedtls_ssl_cache_set_max_entries -#define ssl_cache_set_timeout mbedtls_ssl_cache_set_timeout -#define ssl_check_cert_usage mbedtls_ssl_check_cert_usage -#define ssl_ciphersuite_from_id mbedtls_ssl_ciphersuite_from_id -#define ssl_ciphersuite_from_string mbedtls_ssl_ciphersuite_from_string -#define ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t -#define ssl_ciphersuite_uses_ec mbedtls_ssl_ciphersuite_uses_ec -#define ssl_ciphersuite_uses_psk mbedtls_ssl_ciphersuite_uses_psk -#define ssl_close_notify mbedtls_ssl_close_notify -#define ssl_context mbedtls_ssl_context -#define ssl_cookie_check mbedtls_ssl_cookie_check -#define ssl_cookie_check_t mbedtls_ssl_cookie_check_t -#define ssl_cookie_ctx mbedtls_ssl_cookie_ctx -#define ssl_cookie_free mbedtls_ssl_cookie_free -#define ssl_cookie_init mbedtls_ssl_cookie_init -#define ssl_cookie_set_timeout mbedtls_ssl_cookie_set_timeout -#define ssl_cookie_setup mbedtls_ssl_cookie_setup -#define ssl_cookie_write mbedtls_ssl_cookie_write -#define ssl_cookie_write_t mbedtls_ssl_cookie_write_t -#define ssl_derive_keys mbedtls_ssl_derive_keys -#define ssl_dtls_replay_check mbedtls_ssl_dtls_replay_check -#define ssl_dtls_replay_update mbedtls_ssl_dtls_replay_update -#define ssl_fetch_input mbedtls_ssl_fetch_input -#define ssl_flight_item mbedtls_ssl_flight_item -#define ssl_flush_output mbedtls_ssl_flush_output -#define ssl_free mbedtls_ssl_free -#define ssl_get_alpn_protocol mbedtls_ssl_get_alpn_protocol -#define ssl_get_bytes_avail mbedtls_ssl_get_bytes_avail -#define ssl_get_ciphersuite mbedtls_ssl_get_ciphersuite -#define ssl_get_ciphersuite_id mbedtls_ssl_get_ciphersuite_id -#define ssl_get_ciphersuite_name mbedtls_ssl_get_ciphersuite_name -#define ssl_get_ciphersuite_sig_pk_alg mbedtls_ssl_get_ciphersuite_sig_pk_alg -#define ssl_get_peer_cert mbedtls_ssl_get_peer_cert -#define ssl_get_record_expansion mbedtls_ssl_get_record_expansion -#define ssl_get_session mbedtls_ssl_get_session -#define ssl_get_verify_result mbedtls_ssl_get_verify_result -#define ssl_get_version mbedtls_ssl_get_version -#define ssl_handshake mbedtls_ssl_handshake -#define ssl_handshake_client_step mbedtls_ssl_handshake_client_step -#define ssl_handshake_free mbedtls_ssl_handshake_free -#define ssl_handshake_params mbedtls_ssl_handshake_params -#define ssl_handshake_server_step mbedtls_ssl_handshake_server_step -#define ssl_handshake_step mbedtls_ssl_handshake_step -#define ssl_handshake_wrapup mbedtls_ssl_handshake_wrapup -#define ssl_hdr_len mbedtls_ssl_hdr_len -#define ssl_hs_hdr_len mbedtls_ssl_hs_hdr_len -#define ssl_hw_record_activate mbedtls_ssl_hw_record_activate -#define ssl_hw_record_finish mbedtls_ssl_hw_record_finish -#define ssl_hw_record_init mbedtls_ssl_hw_record_init -#define ssl_hw_record_read mbedtls_ssl_hw_record_read -#define ssl_hw_record_reset mbedtls_ssl_hw_record_reset -#define ssl_hw_record_write mbedtls_ssl_hw_record_write -#define ssl_init mbedtls_ssl_init -#define ssl_key_cert mbedtls_ssl_key_cert -#define ssl_legacy_renegotiation mbedtls_ssl_conf_legacy_renegotiation -#define ssl_list_ciphersuites mbedtls_ssl_list_ciphersuites -#define ssl_md_alg_from_hash mbedtls_ssl_md_alg_from_hash -#define ssl_optimize_checksum mbedtls_ssl_optimize_checksum -#define ssl_own_cert mbedtls_ssl_own_cert -#define ssl_own_key mbedtls_ssl_own_key -#define ssl_parse_certificate mbedtls_ssl_parse_certificate -#define ssl_parse_change_cipher_spec mbedtls_ssl_parse_change_cipher_spec -#define ssl_parse_finished mbedtls_ssl_parse_finished -#define ssl_pk_alg_from_sig mbedtls_ssl_pk_alg_from_sig -#define ssl_pkcs11_decrypt mbedtls_ssl_pkcs11_decrypt -#define ssl_pkcs11_key_len mbedtls_ssl_pkcs11_key_len -#define ssl_pkcs11_sign mbedtls_ssl_pkcs11_sign -#define ssl_psk_derive_premaster mbedtls_ssl_psk_derive_premaster -#define ssl_read mbedtls_ssl_read -#define ssl_read_record mbedtls_ssl_read_record -#define ssl_read_version mbedtls_ssl_read_version -#define ssl_recv_flight_completed mbedtls_ssl_recv_flight_completed -#define ssl_renegotiate mbedtls_ssl_renegotiate -#define ssl_resend mbedtls_ssl_resend -#define ssl_reset_checksum mbedtls_ssl_reset_checksum -#define ssl_send_alert_message mbedtls_ssl_send_alert_message -#define ssl_send_fatal_handshake_failure mbedtls_ssl_send_fatal_handshake_failure -#define ssl_send_flight_completed mbedtls_ssl_send_flight_completed -#define ssl_session mbedtls_ssl_session -#define ssl_session_free mbedtls_ssl_session_free -#define ssl_session_init mbedtls_ssl_session_init -#define ssl_session_reset mbedtls_ssl_session_reset -#define ssl_set_alpn_protocols mbedtls_ssl_conf_alpn_protocols -#define ssl_set_arc4_support mbedtls_ssl_conf_arc4_support -#define ssl_set_authmode mbedtls_ssl_conf_authmode -#define ssl_set_bio mbedtls_ssl_set_bio -#define ssl_set_ca_chain mbedtls_ssl_conf_ca_chain -#define ssl_set_cbc_record_splitting mbedtls_ssl_conf_cbc_record_splitting -#define ssl_set_ciphersuites mbedtls_ssl_conf_ciphersuites -#define ssl_set_ciphersuites_for_version mbedtls_ssl_conf_ciphersuites_for_version -#define ssl_set_client_transport_id mbedtls_ssl_set_client_transport_id -#define ssl_set_curves mbedtls_ssl_conf_curves -#define ssl_set_dbg mbedtls_ssl_conf_dbg -#define ssl_set_dh_param mbedtls_ssl_conf_dh_param -#define ssl_set_dh_param_ctx mbedtls_ssl_conf_dh_param_ctx -#define ssl_set_dtls_anti_replay mbedtls_ssl_conf_dtls_anti_replay -#define ssl_set_dtls_badmac_limit mbedtls_ssl_conf_dtls_badmac_limit -#define ssl_set_dtls_cookies mbedtls_ssl_conf_dtls_cookies -#define ssl_set_encrypt_then_mac mbedtls_ssl_conf_encrypt_then_mac -#define ssl_set_endpoint mbedtls_ssl_conf_endpoint -#define ssl_set_extended_master_secret mbedtls_ssl_conf_extended_master_secret -#define ssl_set_fallback mbedtls_ssl_conf_fallback -#define ssl_set_handshake_timeout mbedtls_ssl_conf_handshake_timeout -#define ssl_set_hostname mbedtls_ssl_set_hostname -#define ssl_set_max_frag_len mbedtls_ssl_conf_max_frag_len -#define ssl_set_max_version mbedtls_ssl_conf_max_version -#define ssl_set_min_version mbedtls_ssl_conf_min_version -#define ssl_set_own_cert mbedtls_ssl_conf_own_cert -#define ssl_set_psk mbedtls_ssl_conf_psk -#define ssl_set_psk_cb mbedtls_ssl_conf_psk_cb -#define ssl_set_renegotiation mbedtls_ssl_conf_renegotiation -#define ssl_set_renegotiation_enforced mbedtls_ssl_conf_renegotiation_enforced -#define ssl_set_renegotiation_period mbedtls_ssl_conf_renegotiation_period -#define ssl_set_rng mbedtls_ssl_conf_rng -#define ssl_set_session mbedtls_ssl_set_session -#define ssl_set_session_cache mbedtls_ssl_conf_session_cache -#define ssl_set_session_tickets mbedtls_ssl_conf_session_tickets -#define ssl_set_sni mbedtls_ssl_conf_sni -#define ssl_set_transport mbedtls_ssl_conf_transport -#define ssl_set_truncated_hmac mbedtls_ssl_conf_truncated_hmac -#define ssl_set_verify mbedtls_ssl_conf_verify -#define ssl_sig_from_pk mbedtls_ssl_sig_from_pk -#define ssl_states mbedtls_ssl_states -#define ssl_transform mbedtls_ssl_transform -#define ssl_transform_free mbedtls_ssl_transform_free -#define ssl_write mbedtls_ssl_write -#define ssl_write_certificate mbedtls_ssl_write_certificate -#define ssl_write_change_cipher_spec mbedtls_ssl_write_change_cipher_spec -#define ssl_write_finished mbedtls_ssl_write_finished -#define ssl_write_record mbedtls_ssl_write_record -#define ssl_write_version mbedtls_ssl_write_version -#define supported_ciphers mbedtls_cipher_supported -#define t_sint mbedtls_mpi_sint -#define t_udbl mbedtls_t_udbl -#define t_uint mbedtls_mpi_uint -#define test_ca_crt mbedtls_test_ca_crt -#define test_ca_crt_ec mbedtls_test_ca_crt_ec -#define test_ca_crt_rsa mbedtls_test_ca_crt_rsa -#define test_ca_key mbedtls_test_ca_key -#define test_ca_key_ec mbedtls_test_ca_key_ec -#define test_ca_key_rsa mbedtls_test_ca_key_rsa -#define test_ca_list mbedtls_test_cas_pem -#define test_ca_pwd mbedtls_test_ca_pwd -#define test_ca_pwd_ec mbedtls_test_ca_pwd_ec -#define test_ca_pwd_rsa mbedtls_test_ca_pwd_rsa -#define test_cli_crt mbedtls_test_cli_crt -#define test_cli_crt_ec mbedtls_test_cli_crt_ec -#define test_cli_crt_rsa mbedtls_test_cli_crt_rsa -#define test_cli_key mbedtls_test_cli_key -#define test_cli_key_ec mbedtls_test_cli_key_ec -#define test_cli_key_rsa mbedtls_test_cli_key_rsa -#define test_srv_crt mbedtls_test_srv_crt -#define test_srv_crt_ec mbedtls_test_srv_crt_ec -#define test_srv_crt_rsa mbedtls_test_srv_crt_rsa -#define test_srv_key mbedtls_test_srv_key -#define test_srv_key_ec mbedtls_test_srv_key_ec -#define test_srv_key_rsa mbedtls_test_srv_key_rsa -#define threading_mutex_t mbedtls_threading_mutex_t -#define threading_set_alt mbedtls_threading_set_alt -#define timing_self_test mbedtls_timing_self_test -#define version_check_feature mbedtls_version_check_feature -#define version_get_number mbedtls_version_get_number -#define version_get_string mbedtls_version_get_string -#define version_get_string_full mbedtls_version_get_string_full -#define x509_bitstring mbedtls_x509_bitstring -#define x509_buf mbedtls_x509_buf -#define x509_crl mbedtls_x509_crl -#define x509_crl_entry mbedtls_x509_crl_entry -#define x509_crl_free mbedtls_x509_crl_free -#define x509_crl_info mbedtls_x509_crl_info -#define x509_crl_init mbedtls_x509_crl_init -#define x509_crl_parse mbedtls_x509_crl_parse -#define x509_crl_parse_der mbedtls_x509_crl_parse_der -#define x509_crl_parse_file mbedtls_x509_crl_parse_file -#define x509_crt mbedtls_x509_crt -#define x509_crt_check_extended_key_usage mbedtls_x509_crt_check_extended_key_usage -#define x509_crt_check_key_usage mbedtls_x509_crt_check_key_usage -#define x509_crt_free mbedtls_x509_crt_free -#define x509_crt_info mbedtls_x509_crt_info -#define x509_crt_init mbedtls_x509_crt_init -#define x509_crt_parse mbedtls_x509_crt_parse -#define x509_crt_parse_der mbedtls_x509_crt_parse_der -#define x509_crt_parse_file mbedtls_x509_crt_parse_file -#define x509_crt_parse_path mbedtls_x509_crt_parse_path -#define x509_crt_revoked mbedtls_x509_crt_is_revoked -#define x509_crt_verify mbedtls_x509_crt_verify -#define x509_csr mbedtls_x509_csr -#define x509_csr_free mbedtls_x509_csr_free -#define x509_csr_info mbedtls_x509_csr_info -#define x509_csr_init mbedtls_x509_csr_init -#define x509_csr_parse mbedtls_x509_csr_parse -#define x509_csr_parse_der mbedtls_x509_csr_parse_der -#define x509_csr_parse_file mbedtls_x509_csr_parse_file -#define x509_dn_gets mbedtls_x509_dn_gets -#define x509_get_alg mbedtls_x509_get_alg -#define x509_get_alg_null mbedtls_x509_get_alg_null -#define x509_get_ext mbedtls_x509_get_ext -#define x509_get_name mbedtls_x509_get_name -#define x509_get_rsassa_pss_params mbedtls_x509_get_rsassa_pss_params -#define x509_get_serial mbedtls_x509_get_serial -#define x509_get_sig mbedtls_x509_get_sig -#define x509_get_sig_alg mbedtls_x509_get_sig_alg -#define x509_get_time mbedtls_x509_get_time -#define x509_key_size_helper mbedtls_x509_key_size_helper -#define x509_name mbedtls_x509_name -#define x509_self_test mbedtls_x509_self_test -#define x509_sequence mbedtls_x509_sequence -#define x509_serial_gets mbedtls_x509_serial_gets -#define x509_set_extension mbedtls_x509_set_extension -#define x509_sig_alg_gets mbedtls_x509_sig_alg_gets -#define x509_string_to_names mbedtls_x509_string_to_names -#define x509_time mbedtls_x509_time -#define x509_time_expired mbedtls_x509_time_is_past -#define x509_time_future mbedtls_x509_time_is_future -#define x509_write_extensions mbedtls_x509_write_extensions -#define x509_write_names mbedtls_x509_write_names -#define x509_write_sig mbedtls_x509_write_sig -#define x509write_cert mbedtls_x509write_cert -#define x509write_crt_der mbedtls_x509write_crt_der -#define x509write_crt_free mbedtls_x509write_crt_free -#define x509write_crt_init mbedtls_x509write_crt_init -#define x509write_crt_pem mbedtls_x509write_crt_pem -#define x509write_crt_set_authority_key_identifier mbedtls_x509write_crt_set_authority_key_identifier -#define x509write_crt_set_basic_constraints mbedtls_x509write_crt_set_basic_constraints -#define x509write_crt_set_extension mbedtls_x509write_crt_set_extension -#define x509write_crt_set_issuer_key mbedtls_x509write_crt_set_issuer_key -#define x509write_crt_set_issuer_name mbedtls_x509write_crt_set_issuer_name -#define x509write_crt_set_key_usage mbedtls_x509write_crt_set_key_usage -#define x509write_crt_set_md_alg mbedtls_x509write_crt_set_md_alg -#define x509write_crt_set_ns_cert_type mbedtls_x509write_crt_set_ns_cert_type -#define x509write_crt_set_serial mbedtls_x509write_crt_set_serial -#define x509write_crt_set_subject_key mbedtls_x509write_crt_set_subject_key -#define x509write_crt_set_subject_key_identifier mbedtls_x509write_crt_set_subject_key_identifier -#define x509write_crt_set_subject_name mbedtls_x509write_crt_set_subject_name -#define x509write_crt_set_validity mbedtls_x509write_crt_set_validity -#define x509write_crt_set_version mbedtls_x509write_crt_set_version -#define x509write_csr mbedtls_x509write_csr -#define x509write_csr_der mbedtls_x509write_csr_der -#define x509write_csr_free mbedtls_x509write_csr_free -#define x509write_csr_init mbedtls_x509write_csr_init -#define x509write_csr_pem mbedtls_x509write_csr_pem -#define x509write_csr_set_extension mbedtls_x509write_csr_set_extension -#define x509write_csr_set_key mbedtls_x509write_csr_set_key -#define x509write_csr_set_key_usage mbedtls_x509write_csr_set_key_usage -#define x509write_csr_set_md_alg mbedtls_x509write_csr_set_md_alg -#define x509write_csr_set_ns_cert_type mbedtls_x509write_csr_set_ns_cert_type -#define x509write_csr_set_subject_name mbedtls_x509write_csr_set_subject_name -#define xtea_context mbedtls_xtea_context -#define xtea_crypt_cbc mbedtls_xtea_crypt_cbc -#define xtea_crypt_ecb mbedtls_xtea_crypt_ecb -#define xtea_free mbedtls_xtea_free -#define xtea_init mbedtls_xtea_init -#define xtea_self_test mbedtls_xtea_self_test -#define xtea_setup mbedtls_xtea_setup - -#endif /* compat-1.3.h */ -#endif /* MBEDTLS_DEPRECATED_REMOVED */ diff --git a/mbedtls/config.h b/mbedtls/config.h deleted file mode 100644 index b2e1495c6..000000000 --- a/mbedtls/config.h +++ /dev/null @@ -1,3445 +0,0 @@ -#pragma GCC system_header -/** - * \file config.h - * - * \brief Configuration options (set of defines) - * - * This set of compile-time options may be used to enable - * or disable features selectively, and reduce the global - * memory footprint. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_CONFIG_H -#define MBEDTLS_CONFIG_H - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - -/** - * \name SECTION: System support - * - * This section sets system specific settings. - * \{ - */ - -/** - * \def MBEDTLS_HAVE_ASM - * - * The compiler has support for asm(). - * - * Requires support for asm() in compiler. - * - * Used in: - * library/aria.c - * library/timing.c - * include/mbedtls/bn_mul.h - * - * Required by: - * MBEDTLS_AESNI_C - * MBEDTLS_PADLOCK_C - * - * Comment to disable the use of assembly code. - */ -//#define MBEDTLS_HAVE_ASM - -/** - * \def MBEDTLS_NO_UDBL_DIVISION - * - * The platform lacks support for double-width integer division (64-bit - * division on a 32-bit platform, 128-bit division on a 64-bit platform). - * - * Used in: - * include/mbedtls/bignum.h - * library/bignum.c - * - * The bignum code uses double-width division to speed up some operations. - * Double-width division is often implemented in software that needs to - * be linked with the program. The presence of a double-width integer - * type is usually detected automatically through preprocessor macros, - * but the automatic detection cannot know whether the code needs to - * and can be linked with an implementation of division for that type. - * By default division is assumed to be usable if the type is present. - * Uncomment this option to prevent the use of double-width division. - * - * Note that division for the native integer type is always required. - * Furthermore, a 64-bit type is always required even on a 32-bit - * platform, but it need not support multiplication or division. In some - * cases it is also desirable to disable some double-width operations. For - * example, if double-width division is implemented in software, disabling - * it can reduce code size in some embedded targets. - */ -//#define MBEDTLS_NO_UDBL_DIVISION - -/** - * \def MBEDTLS_NO_64BIT_MULTIPLICATION - * - * The platform lacks support for 32x32 -> 64-bit multiplication. - * - * Used in: - * library/poly1305.c - * - * Some parts of the library may use multiplication of two unsigned 32-bit - * operands with a 64-bit result in order to speed up computations. On some - * platforms, this is not available in hardware and has to be implemented in - * software, usually in a library provided by the toolchain. - * - * Sometimes it is not desirable to have to link to that library. This option - * removes the dependency of that library on platforms that lack a hardware - * 64-bit multiplier by embedding a software implementation in Mbed TLS. - * - * Note that depending on the compiler, this may decrease performance compared - * to using the library function provided by the toolchain. - */ -//#define MBEDTLS_NO_64BIT_MULTIPLICATION - -/** - * \def MBEDTLS_HAVE_SSE2 - * - * CPU supports SSE2 instruction set. - * - * Uncomment if the CPU supports SSE2 (IA-32 specific). - */ -//#define MBEDTLS_HAVE_SSE2 - -/** - * \def MBEDTLS_HAVE_TIME - * - * System has time.h and time(). - * The time does not need to be correct, only time differences are used, - * by contrast with MBEDTLS_HAVE_TIME_DATE - * - * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, - * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and - * MBEDTLS_PLATFORM_STD_TIME. - * - * Comment if your system does not support time functions - */ -#define MBEDTLS_HAVE_TIME - -/** - * \def MBEDTLS_HAVE_TIME_DATE - * - * System has time.h, time(), and an implementation for - * mbedtls_platform_gmtime_r() (see below). - * The time needs to be correct (not necessarily very accurate, but at least - * the date should be correct). This is used to verify the validity period of - * X.509 certificates. - * - * Comment if your system does not have a correct clock. - * - * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that - * behaves similarly to the gmtime_r() function from the C standard. Refer to - * the documentation for mbedtls_platform_gmtime_r() for more information. - * - * \note It is possible to configure an implementation for - * mbedtls_platform_gmtime_r() at compile-time by using the macro - * MBEDTLS_PLATFORM_GMTIME_R_ALT. - */ -#define MBEDTLS_HAVE_TIME_DATE - -/** - * \def MBEDTLS_PLATFORM_MEMORY - * - * Enable the memory allocation layer. - * - * By default mbed TLS uses the system-provided calloc() and free(). - * This allows different allocators (self-implemented or provided) to be - * provided to the platform abstraction layer. - * - * Enabling MBEDTLS_PLATFORM_MEMORY without the - * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide - * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and - * free() function pointer at runtime. - * - * Enabling MBEDTLS_PLATFORM_MEMORY and specifying - * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the - * alternate function at compile time. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Enable this layer to allow use of alternative memory allocators. - */ -//#define MBEDTLS_PLATFORM_MEMORY - -/** - * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - * - * Do not assign standard functions in the platform layer (e.g. calloc() to - * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) - * - * This makes sure there are no linking errors on platforms that do not support - * these functions. You will HAVE to provide alternatives, either at runtime - * via the platform_set_xxx() functions or at compile time by setting - * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a - * MBEDTLS_PLATFORM_XXX_MACRO. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Uncomment to prevent default assignment of standard functions in the - * platform layer. - */ -//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - -/** - * \def MBEDTLS_PLATFORM_EXIT_ALT - * - * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the - * function in the platform abstraction layer. - * - * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will - * provide a function "mbedtls_platform_set_printf()" that allows you to set an - * alternative printf function pointer. - * - * All these define require MBEDTLS_PLATFORM_C to be defined! - * - * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; - * it will be enabled automatically by check_config.h - * - * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as - * MBEDTLS_PLATFORM_XXX_MACRO! - * - * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME - * - * Uncomment a macro to enable alternate implementation of specific base - * platform function - */ -//#define MBEDTLS_PLATFORM_EXIT_ALT -//#define MBEDTLS_PLATFORM_TIME_ALT -//#define MBEDTLS_PLATFORM_FPRINTF_ALT -//#define MBEDTLS_PLATFORM_PRINTF_ALT -//#define MBEDTLS_PLATFORM_SNPRINTF_ALT -//#define MBEDTLS_PLATFORM_NV_SEED_ALT -//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT - -/** - * \def MBEDTLS_DEPRECATED_WARNING - * - * Mark deprecated functions so that they generate a warning if used. - * Functions deprecated in one version will usually be removed in the next - * version. You can enable this to help you prepare the transition to a new - * major version by making sure your code is not using these functions. - * - * This only works with GCC and Clang. With other compilers, you may want to - * use MBEDTLS_DEPRECATED_REMOVED - * - * Uncomment to get warnings on using deprecated functions. - */ -//#define MBEDTLS_DEPRECATED_WARNING - -/** - * \def MBEDTLS_DEPRECATED_REMOVED - * - * Remove deprecated functions so that they generate an error if used. - * Functions deprecated in one version will usually be removed in the next - * version. You can enable this to help you prepare the transition to a new - * major version by making sure your code is not using these functions. - * - * Uncomment to get errors on using deprecated functions. - */ -//#define MBEDTLS_DEPRECATED_REMOVED - -/** - * \def MBEDTLS_CHECK_PARAMS - * - * This configuration option controls whether the library validates more of - * the parameters passed to it. - * - * When this flag is not defined, the library only attempts to validate an - * input parameter if: (1) they may come from the outside world (such as the - * network, the filesystem, etc.) or (2) not validating them could result in - * internal memory errors such as overflowing a buffer controlled by the - * library. On the other hand, it doesn't attempt to validate parameters whose - * values are fully controlled by the application (such as pointers). - * - * When this flag is defined, the library additionally attempts to validate - * parameters that are fully controlled by the application, and should always - * be valid if the application code is fully correct and trusted. - * - * For example, when a function accepts as input a pointer to a buffer that may - * contain untrusted data, and its documentation mentions that this pointer - * must not be NULL: - * - The pointer is checked to be non-NULL only if this option is enabled. - * - The content of the buffer is always validated. - * - * When this flag is defined, if a library function receives a parameter that - * is invalid: - * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED(). - * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function - * will immediately return. If the function returns an Mbed TLS error code, - * the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA. - * - * When defining this flag, you also need to arrange a definition for - * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods: - * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a - * function mbedtls_param_failed(), but the library does not define this - * function. If you do not make any other arrangements, you must provide - * the function mbedtls_param_failed() in your application. - * See `platform_util.h` for its prototype. - * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the - * library defines #MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`. - * You can still supply an alternative definition of - * MBEDTLS_PARAM_FAILED(), which may call `assert`. - * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h` - * or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`, - * the library will call the macro that you defined and will not supply - * its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`, - * you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source - * files include ``. - * - * Uncomment to enable validation of application-controlled parameters. - */ -//#define MBEDTLS_CHECK_PARAMS - -/** - * \def MBEDTLS_CHECK_PARAMS_ASSERT - * - * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to - * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined. - * - * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to - * calling a function mbedtls_param_failed(). See the documentation of - * #MBEDTLS_CHECK_PARAMS for details. - * - * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`. - */ -//#define MBEDTLS_CHECK_PARAMS_ASSERT - -/* \} name SECTION: System support */ - -/** - * \name SECTION: mbed TLS feature support - * - * This section sets support for features that are or are not needed - * within the modules that are enabled. - * \{ - */ - -/** - * \def MBEDTLS_TIMING_ALT - * - * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), - * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() - * - * Only works if you have MBEDTLS_TIMING_C enabled. - * - * You will need to provide a header "timing_alt.h" and an implementation at - * compile time. - */ -//#define MBEDTLS_TIMING_ALT - -/** - * \def MBEDTLS_AES_ALT - * - * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your - * alternate core implementation of a symmetric crypto, an arithmetic or hash - * module (e.g. platform specific assembly optimized implementations). Keep - * in mind that the function prototypes should remain the same. - * - * This replaces the whole module. If you only want to replace one of the - * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer - * provide the "struct mbedtls_aes_context" definition and omit the base - * function declarations and implementations. "aes_alt.h" will be included from - * "aes.h" to include the new function definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * module. - * - * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their - * use constitutes a security risk. If possible, we recommend - * avoiding dependencies on them, and considering stronger message - * digests and ciphers instead. - * - */ -//#define MBEDTLS_AES_ALT -//#define MBEDTLS_ARC4_ALT -//#define MBEDTLS_ARIA_ALT -//#define MBEDTLS_BLOWFISH_ALT -//#define MBEDTLS_CAMELLIA_ALT -//#define MBEDTLS_CCM_ALT -//#define MBEDTLS_CHACHA20_ALT -//#define MBEDTLS_CHACHAPOLY_ALT -//#define MBEDTLS_CMAC_ALT -//#define MBEDTLS_DES_ALT -//#define MBEDTLS_DHM_ALT -//#define MBEDTLS_ECJPAKE_ALT -//#define MBEDTLS_GCM_ALT -//#define MBEDTLS_NIST_KW_ALT -//#define MBEDTLS_MD2_ALT -//#define MBEDTLS_MD4_ALT -//#define MBEDTLS_MD5_ALT -//#define MBEDTLS_POLY1305_ALT -//#define MBEDTLS_RIPEMD160_ALT -//#define MBEDTLS_RSA_ALT -//#define MBEDTLS_SHA1_ALT -//#define MBEDTLS_SHA256_ALT -//#define MBEDTLS_SHA512_ALT -//#define MBEDTLS_XTEA_ALT - -/* - * When replacing the elliptic curve module, pleace consider, that it is - * implemented with two .c files: - * - ecp.c - * - ecp_curves.c - * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT - * macros as described above. The only difference is that you have to make sure - * that you provide functionality for both .c files. - */ -//#define MBEDTLS_ECP_ALT - -/** - * \def MBEDTLS_MD2_PROCESS_ALT - * - * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you - * alternate core implementation of symmetric crypto or hash function. Keep in - * mind that function prototypes should remain the same. - * - * This replaces only one function. The header file from mbed TLS is still - * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will - * no longer provide the mbedtls_sha1_process() function, but it will still provide - * the other function (using your mbedtls_sha1_process() function) and the definition - * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible - * with this definition. - * - * \note Because of a signature change, the core AES encryption and decryption routines are - * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, - * respectively. When setting up alternative implementations, these functions should - * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt - * must stay untouched. - * - * \note If you use the AES_xxx_ALT macros, then it is recommended to also set - * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES - * tables. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - * - * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use - * constitutes a security risk. If possible, we recommend avoiding - * dependencies on them, and considering stronger message digests - * and ciphers instead. - * - * \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are - * enabled, then the deterministic ECDH signature functions pass the - * the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore - * alternative implementations should use the RNG only for generating - * the ephemeral key and nothing else. If this is not possible, then - * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative - * implementation should be provided for mbedtls_ecdsa_sign_det_ext() - * (and for mbedtls_ecdsa_sign_det() too if backward compatibility is - * desirable). - * - */ -//#define MBEDTLS_MD2_PROCESS_ALT -//#define MBEDTLS_MD4_PROCESS_ALT -//#define MBEDTLS_MD5_PROCESS_ALT -//#define MBEDTLS_RIPEMD160_PROCESS_ALT -//#define MBEDTLS_SHA1_PROCESS_ALT -//#define MBEDTLS_SHA256_PROCESS_ALT -//#define MBEDTLS_SHA512_PROCESS_ALT -//#define MBEDTLS_DES_SETKEY_ALT -//#define MBEDTLS_DES_CRYPT_ECB_ALT -//#define MBEDTLS_DES3_CRYPT_ECB_ALT -//#define MBEDTLS_AES_SETKEY_ENC_ALT -//#define MBEDTLS_AES_SETKEY_DEC_ALT -//#define MBEDTLS_AES_ENCRYPT_ALT -//#define MBEDTLS_AES_DECRYPT_ALT -//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT -//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT -//#define MBEDTLS_ECDSA_VERIFY_ALT -//#define MBEDTLS_ECDSA_SIGN_ALT -//#define MBEDTLS_ECDSA_GENKEY_ALT - -/** - * \def MBEDTLS_ECP_INTERNAL_ALT - * - * Expose a part of the internal interface of the Elliptic Curve Point module. - * - * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your - * alternative core implementation of elliptic curve arithmetic. Keep in mind - * that function prototypes should remain the same. - * - * This partially replaces one function. The header file from mbed TLS is still - * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation - * is still present and it is used for group structures not supported by the - * alternative. - * - * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT - * and implementing the following functions: - * unsigned char mbedtls_internal_ecp_grp_capable( - * const mbedtls_ecp_group *grp ) - * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) - * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) - * The mbedtls_internal_ecp_grp_capable function should return 1 if the - * replacement functions implement arithmetic for the given group and 0 - * otherwise. - * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are - * called before and after each point operation and provide an opportunity to - * implement optimized set up and tear down instructions. - * - * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and - * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac - * function, but will use your mbedtls_internal_ecp_double_jac if the group is - * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when - * receives it as an argument). If the group is not supported then the original - * implementation is used. The other functions and the definition of - * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your - * implementation of mbedtls_internal_ecp_double_jac and - * mbedtls_internal_ecp_grp_capable must be compatible with this definition. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - */ -/* Required for all the functions in this section */ -//#define MBEDTLS_ECP_INTERNAL_ALT -/* Support for Weierstrass curves with Jacobi representation */ -//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT -//#define MBEDTLS_ECP_ADD_MIXED_ALT -//#define MBEDTLS_ECP_DOUBLE_JAC_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT -/* Support for curves with Montgomery arithmetic */ -//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT -//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT -//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT - -/** - * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - * - * Enable testing of the constant-flow nature of some sensitive functions with - * clang's MemorySanitizer. This causes some existing tests to also test - * this non-functional property of the code under test. - * - * This setting requires compiling with clang -fsanitize=memory. The test - * suites can then be run normally. - * - * \warning This macro is only used for extended testing; it is not considered - * part of the library's API, so it may change or disappear at any time. - * - * Uncomment to enable testing of the constant-flow nature of selected code. - */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - -/** - * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - * - * Enable testing of the constant-flow nature of some sensitive functions with - * valgrind's memcheck tool. This causes some existing tests to also test - * this non-functional property of the code under test. - * - * This setting requires valgrind headers for building, and is only useful for - * testing if the tests suites are run with valgrind's memcheck. This can be - * done for an individual test suite with 'valgrind ./test_suite_xxx', or when - * using CMake, this can be done for all test suites with 'make memcheck'. - * - * \warning This macro is only used for extended testing; it is not considered - * part of the library's API, so it may change or disappear at any time. - * - * Uncomment to enable testing of the constant-flow nature of selected code. - */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - -/** - * \def MBEDTLS_TEST_NULL_ENTROPY - * - * Enables testing and use of mbed TLS without any configured entropy sources. - * This permits use of the library on platforms before an entropy source has - * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the - * MBEDTLS_ENTROPY_NV_SEED switches). - * - * WARNING! This switch MUST be disabled in production builds, and is suitable - * only for development. - * Enabling the switch negates any security provided by the library. - * - * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - */ -//#define MBEDTLS_TEST_NULL_ENTROPY - -/** - * \def MBEDTLS_ENTROPY_HARDWARE_ALT - * - * Uncomment this macro to let mbed TLS use your own implementation of a - * hardware entropy collector. - * - * Your function must be called \c mbedtls_hardware_poll(), have the same - * prototype as declared in entropy_poll.h, and accept NULL as first argument. - * - * Uncomment to use your own hardware entropy collector. - */ -//#define MBEDTLS_ENTROPY_HARDWARE_ALT - -/** - * \def MBEDTLS_AES_ROM_TABLES - * - * Use precomputed AES tables stored in ROM. - * - * Uncomment this macro to use precomputed AES tables stored in ROM. - * Comment this macro to generate AES tables in RAM at runtime. - * - * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb - * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the - * initialization time before the first AES operation can be performed. - * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c - * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded - * performance if ROM access is slower than RAM access. - * - * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. - * - */ -//#define MBEDTLS_AES_ROM_TABLES - -/** - * \def MBEDTLS_AES_FEWER_TABLES - * - * Use less ROM/RAM for AES tables. - * - * Uncommenting this macro omits 75% of the AES tables from - * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) - * by computing their values on the fly during operations - * (the tables are entry-wise rotations of one another). - * - * Tradeoff: Uncommenting this reduces the RAM / ROM footprint - * by ~6kb but at the cost of more arithmetic operations during - * runtime. Specifically, one has to compare 4 accesses within - * different tables to 4 accesses with additional arithmetic - * operations within the same table. The performance gain/loss - * depends on the system and memory details. - * - * This option is independent of \c MBEDTLS_AES_ROM_TABLES. - * - */ -//#define MBEDTLS_AES_FEWER_TABLES - -/** - * \def MBEDTLS_CAMELLIA_SMALL_MEMORY - * - * Use less ROM for the Camellia implementation (saves about 768 bytes). - * - * Uncomment this macro to use less memory for Camellia. - */ -//#define MBEDTLS_CAMELLIA_SMALL_MEMORY - -/** - * \def MBEDTLS_CIPHER_MODE_CBC - * - * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CBC - -/** - * \def MBEDTLS_CIPHER_MODE_CFB - * - * Enable Cipher Feedback mode (CFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CFB - -/** - * \def MBEDTLS_CIPHER_MODE_CTR - * - * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CTR - -/** - * \def MBEDTLS_CIPHER_MODE_OFB - * - * Enable Output Feedback mode (OFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_OFB - -/** - * \def MBEDTLS_CIPHER_MODE_XTS - * - * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. - */ -#define MBEDTLS_CIPHER_MODE_XTS - -/** - * \def MBEDTLS_CIPHER_NULL_CIPHER - * - * Enable NULL cipher. - * Warning: Only do so when you know what you are doing. This allows for - * encryption or channels without any security! - * - * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable - * the following ciphersuites: - * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA - * - * Uncomment this macro to enable the NULL cipher and ciphersuites - */ -//#define MBEDTLS_CIPHER_NULL_CIPHER - -/** - * \def MBEDTLS_CIPHER_PADDING_PKCS7 - * - * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for - * specific padding modes in the cipher layer with cipher modes that support - * padding (e.g. CBC) - * - * If you disable all padding modes, only full blocks can be used with CBC. - * - * Enable padding modes in the cipher layer. - */ -#define MBEDTLS_CIPHER_PADDING_PKCS7 -#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#define MBEDTLS_CIPHER_PADDING_ZEROS - -/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - * - * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. - * By default, CTR_DRBG uses a 256-bit key. - */ -//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - -/** - * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES - * - * Enable weak ciphersuites in SSL / TLS. - * Warning: Only do so when you know what you are doing. This allows for - * channels with virtually no security at all! - * - * This enables the following ciphersuites: - * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA - * - * Uncomment this macro to enable weak ciphersuites - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers instead. - */ -//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES - -/** - * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES - * - * Remove RC4 ciphersuites by default in SSL / TLS. - * This flag removes the ciphersuites based on RC4 from the default list as - * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to - * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them - * explicitly. - * - * Uncomment this macro to remove RC4 ciphersuites by default. - */ -#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES - -/** - * \def MBEDTLS_REMOVE_3DES_CIPHERSUITES - * - * Remove 3DES ciphersuites by default in SSL / TLS. - * This flag removes the ciphersuites based on 3DES from the default list as - * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible - * to enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including - * them explicitly. - * - * A man-in-the-browser attacker can recover authentication tokens sent through - * a TLS connection using a 3DES based cipher suite (see "On the Practical - * (In-)Security of 64-bit Block Ciphers" by Karthikeyan Bhargavan and Gaëtan - * Leurent, see https://sweet32.info/SWEET32_CCS16.pdf). If this attack falls - * in your threat model or you are unsure, then you should keep this option - * enabled to remove 3DES based cipher suites. - * - * Comment this macro to keep 3DES in the default ciphersuite list. - */ -#define MBEDTLS_REMOVE_3DES_CIPHERSUITES - -/** - * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED - * - * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve - * module. By default all supported curves are enabled. - * - * Comment macros to disable the curve and functions for it - */ -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_ECP_DP_CURVE448_ENABLED - -/** - * \def MBEDTLS_ECP_NIST_OPTIM - * - * Enable specific 'modulo p' routines for each NIST prime. - * Depending on the prime and architecture, makes operations 4 to 8 times - * faster on the corresponding curve. - * - * Comment this macro to disable NIST curves optimisation. - */ -#define MBEDTLS_ECP_NIST_OPTIM - -/** - * \def MBEDTLS_ECP_NO_INTERNAL_RNG - * - * When this option is disabled, mbedtls_ecp_mul() will make use of an - * internal RNG when called with a NULL \c f_rng argument, in order to protect - * against some side-channel attacks. - * - * This protection introduces a dependency of the ECP module on one of the - * DRBG or SHA modules (HMAC-DRBG, CTR-DRBG, SHA-512 or SHA-256.) For very - * constrained applications that don't require this protection (for example, - * because you're only doing signature verification, so not manipulating any - * secret, or because local/physical side-channel attacks are outside your - * threat model), it might be desirable to get rid of that dependency. - * - * \warning Enabling this option makes some uses of ECP vulnerable to some - * side-channel attacks. Only enable it if you know that's not a problem for - * your use case. - * - * Uncomment this macro to disable some counter-measures in ECP. - */ -//#define MBEDTLS_ECP_NO_INTERNAL_RNG - -/** - * \def MBEDTLS_ECP_RESTARTABLE - * - * Enable "non-blocking" ECC operations that can return early and be resumed. - * - * This allows various functions to pause by returning - * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in - * order to further progress and eventually complete their operation. This is - * controlled through mbedtls_ecp_set_max_ops() which limits the maximum - * number of ECC operations a function may perform before pausing; see - * mbedtls_ecp_set_max_ops() for more information. - * - * This is useful in non-threaded environments if you want to avoid blocking - * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. - * - * Uncomment this macro to enable restartable ECC computations. - * - * \note This option only works with the default software implementation of - * elliptic curve functionality. It is incompatible with - * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT. - */ -//#define MBEDTLS_ECP_RESTARTABLE - -/** - * \def MBEDTLS_ECDSA_DETERMINISTIC - * - * Enable deterministic ECDSA (RFC 6979). - * Standard ECDSA is "fragile" in the sense that lack of entropy when signing - * may result in a compromise of the long-term signing key. This is avoided by - * the deterministic variant. - * - * Requires: MBEDTLS_HMAC_DRBG_C - * - * Comment this macro to disable deterministic ECDSA. - */ -#define MBEDTLS_ECDSA_DETERMINISTIC - -/** - * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - * - * Enable the PSK based ciphersuite modes in SSL / TLS. - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - * - * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - * - * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - * - * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - * - * Enable the RSA-only based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - * - * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - * - * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - * - * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - * - * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - * - * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - * - * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Requires: MBEDTLS_ECJPAKE_C - * MBEDTLS_SHA256_C - * MBEDTLS_ECP_DP_SECP256R1_ENABLED - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 - */ -//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - -/** - * \def MBEDTLS_PK_PARSE_EC_EXTENDED - * - * Enhance support for reading EC keys using variants of SEC1 not allowed by - * RFC 5915 and RFC 5480. - * - * Currently this means parsing the SpecifiedECDomain choice of EC - * parameters (only known groups are supported, not arbitrary domains, to - * avoid validation issues). - * - * Disable if you only need to support RFC 5915 + 5480 key formats. - */ -#define MBEDTLS_PK_PARSE_EC_EXTENDED - -/** - * \def MBEDTLS_ERROR_STRERROR_DUMMY - * - * Enable a dummy error function to make use of mbedtls_strerror() in - * third party libraries easier when MBEDTLS_ERROR_C is disabled - * (no effect when MBEDTLS_ERROR_C is enabled). - * - * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're - * not using mbedtls_strerror() or error_strerror() in your application. - * - * Disable if you run into name conflicts and want to really remove the - * mbedtls_strerror() - */ -#define MBEDTLS_ERROR_STRERROR_DUMMY - -/** - * \def MBEDTLS_GENPRIME - * - * Enable the prime-number generation code. - * - * Requires: MBEDTLS_BIGNUM_C - */ -#define MBEDTLS_GENPRIME - -/** - * \def MBEDTLS_FS_IO - * - * Enable functions that use the filesystem. - */ -#define MBEDTLS_FS_IO - -/** - * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - * Do not add default entropy sources. These are the platform specific, - * mbedtls_timing_hardclock and HAVEGE based poll functions. - * - * This is useful to have more control over the added entropy sources in an - * application. - * - * Uncomment this macro to prevent loading of default entropy functions. - */ -//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - -/** - * \def MBEDTLS_NO_PLATFORM_ENTROPY - * - * Do not use built-in platform entropy functions. - * This is useful if your platform does not support - * standards like the /dev/urandom or Windows CryptoAPI. - * - * Uncomment this macro to disable the built-in platform entropy functions. - */ -//#define MBEDTLS_NO_PLATFORM_ENTROPY - -/** - * \def MBEDTLS_ENTROPY_FORCE_SHA256 - * - * Force the entropy accumulator to use a SHA-256 accumulator instead of the - * default SHA-512 based one (if both are available). - * - * Requires: MBEDTLS_SHA256_C - * - * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option - * if you have performance concerns. - * - * This option is only useful if both MBEDTLS_SHA256_C and - * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. - */ -//#define MBEDTLS_ENTROPY_FORCE_SHA256 - -/** - * \def MBEDTLS_ENTROPY_NV_SEED - * - * Enable the non-volatile (NV) seed file-based entropy source. - * (Also enables the NV seed read/write functions in the platform layer) - * - * This is crucial (if not required) on systems that do not have a - * cryptographic entropy source (in hardware or kernel) available. - * - * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C - * - * \note The read/write functions that are used by the entropy source are - * determined in the platform layer, and can be modified at runtime and/or - * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. - * - * \note If you use the default implementation functions that read a seedfile - * with regular fopen(), please make sure you make a seedfile with the - * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at - * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from - * and written to or you will get an entropy source error! The default - * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE - * bytes from the file. - * - * \note The entropy collector will write to the seed file before entropy is - * given to an external source, to update it. - */ -//#define MBEDTLS_ENTROPY_NV_SEED - -/** - * \def MBEDTLS_MEMORY_DEBUG - * - * Enable debugging of buffer allocator memory issues. Automatically prints - * (to stderr) all (fatal) messages on memory allocation issues. Enables - * function for 'debug output' of allocated memory. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Uncomment this macro to let the buffer allocator print out error messages. - */ -//#define MBEDTLS_MEMORY_DEBUG - -/** - * \def MBEDTLS_MEMORY_BACKTRACE - * - * Include backtrace information with each allocated block. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * GLIBC-compatible backtrace() an backtrace_symbols() support - * - * Uncomment this macro to include backtrace information - */ -//#define MBEDTLS_MEMORY_BACKTRACE - -/** - * \def MBEDTLS_PK_RSA_ALT_SUPPORT - * - * Support external private RSA keys (eg from a HSM) in the PK layer. - * - * Comment this macro to disable support for external private RSA keys. - */ -#define MBEDTLS_PK_RSA_ALT_SUPPORT - -/** - * \def MBEDTLS_PKCS1_V15 - * - * Enable support for PKCS#1 v1.5 encoding. - * - * Requires: MBEDTLS_RSA_C - * - * This enables support for PKCS#1 v1.5 operations. - */ -#define MBEDTLS_PKCS1_V15 - -/** - * \def MBEDTLS_PKCS1_V21 - * - * Enable support for PKCS#1 v2.1 encoding. - * - * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C - * - * This enables support for RSAES-OAEP and RSASSA-PSS operations. - */ -#define MBEDTLS_PKCS1_V21 - -/** - * \def MBEDTLS_RSA_NO_CRT - * - * Do not use the Chinese Remainder Theorem - * for the RSA private operation. - * - * Uncomment this macro to disable the use of CRT in RSA. - * - */ -//#define MBEDTLS_RSA_NO_CRT - -/** - * \def MBEDTLS_SELF_TEST - * - * Enable the checkup functions (*_self_test). - */ -#define MBEDTLS_SELF_TEST - -/** - * \def MBEDTLS_SHA256_SMALLER - * - * Enable an implementation of SHA-256 that has lower ROM footprint but also - * lower performance. - * - * The default implementation is meant to be a reasonnable compromise between - * performance and size. This version optimizes more aggressively for size at - * the expense of performance. Eg on Cortex-M4 it reduces the size of - * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about - * 30%. - * - * Uncomment to enable the smaller implementation of SHA256. - */ -//#define MBEDTLS_SHA256_SMALLER - -/** - * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES - * - * Enable sending of alert messages in case of encountered errors as per RFC. - * If you choose not to send the alert messages, mbed TLS can still communicate - * with other servers, only debugging of failures is harder. - * - * The advantage of not sending alert messages, is that no information is given - * about reasons for failures thus preventing adversaries of gaining intel. - * - * Enable sending of all alert messages - */ -#define MBEDTLS_SSL_ALL_ALERT_MESSAGES - -/** - * \def MBEDTLS_SSL_ASYNC_PRIVATE - * - * Enable asynchronous external private key operations in SSL. This allows - * you to configure an SSL connection to call an external cryptographic - * module to perform private key operations instead of performing the - * operation inside the library. - * - */ -//#define MBEDTLS_SSL_ASYNC_PRIVATE - -/** - * \def MBEDTLS_SSL_DEBUG_ALL - * - * Enable the debug messages in SSL module for all issues. - * Debug messages have been disabled in some places to prevent timing - * attacks due to (unbalanced) debugging function calls. - * - * If you need all error reporting you should enable this during debugging, - * but remove this for production servers that should log as well. - * - * Uncomment this macro to report all debug messages on errors introducing - * a timing side-channel. - * - */ -//#define MBEDTLS_SSL_DEBUG_ALL - -/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC - * - * Enable support for Encrypt-then-MAC, RFC 7366. - * - * This allows peers that both support it to use a more robust protection for - * ciphersuites using CBC, providing deep resistance against timing attacks - * on the padding or underlying cipher. - * - * This only affects CBC ciphersuites, and is useless if none is defined. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Encrypt-then-MAC - */ -#define MBEDTLS_SSL_ENCRYPT_THEN_MAC - -/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET - * - * Enable support for Extended Master Secret, aka Session Hash - * (draft-ietf-tls-session-hash-02). - * - * This was introduced as "the proper fix" to the Triple Handshake familiy of - * attacks, but it is recommended to always use it (even if you disable - * renegotiation), since it actually fixes a more fundamental issue in the - * original SSL/TLS design, and has implications beyond Triple Handshake. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Extended Master Secret. - */ -#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET - -/** - * \def MBEDTLS_SSL_FALLBACK_SCSV - * - * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00). - * - * For servers, it is recommended to always enable this, unless you support - * only one version of TLS, or know for sure that none of your clients - * implements a fallback strategy. - * - * For clients, you only need this if you're using a fallback strategy, which - * is not recommended in the first place, unless you absolutely need it to - * interoperate with buggy (version-intolerant) servers. - * - * Comment this macro to disable support for FALLBACK_SCSV - */ -#define MBEDTLS_SSL_FALLBACK_SCSV - -/** - * \def MBEDTLS_SSL_HW_RECORD_ACCEL - * - * Enable hooking functions in SSL module for hardware acceleration of - * individual records. - * - * Uncomment this macro to enable hooking functions. - */ -//#define MBEDTLS_SSL_HW_RECORD_ACCEL - -/** - * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING - * - * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. - * - * This is a countermeasure to the BEAST attack, which also minimizes the risk - * of interoperability issues compared to sending 0-length records. - * - * Comment this macro to disable 1/n-1 record splitting. - */ -#define MBEDTLS_SSL_CBC_RECORD_SPLITTING - -/** - * \def MBEDTLS_SSL_RENEGOTIATION - * - * Enable support for TLS renegotiation. - * - * The two main uses of renegotiation are (1) refresh keys on long-lived - * connections and (2) client authentication after the initial handshake. - * If you don't need renegotiation, it's probably better to disable it, since - * it has been associated with security issues in the past and is easy to - * misuse/misunderstand. - * - * Comment this to disable support for renegotiation. - * - * \note Even if this option is disabled, both client and server are aware - * of the Renegotiation Indication Extension (RFC 5746) used to - * prevent the SSL renegotiation attack (see RFC 5746 Sect. 1). - * (See \c mbedtls_ssl_conf_legacy_renegotiation for the - * configuration of this extension). - * - */ -#define MBEDTLS_SSL_RENEGOTIATION - -/** - * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - * - * Enable support for receiving and parsing SSLv2 Client Hello messages for the - * SSL Server module (MBEDTLS_SSL_SRV_C). - * - * Uncomment this macro to enable support for SSLv2 Client Hello messages. - */ -//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - -/** - * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - * - * Pick the ciphersuite according to the client's preferences rather than ours - * in the SSL Server module (MBEDTLS_SSL_SRV_C). - * - * Uncomment this macro to respect client's ciphersuite order - */ -//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - -/** - * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - * - * Enable support for RFC 6066 max_fragment_length extension in SSL. - * - * Comment this macro to disable support for the max_fragment_length extension - */ -#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - -/** - * \def MBEDTLS_SSL_PROTO_SSL3 - * - * Enable support for SSL 3.0. - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for SSL 3.0 - */ -//#define MBEDTLS_SSL_PROTO_SSL3 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1 - * - * Enable support for TLS 1.0. - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for TLS 1.0 - */ -#define MBEDTLS_SSL_PROTO_TLS1 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_1 - * - * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for TLS 1.1 / DTLS 1.0 - */ -#define MBEDTLS_SSL_PROTO_TLS1_1 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_2 - * - * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). - * - * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C - * (Depends on ciphersuites) - * - * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 - */ -#define MBEDTLS_SSL_PROTO_TLS1_2 - -/** - * \def MBEDTLS_SSL_PROTO_DTLS - * - * Enable support for DTLS (all available versions). - * - * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, - * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_1 - * or MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for DTLS - */ -#define MBEDTLS_SSL_PROTO_DTLS - -/** - * \def MBEDTLS_SSL_ALPN - * - * Enable support for RFC 7301 Application Layer Protocol Negotiation. - * - * Comment this macro to disable support for ALPN. - */ -#define MBEDTLS_SSL_ALPN - -/** - * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY - * - * Enable support for the anti-replay mechanism in DTLS. - * - * Requires: MBEDTLS_SSL_TLS_C - * MBEDTLS_SSL_PROTO_DTLS - * - * \warning Disabling this is often a security risk! - * See mbedtls_ssl_conf_dtls_anti_replay() for details. - * - * Comment this to disable anti-replay in DTLS. - */ -#define MBEDTLS_SSL_DTLS_ANTI_REPLAY - -/** - * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Enable support for HelloVerifyRequest on DTLS servers. - * - * This feature is highly recommended to prevent DTLS servers being used as - * amplifiers in DoS attacks against other hosts. It should always be enabled - * unless you know for sure amplification cannot be a problem in the - * environment in which your server operates. - * - * \warning Disabling this can ba a security risk! (see above) - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Comment this to disable support for HelloVerifyRequest. - */ -#define MBEDTLS_SSL_DTLS_HELLO_VERIFY - -/** - * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - * - * Enable server-side support for clients that reconnect from the same port. - * - * Some clients unexpectedly close the connection and try to reconnect using the - * same source port. This needs special support from the server to handle the - * new connection securely, as described in section 4.2.8 of RFC 6347. This - * flag enables that support. - * - * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Comment this to disable support for clients reusing the source port. - */ -#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - -/** - * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT - * - * Enable support for a limit of records with bad MAC. - * - * See mbedtls_ssl_conf_dtls_badmac_limit(). - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - */ -#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT - -/** - * \def MBEDTLS_SSL_SESSION_TICKETS - * - * Enable support for RFC 5077 session tickets in SSL. - * Client-side, provides full support for session tickets (maintenance of a - * session store remains the responsibility of the application, though). - * Server-side, you also need to provide callbacks for writing and parsing - * tickets, including authenticated encryption and key management. Example - * callbacks are provided by MBEDTLS_SSL_TICKET_C. - * - * Comment this macro to disable support for SSL session tickets - */ -#define MBEDTLS_SSL_SESSION_TICKETS - -/** - * \def MBEDTLS_SSL_EXPORT_KEYS - * - * Enable support for exporting key block and master secret. - * This is required for certain users of TLS, e.g. EAP-TLS. - * - * Comment this macro to disable support for key export - */ -#define MBEDTLS_SSL_EXPORT_KEYS - -/** - * \def MBEDTLS_SSL_SERVER_NAME_INDICATION - * - * Enable support for RFC 6066 server name indication (SNI) in SSL. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - * - * Comment this macro to disable support for server name indication in SSL - */ -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -/** - * \def MBEDTLS_SSL_TRUNCATED_HMAC - * - * Enable support for RFC 6066 truncated HMAC in SSL. - * - * Comment this macro to disable support for truncated HMAC in SSL - */ -#define MBEDTLS_SSL_TRUNCATED_HMAC - -/** - * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT - * - * Fallback to old (pre-2.7), non-conforming implementation of the truncated - * HMAC extension which also truncates the HMAC key. Note that this option is - * only meant for a transitory upgrade period and is likely to be removed in - * a future version of the library. - * - * \warning The old implementation is non-compliant and has a security weakness - * (2^80 brute force attack on the HMAC key used for a single, - * uninterrupted connection). This should only be enabled temporarily - * when (1) the use of truncated HMAC is essential in order to save - * bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use - * the fixed implementation yet (pre-2.7). - * - * \disabled_deprecated This option is deprecated and will likely be removed in a - * future version of Mbed TLS. - * - * Uncomment to fallback to old, non-compliant truncated HMAC implementation. - * - * Requires: MBEDTLS_SSL_TRUNCATED_HMAC - */ -//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT - -/** - * \def MBEDTLS_TEST_HOOKS - * - * Enable features for invasive testing such as introspection functions and - * hooks for fault injection. This enables additional unit tests. - * - * Merely enabling this feature should not change the behavior of the product. - * It only adds new code, and new branching points where the default behavior - * is the same as when this feature is disabled. - * However, this feature increases the attack surface: there is an added - * risk of vulnerabilities, and more gadgets that can make exploits easier. - * Therefore this feature must never be enabled in production. - * - * Uncomment to enable invasive tests. - */ -//#define MBEDTLS_TEST_HOOKS - -/** - * \def MBEDTLS_THREADING_ALT - * - * Provide your own alternate threading implementation. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to allow your own alternate threading implementation. - */ -//#define MBEDTLS_THREADING_ALT - -/** - * \def MBEDTLS_THREADING_PTHREAD - * - * Enable the pthread wrapper layer for the threading layer. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to enable pthread mutexes. - */ -#define MBEDTLS_THREADING_PTHREAD - -/** - * \def MBEDTLS_VERSION_FEATURES - * - * Allow run-time checking of compile-time enabled features. Thus allowing users - * to check at run-time if the library is for instance compiled with threading - * support via mbedtls_version_check_feature(). - * - * Requires: MBEDTLS_VERSION_C - * - * Comment this to disable run-time checking and save ROM space - */ -#define MBEDTLS_VERSION_FEATURES - -/** - * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an extension in a v1 or v2 certificate. - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - -/** - * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an unknown critical extension. - * - * \warning Depending on your PKI use, enabling this can be a security risk! - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - -/** - * \def MBEDTLS_X509_CHECK_KEY_USAGE - * - * Enable verification of the keyUsage extension (CA and leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused - * (intermediate) CA and leaf certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip keyUsage checking for both CA and leaf certificates. - */ -#define MBEDTLS_X509_CHECK_KEY_USAGE - -/** - * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE - * - * Enable verification of the extendedKeyUsage extension (leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip extendedKeyUsage checking for certificates. - */ -#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE - -/** - * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT - * - * Enable parsing and verification of X.509 certificates, CRLs and CSRS - * signed with RSASSA-PSS (aka PKCS#1 v2.1). - * - * Comment this macro to disallow using RSASSA-PSS in certificates. - */ -#define MBEDTLS_X509_RSASSA_PSS_SUPPORT - -/** - * \def MBEDTLS_ZLIB_SUPPORT - * - * If set, the SSL/TLS module uses ZLIB to support compression and - * decompression of packet data. - * - * \warning TLS-level compression MAY REDUCE SECURITY! See for example the - * CRIME attack. Before enabling this option, you should examine with care if - * CRIME or similar exploits may be applicable to your use case. - * - * \note Currently compression can't be used with DTLS. - * - * \disabled_deprecated This feature is deprecated and will be removed - * in the next major revision of the library. - * - * Used in: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This feature requires zlib library and headers to be present. - * - * Uncomment to enable use of ZLIB - */ -//#define MBEDTLS_ZLIB_SUPPORT -/* \} name SECTION: mbed TLS feature support */ - -/** - * \name SECTION: mbed TLS modules - * - * This section enables or disables entire modules in mbed TLS - * \{ - */ - -/** - * \def MBEDTLS_AESNI_C - * - * Enable AES-NI support on x86-64. - * - * Module: library/aesni.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM - * - * This modules adds support for the AES-NI instructions on x86-64 - */ -//#define MBEDTLS_AESNI_C - -/** - * \def MBEDTLS_AES_C - * - * Enable the AES block cipher. - * - * Module: library/aes.c - * Caller: library/cipher.c - * library/pem.c - * library/ctr_drbg.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * - * PEM_PARSE uses AES for decrypting encrypted keys. - */ -#define MBEDTLS_AES_C - -/** - * \def MBEDTLS_ARC4_C - * - * Enable the ARCFOUR stream cipher. - * - * Module: library/arc4.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. If possible, we recommend avoidng dependencies on - * it, and considering stronger ciphers instead. - * - */ -#define MBEDTLS_ARC4_C - -/** - * \def MBEDTLS_ASN1_PARSE_C - * - * Enable the generic ASN1 parser. - * - * Module: library/asn1.c - * Caller: library/x509.c - * library/dhm.c - * library/pkcs12.c - * library/pkcs5.c - * library/pkparse.c - */ -#define MBEDTLS_ASN1_PARSE_C - -/** - * \def MBEDTLS_ASN1_WRITE_C - * - * Enable the generic ASN1 writer. - * - * Module: library/asn1write.c - * Caller: library/ecdsa.c - * library/pkwrite.c - * library/x509_create.c - * library/x509write_crt.c - * library/x509write_csr.c - */ -#define MBEDTLS_ASN1_WRITE_C - -/** - * \def MBEDTLS_BASE64_C - * - * Enable the Base64 module. - * - * Module: library/base64.c - * Caller: library/pem.c - * - * This module is required for PEM support (required by X.509). - */ -#define MBEDTLS_BASE64_C - -/** - * \def MBEDTLS_BIGNUM_C - * - * Enable the multi-precision integer library. - * - * Module: library/bignum.c - * Caller: library/dhm.c - * library/ecp.c - * library/ecdsa.c - * library/rsa.c - * library/rsa_internal.c - * library/ssl_tls.c - * - * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. - */ -#define MBEDTLS_BIGNUM_C - -/** - * \def MBEDTLS_BLOWFISH_C - * - * Enable the Blowfish block cipher. - * - * Module: library/blowfish.c - */ -#define MBEDTLS_BLOWFISH_C - -/** - * \def MBEDTLS_CAMELLIA_C - * - * Enable the Camellia block cipher. - * - * Module: library/camellia.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_CAMELLIA_C - -/** - * \def MBEDTLS_ARIA_C - * - * Enable the ARIA block cipher. - * - * Module: library/aria.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * - * MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 - */ -//#define MBEDTLS_ARIA_C - -/** - * \def MBEDTLS_CCM_C - * - * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. - * - * Module: library/ccm.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C - * - * This module enables the AES-CCM ciphersuites, if other requisites are - * enabled as well. - */ -#define MBEDTLS_CCM_C - -/** - * \def MBEDTLS_CERTS_C - * - * Enable the test certificates. - * - * Module: library/certs.c - * Caller: - * - * This module is used for testing (ssl_client/server). - */ -#define MBEDTLS_CERTS_C - -/** - * \def MBEDTLS_CHACHA20_C - * - * Enable the ChaCha20 stream cipher. - * - * Module: library/chacha20.c - */ -#define MBEDTLS_CHACHA20_C - -/** - * \def MBEDTLS_CHACHAPOLY_C - * - * Enable the ChaCha20-Poly1305 AEAD algorithm. - * - * Module: library/chachapoly.c - * - * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C - */ -#define MBEDTLS_CHACHAPOLY_C - -/** - * \def MBEDTLS_CIPHER_C - * - * Enable the generic cipher layer. - * - * Module: library/cipher.c - * Caller: library/ssl_tls.c - * - * Uncomment to enable generic cipher wrappers. - */ -#define MBEDTLS_CIPHER_C - -/** - * \def MBEDTLS_CMAC_C - * - * Enable the CMAC (Cipher-based Message Authentication Code) mode for block - * ciphers. - * - * Module: library/cmac.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C - * - */ -//#define MBEDTLS_CMAC_C - -/** - * \def MBEDTLS_CTR_DRBG_C - * - * Enable the CTR_DRBG AES-based random generator. - * The CTR_DRBG generator uses AES-256 by default. - * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. - * - * \note To achieve a 256-bit security strength with CTR_DRBG, - * you must use AES-256 *and* use sufficient entropy. - * See ctr_drbg.h for more details. - * - * Module: library/ctr_drbg.c - * Caller: - * - * Requires: MBEDTLS_AES_C - * - * This module provides the CTR_DRBG AES random number generator. - */ -#define MBEDTLS_CTR_DRBG_C - -/** - * \def MBEDTLS_DEBUG_C - * - * Enable the debug functions. - * - * Module: library/debug.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module provides debugging functions. - */ -#define MBEDTLS_DEBUG_C - -/** - * \def MBEDTLS_DES_C - * - * Enable the DES block cipher. - * - * Module: library/des.c - * Caller: library/pem.c - * library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * - * PEM_PARSE uses DES/3DES for decrypting encrypted keys. - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers instead. - */ -#define MBEDTLS_DES_C - -/** - * \def MBEDTLS_DHM_C - * - * Enable the Diffie-Hellman-Merkle module. - * - * Module: library/dhm.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * DHE-RSA, DHE-PSK - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_DHM_C - -/** - * \def MBEDTLS_ECDH_C - * - * Enable the elliptic curve Diffie-Hellman library. - * - * Module: library/ecdh.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK - * - * Requires: MBEDTLS_ECP_C - */ -#define MBEDTLS_ECDH_C - -/** - * \def MBEDTLS_ECDSA_C - * - * Enable the elliptic curve DSA library. - * - * Module: library/ecdsa.c - * Caller: - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C - */ -#define MBEDTLS_ECDSA_C - -/** - * \def MBEDTLS_ECJPAKE_C - * - * Enable the elliptic curve J-PAKE library. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Module: library/ecjpake.c - * Caller: - * - * This module is used by the following key exchanges: - * ECJPAKE - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C - */ -//#define MBEDTLS_ECJPAKE_C - -/** - * \def MBEDTLS_ECP_C - * - * Enable the elliptic curve over GF(p) library. - * - * Module: library/ecp.c - * Caller: library/ecdh.c - * library/ecdsa.c - * library/ecjpake.c - * - * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED - */ -#define MBEDTLS_ECP_C - -/** - * \def MBEDTLS_ENTROPY_C - * - * Enable the platform-specific entropy code. - * - * Module: library/entropy.c - * Caller: - * - * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C - * - * This module provides a generic entropy pool - */ -#define MBEDTLS_ENTROPY_C - -/** - * \def MBEDTLS_ERROR_C - * - * Enable error code to error string conversion. - * - * Module: library/error.c - * Caller: - * - * This module enables mbedtls_strerror(). - */ -#define MBEDTLS_ERROR_C - -/** - * \def MBEDTLS_GCM_C - * - * Enable the Galois/Counter Mode (GCM) for AES. - * - * Module: library/gcm.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C - * - * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other - * requisites are enabled as well. - */ -#define MBEDTLS_GCM_C - -/** - * \def MBEDTLS_HAVEGE_C - * - * Enable the HAVEGE random generator. - * - * Warning: the HAVEGE random generator is not suitable for virtualized - * environments - * - * Warning: the HAVEGE random generator is dependent on timing and specific - * processor traits. It is therefore not advised to use HAVEGE as - * your applications primary random generator or primary entropy pool - * input. As a secondary input to your entropy pool, it IS able add - * the (limited) extra entropy it provides. - * - * Module: library/havege.c - * Caller: - * - * Requires: MBEDTLS_TIMING_C - * - * Uncomment to enable the HAVEGE random generator. - */ -//#define MBEDTLS_HAVEGE_C - -/** - * \def MBEDTLS_HKDF_C - * - * Enable the HKDF algorithm (RFC 5869). - * - * Module: library/hkdf.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * This module adds support for the Hashed Message Authentication Code - * (HMAC)-based key derivation function (HKDF). - */ -#define MBEDTLS_HKDF_C - -/** - * \def MBEDTLS_HMAC_DRBG_C - * - * Enable the HMAC_DRBG random generator. - * - * Module: library/hmac_drbg.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * Uncomment to enable the HMAC_DRBG random number geerator. - */ -#define MBEDTLS_HMAC_DRBG_C - -/** - * \def MBEDTLS_NIST_KW_C - * - * Enable the Key Wrapping mode for 128-bit block ciphers, - * as defined in NIST SP 800-38F. Only KW and KWP modes - * are supported. At the moment, only AES is approved by NIST. - * - * Module: library/nist_kw.c - * - * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C - */ -//#define MBEDTLS_NIST_KW_C - -/** - * \def MBEDTLS_MD_C - * - * Enable the generic message digest layer. - * - * Module: library/md.c - * Caller: - * - * Uncomment to enable generic message digest wrappers. - */ -#define MBEDTLS_MD_C - -/** - * \def MBEDTLS_MD2_C - * - * Enable the MD2 hash algorithm. - * - * Module: library/md2.c - * Caller: - * - * Uncomment to enable support for (rare) MD2-signed X.509 certs. - * - * \warning MD2 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -//#define MBEDTLS_MD2_C - -/** - * \def MBEDTLS_MD4_C - * - * Enable the MD4 hash algorithm. - * - * Module: library/md4.c - * Caller: - * - * Uncomment to enable support for (rare) MD4-signed X.509 certs. - * - * \warning MD4 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -//#define MBEDTLS_MD4_C - -/** - * \def MBEDTLS_MD5_C - * - * Enable the MD5 hash algorithm. - * - * Module: library/md5.c - * Caller: library/md.c - * library/pem.c - * library/ssl_tls.c - * - * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2 - * depending on the handshake parameters. Further, it is used for checking - * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded - * encrypted keys. - * - * \warning MD5 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -#define MBEDTLS_MD5_C - -/** - * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Enable the buffer allocator implementation that makes use of a (stack) - * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() - * calls) - * - * Module: library/memory_buffer_alloc.c - * - * Requires: MBEDTLS_PLATFORM_C - * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) - * - * Enable this module to enable the buffer memory allocator. - */ -//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C - -/** - * \def MBEDTLS_NET_C - * - * Enable the TCP and UDP over IPv6/IPv4 networking routines. - * - * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) - * and Windows. For other platforms, you'll want to disable it, and write your - * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/net_sockets.c - * - * This module provides networking routines. - */ -#define MBEDTLS_NET_C - -/** - * \def MBEDTLS_OID_C - * - * Enable the OID database. - * - * Module: library/oid.c - * Caller: library/asn1write.c - * library/pkcs5.c - * library/pkparse.c - * library/pkwrite.c - * library/rsa.c - * library/x509.c - * library/x509_create.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * This modules translates between OIDs and internal values. - */ -#define MBEDTLS_OID_C - -/** - * \def MBEDTLS_PADLOCK_C - * - * Enable VIA Padlock support on x86. - * - * Module: library/padlock.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM - * - * This modules adds support for the VIA PadLock on x86. - */ -//#define MBEDTLS_PADLOCK_C - -/** - * \def MBEDTLS_PEM_PARSE_C - * - * Enable PEM decoding / parsing. - * - * Module: library/pem.c - * Caller: library/dhm.c - * library/pkparse.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for decoding / parsing PEM files. - */ -#define MBEDTLS_PEM_PARSE_C - -/** - * \def MBEDTLS_PEM_WRITE_C - * - * Enable PEM encoding / writing. - * - * Module: library/pem.c - * Caller: library/pkwrite.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for encoding / writing PEM files. - */ -#define MBEDTLS_PEM_WRITE_C - -/** - * \def MBEDTLS_PK_C - * - * Enable the generic public (asymetric) key layer. - * - * Module: library/pk.c - * Caller: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C - * - * Uncomment to enable generic public key wrappers. - */ -#define MBEDTLS_PK_C - -/** - * \def MBEDTLS_PK_PARSE_C - * - * Enable the generic public (asymetric) key parser. - * - * Module: library/pkparse.c - * Caller: library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key parse functions. - */ -#define MBEDTLS_PK_PARSE_C - -/** - * \def MBEDTLS_PK_WRITE_C - * - * Enable the generic public (asymetric) key writer. - * - * Module: library/pkwrite.c - * Caller: library/x509write.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key write functions. - */ -#define MBEDTLS_PK_WRITE_C - -/** - * \def MBEDTLS_PKCS5_C - * - * Enable PKCS#5 functions. - * - * Module: library/pkcs5.c - * - * Requires: MBEDTLS_MD_C - * - * This module adds support for the PKCS#5 functions. - */ -#define MBEDTLS_PKCS5_C - -/** - * \def MBEDTLS_PKCS11_C - * - * Enable wrapper for PKCS#11 smartcard support. - * - * Module: library/pkcs11.c - * Caller: library/pk.c - * - * Requires: MBEDTLS_PK_C - * - * This module enables SSL/TLS PKCS #11 smartcard support. - * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) - */ -//#define MBEDTLS_PKCS11_C - -/** - * \def MBEDTLS_PKCS12_C - * - * Enable PKCS#12 PBE functions. - * Adds algorithms for parsing PKCS#8 encrypted private keys - * - * Module: library/pkcs12.c - * Caller: library/pkparse.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * Can use: MBEDTLS_ARC4_C - * - * This module enables PKCS#12 functions. - */ -#define MBEDTLS_PKCS12_C - -/** - * \def MBEDTLS_PLATFORM_C - * - * Enable the platform abstraction layer that allows you to re-assign - * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). - * - * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT - * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned - * above to be specified at runtime or compile time respectively. - * - * \note This abstraction layer must be enabled on Windows (including MSYS2) - * as other module rely on it for a fixed snprintf implementation. - * - * Module: library/platform.c - * Caller: Most other .c files - * - * This module enables abstraction of common (libc) functions. - */ -#define MBEDTLS_PLATFORM_C - -/** - * \def MBEDTLS_POLY1305_C - * - * Enable the Poly1305 MAC algorithm. - * - * Module: library/poly1305.c - * Caller: library/chachapoly.c - */ -#define MBEDTLS_POLY1305_C - -/** - * \def MBEDTLS_RIPEMD160_C - * - * Enable the RIPEMD-160 hash algorithm. - * - * Module: library/ripemd160.c - * Caller: library/md.c - * - */ -#define MBEDTLS_RIPEMD160_C - -/** - * \def MBEDTLS_RSA_C - * - * Enable the RSA public-key cryptosystem. - * - * Module: library/rsa.c - * library/rsa_internal.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509.c - * - * This module is used by the following key exchanges: - * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C - */ -#define MBEDTLS_RSA_C - -/** - * \def MBEDTLS_SHA1_C - * - * Enable the SHA1 cryptographic hash algorithm. - * - * Module: library/sha1.c - * Caller: library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509write_crt.c - * - * This module is required for SSL/TLS up to version 1.1, for TLS 1.2 - * depending on the handshake parameters, and for SHA1-signed certificates. - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. If possible, we recommend avoiding dependencies - * on it, and considering stronger message digests instead. - * - */ -#define MBEDTLS_SHA1_C - -/** - * \def MBEDTLS_SHA256_C - * - * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. - * - * Module: library/sha256.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module adds support for SHA-224 and SHA-256. - * This module is required for the SSL/TLS 1.2 PRF function. - */ -#define MBEDTLS_SHA256_C - -/** - * \def MBEDTLS_SHA512_C - * - * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. - * - * Module: library/sha512.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This module adds support for SHA-384 and SHA-512. - */ -#define MBEDTLS_SHA512_C - -/** - * \def MBEDTLS_SSL_CACHE_C - * - * Enable simple SSL cache implementation. - * - * Module: library/ssl_cache.c - * Caller: - * - * Requires: MBEDTLS_SSL_CACHE_C - */ -#define MBEDTLS_SSL_CACHE_C - -/** - * \def MBEDTLS_SSL_COOKIE_C - * - * Enable basic implementation of DTLS cookies for hello verification. - * - * Module: library/ssl_cookie.c - * Caller: - */ -#define MBEDTLS_SSL_COOKIE_C - -/** - * \def MBEDTLS_SSL_TICKET_C - * - * Enable an implementation of TLS server-side callbacks for session tickets. - * - * Module: library/ssl_ticket.c - * Caller: - * - * Requires: MBEDTLS_CIPHER_C - */ -#define MBEDTLS_SSL_TICKET_C - -/** - * \def MBEDTLS_SSL_CLI_C - * - * Enable the SSL/TLS client code. - * - * Module: library/ssl_cli.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS client support. - */ -#define MBEDTLS_SSL_CLI_C - -/** - * \def MBEDTLS_SSL_SRV_C - * - * Enable the SSL/TLS server code. - * - * Module: library/ssl_srv.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS server support. - */ -#define MBEDTLS_SSL_SRV_C - -/** - * \def MBEDTLS_SSL_TLS_C - * - * Enable the generic SSL/TLS code. - * - * Module: library/ssl_tls.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * and at least one of the MBEDTLS_SSL_PROTO_XXX defines - * - * This module is required for SSL/TLS. - */ -#define MBEDTLS_SSL_TLS_C - -/** - * \def MBEDTLS_THREADING_C - * - * Enable the threading abstraction layer. - * By default mbed TLS assumes it is used in a non-threaded environment or that - * contexts are not shared between threads. If you do intend to use contexts - * between threads, you will need to enable this layer to prevent race - * conditions. See also our Knowledge Base article about threading: - * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading - * - * Module: library/threading.c - * - * This allows different threading implementations (self-implemented or - * provided). - * - * You will have to enable either MBEDTLS_THREADING_ALT or - * MBEDTLS_THREADING_PTHREAD. - * - * Enable this layer to allow use of mutexes within mbed TLS - */ -#define MBEDTLS_THREADING_C - -/** - * \def MBEDTLS_TIMING_C - * - * Enable the semi-portable timing interface. - * - * \note The provided implementation only works on POSIX/Unix (including Linux, - * BSD and OS X) and Windows. On other platforms, you can either disable that - * module and provide your own implementations of the callbacks needed by - * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide - * your own implementation of the whole module by setting - * \c MBEDTLS_TIMING_ALT in the current file. - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/timing.c - * Caller: library/havege.c - * - * This module is used by the HAVEGE random number generator. - */ -#define MBEDTLS_TIMING_C - -/** - * \def MBEDTLS_VERSION_C - * - * Enable run-time version information. - * - * Module: library/version.c - * - * This module provides run-time version information. - */ -#define MBEDTLS_VERSION_C - -/** - * \def MBEDTLS_X509_USE_C - * - * Enable X.509 core for using certificates. - * - * Module: library/x509.c - * Caller: library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, - * MBEDTLS_PK_PARSE_C - * - * This module is required for the X.509 parsing modules. - */ -#define MBEDTLS_X509_USE_C - -/** - * \def MBEDTLS_X509_CRT_PARSE_C - * - * Enable X.509 certificate parsing. - * - * Module: library/x509_crt.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 certificate parsing. - */ -#define MBEDTLS_X509_CRT_PARSE_C - -/** - * \def MBEDTLS_X509_CRL_PARSE_C - * - * Enable X.509 CRL parsing. - * - * Module: library/x509_crl.c - * Caller: library/x509_crt.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 CRL parsing. - */ -#define MBEDTLS_X509_CRL_PARSE_C - -/** - * \def MBEDTLS_X509_CSR_PARSE_C - * - * Enable X.509 Certificate Signing Request (CSR) parsing. - * - * Module: library/x509_csr.c - * Caller: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is used for reading X.509 certificate request. - */ -#define MBEDTLS_X509_CSR_PARSE_C - -/** - * \def MBEDTLS_X509_CREATE_C - * - * Enable X.509 core for creating certificates. - * - * Module: library/x509_create.c - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C - * - * This module is the basis for creating X.509 certificates and CSRs. - */ -#define MBEDTLS_X509_CREATE_C - -/** - * \def MBEDTLS_X509_CRT_WRITE_C - * - * Enable creating X.509 certificates. - * - * Module: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate creation. - */ -#define MBEDTLS_X509_CRT_WRITE_C - -/** - * \def MBEDTLS_X509_CSR_WRITE_C - * - * Enable creating X.509 Certificate Signing Requests (CSR). - * - * Module: library/x509_csr_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate request writing. - */ -#define MBEDTLS_X509_CSR_WRITE_C - -/** - * \def MBEDTLS_XTEA_C - * - * Enable the XTEA block cipher. - * - * Module: library/xtea.c - * Caller: - */ -#define MBEDTLS_XTEA_C - -/* \} name SECTION: mbed TLS modules */ - -/** - * \name SECTION: Module configuration options - * - * This section allows for the setting of module specific sizes and - * configuration options. The default values are already present in the - * relevant header files and should suffice for the regular use cases. - * - * Our advice is to enable options and change their values here - * only if you have a good reason and know the consequences. - * - * Please check the respective header file for documentation on these - * parameters (to prevent duplicate documentation). - * \{ - */ - -/* MPI / BIGNUM options */ -//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ -//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ - -/* CTR_DRBG options */ -//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ -//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* HMAC_DRBG options */ -//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* ECP options */ -//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ -//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ -//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ - -/* Entropy options */ -//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ - -/* Memory buffer allocator options */ -//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ - -/* Platform options */ -//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ -//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ - -/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ -/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ -//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ - -/** - * \brief This macro is invoked by the library when an invalid parameter - * is detected that is only checked with #MBEDTLS_CHECK_PARAMS - * (see the documentation of that option for context). - * - * When you leave this undefined here, the library provides - * a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT - * is defined, the default definition is `assert(cond)`, - * otherwise the default definition calls a function - * mbedtls_param_failed(). This function is declared in - * `platform_util.h` for the benefit of the library, but - * you need to define in your application. - * - * When you define this here, this replaces the default - * definition in platform_util.h (which no longer declares the - * function mbedtls_param_failed()) and it is your responsibility - * to make sure this macro expands to something suitable (in - * particular, that all the necessary declarations are visible - * from within the library - you can ensure that by providing - * them in this file next to the macro definition). - * If you define this macro to call `assert`, also define - * #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files - * include ``. - * - * Note that you may define this macro to expand to nothing, in - * which case you don't have to worry about declarations or - * definitions. However, you will then be notified about invalid - * parameters only in non-void functions, and void function will - * just silently return early on invalid parameters, which - * partially negates the benefits of enabling - * #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged. - * - * \param cond The expression that should evaluate to true, but doesn't. - */ -//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) - -/* SSL Cache options */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ - -/* SSL options */ - -/** \def MBEDTLS_SSL_MAX_CONTENT_LEN - * - * Maximum length (in bytes) of incoming and outgoing plaintext fragments. - * - * This determines the size of both the incoming and outgoing TLS I/O buffers - * in such a way that both are capable of holding the specified amount of - * plaintext data, regardless of the protection mechanism used. - * - * To configure incoming and outgoing I/O buffers separately, use - * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN, - * which overwrite the value set by this option. - * - * \note When using a value less than the default of 16KB on the client, it is - * recommended to use the Maximum Fragment Length (MFL) extension to - * inform the server about this limitation. On the server, there - * is no supported, standardized way of informing the client about - * restriction on the maximum size of incoming messages, and unless - * the limitation has been communicated by other means, it is recommended - * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN - * while keeping the default value of 16KB for the incoming buffer. - * - * Uncomment to set the maximum plaintext size of both - * incoming and outgoing I/O buffers. - */ -//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_IN_CONTENT_LEN - * - * Maximum length (in bytes) of incoming plaintext fragments. - * - * This determines the size of the incoming TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * If this option is undefined, it inherits its value from - * #MBEDTLS_SSL_MAX_CONTENT_LEN. - * - * \note When using a value less than the default of 16KB on the client, it is - * recommended to use the Maximum Fragment Length (MFL) extension to - * inform the server about this limitation. On the server, there - * is no supported, standardized way of informing the client about - * restriction on the maximum size of incoming messages, and unless - * the limitation has been communicated by other means, it is recommended - * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN - * while keeping the default value of 16KB for the incoming buffer. - * - * Uncomment to set the maximum plaintext size of the incoming I/O buffer - * independently of the outgoing I/O buffer. - */ -//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_OUT_CONTENT_LEN - * - * Maximum length (in bytes) of outgoing plaintext fragments. - * - * This determines the size of the outgoing TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * If this option undefined, it inherits its value from - * #MBEDTLS_SSL_MAX_CONTENT_LEN. - * - * It is possible to save RAM by setting a smaller outward buffer, while keeping - * the default inward 16384 byte buffer to conform to the TLS specification. - * - * The minimum required outward buffer size is determined by the handshake - * protocol's usage. Handshaking will fail if the outward buffer is too small. - * The specific size requirement depends on the configured ciphers and any - * certificate data which is sent during the handshake. - * - * Uncomment to set the maximum plaintext size of the outgoing I/O buffer - * independently of the incoming I/O buffer. - */ -//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING - * - * Maximum number of heap-allocated bytes for the purpose of - * DTLS handshake message reassembly and future message buffering. - * - * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN - * to account for a reassembled handshake message of maximum size, - * together with its reassembly bitmap. - * - * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) - * should be sufficient for all practical situations as it allows - * to reassembly a large handshake message (such as a certificate) - * while buffering multiple smaller handshake messages. - * - */ -//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 - -//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ -//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ -//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ - -/** - * Complete list of ciphersuites to use, in order of preference. - * - * \warning No dependency checking is done on that field! This option can only - * be used to restrict the set of available ciphersuites. It is your - * responsibility to make sure the needed modules are active. - * - * Use this to save a few hundred bytes of ROM (default ordering of all - * available ciphersuites) and a few to a few hundred bytes of RAM. - * - * The value below is only an example, not the default. - */ -//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - -/* X509 options */ -//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ -//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ - -/** - * Allow SHA-1 in the default TLS configuration for certificate signing. - * Without this build-time option, SHA-1 support must be activated explicitly - * through mbedtls_ssl_conf_cert_profile. Turning on this option is not - * recommended because of it is possible to generate SHA-1 collisions, however - * this may be safe for legacy infrastructure where additional controls apply. - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. If possible, we recommend avoiding dependencies - * on it, and considering stronger message digests instead. - * - */ -// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES - -/** - * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake - * signature and ciphersuite selection. Without this build-time option, SHA-1 - * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes. - * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by - * default. At the time of writing, there is no practical attack on the use - * of SHA-1 in handshake signatures, hence this option is turned on by default - * to preserve compatibility with existing peers, but the general - * warning applies nonetheless: - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. If possible, we recommend avoiding dependencies - * on it, and considering stronger message digests instead. - * - */ -#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE - -/** - * Uncomment the macro to let mbed TLS use your alternate implementation of - * mbedtls_platform_zeroize(). This replaces the default implementation in - * platform_util.c. - * - * mbedtls_platform_zeroize() is a widely used function across the library to - * zero a block of memory. The implementation is expected to be secure in the - * sense that it has been written to prevent the compiler from removing calls - * to mbedtls_platform_zeroize() as part of redundant code elimination - * optimizations. However, it is difficult to guarantee that calls to - * mbedtls_platform_zeroize() will not be optimized by the compiler as older - * versions of the C language standards do not provide a secure implementation - * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to - * configure their own implementation of mbedtls_platform_zeroize(), for - * example by using directives specific to their compiler, features from newer - * C standards (e.g using memset_s() in C11) or calling a secure memset() from - * their system (e.g explicit_bzero() in BSD). - */ -//#define MBEDTLS_PLATFORM_ZEROIZE_ALT - -/** - * Uncomment the macro to let Mbed TLS use your alternate implementation of - * mbedtls_platform_gmtime_r(). This replaces the default implementation in - * platform_util.c. - * - * gmtime() is not a thread-safe function as defined in the C standard. The - * library will try to use safer implementations of this function, such as - * gmtime_r() when available. However, if Mbed TLS cannot identify the target - * system, the implementation of mbedtls_platform_gmtime_r() will default to - * using the standard gmtime(). In this case, calls from the library to - * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex - * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the - * library are also guarded with this mutex to avoid race conditions. However, - * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will - * unconditionally use the implementation for mbedtls_platform_gmtime_r() - * supplied at compile time. - */ -//#define MBEDTLS_PLATFORM_GMTIME_R_ALT - -/* \} name SECTION: Customisation configuration options */ - -/* Target and application specific configurations - * - * Allow user to override any previous default. - * - */ -#if defined(MBEDTLS_USER_CONFIG_FILE) -#include MBEDTLS_USER_CONFIG_FILE -#endif - -#include "check_config.h" - -#endif /* MBEDTLS_CONFIG_H */ diff --git a/mbedtls/ctr_drbg.c b/mbedtls/ctr_drbg.c deleted file mode 100644 index 5d817faa1..000000000 --- a/mbedtls/ctr_drbg.c +++ /dev/null @@ -1,769 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The NIST SP 800-90 DRBGs are described in the following publication. - * - * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CTR_DRBG_C) - -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -/* - * CTR_DRBG context initialization - */ -void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) ); - - ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; -} - -/* - * This function resets CTR_DRBG context to the state immediately - * after initial call of mbedtls_ctr_drbg_init(). - */ -void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_THREADING_C) - /* The mutex is initialized iff f_entropy is set. */ - if( ctx->f_entropy != NULL ) - mbedtls_mutex_free( &ctx->mutex ); -#endif - mbedtls_aes_free( &ctx->aes_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) ); - ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; -} - -void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance ) -{ - ctx->prediction_resistance = resistance; -} - -void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len ) -{ - ctx->entropy_len = len; -} - -void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval ) -{ - ctx->reseed_interval = interval; -} - -static int block_cipher_df( unsigned char *output, - const unsigned char *data, size_t data_len ) -{ - unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16]; - unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; - unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; - unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; - unsigned char *p, *iv; - mbedtls_aes_context aes_ctx; - int ret = 0; - - int i, j; - size_t buf_len, use_len; - - if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) - return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); - - memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 ); - mbedtls_aes_init( &aes_ctx ); - - /* - * Construct IV (16 bytes) and S in buffer - * IV = Counter (in 32-bits) padded to 16 with zeroes - * S = Length input string (in 32-bits) || Length of output (in 32-bits) || - * data || 0x80 - * (Total is padded to a multiple of 16-bytes with zeroes) - */ - p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE; - *p++ = ( data_len >> 24 ) & 0xff; - *p++ = ( data_len >> 16 ) & 0xff; - *p++ = ( data_len >> 8 ) & 0xff; - *p++ = ( data_len ) & 0xff; - p += 3; - *p++ = MBEDTLS_CTR_DRBG_SEEDLEN; - memcpy( p, data, data_len ); - p[data_len] = 0x80; - - buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; - - for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ ) - key[i] = i; - - if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) - { - goto exit; - } - - /* - * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data - */ - for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) - { - p = buf; - memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE ); - use_len = buf_len; - - while( use_len > 0 ) - { - for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ ) - chain[i] ^= p[i]; - p += MBEDTLS_CTR_DRBG_BLOCKSIZE; - use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? - MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; - - if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 ) - { - goto exit; - } - } - - memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE ); - - /* - * Update IV - */ - buf[3]++; - } - - /* - * Do final encryption with reduced data - */ - if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) - { - goto exit; - } - iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; - p = output; - - for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) - { - if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 ) - { - goto exit; - } - memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE ); - p += MBEDTLS_CTR_DRBG_BLOCKSIZE; - } -exit: - mbedtls_aes_free( &aes_ctx ); - /* - * tidy up the stack - */ - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - mbedtls_platform_zeroize( key, sizeof( key ) ); - mbedtls_platform_zeroize( chain, sizeof( chain ) ); - if( 0 != ret ) - { - /* - * wipe partial seed from memory - */ - mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN ); - } - - return( ret ); -} - -/* CTR_DRBG_Update (SP 800-90A §10.2.1.2) - * ctr_drbg_update_internal(ctx, provided_data) - * implements - * CTR_DRBG_Update(provided_data, Key, V) - * with inputs and outputs - * ctx->aes_ctx = Key - * ctx->counter = V - */ -static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, - const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] ) -{ - unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; - unsigned char *p = tmp; - int i, j; - int ret = 0; - - memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); - - for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) - { - /* - * Increase counter - */ - for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) - if( ++ctx->counter[i - 1] != 0 ) - break; - - /* - * Crypt counter block - */ - if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 ) - goto exit; - - p += MBEDTLS_CTR_DRBG_BLOCKSIZE; - } - - for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ ) - tmp[i] ^= data[i]; - - /* - * Update key and counter - */ - if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) - goto exit; - memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE ); - -exit: - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - return( ret ); -} - -/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) - * mbedtls_ctr_drbg_update(ctx, additional, add_len) - * implements - * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, - * security_strength) -> initial_working_state - * with inputs - * ctx->counter = all-bits-0 - * ctx->aes_ctx = context from all-bits-0 key - * additional[:add_len] = entropy_input || nonce || personalization_string - * and with outputs - * ctx = initial_working_state - */ -int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ) -{ - unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; - int ret; - - if( add_len == 0 ) - return( 0 ); - - if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 ) - goto exit; - if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) - goto exit; - -exit: - mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ) -{ - /* MAX_INPUT would be more logical here, but we have to match - * block_cipher_df()'s limits since we can't propagate errors */ - if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) - add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT; - (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len ); -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2) - * mbedtls_ctr_drbg_reseed(ctx, additional, len) - * implements - * CTR_DRBG_Reseed(working_state, entropy_input, additional_input) - * -> new_working_state - * with inputs - * ctx contains working_state - * additional[:len] = additional_input - * and entropy_input comes from calling ctx->f_entropy - * and with output - * ctx contains new_working_state - */ -int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, size_t len ) -{ - unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; - size_t seedlen = 0; - int ret; - - if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || - len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) - return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); - - memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); - - /* - * Gather entropy_len bytes of entropy to seed state - */ - if( 0 != ctx->f_entropy( ctx->p_entropy, seed, - ctx->entropy_len ) ) - { - return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ); - } - - seedlen += ctx->entropy_len; - - /* - * Add additional data - */ - if( additional && len ) - { - memcpy( seed + seedlen, additional, len ); - seedlen += len; - } - - /* - * Reduce to 384 bits - */ - if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 ) - goto exit; - - /* - * Update state - */ - if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 ) - goto exit; - ctx->reseed_counter = 1; - -exit: - mbedtls_platform_zeroize( seed, sizeof( seed ) ); - return( ret ); -} - -/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) - * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len) - * implements - * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, - * security_strength) -> initial_working_state - * with inputs - * custom[:len] = nonce || personalization_string - * where entropy_input comes from f_entropy for ctx->entropy_len bytes - * and with outputs - * ctx = initial_working_state - */ -int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len ) -{ - int ret; - unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; - - memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE ); - - /* The mutex is initialized iff f_entropy is set. */ -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif - - mbedtls_aes_init( &ctx->aes_ctx ); - - ctx->f_entropy = f_entropy; - ctx->p_entropy = p_entropy; - - if( ctx->entropy_len == 0 ) - ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN; - - /* - * Initialize with an empty key - */ - if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) - { - return( ret ); - } - return( 0 ); -} - -/* Backward compatibility wrapper */ -int mbedtls_ctr_drbg_seed_entropy_len( - mbedtls_ctr_drbg_context *ctx, - int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy, - const unsigned char *custom, size_t len, - size_t entropy_len ) -{ - mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len ); - return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) ); -} - -/* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2) - * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len) - * implements - * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len]) - * -> working_state_after_reseed - * if required, then - * CTR_DRBG_Generate(working_state_after_reseed, - * requested_number_of_bits, additional_input) - * -> status, returned_bits, new_working_state - * with inputs - * ctx contains working_state - * requested_number_of_bits = 8 * output_len - * additional[:add_len] = additional_input - * and entropy_input comes from calling ctx->f_entropy - * and with outputs - * status = SUCCESS (this function does the reseed internally) - * returned_bits = output[:output_len] - * ctx contains new_working_state - */ -int mbedtls_ctr_drbg_random_with_add( void *p_rng, - unsigned char *output, size_t output_len, - const unsigned char *additional, size_t add_len ) -{ - int ret = 0; - mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; - unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; - unsigned char *p = output; - unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; - int i; - size_t use_len; - - if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST ) - return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG ); - - if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT ) - return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); - - memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); - - if( ctx->reseed_counter > ctx->reseed_interval || - ctx->prediction_resistance ) - { - if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) - { - return( ret ); - } - add_len = 0; - } - - if( add_len > 0 ) - { - if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 ) - goto exit; - if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) - goto exit; - } - - while( output_len > 0 ) - { - /* - * Increase counter - */ - for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) - if( ++ctx->counter[i - 1] != 0 ) - break; - - /* - * Crypt counter block - */ - if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 ) - goto exit; - - use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : - output_len; - /* - * Copy random block to destination - */ - memcpy( p, tmp, use_len ); - p += use_len; - output_len -= use_len; - } - - if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) - goto exit; - - ctx->reseed_counter++; - -exit: - mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - return( ret ); -} - -int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) -{ - int ret; - mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -#if defined(MBEDTLS_FS_IO) -int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) -{ - int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - FILE *f; - unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; - - if( ( f = fopen( path, "wb" ) ) == NULL ) - return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); - - if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 ) - goto exit; - - if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT ) - ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - else - ret = 0; - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - fclose( f ); - return( ret ); -} - -int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) -{ - int ret = 0; - FILE *f = NULL; - size_t n; - unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; - unsigned char c; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); - - n = fread( buf, 1, sizeof( buf ), f ); - if( fread( &c, 1, 1, f ) != 0 ) - { - ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - goto exit; - } - if( n == 0 || ferror( f ) ) - { - ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - goto exit; - } - fclose( f ); - f = NULL; - - ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n ); - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - if( f != NULL ) - fclose( f ); - if( ret != 0 ) - return( ret ); - return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) ); -} -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char entropy_source_pr[96] = - { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, - 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, - 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, - 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, - 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, - 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, - 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, - 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, - 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, - 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, - 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, - 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; - -static const unsigned char entropy_source_nopr[64] = - { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, - 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, - 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, - 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, - 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, - 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, - 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, - 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; - -static const unsigned char nonce_pers_pr[16] = - { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, - 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; - -static const unsigned char nonce_pers_nopr[16] = - { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, - 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; - -static const unsigned char result_pr[16] = - { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, - 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; - -static const unsigned char result_nopr[16] = - { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, - 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; - -static size_t test_offset; -static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, - size_t len ) -{ - const unsigned char *p = data; - memcpy( buf, p + test_offset, len ); - test_offset += len; - return( 0 ); -} - -#define CHK( c ) if( (c) != 0 ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf( "failed\n" ); \ - return( 1 ); \ - } - -/* - * Checkup routine - */ -int mbedtls_ctr_drbg_self_test( int verbose ) -{ - mbedtls_ctr_drbg_context ctx; - unsigned char buf[16]; - - mbedtls_ctr_drbg_init( &ctx ); - - /* - * Based on a NIST CTR_DRBG test vector (PR = True) - */ - if( verbose != 0 ) - mbedtls_printf( " CTR_DRBG (PR = TRUE) : " ); - - test_offset = 0; - mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 ); - CHK( mbedtls_ctr_drbg_seed( &ctx, - ctr_drbg_self_test_entropy, - (void *) entropy_source_pr, - nonce_pers_pr, 16 ) ); - mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); - CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); - CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); - CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); - - mbedtls_ctr_drbg_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - /* - * Based on a NIST CTR_DRBG test vector (PR = FALSE) - */ - if( verbose != 0 ) - mbedtls_printf( " CTR_DRBG (PR = FALSE): " ); - - mbedtls_ctr_drbg_init( &ctx ); - - test_offset = 0; - mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 ); - CHK( mbedtls_ctr_drbg_seed( &ctx, - ctr_drbg_self_test_entropy, - (void *) entropy_source_nopr, - nonce_pers_nopr, 16 ) ); - CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); - CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); - CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); - CHK( memcmp( buf, result_nopr, 16 ) ); - - mbedtls_ctr_drbg_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CTR_DRBG_C */ diff --git a/mbedtls/ctr_drbg.h b/mbedtls/ctr_drbg.h deleted file mode 100644 index a5e8d0aba..000000000 --- a/mbedtls/ctr_drbg.h +++ /dev/null @@ -1,585 +0,0 @@ -#pragma GCC system_header -/** - * \file ctr_drbg.h - * - * \brief This file contains definitions and functions for the - * CTR_DRBG pseudorandom generator. - * - * CTR_DRBG is a standardized way of building a PRNG from a block-cipher - * in counter mode operation, as defined in NIST SP 800-90A: - * Recommendation for Random Number Generation Using Deterministic Random - * Bit Generators. - * - * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 - * (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time) - * as the underlying block cipher, with a derivation function. - * The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy. - * See the documentation of mbedtls_ctr_drbg_seed() for more details. - * - * Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2, - * here are the security strengths achieved in typical configuration: - * - 256 bits under the default configuration of the library, with AES-256 - * and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. - * - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set - * to 32 or more, and the DRBG is initialized with an explicit - * nonce in the \c custom parameter to mbedtls_ctr_drbg_seed(). - * - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is - * between 24 and 47 and the DRBG is not initialized with an explicit - * nonce (see mbedtls_ctr_drbg_seed()). - * - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled) - * and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is - * always the case unless it is explicitly set to a different value - * in config.h). - * - * Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to: - * - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol - * \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time. - * This is the default configuration of the library. - * - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time. - * - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_CTR_DRBG_H -#define MBEDTLS_CTR_DRBG_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "aes.h" - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */ -#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< The requested random buffer length is too big. */ -#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< The input (entropy + additional data) is too large. */ -#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read or write error in file. */ - -#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */ - -#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -#define MBEDTLS_CTR_DRBG_KEYSIZE 16 -/**< The key size in bytes used by the cipher. - * - * Compile-time choice: 16 bytes (128 bits) - * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled. - */ -#else -#define MBEDTLS_CTR_DRBG_KEYSIZE 32 -/**< The key size in bytes used by the cipher. - * - * Compile-time choice: 32 bytes (256 bits) - * because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled. - */ -#endif - -#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */ -#define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */ - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them using the compiler command - * line. - * \{ - */ - -/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN - * - * \brief The amount of entropy used per seed by default, in bytes. - */ -#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) -#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) -/** This is 48 bytes because the entropy module uses SHA-512 - * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled). - */ -#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 - -#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ - -/** This is 32 bytes because the entropy module uses SHA-256 - * (the SHA512 module is disabled or - * \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled). - */ -#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -/** \warning To achieve a 256-bit security strength, you must pass a nonce - * to mbedtls_ctr_drbg_seed(). - */ -#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */ -#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 -#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ -#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */ - -#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) -#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 -/**< The interval before reseed is performed by default. */ -#endif - -#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT) -#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 -/**< The maximum number of additional input Bytes. */ -#endif - -#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST) -#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 -/**< The maximum number of requested Bytes per call. */ -#endif - -#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) -#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 -/**< The maximum size of seed or reseed buffer in bytes. */ -#endif - -/* \} name SECTION: Module settings */ - -#define MBEDTLS_CTR_DRBG_PR_OFF 0 -/**< Prediction resistance is disabled. */ -#define MBEDTLS_CTR_DRBG_PR_ON 1 -/**< Prediction resistance is enabled. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief The CTR_DRBG context structure. - */ -typedef struct mbedtls_ctr_drbg_context -{ - unsigned char counter[16]; /*!< The counter (V). */ - int reseed_counter; /*!< The reseed counter. */ - int prediction_resistance; /*!< This determines whether prediction - resistance is enabled, that is - whether to systematically reseed before - each random generation. */ - size_t entropy_len; /*!< The amount of entropy grabbed on each - seed or reseed operation. */ - int reseed_interval; /*!< The reseed interval. */ - - mbedtls_aes_context aes_ctx; /*!< The AES context. */ - - /* - * Callbacks (Entropy) - */ - int (*f_entropy)(void *, unsigned char *, size_t); - /*!< The entropy callback function. */ - - void *p_entropy; /*!< The context for the entropy function. */ - -#if defined(MBEDTLS_THREADING_C) - /* Invariant: the mutex is initialized if and only if f_entropy != NULL. - * This means that the mutex is initialized during the initial seeding - * in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free(). - * - * Note that this invariant may change without notice. Do not rely on it - * and do not access the mutex directly in application code. - */ - mbedtls_threading_mutex_t mutex; -#endif -} -mbedtls_ctr_drbg_context; - -/** - * \brief This function initializes the CTR_DRBG context, - * and prepares it for mbedtls_ctr_drbg_seed() - * or mbedtls_ctr_drbg_free(). - * - * \note The reseed interval is - * #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default. - * You can override it by calling - * mbedtls_ctr_drbg_set_reseed_interval(). - * - * \param ctx The CTR_DRBG context to initialize. - */ -void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); - -/** - * \brief This function seeds and sets up the CTR_DRBG - * entropy source for future reseeds. - * - * A typical choice for the \p f_entropy and \p p_entropy parameters is - * to use the entropy module: - * - \p f_entropy is mbedtls_entropy_func(); - * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized - * with mbedtls_entropy_init() (which registers the platform's default - * entropy sources). - * - * The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default. - * You can override it by calling mbedtls_ctr_drbg_set_entropy_len(). - * - * You can provide a personalization string in addition to the - * entropy source, to make this instantiation as unique as possible. - * - * \note The _seed_material_ value passed to the derivation - * function in the CTR_DRBG Instantiate Process - * described in NIST SP 800-90A §10.2.1.3.2 - * is the concatenation of the string obtained from - * calling \p f_entropy and the \p custom string. - * The origin of the nonce depends on the value of - * the entropy length relative to the security strength. - * - If the entropy length is at least 1.5 times the - * security strength then the nonce is taken from the - * string obtained with \p f_entropy. - * - If the entropy length is less than the security - * strength, then the nonce is taken from \p custom. - * In this case, for compliance with SP 800-90A, - * you must pass a unique value of \p custom at - * each invocation. See SP 800-90A §8.6.7 for more - * details. - */ -#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 -/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than - * #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the - * maximum security strength permitted by CTR_DRBG, - * you must pass a value of \p custom that is a nonce: - * this value must never be repeated in subsequent - * runs of the same application or on a different - * device. - */ -#endif -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * after this function returns successfully, - * it is safe to call mbedtls_ctr_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * \param ctx The CTR_DRBG context to seed. - * It must have been initialized with - * mbedtls_ctr_drbg_init(). - * After a successful call to mbedtls_ctr_drbg_seed(), - * you may not call mbedtls_ctr_drbg_seed() again on - * the same context unless you call - * mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init() - * again first. - * After a failed call to mbedtls_ctr_drbg_seed(), - * you must call mbedtls_ctr_drbg_free(). - * \param f_entropy The entropy callback, taking as arguments the - * \p p_entropy context, the buffer to fill, and the - * length of the buffer. - * \p f_entropy is always called with a buffer size - * equal to the entropy length. - * \param p_entropy The entropy context to pass to \p f_entropy. - * \param custom The personalization string. - * This can be \c NULL, in which case the personalization - * string is empty regardless of the value of \p len. - * \param len The length of the personalization string. - * This must be at most - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - * - #MBEDTLS_CTR_DRBG_ENTROPY_LEN. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. - */ -int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len ); - -/** - * \brief This function resets CTR_DRBG context to the state immediately - * after initial call of mbedtls_ctr_drbg_init(). - * - * \param ctx The CTR_DRBG context to clear. - */ -void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ); - -/** - * \brief This function turns prediction resistance on or off. - * The default value is off. - * - * \note If enabled, entropy is gathered at the beginning of - * every call to mbedtls_ctr_drbg_random_with_add() - * or mbedtls_ctr_drbg_random(). - * Only use this if your entropy source has sufficient - * throughput. - * - * \param ctx The CTR_DRBG context. - * \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF. - */ -void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, - int resistance ); - -/** - * \brief This function sets the amount of entropy grabbed on each - * seed or reseed. - * - * The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN. - * - * \note The security strength of CTR_DRBG is bounded by the - * entropy length. Thus: - * - When using AES-256 - * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled, - * which is the default), - * \p len must be at least 32 (in bytes) - * to achieve a 256-bit strength. - * - When using AES-128 - * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled) - * \p len must be at least 16 (in bytes) - * to achieve a 128-bit strength. - * - * \param ctx The CTR_DRBG context. - * \param len The amount of entropy to grab, in bytes. - * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. - */ -void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, - size_t len ); - -/** - * \brief This function sets the reseed interval. - * - * The reseed interval is the number of calls to mbedtls_ctr_drbg_random() - * or mbedtls_ctr_drbg_random_with_add() after which the entropy function - * is called again. - * - * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. - * - * \param ctx The CTR_DRBG context. - * \param interval The reseed interval. - */ -void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, - int interval ); - -/** - * \brief This function reseeds the CTR_DRBG context, that is - * extracts data from the entropy source. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param ctx The CTR_DRBG context. - * \param additional Additional data to add to the state. Can be \c NULL. - * \param len The length of the additional data. - * This must be less than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len - * where \c entropy_len is the entropy length - * configured for the context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. - */ -int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, size_t len ); - -/** - * \brief This function updates the state of the CTR_DRBG context. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param ctx The CTR_DRBG context. - * \param additional The data to update the state with. This must not be - * \c NULL unless \p add_len is \c 0. - * \param add_len Length of \p additional in bytes. This must be at - * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if - * \p add_len is more than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. - * \return An error from the underlying AES cipher on failure. - */ -int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ); - -/** - * \brief This function updates a CTR_DRBG instance with additional - * data and uses it to generate random data. - * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param p_rng The CTR_DRBG context. This must be a pointer to a - * #mbedtls_ctr_drbg_context structure. - * \param output The buffer to fill. - * \param output_len The length of the buffer in bytes. - * \param additional Additional data to update. Can be \c NULL, in which - * case the additional data is empty regardless of - * the value of \p add_len. - * \param add_len The length of the additional data - * if \p additional is not \c NULL. - * This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT - * and less than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len - * where \c entropy_len is the entropy length - * configured for the context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or - * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. - */ -int mbedtls_ctr_drbg_random_with_add( void *p_rng, - unsigned char *output, size_t output_len, - const unsigned char *additional, size_t add_len ); - -/** - * \brief This function uses CTR_DRBG to generate random data. - * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. - */ -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * it is safe to call mbedtls_ctr_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * \param p_rng The CTR_DRBG context. This must be a pointer to a - * #mbedtls_ctr_drbg_context structure. - * \param output The buffer to fill. - * \param output_len The length of the buffer in bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or - * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. - */ -int mbedtls_ctr_drbg_random( void *p_rng, - unsigned char *output, size_t output_len ); - - -#if ! defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function updates the state of the CTR_DRBG context. - * - * \disabled_deprecated Superseded by mbedtls_ctr_drbg_update_ret() - * in 2.16.0. - * - * \note If \p add_len is greater than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used. - * The remaining Bytes are silently discarded. - * - * \param ctx The CTR_DRBG context. - * \param additional The data to update the state with. - * \param add_len Length of \p additional data. - */ -MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update( - mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ); -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_FS_IO) -/** - * \brief This function writes a seed file. - * - * \param ctx The CTR_DRBG context. - * \param path The name of the file. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed - * failure. - */ -int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); - -/** - * \brief This function reads and updates a seed file. The seed - * is added to this instance. - * - * \param ctx The CTR_DRBG context. - * \param path The name of the file. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on - * reseed failure. - * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing - * seed file is too large. - */ -int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The CTR_DRBG checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_ctr_drbg_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -/* Internal functions (do not call directly) */ -int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *, - int (*)(void *, unsigned char *, size_t), void *, - const unsigned char *, size_t, size_t ); - -#ifdef __cplusplus -} -#endif - -#endif /* ctr_drbg.h */ diff --git a/mbedtls/debug.c b/mbedtls/debug.c deleted file mode 100644 index 4fe7c32bd..000000000 --- a/mbedtls/debug.c +++ /dev/null @@ -1,476 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Debugging routines - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_DEBUG_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#define mbedtls_time_t time_t -#define mbedtls_snprintf snprintf -#endif - -#include "mbedtls/debug.h" - -#include -#include -#include - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#define DEBUG_BUF_SIZE 512 - -static int debug_threshold = 0; - -void mbedtls_debug_set_threshold( int threshold ) -{ - debug_threshold = threshold; -} - -/* - * All calls to f_dbg must be made via this function - */ -static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *str ) -{ - /* - * If in a threaded environment, we need a thread identifier. - * Since there is no portable way to get one, use the address of the ssl - * context instead, as it shouldn't be shared between threads. - */ -#if defined(MBEDTLS_THREADING_C) - char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */ - mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void*)ssl, str ); - ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr ); -#else - ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str ); -#endif -} - -void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *format, ... ) -{ - va_list argp; - char str[DEBUG_BUF_SIZE]; - int ret; - - if( NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold ) - { - return; - } - - va_start( argp, format ); -#if defined(_WIN32) -#if defined(_TRUNCATE) && !defined(__MINGW32__) - ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp ); -#else - ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); - if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE ) - { - str[DEBUG_BUF_SIZE-1] = '\0'; - ret = -1; - } -#endif -#else - ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); -#endif - va_end( argp ); - - if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 ) - { - str[ret] = '\n'; - str[ret + 1] = '\0'; - } - - debug_send_line( ssl, level, file, line, str ); -} - -void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, int ret ) -{ - char str[DEBUG_BUF_SIZE]; - - if( NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold ) - { - return; - } - - /* - * With non-blocking I/O and examples that just retry immediately, - * the logs would be quickly flooded with WANT_READ, so ignore that. - * Don't ignore WANT_WRITE however, since is is usually rare. - */ - if( ret == MBEDTLS_ERR_SSL_WANT_READ ) - return; - - mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n", - text, ret, -ret ); - - debug_send_line( ssl, level, file, line, str ); -} - -void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, const char *text, - const unsigned char *buf, size_t len ) -{ - char str[DEBUG_BUF_SIZE]; - char txt[17]; - size_t i, idx = 0; - - if( NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold ) - { - return; - } - - mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n", - text, (unsigned int) len ); - - debug_send_line( ssl, level, file, line, str ); - - idx = 0; - memset( txt, 0, sizeof( txt ) ); - for( i = 0; i < len; i++ ) - { - if( i >= 4096 ) - break; - - if( i % 16 == 0 ) - { - if( i > 0 ) - { - mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt ); - debug_send_line( ssl, level, file, line, str ); - - idx = 0; - memset( txt, 0, sizeof( txt ) ); - } - - idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "%04x: ", - (unsigned int) i ); - - } - - idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", - (unsigned int) buf[i] ); - txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ; - } - - if( len > 0 ) - { - for( /* i = i */; i % 16 != 0; i++ ) - idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " " ); - - mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt ); - debug_send_line( ssl, level, file, line, str ); - } -} - -#if defined(MBEDTLS_ECP_C) -void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_ecp_point *X ) -{ - char str[DEBUG_BUF_SIZE]; - - if( NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold ) - { - return; - } - - mbedtls_snprintf( str, sizeof( str ), "%s(X)", text ); - mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X ); - - mbedtls_snprintf( str, sizeof( str ), "%s(Y)", text ); - mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y ); -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_BIGNUM_C) -void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_mpi *X ) -{ - char str[DEBUG_BUF_SIZE]; - size_t bitlen; - size_t idx = 0; - - if( NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - NULL == X || - level > debug_threshold ) - { - return; - } - - bitlen = mbedtls_mpi_bitlen( X ); - - mbedtls_snprintf( str, sizeof( str ), "value of '%s' (%u bits) is:\n", - text, (unsigned) bitlen ); - debug_send_line( ssl, level, file, line, str ); - - if( bitlen == 0 ) - { - str[0] = ' '; str[1] = '0'; str[2] = '0'; - idx = 3; - } - else - { - int n; - for( n = (int) ( ( bitlen - 1 ) / 8 ); n >= 0; n-- ) - { - size_t limb_offset = n / sizeof( mbedtls_mpi_uint ); - size_t offset_in_limb = n % sizeof( mbedtls_mpi_uint ); - unsigned char octet = - ( X->p[limb_offset] >> ( offset_in_limb * 8 ) ) & 0xff; - mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", octet ); - idx += 3; - /* Wrap lines after 16 octets that each take 3 columns */ - if( idx >= 3 * 16 ) - { - mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" ); - debug_send_line( ssl, level, file, line, str ); - idx = 0; - } - } - } - - if( idx != 0 ) - { - mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" ); - debug_send_line( ssl, level, file, line, str ); - } -} -#endif /* MBEDTLS_BIGNUM_C */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static void debug_print_pk( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_pk_context *pk ) -{ - size_t i; - mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS]; - char name[16]; - - memset( items, 0, sizeof( items ) ); - - if( mbedtls_pk_debug( pk, items ) != 0 ) - { - debug_send_line( ssl, level, file, line, - "invalid PK context\n" ); - return; - } - - for( i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++ ) - { - if( items[i].type == MBEDTLS_PK_DEBUG_NONE ) - return; - - mbedtls_snprintf( name, sizeof( name ), "%s%s", text, items[i].name ); - name[sizeof( name ) - 1] = '\0'; - - if( items[i].type == MBEDTLS_PK_DEBUG_MPI ) - mbedtls_debug_print_mpi( ssl, level, file, line, name, items[i].value ); - else -#if defined(MBEDTLS_ECP_C) - if( items[i].type == MBEDTLS_PK_DEBUG_ECP ) - mbedtls_debug_print_ecp( ssl, level, file, line, name, items[i].value ); - else -#endif - debug_send_line( ssl, level, file, line, - "should not happen\n" ); - } -} - -static void debug_print_line_by_line( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, const char *text ) -{ - char str[DEBUG_BUF_SIZE]; - const char *start, *cur; - - start = text; - for( cur = text; *cur != '\0'; cur++ ) - { - if( *cur == '\n' ) - { - size_t len = cur - start + 1; - if( len > DEBUG_BUF_SIZE - 1 ) - len = DEBUG_BUF_SIZE - 1; - - memcpy( str, start, len ); - str[len] = '\0'; - - debug_send_line( ssl, level, file, line, str ); - - start = cur + 1; - } - } -} - -void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_x509_crt *crt ) -{ - char str[DEBUG_BUF_SIZE]; - int i = 0; - - if( NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - NULL == crt || - level > debug_threshold ) - { - return; - } - - while( crt != NULL ) - { - char buf[1024]; - - mbedtls_snprintf( str, sizeof( str ), "%s #%d:\n", text, ++i ); - debug_send_line( ssl, level, file, line, str ); - - mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt ); - debug_print_line_by_line( ssl, level, file, line, buf ); - - debug_print_pk( ssl, level, file, line, "crt->", &crt->pk ); - - crt = crt->next; - } -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_ECDH_C) -static void mbedtls_debug_printf_ecdh_internal( const mbedtls_ssl_context *ssl, - int level, const char *file, - int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr ) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - const mbedtls_ecdh_context* ctx = ecdh; -#else - const mbedtls_ecdh_context_mbed* ctx = &ecdh->ctx.mbed_ecdh; -#endif - - switch( attr ) - { - case MBEDTLS_DEBUG_ECDH_Q: - mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Q", - &ctx->Q ); - break; - case MBEDTLS_DEBUG_ECDH_QP: - mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Qp", - &ctx->Qp ); - break; - case MBEDTLS_DEBUG_ECDH_Z: - mbedtls_debug_print_mpi( ssl, level, file, line, "ECDH: z", - &ctx->z ); - break; - default: - break; - } -} - -void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr ) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, attr ); -#else - switch( ecdh->var ) - { - default: - mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, - attr ); - } -#endif -} -#endif /* MBEDTLS_ECDH_C */ - -#endif /* MBEDTLS_DEBUG_C */ diff --git a/mbedtls/debug.h b/mbedtls/debug.h deleted file mode 100644 index 45bb3e0cd..000000000 --- a/mbedtls/debug.h +++ /dev/null @@ -1,291 +0,0 @@ -#pragma GCC system_header -/** - * \file debug.h - * - * \brief Functions for controlling and providing debug output from the library. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_DEBUG_H -#define MBEDTLS_DEBUG_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#if defined(MBEDTLS_ECP_C) -#include "ecp.h" -#endif - -#if defined(MBEDTLS_DEBUG_C) - -#define MBEDTLS_DEBUG_STRIP_PARENS( ... ) __VA_ARGS__ - -#define MBEDTLS_SSL_DEBUG_MSG( level, args ) \ - mbedtls_debug_print_msg( ssl, level, __FILE__, __LINE__, \ - MBEDTLS_DEBUG_STRIP_PARENS args ) - -#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) \ - mbedtls_debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret ) - -#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) \ - mbedtls_debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len ) - -#if defined(MBEDTLS_BIGNUM_C) -#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) \ - mbedtls_debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X ) -#endif - -#if defined(MBEDTLS_ECP_C) -#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) \ - mbedtls_debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X ) -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) \ - mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt ) -#endif - -#if defined(MBEDTLS_ECDH_C) -#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) \ - mbedtls_debug_printf_ecdh( ssl, level, __FILE__, __LINE__, ecdh, attr ) -#endif - -#else /* MBEDTLS_DEBUG_C */ - -#define MBEDTLS_SSL_DEBUG_MSG( level, args ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) do { } while( 0 ) - -#endif /* MBEDTLS_DEBUG_C */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Set the threshold error level to handle globally all debug output. - * Debug messages that have a level over the threshold value are - * discarded. - * (Default value: 0 = No debug ) - * - * \param threshold theshold level of messages to filter on. Messages at a - * higher level will be discarded. - * - Debug levels - * - 0 No debug - * - 1 Error - * - 2 State change - * - 3 Informational - * - 4 Verbose - */ -void mbedtls_debug_set_threshold( int threshold ); - -/** - * \brief Print a message to the debug output. This function is always used - * through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl - * context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the message has occurred in - * \param line line number the message has occurred at - * \param format format specifier, in printf format - * \param ... variables used by the format specifier - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *format, ... ); - -/** - * \brief Print the return value of a function to the debug output. This - * function is always used through the MBEDTLS_SSL_DEBUG_RET() macro, - * which supplies the ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text the name of the function that returned the error - * \param ret the return code value - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, int ret ); - -/** - * \brief Output a buffer of size len bytes to the debug output. This function - * is always used through the MBEDTLS_SSL_DEBUG_BUF() macro, - * which supplies the ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the buffer being dumped. Normally the - * variable or buffer name - * \param buf the buffer to be outputted - * \param len length of the buffer - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, const char *text, - const unsigned char *buf, size_t len ); - -#if defined(MBEDTLS_BIGNUM_C) -/** - * \brief Print a MPI variable to the debug output. This function is always - * used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the - * ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the MPI being output. Normally the - * variable name - * \param X the MPI variable - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_mpi *X ); -#endif - -#if defined(MBEDTLS_ECP_C) -/** - * \brief Print an ECP point to the debug output. This function is always - * used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the - * ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the ECP point being output. Normally the - * variable name - * \param X the ECP point - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_ecp_point *X ); -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Print a X.509 certificate structure to the debug output. This - * function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro, - * which supplies the ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the certificate being output - * \param crt X.509 certificate structure - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_x509_crt *crt ); -#endif - -#if defined(MBEDTLS_ECDH_C) -typedef enum -{ - MBEDTLS_DEBUG_ECDH_Q, - MBEDTLS_DEBUG_ECDH_QP, - MBEDTLS_DEBUG_ECDH_Z, -} mbedtls_debug_ecdh_attr; - -/** - * \brief Print a field of the ECDH structure in the SSL context to the debug - * output. This function is always used through the - * MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file - * and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param ecdh the ECDH context - * \param attr the identifier of the attribute being output - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* debug.h */ - diff --git a/mbedtls/des.c b/mbedtls/des.c deleted file mode 100644 index 1bd7024f9..000000000 --- a/mbedtls/des.c +++ /dev/null @@ -1,1102 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * FIPS-46-3 compliant Triple-DES implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * DES, on which TDES is based, was originally designed by Horst Feistel - * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). - * - * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_DES_C) - -#include "mbedtls/des.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_DES_ALT) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * Expanded DES S-boxes - */ -static const uint32_t SB1[64] = -{ - 0x01010400, 0x00000000, 0x00010000, 0x01010404, - 0x01010004, 0x00010404, 0x00000004, 0x00010000, - 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, - 0x00000404, 0x01000400, 0x01000400, 0x00010400, - 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, - 0x00000000, 0x00000404, 0x00010404, 0x01000000, - 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, - 0x01010004, 0x00010000, 0x00010400, 0x01000004, - 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, - 0x01000004, 0x00000404, 0x00010404, 0x01010400, - 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004 -}; - -static const uint32_t SB2[64] = -{ - 0x80108020, 0x80008000, 0x00008000, 0x00108020, - 0x00100000, 0x00000020, 0x80100020, 0x80008020, - 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, - 0x00108000, 0x00100020, 0x80008020, 0x00000000, - 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, - 0x00008020, 0x80108000, 0x80100000, 0x00008020, - 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, - 0x80100000, 0x80008000, 0x00000020, 0x80108020, - 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, - 0x00100020, 0x80008020, 0x80000020, 0x00100020, - 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000 -}; - -static const uint32_t SB3[64] = -{ - 0x00000208, 0x08020200, 0x00000000, 0x08020008, - 0x08000200, 0x00000000, 0x00020208, 0x08000200, - 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, - 0x08000000, 0x00000008, 0x08020200, 0x00000200, - 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, - 0x00000008, 0x08020208, 0x00000200, 0x08000000, - 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, - 0x00000200, 0x00020008, 0x08020208, 0x08000200, - 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, - 0x00000008, 0x00020208, 0x00020200, 0x08000008, - 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200 -}; - -static const uint32_t SB4[64] = -{ - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802080, 0x00800081, 0x00800001, 0x00002001, - 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, - 0x00000001, 0x00002000, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, - 0x00002000, 0x00802080, 0x00802081, 0x00000081, - 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, - 0x00002080, 0x00800080, 0x00800081, 0x00000001, - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, - 0x00800001, 0x00002001, 0x00802080, 0x00800081, - 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080 -}; - -static const uint32_t SB5[64] = -{ - 0x00000100, 0x02080100, 0x02080000, 0x42000100, - 0x00080000, 0x00000100, 0x40000000, 0x02080000, - 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, - 0x02000000, 0x40080000, 0x40080000, 0x00000000, - 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, - 0x02080100, 0x02000000, 0x42000000, 0x00080100, - 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, - 0x02000100, 0x40000000, 0x42080000, 0x02080100, - 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, - 0x02080000, 0x00000000, 0x40080000, 0x42000000, - 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100 -}; - -static const uint32_t SB6[64] = -{ - 0x20000010, 0x20400000, 0x00004000, 0x20404010, - 0x20400000, 0x00000010, 0x20404010, 0x00400000, - 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, - 0x00000000, 0x00400010, 0x20004010, 0x00004000, - 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, - 0x00004010, 0x00404000, 0x20404000, 0x20000000, - 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, - 0x00400000, 0x20004000, 0x20000000, 0x00004010, - 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, - 0x00000010, 0x00004000, 0x20400000, 0x00404010, - 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010 -}; - -static const uint32_t SB7[64] = -{ - 0x00200000, 0x04200002, 0x04000802, 0x00000000, - 0x00000800, 0x04000802, 0x00200802, 0x04200800, - 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, - 0x04000800, 0x00200802, 0x00200002, 0x04000800, - 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, - 0x00200800, 0x00000002, 0x04000000, 0x00200800, - 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, - 0x00200002, 0x04000000, 0x04000800, 0x00200000, - 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, - 0x00200800, 0x00000000, 0x00000002, 0x04200802, - 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002 -}; - -static const uint32_t SB8[64] = -{ - 0x10001040, 0x00001000, 0x00040000, 0x10041040, - 0x10000000, 0x10001040, 0x00000040, 0x10000000, - 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, - 0x10040000, 0x10000040, 0x10001000, 0x00001040, - 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, - 0x10000040, 0x10001000, 0x00041040, 0x00040000, - 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, - 0x10001000, 0x00000040, 0x10000040, 0x10040000, - 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, - 0x10040000, 0x10001000, 0x10001040, 0x00000000, - 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000 -}; - -/* - * PC1: left and right halves bit-swap - */ -static const uint32_t LHs[16] = -{ - 0x00000000, 0x00000001, 0x00000100, 0x00000101, - 0x00010000, 0x00010001, 0x00010100, 0x00010101, - 0x01000000, 0x01000001, 0x01000100, 0x01000101, - 0x01010000, 0x01010001, 0x01010100, 0x01010101 -}; - -static const uint32_t RHs[16] = -{ - 0x00000000, 0x01000000, 0x00010000, 0x01010000, - 0x00000100, 0x01000100, 0x00010100, 0x01010100, - 0x00000001, 0x01000001, 0x00010001, 0x01010001, - 0x00000101, 0x01000101, 0x00010101, 0x01010101, -}; - -/* - * Initial Permutation macro - */ -#define DES_IP(X,Y) \ - do \ - { \ - T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ - T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ - T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ - T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ - (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \ - T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \ - (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \ - } while( 0 ) - -/* - * Final Permutation macro - */ -#define DES_FP(X,Y) \ - do \ - { \ - (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \ - T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \ - (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \ - T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ - T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ - T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ - T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ - } while( 0 ) - -/* - * DES round macro - */ -#define DES_ROUND(X,Y) \ - do \ - { \ - T = *SK++ ^ (X); \ - (Y) ^= SB8[ (T ) & 0x3F ] ^ \ - SB6[ (T >> 8) & 0x3F ] ^ \ - SB4[ (T >> 16) & 0x3F ] ^ \ - SB2[ (T >> 24) & 0x3F ]; \ - \ - T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \ - (Y) ^= SB7[ (T ) & 0x3F ] ^ \ - SB5[ (T >> 8) & 0x3F ] ^ \ - SB3[ (T >> 16) & 0x3F ] ^ \ - SB1[ (T >> 24) & 0x3F ]; \ - } while( 0 ) - -#define SWAP(a,b) \ - do \ - { \ - uint32_t t = (a); (a) = (b); (b) = t; t = 0; \ - } while( 0 ) - -void mbedtls_des_init( mbedtls_des_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_des_context ) ); -} - -void mbedtls_des_free( mbedtls_des_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) ); -} - -void mbedtls_des3_init( mbedtls_des3_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_des3_context ) ); -} - -void mbedtls_des3_free( mbedtls_des3_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) ); -} - -static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, - 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44, - 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81, - 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112, - 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140, - 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168, - 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196, - 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224, - 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253, - 254 }; - -void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] ) -{ - int i; - - for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ ) - key[i] = odd_parity_table[key[i] / 2]; -} - -/* - * Check the given key's parity, returns 1 on failure, 0 on SUCCESS - */ -int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) -{ - int i; - - for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ ) - if( key[i] != odd_parity_table[key[i] / 2] ) - return( 1 ); - - return( 0 ); -} - -/* - * Table of weak and semi-weak keys - * - * Source: http://en.wikipedia.org/wiki/Weak_key - * - * Weak: - * Alternating ones + zeros (0x0101010101010101) - * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) - * '0xE0E0E0E0F1F1F1F1' - * '0x1F1F1F1F0E0E0E0E' - * - * Semi-weak: - * 0x011F011F010E010E and 0x1F011F010E010E01 - * 0x01E001E001F101F1 and 0xE001E001F101F101 - * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 - * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E - * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E - * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 - * - */ - -#define WEAK_KEY_COUNT 16 - -static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] = -{ - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, - { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, - { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, - { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, - - { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, - { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, - { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, - { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, - { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, - { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, - { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, - { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, - { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, - { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, - { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, - { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } -}; - -int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) -{ - int i; - - for( i = 0; i < WEAK_KEY_COUNT; i++ ) - if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 ) - return( 1 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DES_SETKEY_ALT) -void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) -{ - int i; - uint32_t X, Y, T; - - GET_UINT32_BE( X, key, 0 ); - GET_UINT32_BE( Y, key, 4 ); - - /* - * Permuted Choice 1 - */ - T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); - T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); - - X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) - | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) - | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) - | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); - - Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) - | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) - | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) - | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); - - X &= 0x0FFFFFFF; - Y &= 0x0FFFFFFF; - - /* - * calculate subkeys - */ - for( i = 0; i < 16; i++ ) - { - if( i < 2 || i == 8 || i == 15 ) - { - X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; - Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; - } - else - { - X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; - Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; - } - - *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) - | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) - | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) - | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) - | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) - | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) - | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) - | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) - | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) - | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) - | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); - - *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) - | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) - | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) - | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) - | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) - | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) - | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) - | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) - | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) - | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) - | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); - } -} -#endif /* !MBEDTLS_DES_SETKEY_ALT */ - -/* - * DES key schedule (56-bit, encryption) - */ -int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) -{ - mbedtls_des_setkey( ctx->sk, key ); - - return( 0 ); -} - -/* - * DES key schedule (56-bit, decryption) - */ -int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) -{ - int i; - - mbedtls_des_setkey( ctx->sk, key ); - - for( i = 0; i < 16; i += 2 ) - { - SWAP( ctx->sk[i ], ctx->sk[30 - i] ); - SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); - } - - return( 0 ); -} - -static void des3_set2key( uint32_t esk[96], - uint32_t dsk[96], - const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] ) -{ - int i; - - mbedtls_des_setkey( esk, key ); - mbedtls_des_setkey( dsk + 32, key + 8 ); - - for( i = 0; i < 32; i += 2 ) - { - dsk[i ] = esk[30 - i]; - dsk[i + 1] = esk[31 - i]; - - esk[i + 32] = dsk[62 - i]; - esk[i + 33] = dsk[63 - i]; - - esk[i + 64] = esk[i ]; - esk[i + 65] = esk[i + 1]; - - dsk[i + 64] = dsk[i ]; - dsk[i + 65] = dsk[i + 1]; - } -} - -/* - * Triple-DES key schedule (112-bit, encryption) - */ -int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ) -{ - uint32_t sk[96]; - - des3_set2key( ctx->sk, sk, key ); - mbedtls_platform_zeroize( sk, sizeof( sk ) ); - - return( 0 ); -} - -/* - * Triple-DES key schedule (112-bit, decryption) - */ -int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ) -{ - uint32_t sk[96]; - - des3_set2key( sk, ctx->sk, key ); - mbedtls_platform_zeroize( sk, sizeof( sk ) ); - - return( 0 ); -} - -static void des3_set3key( uint32_t esk[96], - uint32_t dsk[96], - const unsigned char key[24] ) -{ - int i; - - mbedtls_des_setkey( esk, key ); - mbedtls_des_setkey( dsk + 32, key + 8 ); - mbedtls_des_setkey( esk + 64, key + 16 ); - - for( i = 0; i < 32; i += 2 ) - { - dsk[i ] = esk[94 - i]; - dsk[i + 1] = esk[95 - i]; - - esk[i + 32] = dsk[62 - i]; - esk[i + 33] = dsk[63 - i]; - - dsk[i + 64] = esk[30 - i]; - dsk[i + 65] = esk[31 - i]; - } -} - -/* - * Triple-DES key schedule (168-bit, encryption) - */ -int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) -{ - uint32_t sk[96]; - - des3_set3key( ctx->sk, sk, key ); - mbedtls_platform_zeroize( sk, sizeof( sk ) ); - - return( 0 ); -} - -/* - * Triple-DES key schedule (168-bit, decryption) - */ -int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) -{ - uint32_t sk[96]; - - des3_set3key( sk, ctx->sk, key ); - mbedtls_platform_zeroize( sk, sizeof( sk ) ); - - return( 0 ); -} - -/* - * DES-ECB block encryption/decryption - */ -#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT) -int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx, - const unsigned char input[8], - unsigned char output[8] ) -{ - int i; - uint32_t X, Y, T, *SK; - - SK = ctx->sk; - - GET_UINT32_BE( X, input, 0 ); - GET_UINT32_BE( Y, input, 4 ); - - DES_IP( X, Y ); - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( Y, X ); - DES_ROUND( X, Y ); - } - - DES_FP( Y, X ); - - PUT_UINT32_BE( Y, output, 0 ); - PUT_UINT32_BE( X, output, 4 ); - - return( 0 ); -} -#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * DES-CBC buffer encryption/decryption - */ -int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[8]; - - if( length % 8 ) - return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_DES_ENCRYPT ) - { - while( length > 0 ) - { - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_des_crypt_ecb( ctx, output, output ); - memcpy( iv, output, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } - else /* MBEDTLS_DES_DECRYPT */ - { - while( length > 0 ) - { - memcpy( temp, input, 8 ); - mbedtls_des_crypt_ecb( ctx, input, output ); - - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -/* - * 3DES-ECB block encryption/decryption - */ -#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT) -int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx, - const unsigned char input[8], - unsigned char output[8] ) -{ - int i; - uint32_t X, Y, T, *SK; - - SK = ctx->sk; - - GET_UINT32_BE( X, input, 0 ); - GET_UINT32_BE( Y, input, 4 ); - - DES_IP( X, Y ); - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( Y, X ); - DES_ROUND( X, Y ); - } - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( X, Y ); - DES_ROUND( Y, X ); - } - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( Y, X ); - DES_ROUND( X, Y ); - } - - DES_FP( Y, X ); - - PUT_UINT32_BE( Y, output, 0 ); - PUT_UINT32_BE( X, output, 4 ); - - return( 0 ); -} -#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * 3DES-CBC buffer encryption/decryption - */ -int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[8]; - - if( length % 8 ) - return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_DES_ENCRYPT ) - { - while( length > 0 ) - { - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_des3_crypt_ecb( ctx, output, output ); - memcpy( iv, output, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } - else /* MBEDTLS_DES_DECRYPT */ - { - while( length > 0 ) - { - memcpy( temp, input, 8 ); - mbedtls_des3_crypt_ecb( ctx, input, output ); - - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#endif /* !MBEDTLS_DES_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * DES and 3DES test vectors from: - * - * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip - */ -static const unsigned char des3_test_keys[24] = -{ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, - 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 -}; - -static const unsigned char des3_test_buf[8] = -{ - 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 -}; - -static const unsigned char des3_test_ecb_dec[3][8] = -{ - { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D }, - { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB }, - { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A } -}; - -static const unsigned char des3_test_ecb_enc[3][8] = -{ - { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B }, - { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 }, - { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const unsigned char des3_test_iv[8] = -{ - 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, -}; - -static const unsigned char des3_test_cbc_dec[3][8] = -{ - { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, - { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 }, - { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C } -}; - -static const unsigned char des3_test_cbc_enc[3][8] = -{ - { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 }, - { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, - { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -/* - * Checkup routine - */ -int mbedtls_des_self_test( int verbose ) -{ - int i, j, u, v, ret = 0; - mbedtls_des_context ctx; - mbedtls_des3_context ctx3; - unsigned char buf[8]; -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char prv[8]; - unsigned char iv[8]; -#endif - - mbedtls_des_init( &ctx ); - mbedtls_des3_init( &ctx3 ); - /* - * ECB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " DES%c-ECB-%3d (%s): ", - ( u == 0 ) ? ' ' : '3', 56 + u * 56, - ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( buf, des3_test_buf, 8 ); - - switch( i ) - { - case 0: - mbedtls_des_setkey_dec( &ctx, des3_test_keys ); - break; - - case 1: - mbedtls_des_setkey_enc( &ctx, des3_test_keys ); - break; - - case 2: - mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); - break; - - case 3: - mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); - break; - - case 4: - mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); - break; - - case 5: - mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); - break; - - default: - return( 1 ); - } - - for( j = 0; j < 10000; j++ ) - { - if( u == 0 ) - mbedtls_des_crypt_ecb( &ctx, buf, buf ); - else - mbedtls_des3_crypt_ecb( &ctx3, buf, buf ); - } - - if( ( v == MBEDTLS_DES_DECRYPT && - memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || - ( v != MBEDTLS_DES_DECRYPT && - memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /* - * CBC mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " DES%c-CBC-%3d (%s): ", - ( u == 0 ) ? ' ' : '3', 56 + u * 56, - ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, des3_test_iv, 8 ); - memcpy( prv, des3_test_iv, 8 ); - memcpy( buf, des3_test_buf, 8 ); - - switch( i ) - { - case 0: - mbedtls_des_setkey_dec( &ctx, des3_test_keys ); - break; - - case 1: - mbedtls_des_setkey_enc( &ctx, des3_test_keys ); - break; - - case 2: - mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); - break; - - case 3: - mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); - break; - - case 4: - mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); - break; - - case 5: - mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); - break; - - default: - return( 1 ); - } - - if( v == MBEDTLS_DES_DECRYPT ) - { - for( j = 0; j < 10000; j++ ) - { - if( u == 0 ) - mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); - else - mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); - } - } - else - { - for( j = 0; j < 10000; j++ ) - { - unsigned char tmp[8]; - - if( u == 0 ) - mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); - else - mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); - - memcpy( tmp, prv, 8 ); - memcpy( prv, buf, 8 ); - memcpy( buf, tmp, 8 ); - } - - memcpy( buf, prv, 8 ); - } - - if( ( v == MBEDTLS_DES_DECRYPT && - memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || - ( v != MBEDTLS_DES_DECRYPT && - memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -exit: - mbedtls_des_free( &ctx ); - mbedtls_des3_free( &ctx3 ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_DES_C */ diff --git a/mbedtls/des.h b/mbedtls/des.h deleted file mode 100644 index bd35ea38c..000000000 --- a/mbedtls/des.h +++ /dev/null @@ -1,382 +0,0 @@ -#pragma GCC system_header -/** - * \file des.h - * - * \brief DES block cipher - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - * - */ -#ifndef MBEDTLS_DES_H -#define MBEDTLS_DES_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#define MBEDTLS_DES_ENCRYPT 1 -#define MBEDTLS_DES_DECRYPT 0 - -#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ - -/* MBEDTLS_ERR_DES_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED -0x0033 /**< DES hardware accelerator failed. */ - -#define MBEDTLS_DES_KEY_SIZE 8 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_DES_ALT) -// Regular implementation -// - -/** - * \brief DES context structure - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -typedef struct mbedtls_des_context -{ - uint32_t sk[32]; /*!< DES subkeys */ -} -mbedtls_des_context; - -/** - * \brief Triple-DES context structure - */ -typedef struct mbedtls_des3_context -{ - uint32_t sk[96]; /*!< 3DES subkeys */ -} -mbedtls_des3_context; - -#else /* MBEDTLS_DES_ALT */ -#include "des_alt.h" -#endif /* MBEDTLS_DES_ALT */ - -/** - * \brief Initialize DES context - * - * \param ctx DES context to be initialized - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des_init( mbedtls_des_context *ctx ); - -/** - * \brief Clear DES context - * - * \param ctx DES context to be cleared - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des_free( mbedtls_des_context *ctx ); - -/** - * \brief Initialize Triple-DES context - * - * \param ctx DES3 context to be initialized - */ -void mbedtls_des3_init( mbedtls_des3_context *ctx ); - -/** - * \brief Clear Triple-DES context - * - * \param ctx DES3 context to be cleared - */ -void mbedtls_des3_free( mbedtls_des3_context *ctx ); - -/** - * \brief Set key parity on the given key to odd. - * - * DES keys are 56 bits long, but each byte is padded with - * a parity bit to allow verification. - * - * \param key 8-byte secret key - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] ); - -/** - * \brief Check that key parity on the given key is odd. - * - * DES keys are 56 bits long, but each byte is padded with - * a parity bit to allow verification. - * - * \param key 8-byte secret key - * - * \return 0 is parity was ok, 1 if parity was not correct. - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); - -/** - * \brief Check that key is not a weak or semi-weak DES key - * - * \param key 8-byte secret key - * - * \return 0 if no weak key was found, 1 if a weak key was identified. - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); - -/** - * \brief DES key schedule (56-bit, encryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - * - * \return 0 - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); - -/** - * \brief DES key schedule (56-bit, decryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - * - * \return 0 - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); - -/** - * \brief Triple-DES key schedule (112-bit, encryption) - * - * \param ctx 3DES context to be initialized - * \param key 16-byte secret key - * - * \return 0 - */ -int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ); - -/** - * \brief Triple-DES key schedule (112-bit, decryption) - * - * \param ctx 3DES context to be initialized - * \param key 16-byte secret key - * - * \return 0 - */ -int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ); - -/** - * \brief Triple-DES key schedule (168-bit, encryption) - * - * \param ctx 3DES context to be initialized - * \param key 24-byte secret key - * - * \return 0 - */ -int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ); - -/** - * \brief Triple-DES key schedule (168-bit, decryption) - * - * \param ctx 3DES context to be initialized - * \param key 24-byte secret key - * - * \return 0 - */ -int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ); - -/** - * \brief DES-ECB block encryption/decryption - * - * \param ctx DES context - * \param input 64-bit input block - * \param output 64-bit output block - * - * \return 0 if successful - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx, - const unsigned char input[8], - unsigned char output[8] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief DES-CBC buffer encryption/decryption - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx DES context - * \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -/** - * \brief 3DES-ECB block encryption/decryption - * - * \param ctx 3DES context - * \param input 64-bit input block - * \param output 64-bit output block - * - * \return 0 if successful - */ -int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx, - const unsigned char input[8], - unsigned char output[8] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief 3DES-CBC buffer encryption/decryption - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx 3DES context - * \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH - */ -int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -/** - * \brief Internal function for key expansion. - * (Only exposed to allow overriding it, - * see MBEDTLS_DES_SETKEY_ALT) - * - * \param SK Round keys - * \param key Base key - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des_setkey( uint32_t SK[32], - const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_des_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* des.h */ diff --git a/mbedtls/dhm.c b/mbedtls/dhm.c deleted file mode 100644 index 66e816cee..000000000 --- a/mbedtls/dhm.c +++ /dev/null @@ -1,773 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Diffie-Hellman-Merkle key exchange - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The following sources were referenced in the design of this implementation - * of the Diffie-Hellman-Merkle algorithm: - * - * [1] Handbook of Applied Cryptography - 1997, Chapter 12 - * Menezes, van Oorschot and Vanstone - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_DHM_C) - -#include "mbedtls/dhm.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if !defined(MBEDTLS_DHM_ALT) - -#define DHM_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA ) -#define DHM_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * helper to validate the mbedtls_mpi size and import it - */ -static int dhm_read_bignum( mbedtls_mpi *X, - unsigned char **p, - const unsigned char *end ) -{ - int ret, n; - - if( end - *p < 2 ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - n = ( (*p)[0] << 8 ) | (*p)[1]; - (*p) += 2; - - if( (int)( end - *p ) < n ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 ) - return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret ); - - (*p) += n; - - return( 0 ); -} - -/* - * Verify sanity of parameter with regards to P - * - * Parameter should be: 2 <= public_param <= P - 2 - * - * This means that we need to return an error if - * public_param < 2 or public_param > P-2 - * - * For more information on the attack, see: - * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf - * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 - */ -static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P ) -{ - mbedtls_mpi U; - int ret = 0; - - mbedtls_mpi_init( &U ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) ); - - if( mbedtls_mpi_cmp_int( param, 2 ) < 0 || - mbedtls_mpi_cmp_mpi( param, &U ) > 0 ) - { - ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - -cleanup: - mbedtls_mpi_free( &U ); - return( ret ); -} - -void mbedtls_dhm_init( mbedtls_dhm_context *ctx ) -{ - DHM_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_dhm_context ) ); -} - -/* - * Parse the ServerKeyExchange parameters - */ -int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, - unsigned char **p, - const unsigned char *end ) -{ - int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( p != NULL && *p != NULL ); - DHM_VALIDATE_RET( end != NULL ); - - if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 || - ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 || - ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 ) - return( ret ); - - if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) - return( ret ); - - ctx->len = mbedtls_mpi_size( &ctx->P ); - - return( 0 ); -} - -/* - * Pick a random R in the range [2, M-2] for blinding or key generation. - */ -static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret, count; - size_t m_size = mbedtls_mpi_size( M ); - size_t m_bitlen = mbedtls_mpi_bitlen( M ); - - count = 0; - do - { - if( count++ > 30 ) - return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, m_size, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, ( m_size * 8 ) - m_bitlen ) ); - } - while( dhm_check_range( R, M ) != 0 ); - -cleanup: - return( ret ); -} - -static int dhm_make_common( mbedtls_dhm_context *ctx, int x_size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret = 0; - - if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - if( x_size < 0 ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - if( (unsigned) x_size < mbedtls_mpi_size( &ctx->P ) ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) ); - } - else - { - /* Generate X as large as possible ( <= P - 2 ) */ - ret = dhm_random_below( &ctx->X, &ctx->P, f_rng, p_rng ); - if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) - return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED ); - if( ret != 0 ) - return( ret ); - } - - /* - * Calculate GX = G^X mod P - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, - &ctx->P , &ctx->RP ) ); - - if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) - return( ret ); - -cleanup: - return( ret ); -} - -/* - * Setup and write the ServerKeyExchange parameters - */ -int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - size_t n1, n2, n3; - unsigned char *p; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( output != NULL ); - DHM_VALIDATE_RET( olen != NULL ); - DHM_VALIDATE_RET( f_rng != NULL ); - - ret = dhm_make_common( ctx, x_size, f_rng, p_rng ); - if( ret != 0 ) - goto cleanup; - - /* - * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are - * not required". We omit leading zeros for compactness. - */ -#define DHM_MPI_EXPORT( X, n ) \ - do { \ - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \ - p + 2, \ - ( n ) ) ); \ - *p++ = (unsigned char)( ( n ) >> 8 ); \ - *p++ = (unsigned char)( ( n ) ); \ - p += ( n ); \ - } while( 0 ) - - n1 = mbedtls_mpi_size( &ctx->P ); - n2 = mbedtls_mpi_size( &ctx->G ); - n3 = mbedtls_mpi_size( &ctx->GX ); - - p = output; - DHM_MPI_EXPORT( &ctx->P , n1 ); - DHM_MPI_EXPORT( &ctx->G , n2 ); - DHM_MPI_EXPORT( &ctx->GX, n3 ); - - *olen = p - output; - - ctx->len = n1; - -cleanup: - if( ret != 0 && ret > -128 ) - return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret ); - return( ret ); -} - -/* - * Set prime modulus and generator - */ -int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx, - const mbedtls_mpi *P, - const mbedtls_mpi *G ) -{ - int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( P != NULL ); - DHM_VALIDATE_RET( G != NULL ); - - if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 || - ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 ) - { - return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret ); - } - - ctx->len = mbedtls_mpi_size( &ctx->P ); - return( 0 ); -} - -/* - * Import the peer's public value G^Y - */ -int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, - const unsigned char *input, size_t ilen ) -{ - int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( input != NULL ); - - if( ilen < 1 || ilen > ctx->len ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 ) - return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret ); - - return( 0 ); -} - -/* - * Create own private value X and export G^X - */ -int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( output != NULL ); - DHM_VALIDATE_RET( f_rng != NULL ); - - if( olen < 1 || olen > ctx->len ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - ret = dhm_make_common( ctx, x_size, f_rng, p_rng ); - if( ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED ) - return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED ); - if( ret != 0 ) - goto cleanup; - - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) ); - -cleanup: - if( ret != 0 && ret > -128 ) - return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret ); - - return( ret ); -} - - -/* - * Use the blinding method and optimisation suggested in section 10 of: - * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, - * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer - * Berlin Heidelberg, 1996. p. 104-113. - */ -static int dhm_update_blinding( mbedtls_dhm_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - mbedtls_mpi R; - - mbedtls_mpi_init( &R ); - - /* - * Don't use any blinding the first time a particular X is used, - * but remember it to use blinding next time. - */ - if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) ); - - return( 0 ); - } - - /* - * Ok, we need blinding. Can we re-use existing values? - * If yes, just update them by squaring them. - */ - if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); - - return( 0 ); - } - - /* - * We need to generate blinding values from scratch - */ - - /* Vi = random( 2, P-2 ) */ - MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) ); - - /* Vf = Vi^-X mod P - * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod), - * then elevate to the Xth power. */ - MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) ); - -cleanup: - mbedtls_mpi_free( &R ); - - return( ret ); -} - -/* - * Derive and export the shared secret (G^Y)^X mod P - */ -int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, - unsigned char *output, size_t output_size, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_mpi GYb; - DHM_VALIDATE_RET( ctx != NULL ); - DHM_VALIDATE_RET( output != NULL ); - DHM_VALIDATE_RET( olen != NULL ); - - if( output_size < ctx->len ) - return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); - - if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) - return( ret ); - - mbedtls_mpi_init( &GYb ); - - /* Blind peer's value */ - if( f_rng != NULL ) - { - MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) ); - } - else - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) ); - - /* Do modular exponentiation */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X, - &ctx->P, &ctx->RP ) ); - - /* Unblind secret value */ - if( f_rng != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) ); - } - - /* Output the secret without any leading zero byte. This is mandatory - * for TLS per RFC 5246 §8.1.2. */ - *olen = mbedtls_mpi_size( &ctx->K ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) ); - -cleanup: - mbedtls_mpi_free( &GYb ); - - if( ret != 0 ) - return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret ); - - return( 0 ); -} - -/* - * Free the components of a DHM key - */ -void mbedtls_dhm_free( mbedtls_dhm_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_mpi_free( &ctx->pX ); - mbedtls_mpi_free( &ctx->Vf ); - mbedtls_mpi_free( &ctx->Vi ); - mbedtls_mpi_free( &ctx->RP ); - mbedtls_mpi_free( &ctx->K ); - mbedtls_mpi_free( &ctx->GY ); - mbedtls_mpi_free( &ctx->GX ); - mbedtls_mpi_free( &ctx->X ); - mbedtls_mpi_free( &ctx->G ); - mbedtls_mpi_free( &ctx->P ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) ); -} - -#if defined(MBEDTLS_ASN1_PARSE_C) -/* - * Parse DHM parameters - */ -int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, - size_t dhminlen ) -{ - int ret; - size_t len; - unsigned char *p, *end; -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_context pem; -#endif /* MBEDTLS_PEM_PARSE_C */ - - DHM_VALIDATE_RET( dhm != NULL ); - DHM_VALIDATE_RET( dhmin != NULL ); - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init( &pem ); - - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN DH PARAMETERS-----", - "-----END DH PARAMETERS-----", - dhmin, NULL, 0, &dhminlen ); - - if( ret == 0 ) - { - /* - * Was PEM encoded - */ - dhminlen = pem.buflen; - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - goto exit; - - p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin; -#else - p = (unsigned char *) dhmin; -#endif /* MBEDTLS_PEM_PARSE_C */ - end = p + dhminlen; - - /* - * DHParams ::= SEQUENCE { - * prime INTEGER, -- P - * generator INTEGER, -- g - * privateValueLength INTEGER OPTIONAL - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; - goto exit; - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 ) - { - ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; - goto exit; - } - - if( p != end ) - { - /* This might be the optional privateValueLength. - * If so, we can cleanly discard it */ - mbedtls_mpi rec; - mbedtls_mpi_init( &rec ); - ret = mbedtls_asn1_get_mpi( &p, end, &rec ); - mbedtls_mpi_free( &rec ); - if ( ret != 0 ) - { - ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; - goto exit; - } - if ( p != end ) - { - ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - goto exit; - } - } - - ret = 0; - - dhm->len = mbedtls_mpi_size( &dhm->P ); - -exit: -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_free( &pem ); -#endif - if( ret != 0 ) - mbedtls_dhm_free( dhm ); - - return( ret ); -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load all data from a file into a given buffer. - * - * The file is expected to contain either PEM or DER encoded data. - * A terminating null byte is always appended. It is included in the announced - * length only if the data looks like it is PEM encoded. - */ -static int load_file( const char *path, unsigned char **buf, size_t *n ) -{ - FILE *f; - long size; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); - - fseek( f, 0, SEEK_END ); - if( ( size = ftell( f ) ) == -1 ) - { - fclose( f ); - return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); - } - fseek( f, 0, SEEK_SET ); - - *n = (size_t) size; - - if( *n + 1 == 0 || - ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) - { - fclose( f ); - return( MBEDTLS_ERR_DHM_ALLOC_FAILED ); - } - - if( fread( *buf, 1, *n, f ) != *n ) - { - fclose( f ); - - mbedtls_platform_zeroize( *buf, *n + 1 ); - mbedtls_free( *buf ); - - return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); - } - - fclose( f ); - - (*buf)[*n] = '\0'; - - if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) - ++*n; - - return( 0 ); -} - -/* - * Load and parse DHM parameters - */ -int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) -{ - int ret; - size_t n; - unsigned char *buf; - DHM_VALIDATE_RET( dhm != NULL ); - DHM_VALIDATE_RET( path != NULL ); - - if( ( ret = load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - ret = mbedtls_dhm_parse_dhm( dhm, buf, n ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ -#endif /* MBEDTLS_ASN1_PARSE_C */ -#endif /* MBEDTLS_DHM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -#if defined(MBEDTLS_PEM_PARSE_C) -static const char mbedtls_test_dhm_params[] = -"-----BEGIN DH PARAMETERS-----\r\n" -"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" -"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" -"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" -"-----END DH PARAMETERS-----\r\n"; -#else /* MBEDTLS_PEM_PARSE_C */ -static const char mbedtls_test_dhm_params[] = { - 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44, - 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d, - 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3, - 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1, - 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18, - 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a, - 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1, - 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6, - 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64, - 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8, - 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f, - 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 }; -#endif /* MBEDTLS_PEM_PARSE_C */ - -static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params ); - -/* - * Checkup routine - */ -int mbedtls_dhm_self_test( int verbose ) -{ - int ret; - mbedtls_dhm_context dhm; - - mbedtls_dhm_init( &dhm ); - - if( verbose != 0 ) - mbedtls_printf( " DHM parameter load: " ); - - if( ( ret = mbedtls_dhm_parse_dhm( &dhm, - (const unsigned char *) mbedtls_test_dhm_params, - mbedtls_test_dhm_params_len ) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n\n" ); - -exit: - mbedtls_dhm_free( &dhm ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_DHM_C */ diff --git a/mbedtls/dhm.h b/mbedtls/dhm.h deleted file mode 100644 index c95369a0e..000000000 --- a/mbedtls/dhm.h +++ /dev/null @@ -1,1122 +0,0 @@ -#pragma GCC system_header -/** - * \file dhm.h - * - * \brief This file contains Diffie-Hellman-Merkle (DHM) key exchange - * definitions and functions. - * - * Diffie-Hellman-Merkle (DHM) key exchange is defined in - * RFC-2631: Diffie-Hellman Key Agreement Method and - * Public-Key Cryptography Standards (PKCS) #3: Diffie - * Hellman Key Agreement Standard. - * - * RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for - * Internet Key Exchange (IKE) defines a number of standardized - * Diffie-Hellman groups for IKE. - * - * RFC-5114: Additional Diffie-Hellman Groups for Use with IETF - * Standards defines a number of standardized Diffie-Hellman - * groups that can be used. - * - * \warning The security of the DHM key exchange relies on the proper choice - * of prime modulus - optimally, it should be a safe prime. The usage - * of non-safe primes both decreases the difficulty of the underlying - * discrete logarithm problem and can lead to small subgroup attacks - * leaking private exponent bits when invalid public keys are used - * and not detected. This is especially relevant if the same DHM - * parameters are reused for multiple key exchanges as in static DHM, - * while the criticality of small-subgroup attacks is lower for - * ephemeral DHM. - * - * \warning For performance reasons, the code does neither perform primality - * nor safe primality tests, nor the expensive checks for invalid - * subgroups. Moreover, even if these were performed, non-standardized - * primes cannot be trusted because of the possibility of backdoors - * that can't be effectively checked for. - * - * \warning Diffie-Hellman-Merkle is therefore a security risk when not using - * standardized primes generated using a trustworthy ("nothing up - * my sleeve") method, such as the RFC 3526 / 7919 primes. In the TLS - * protocol, DH parameters need to be negotiated, so using the default - * primes systematically is not always an option. If possible, use - * Elliptic Curve Diffie-Hellman (ECDH), which has better performance, - * and for which the TLS protocol mandates the use of standard - * parameters. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_DHM_H -#define MBEDTLS_DHM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif -#include "bignum.h" - -/* - * DHM Error codes - */ -#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA -0x3080 /**< Bad input parameters. */ -#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED -0x3100 /**< Reading of the DHM parameters failed. */ -#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 /**< Making of the DHM parameters failed. */ -#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED -0x3200 /**< Reading of the public values failed. */ -#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 /**< Making of the public value failed. */ -#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED -0x3300 /**< Calculation of the DHM secret failed. */ -#define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380 /**< The ASN.1 data is not formatted correctly. */ -#define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400 /**< Allocation of memory failed. */ -#define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480 /**< Read or write of file failed. */ - -/* MBEDTLS_ERR_DHM_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED -0x3500 /**< DHM hardware accelerator failed. */ - -#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED -0x3580 /**< Setting the modulus and generator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_DHM_ALT) - -/** - * \brief The DHM context structure. - */ -typedef struct mbedtls_dhm_context -{ - size_t len; /*!< The size of \p P in Bytes. */ - mbedtls_mpi P; /*!< The prime modulus. */ - mbedtls_mpi G; /*!< The generator. */ - mbedtls_mpi X; /*!< Our secret value. */ - mbedtls_mpi GX; /*!< Our public key = \c G^X mod \c P. */ - mbedtls_mpi GY; /*!< The public key of the peer = \c G^Y mod \c P. */ - mbedtls_mpi K; /*!< The shared secret = \c G^(XY) mod \c P. */ - mbedtls_mpi RP; /*!< The cached value = \c R^2 mod \c P. */ - mbedtls_mpi Vi; /*!< The blinding value. */ - mbedtls_mpi Vf; /*!< The unblinding value. */ - mbedtls_mpi pX; /*!< The previous \c X. */ -} -mbedtls_dhm_context; - -#else /* MBEDTLS_DHM_ALT */ -#include "dhm_alt.h" -#endif /* MBEDTLS_DHM_ALT */ - -/** - * \brief This function initializes the DHM context. - * - * \param ctx The DHM context to initialize. - */ -void mbedtls_dhm_init( mbedtls_dhm_context *ctx ); - -/** - * \brief This function parses the DHM parameters in a - * TLS ServerKeyExchange handshake message - * (DHM modulus, generator, and public key). - * - * \note In a TLS handshake, this is the how the client - * sets up its DHM context from the server's public - * DHM key material. - * - * \param ctx The DHM context to use. This must be initialized. - * \param p On input, *p must be the start of the input buffer. - * On output, *p is updated to point to the end of the data - * that has been read. On success, this is the first byte - * past the end of the ServerKeyExchange parameters. - * On error, this is the point at which an error has been - * detected, which is usually not useful except to debug - * failures. - * \param end The end of the input buffer. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, - unsigned char **p, - const unsigned char *end ); - -/** - * \brief This function generates a DHM key pair and exports its - * public part together with the DHM parameters in the format - * used in a TLS ServerKeyExchange handshake message. - * - * \note This function assumes that the DHM parameters \c ctx->P - * and \c ctx->G have already been properly set. For that, use - * mbedtls_dhm_set_group() below in conjunction with - * mbedtls_mpi_read_binary() and mbedtls_mpi_read_string(). - * - * \note In a TLS handshake, this is the how the server generates - * and exports its DHM key material. - * - * \param ctx The DHM context to use. This must be initialized - * and have the DHM parameters set. It may or may not - * already have imported the peer's public key. - * \param x_size The private key size in Bytes. - * \param olen The address at which to store the number of Bytes - * written on success. This must not be \c NULL. - * \param output The destination buffer. This must be a writable buffer of - * sufficient size to hold the reduced binary presentation of - * the modulus, the generator and the public key, each wrapped - * with a 2-byte length field. It is the responsibility of the - * caller to ensure that enough space is available. Refer to - * mbedtls_mpi_size() to computing the byte-size of an MPI. - * \param f_rng The RNG function. Must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function sets the prime modulus and generator. - * - * \note This function can be used to set \c ctx->P, \c ctx->G - * in preparation for mbedtls_dhm_make_params(). - * - * \param ctx The DHM context to configure. This must be initialized. - * \param P The MPI holding the DHM prime modulus. This must be - * an initialized MPI. - * \param G The MPI holding the DHM generator. This must be an - * initialized MPI. - * - * \return \c 0 if successful. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx, - const mbedtls_mpi *P, - const mbedtls_mpi *G ); - -/** - * \brief This function imports the raw public value of the peer. - * - * \note In a TLS handshake, this is the how the server imports - * the Client's public DHM key. - * - * \param ctx The DHM context to use. This must be initialized and have - * its DHM parameters set, e.g. via mbedtls_dhm_set_group(). - * It may or may not already have generated its own private key. - * \param input The input buffer containing the \c G^Y value of the peer. - * This must be a readable buffer of size \p ilen Bytes. - * \param ilen The size of the input buffer \p input in Bytes. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, - const unsigned char *input, size_t ilen ); - -/** - * \brief This function creates a DHM key pair and exports - * the raw public key in big-endian format. - * - * \note The destination buffer is always fully written - * so as to contain a big-endian representation of G^X mod P. - * If it is larger than \c ctx->len, it is padded accordingly - * with zero-bytes at the beginning. - * - * \param ctx The DHM context to use. This must be initialized and - * have the DHM parameters set. It may or may not already - * have imported the peer's public key. - * \param x_size The private key size in Bytes. - * \param output The destination buffer. This must be a writable buffer of - * size \p olen Bytes. - * \param olen The length of the destination buffer. This must be at least - * equal to `ctx->len` (the size of \c P). - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function derives and exports the shared secret - * \c (G^Y)^X mod \c P. - * - * \note If \p f_rng is not \c NULL, it is used to blind the input as - * a countermeasure against timing attacks. Blinding is used - * only if our private key \c X is re-used, and not used - * otherwise. We recommend always passing a non-NULL - * \p f_rng argument. - * - * \param ctx The DHM context to use. This must be initialized - * and have its own private key generated and the peer's - * public key imported. - * \param output The buffer to write the generated shared key to. This - * must be a writable buffer of size \p output_size Bytes. - * \param output_size The size of the destination buffer. This must be at - * least the size of \c ctx->len (the size of \c P). - * \param olen On exit, holds the actual number of Bytes written. - * \param f_rng The RNG function, for blinding purposes. This may - * b \c NULL if blinding isn't needed. - * \param p_rng The RNG context. This may be \c NULL if \p f_rng - * doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, - unsigned char *output, size_t output_size, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function frees and clears the components - * of a DHM context. - * - * \param ctx The DHM context to free and clear. This may be \c NULL, - * in which case this function is a no-op. If it is not \c NULL, - * it must point to an initialized DHM context. - */ -void mbedtls_dhm_free( mbedtls_dhm_context *ctx ); - -#if defined(MBEDTLS_ASN1_PARSE_C) -/** \ingroup x509_module */ -/** - * \brief This function parses DHM parameters in PEM or DER format. - * - * \param dhm The DHM context to import the DHM parameters into. - * This must be initialized. - * \param dhmin The input buffer. This must be a readable buffer of - * length \p dhminlen Bytes. - * \param dhminlen The size of the input buffer \p dhmin, including the - * terminating \c NULL Byte for PEM data. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error - * code on failure. - */ -int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, - size_t dhminlen ); - -#if defined(MBEDTLS_FS_IO) -/** \ingroup x509_module */ -/** - * \brief This function loads and parses DHM parameters from a file. - * - * \param dhm The DHM context to load the parameters to. - * This must be initialized. - * \param path The filename to read the DHM parameters from. - * This must not be \c NULL. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX - * error code on failure. - */ -int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ); -#endif /* MBEDTLS_FS_IO */ -#endif /* MBEDTLS_ASN1_PARSE_C */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The DMH checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_dhm_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ -#ifdef __cplusplus -} -#endif - -/** - * RFC 3526, RFC 5114 and RFC 7919 standardize a number of - * Diffie-Hellman groups, some of which are included here - * for use within the SSL/TLS module and the user's convenience - * when configuring the Diffie-Hellman parameters by hand - * through \c mbedtls_ssl_conf_dh_param. - * - * The following lists the source of the above groups in the standards: - * - RFC 5114 section 2.2: 2048-bit MODP Group with 224-bit Prime Order Subgroup - * - RFC 3526 section 3: 2048-bit MODP Group - * - RFC 3526 section 4: 3072-bit MODP Group - * - RFC 3526 section 5: 4096-bit MODP Group - * - RFC 7919 section A.1: ffdhe2048 - * - RFC 7919 section A.2: ffdhe3072 - * - RFC 7919 section A.3: ffdhe4096 - * - RFC 7919 section A.4: ffdhe6144 - * - RFC 7919 section A.5: ffdhe8192 - * - * The constants with suffix "_p" denote the chosen prime moduli, while - * the constants with suffix "_g" denote the chosen generator - * of the associated prime field. - * - * The constants further suffixed with "_bin" are provided in binary format, - * while all other constants represent null-terminated strings holding the - * hexadecimal presentation of the respective numbers. - * - * The primes from RFC 3526 and RFC 7919 have been generating by the following - * trust-worthy procedure: - * - Fix N in { 2048, 3072, 4096, 6144, 8192 } and consider the N-bit number - * the first and last 64 bits are all 1, and the remaining N - 128 bits of - * which are 0x7ff...ff. - * - Add the smallest multiple of the first N - 129 bits of the binary expansion - * of pi (for RFC 5236) or e (for RFC 7919) to this intermediate bit-string - * such that the resulting integer is a safe-prime. - * - The result is the respective RFC 3526 / 7919 prime, and the corresponding - * generator is always chosen to be 2 (which is a square for these prime, - * hence the corresponding subgroup has order (p-1)/2 and avoids leaking a - * bit in the private exponent). - * - */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - -/** - * \warning The origin of the primes in RFC 5114 is not documented and - * their use therefore constitutes a security risk! - * - * \disabled_deprecated The hex-encoded primes from RFC 5114 are deprecated and are - * likely to be removed in a future version of the library without - * replacement. - */ - -/** - * The hexadecimal presentation of the prime underlying the - * 2048-bit MODP Group with 224-bit Prime Order Subgroup, as defined - * in RFC-5114: Additional Diffie-Hellman Groups for Use with - * IETF Standards. - */ -#define MBEDTLS_DHM_RFC5114_MODP_2048_P \ - MBEDTLS_DEPRECATED_STRING_CONSTANT( \ - "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" \ - "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" \ - "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" \ - "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" \ - "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" \ - "B3BF8A317091883681286130BC8985DB1602E714415D9330" \ - "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" \ - "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" \ - "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" \ - "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" \ - "CF9DE5384E71B81C0AC4DFFE0C10E64F" ) - -/** - * The hexadecimal presentation of the chosen generator of the 2048-bit MODP - * Group with 224-bit Prime Order Subgroup, as defined in RFC-5114: - * Additional Diffie-Hellman Groups for Use with IETF Standards. - */ -#define MBEDTLS_DHM_RFC5114_MODP_2048_G \ - MBEDTLS_DEPRECATED_STRING_CONSTANT( \ - "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" \ - "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" \ - "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" \ - "C17669101999024AF4D027275AC1348BB8A762D0521BC98A" \ - "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" \ - "F180EB34118E98D119529A45D6F834566E3025E316A330EF" \ - "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" \ - "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" \ - "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" \ - "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" \ - "81BC087F2A7065B384B890D3191F2BFA" ) - -/** - * The hexadecimal presentation of the prime underlying the 2048-bit MODP - * Group, as defined in RFC-3526: More Modular Exponential (MODP) - * Diffie-Hellman groups for Internet Key Exchange (IKE). - * - * \disabled_deprecated The hex-encoded primes from RFC 3625 are deprecated and - * superseded by the corresponding macros providing them as - * binary constants. Their hex-encoded constants are likely - * to be removed in a future version of the library. - * - */ -#define MBEDTLS_DHM_RFC3526_MODP_2048_P \ - MBEDTLS_DEPRECATED_STRING_CONSTANT( \ - "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ - "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ - "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ - "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ - "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ - "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ - "15728E5A8AACAA68FFFFFFFFFFFFFFFF" ) - -/** - * The hexadecimal presentation of the chosen generator of the 2048-bit MODP - * Group, as defined in RFC-3526: More Modular Exponential (MODP) - * Diffie-Hellman groups for Internet Key Exchange (IKE). - */ -#define MBEDTLS_DHM_RFC3526_MODP_2048_G \ - MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" ) - -/** - * The hexadecimal presentation of the prime underlying the 3072-bit MODP - * Group, as defined in RFC-3072: More Modular Exponential (MODP) - * Diffie-Hellman groups for Internet Key Exchange (IKE). - */ -#define MBEDTLS_DHM_RFC3526_MODP_3072_P \ - MBEDTLS_DEPRECATED_STRING_CONSTANT( \ - "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ - "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ - "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ - "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ - "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ - "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ - "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ - "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ - "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ - "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ - "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ - "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" ) - -/** - * The hexadecimal presentation of the chosen generator of the 3072-bit MODP - * Group, as defined in RFC-3526: More Modular Exponential (MODP) - * Diffie-Hellman groups for Internet Key Exchange (IKE). - */ -#define MBEDTLS_DHM_RFC3526_MODP_3072_G \ - MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" ) - -/** - * The hexadecimal presentation of the prime underlying the 4096-bit MODP - * Group, as defined in RFC-3526: More Modular Exponential (MODP) - * Diffie-Hellman groups for Internet Key Exchange (IKE). - */ -#define MBEDTLS_DHM_RFC3526_MODP_4096_P \ - MBEDTLS_DEPRECATED_STRING_CONSTANT( \ - "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ - "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ - "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ - "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ - "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ - "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ - "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ - "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ - "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ - "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ - "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ - "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \ - "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \ - "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \ - "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \ - "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \ - "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" \ - "FFFFFFFFFFFFFFFF" ) - -/** - * The hexadecimal presentation of the chosen generator of the 4096-bit MODP - * Group, as defined in RFC-3526: More Modular Exponential (MODP) - * Diffie-Hellman groups for Internet Key Exchange (IKE). - */ -#define MBEDTLS_DHM_RFC3526_MODP_4096_G \ - MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" ) - -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/* - * Trustworthy DHM parameters in binary form - */ - -#define MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC3526_MODP_4096_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, \ - 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, \ - 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, \ - 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, \ - 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, \ - 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, \ - 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, \ - 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, \ - 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, \ - 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, \ - 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, \ - 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, \ - 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, \ - 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, \ - 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, \ - 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, \ - 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC3526_MODP_4096_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, } - -#define MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ - 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ - 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ - 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ - 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ - 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ - 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ - 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ - 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ - 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ - 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ - 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ - 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ - 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ - 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ - 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ - 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ - 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ - 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ - 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ - 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ - 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ - 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ - 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ - 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ - 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ - 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ - 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ - 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ - 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ - 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ - 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ - 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ - 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ - 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ - 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ - 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ - 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ - 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ - 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ - 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ - 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ - 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ - 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ - 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ - 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ - 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ - 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ - 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ - 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ - 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ - 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ - 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ - 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ - 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ - 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ - 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ - 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ - 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ - 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ - 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ - 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ - 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ - 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ - 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ - 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ - 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ - 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ - 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ - 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ - 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ - 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ - 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ - 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ - 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ - 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ - 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ - 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ - 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ - 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ - 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ - 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ - 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ - 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ - 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ - 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ - 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ - 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ - 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ - 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ - 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ - 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ - 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ - 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ - 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ - 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ - 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ - 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ - 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ - 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ - 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ - 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ - 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ - 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ - 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ - 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ - 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ - 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ - 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ - 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ - 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ - 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ - 0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ - 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ - 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ - 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ - 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ - 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ - 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ - 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ - 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ - 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ - 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ - 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ - 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ - 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ - 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ - 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ - 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ - 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ - 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ - 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ - 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ - 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ - 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ - 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ - 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ - 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ - 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ - 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ - 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ - 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ - 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ - 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ - 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ - 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ - 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ - 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ - 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ - 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ - 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ - 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ - 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ - 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ - 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ - 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ - 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ - 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ - 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ - 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ - 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ - 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ - 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ - 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ - 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ - 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ - 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ - 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ - 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ - 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ - 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ - 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ - 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ - 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ - 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ - 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ - 0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA, \ - 0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38, \ - 0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64, \ - 0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43, \ - 0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E, \ - 0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF, \ - 0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29, \ - 0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65, \ - 0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02, \ - 0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4, \ - 0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82, \ - 0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C, \ - 0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51, \ - 0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22, \ - 0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74, \ - 0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE, \ - 0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C, \ - 0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC, \ - 0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B, \ - 0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9, \ - 0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0, \ - 0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31, \ - 0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57, \ - 0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8, \ - 0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E, \ - 0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30, \ - 0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E, \ - 0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE, \ - 0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D, \ - 0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D, \ - 0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E, \ - 0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C, \ - 0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN { 0x02 } - -#endif /* dhm.h */ diff --git a/mbedtls/ecdh.c b/mbedtls/ecdh.c deleted file mode 100644 index cd6cb10c8..000000000 --- a/mbedtls/ecdh.c +++ /dev/null @@ -1,714 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Elliptic curve Diffie-Hellman - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * References: - * - * SEC1 http://www.secg.org/index.php?action=secg,docs_secg - * RFC 4492 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ECDH_C) - -#include "mbedtls/ecdh.h" -#include "mbedtls/platform_util.h" - -#include - -/* Parameter validation macros based on platform_util.h */ -#define ECDH_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECDH_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) -typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed; -#endif - -static mbedtls_ecp_group_id mbedtls_ecdh_grp_id( - const mbedtls_ecdh_context *ctx ) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ctx->grp.id ); -#else - return( ctx->grp_id ); -#endif -} - -#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) -/* - * Generate public key (restartable version) - * - * Note: this internal function relies on its caller preserving the value of - * the output parameter 'd' across continuation calls. This would not be - * acceptable for a public function but is OK here as we control call sites. - */ -static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - - /* If multiplication is in progress, we already generated a privkey */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx == NULL || rs_ctx->rsm == NULL ) -#endif - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G, - f_rng, p_rng, rs_ctx ) ); - -cleanup: - return( ret ); -} - -/* - * Generate public key - */ -int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECDH_VALIDATE_RET( grp != NULL ); - ECDH_VALIDATE_RET( d != NULL ); - ECDH_VALIDATE_RET( Q != NULL ); - ECDH_VALIDATE_RET( f_rng != NULL ); - return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) ); -} -#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */ - -#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) -/* - * Compute shared secret (SEC1 3.3.1) - */ -static int ecdh_compute_shared_restartable( mbedtls_ecp_group *grp, - mbedtls_mpi *z, - const mbedtls_ecp_point *Q, const mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_ecp_point P; - - mbedtls_ecp_point_init( &P ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &P, d, Q, - f_rng, p_rng, rs_ctx ) ); - - if( mbedtls_ecp_is_zero( &P ) ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) ); - -cleanup: - mbedtls_ecp_point_free( &P ); - - return( ret ); -} - -/* - * Compute shared secret (SEC1 3.3.1) - */ -int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, - const mbedtls_ecp_point *Q, const mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECDH_VALIDATE_RET( grp != NULL ); - ECDH_VALIDATE_RET( Q != NULL ); - ECDH_VALIDATE_RET( d != NULL ); - ECDH_VALIDATE_RET( z != NULL ); - return( ecdh_compute_shared_restartable( grp, z, Q, d, - f_rng, p_rng, NULL ) ); -} -#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ - -static void ecdh_init_internal( mbedtls_ecdh_context_mbed *ctx ) -{ - mbedtls_ecp_group_init( &ctx->grp ); - mbedtls_mpi_init( &ctx->d ); - mbedtls_ecp_point_init( &ctx->Q ); - mbedtls_ecp_point_init( &ctx->Qp ); - mbedtls_mpi_init( &ctx->z ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_init( &ctx->rs ); -#endif -} - -/* - * Initialize context - */ -void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ) -{ - ECDH_VALIDATE( ctx != NULL ); - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - ecdh_init_internal( ctx ); - mbedtls_ecp_point_init( &ctx->Vi ); - mbedtls_ecp_point_init( &ctx->Vf ); - mbedtls_mpi_init( &ctx->_d ); -#else - memset( ctx, 0, sizeof( mbedtls_ecdh_context ) ); - - ctx->var = MBEDTLS_ECDH_VARIANT_NONE; -#endif - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; -#if defined(MBEDTLS_ECP_RESTARTABLE) - ctx->restart_enabled = 0; -#endif -} - -static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx, - mbedtls_ecp_group_id grp_id ) -{ - int ret; - - ret = mbedtls_ecp_group_load( &ctx->grp, grp_id ); - if( ret != 0 ) - { - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - } - - return( 0 ); -} - -/* - * Setup context - */ -int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id ) -{ - ECDH_VALIDATE_RET( ctx != NULL ); - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_setup_internal( ctx, grp_id ) ); -#else - switch( grp_id ) - { - default: - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; - ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; - ctx->grp_id = grp_id; - ecdh_init_internal( &ctx->ctx.mbed_ecdh ); - return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) ); - } -#endif -} - -static void ecdh_free_internal( mbedtls_ecdh_context_mbed *ctx ) -{ - mbedtls_ecp_group_free( &ctx->grp ); - mbedtls_mpi_free( &ctx->d ); - mbedtls_ecp_point_free( &ctx->Q ); - mbedtls_ecp_point_free( &ctx->Qp ); - mbedtls_mpi_free( &ctx->z ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_free( &ctx->rs ); -#endif -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Enable restartable operations for context - */ -void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx ) -{ - ECDH_VALIDATE( ctx != NULL ); - - ctx->restart_enabled = 1; -} -#endif - -/* - * Free context - */ -void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - mbedtls_ecp_point_free( &ctx->Vi ); - mbedtls_ecp_point_free( &ctx->Vf ); - mbedtls_mpi_free( &ctx->_d ); - ecdh_free_internal( ctx ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - ecdh_free_internal( &ctx->ctx.mbed_ecdh ); - break; - default: - break; - } - - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; - ctx->var = MBEDTLS_ECDH_VARIANT_NONE; - ctx->grp_id = MBEDTLS_ECP_DP_NONE; -#endif -} - -static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx, - size_t *olen, int point_format, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng, - int restart_enabled ) -{ - int ret; - size_t grp_len, pt_len; -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx *rs_ctx = NULL; -#endif - - if( ctx->grp.pbits == 0 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( restart_enabled ) - rs_ctx = &ctx->rs; -#else - (void) restart_enabled; -#endif - - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng, rs_ctx ) ) != 0 ) - return( ret ); -#else - if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng ) ) != 0 ) - return( ret ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, - blen ) ) != 0 ) - return( ret ); - - buf += grp_len; - blen -= grp_len; - - if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, - &pt_len, buf, blen ) ) != 0 ) - return( ret ); - - *olen = grp_len + pt_len; - return( 0 ); -} - -/* - * Setup and write the ServerKeyExhange parameters (RFC 4492) - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ -int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int restart_enabled = 0; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( olen != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - ECDH_VALIDATE_RET( f_rng != NULL ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - restart_enabled = ctx->restart_enabled; -#else - (void) restart_enabled; -#endif - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_make_params_internal( ctx, olen, ctx->point_format, buf, blen, - f_rng, p_rng, restart_enabled ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen, - ctx->point_format, buf, blen, - f_rng, p_rng, - restart_enabled ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx, - const unsigned char **buf, - const unsigned char *end ) -{ - return( mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, - end - *buf ) ); -} - -/* - * Read the ServerKeyExhange parameters (RFC 4492) - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ -int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, - const unsigned char **buf, - const unsigned char *end ) -{ - int ret; - mbedtls_ecp_group_id grp_id; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - ECDH_VALIDATE_RET( *buf != NULL ); - ECDH_VALIDATE_RET( end != NULL ); - - if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) ) - != 0 ) - return( ret ); - - if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_read_params_internal( ctx, buf, end ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh, - buf, end ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx, - const mbedtls_ecp_keypair *key, - mbedtls_ecdh_side side ) -{ - int ret; - - /* If it's not our key, just import the public part as Qp */ - if( side == MBEDTLS_ECDH_THEIRS ) - return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) ); - - /* Our key: import public (as Q) and private parts */ - if( side != MBEDTLS_ECDH_OURS ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 || - ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * Get parameters from a keypair - */ -int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, - const mbedtls_ecp_keypair *key, - mbedtls_ecdh_side side ) -{ - int ret; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( key != NULL ); - ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS || - side == MBEDTLS_ECDH_THEIRS ); - - if( mbedtls_ecdh_grp_id( ctx ) == MBEDTLS_ECP_DP_NONE ) - { - /* This is the first call to get_params(). Set up the context - * for use with the group. */ - if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 ) - return( ret ); - } - else - { - /* This is not the first call to get_params(). Check that the - * current key's group is the same as the context's, which was set - * from the first key's group. */ - if( mbedtls_ecdh_grp_id( ctx ) != key->grp.id ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_get_params_internal( ctx, key, side ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh, - key, side ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx, - size_t *olen, int point_format, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng, - int restart_enabled ) -{ - int ret; -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx *rs_ctx = NULL; -#endif - - if( ctx->grp.pbits == 0 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( restart_enabled ) - rs_ctx = &ctx->rs; -#else - (void) restart_enabled; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng, rs_ctx ) ) != 0 ) - return( ret ); -#else - if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng ) ) != 0 ) - return( ret ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, olen, - buf, blen ); -} - -/* - * Setup and export the client public value - */ -int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int restart_enabled = 0; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( olen != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - ECDH_VALIDATE_RET( f_rng != NULL ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - restart_enabled = ctx->restart_enabled; -#endif - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_make_public_internal( ctx, olen, ctx->point_format, buf, blen, - f_rng, p_rng, restart_enabled ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen, - ctx->point_format, buf, blen, - f_rng, p_rng, - restart_enabled ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx, - const unsigned char *buf, size_t blen ) -{ - int ret; - const unsigned char *p = buf; - - if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, - blen ) ) != 0 ) - return( ret ); - - if( (size_t)( p - buf ) != blen ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - return( 0 ); -} - -/* - * Parse and import the client's public value - */ -int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, - const unsigned char *buf, size_t blen ) -{ - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_read_public_internal( ctx, buf, blen ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh, - buf, blen ) ); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx, - size_t *olen, unsigned char *buf, - size_t blen, - int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng, - int restart_enabled ) -{ - int ret; -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx *rs_ctx = NULL; -#endif - - if( ctx == NULL || ctx->grp.pbits == 0 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( restart_enabled ) - rs_ctx = &ctx->rs; -#else - (void) restart_enabled; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( ( ret = ecdh_compute_shared_restartable( &ctx->grp, &ctx->z, &ctx->Qp, - &ctx->d, f_rng, p_rng, - rs_ctx ) ) != 0 ) - { - return( ret ); - } -#else - if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, - &ctx->d, f_rng, p_rng ) ) != 0 ) - { - return( ret ); - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - if( mbedtls_mpi_size( &ctx->z ) > blen ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); - return mbedtls_mpi_write_binary( &ctx->z, buf, *olen ); -} - -/* - * Derive and export the shared secret - */ -int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int restart_enabled = 0; - ECDH_VALIDATE_RET( ctx != NULL ); - ECDH_VALIDATE_RET( olen != NULL ); - ECDH_VALIDATE_RET( buf != NULL ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - restart_enabled = ctx->restart_enabled; -#endif - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return( ecdh_calc_secret_internal( ctx, olen, buf, blen, f_rng, p_rng, - restart_enabled ) ); -#else - switch( ctx->var ) - { - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf, - blen, f_rng, p_rng, - restart_enabled ) ); - default: - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } -#endif -} - -#endif /* MBEDTLS_ECDH_C */ diff --git a/mbedtls/ecdh.h b/mbedtls/ecdh.h deleted file mode 100644 index ca0175705..000000000 --- a/mbedtls/ecdh.h +++ /dev/null @@ -1,466 +0,0 @@ -#pragma GCC system_header -/** - * \file ecdh.h - * - * \brief This file contains ECDH definitions and functions. - * - * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous - * key agreement protocol allowing two parties to establish a shared - * secret over an insecure channel. Each party must have an - * elliptic-curve public–private key pair. - * - * For more information, see NIST SP 800-56A Rev. 2: Recommendation for - * Pair-Wise Key Establishment Schemes Using Discrete Logarithm - * Cryptography. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_ECDH_H -#define MBEDTLS_ECDH_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ecp.h" - -/* - * Use a backward compatible ECDH context. - * - * This flag is always enabled for now and future versions might add a - * configuration option that conditionally undefines this flag. - * The configuration option in question may have a different name. - * - * Features undefining this flag, must have a warning in their description in - * config.h stating that the feature breaks backward compatibility. - */ -#define MBEDTLS_ECDH_LEGACY_CONTEXT - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Defines the source of the imported EC key. - */ -typedef enum -{ - MBEDTLS_ECDH_OURS, /**< Our key. */ - MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */ -} mbedtls_ecdh_side; - -#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) -/** - * Defines the ECDH implementation used. - * - * Later versions of the library may add new variants, therefore users should - * not make any assumptions about them. - */ -typedef enum -{ - MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */ - MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */ -} mbedtls_ecdh_variant; - -/** - * The context used by the default ECDH implementation. - * - * Later versions might change the structure of this context, therefore users - * should not make any assumptions about the structure of - * mbedtls_ecdh_context_mbed. - */ -typedef struct mbedtls_ecdh_context_mbed -{ - mbedtls_ecp_group grp; /*!< The elliptic curve used. */ - mbedtls_mpi d; /*!< The private key. */ - mbedtls_ecp_point Q; /*!< The public key. */ - mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */ - mbedtls_mpi z; /*!< The shared secret. */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */ -#endif -} mbedtls_ecdh_context_mbed; -#endif - -/** - * - * \warning Performing multiple operations concurrently on the same - * ECDSA context is not supported; objects of this type - * should not be shared between multiple threads. - * \brief The ECDH context structure. - */ -typedef struct mbedtls_ecdh_context -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - mbedtls_ecp_group grp; /*!< The elliptic curve used. */ - mbedtls_mpi d; /*!< The private key. */ - mbedtls_ecp_point Q; /*!< The public key. */ - mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */ - mbedtls_mpi z; /*!< The shared secret. */ - int point_format; /*!< The format of point export in TLS messages. */ - mbedtls_ecp_point Vi; /*!< The blinding value. */ - mbedtls_ecp_point Vf; /*!< The unblinding value. */ - mbedtls_mpi _d; /*!< The previous \p d. */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - int restart_enabled; /*!< The flag for restartable mode. */ - mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */ -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#else - uint8_t point_format; /*!< The format of point export in TLS messages - as defined in RFC 4492. */ - mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */ - mbedtls_ecdh_variant var; /*!< The ECDH implementation/structure used. */ - union - { - mbedtls_ecdh_context_mbed mbed_ecdh; - } ctx; /*!< Implementation-specific context. The - context in use is specified by the \c var - field. */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - uint8_t restart_enabled; /*!< The flag for restartable mode. Functions of - an alternative implementation not supporting - restartable mode must return - MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error - if this flag is set. */ -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ -} -mbedtls_ecdh_context; - -/** - * \brief This function generates an ECDH keypair on an elliptic - * curve. - * - * This function performs the first of two core computations - * implemented during the ECDH key exchange. The second core - * computation is performed by mbedtls_ecdh_compute_shared(). - * - * \see ecp.h - * - * \param grp The ECP group to use. This must be initialized and have - * domain parameters loaded, for example through - * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). - * \param d The destination MPI (private key). - * This must be initialized. - * \param Q The destination point (public key). - * This must be initialized. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL in case \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return Another \c MBEDTLS_ERR_ECP_XXX or - * \c MBEDTLS_MPI_XXX error code on failure. - */ -int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function computes the shared secret. - * - * This function performs the second of two core computations - * implemented during the ECDH key exchange. The first core - * computation is performed by mbedtls_ecdh_gen_public(). - * - * \see ecp.h - * - * \note If \p f_rng is not NULL, it is used to implement - * countermeasures against side-channel attacks. - * For more information, see mbedtls_ecp_mul(). - * - * \param grp The ECP group to use. This must be initialized and have - * domain parameters loaded, for example through - * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). - * \param z The destination MPI (shared secret). - * This must be initialized. - * \param Q The public key from another party. - * This must be initialized. - * \param d Our secret exponent (private key). - * This must be initialized. - * \param f_rng The RNG function. This may be \c NULL if randomization - * of intermediate results during the ECP computations is - * not needed (discouraged). See the documentation of - * mbedtls_ecp_mul() for more. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a - * context argument. - * - * \return \c 0 on success. - * \return Another \c MBEDTLS_ERR_ECP_XXX or - * \c MBEDTLS_MPI_XXX error code on failure. - */ -int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, - const mbedtls_ecp_point *Q, const mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function initializes an ECDH context. - * - * \param ctx The ECDH context to initialize. This must not be \c NULL. - */ -void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ); - -/** - * \brief This function sets up the ECDH context with the information - * given. - * - * This function should be called after mbedtls_ecdh_init() but - * before mbedtls_ecdh_make_params(). There is no need to call - * this function before mbedtls_ecdh_read_params(). - * - * This is the first function used by a TLS server for ECDHE - * ciphersuites. - * - * \param ctx The ECDH context to set up. This must be initialized. - * \param grp_id The group id of the group to set up the context for. - * - * \return \c 0 on success. - */ -int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, - mbedtls_ecp_group_id grp_id ); - -/** - * \brief This function frees a context. - * - * \param ctx The context to free. This may be \c NULL, in which - * case this function does nothing. If it is not \c NULL, - * it must point to an initialized ECDH context. - */ -void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ); - -/** - * \brief This function generates an EC key pair and exports its - * in the format used in a TLS ServerKeyExchange handshake - * message. - * - * This is the second function used by a TLS server for ECDHE - * ciphersuites. (It is called after mbedtls_ecdh_setup().) - * - * \see ecp.h - * - * \param ctx The ECDH context to use. This must be initialized - * and bound to a group, for example via mbedtls_ecdh_setup(). - * \param olen The address at which to store the number of Bytes written. - * \param buf The destination buffer. This must be a writable buffer of - * length \p blen Bytes. - * \param blen The length of the destination buffer \p buf in Bytes. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL in case \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. - */ -int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function parses the ECDHE parameters in a - * TLS ServerKeyExchange handshake message. - * - * \note In a TLS handshake, this is the how the client - * sets up its ECDHE context from the server's public - * ECDHE key material. - * - * \see ecp.h - * - * \param ctx The ECDHE context to use. This must be initialized. - * \param buf On input, \c *buf must be the start of the input buffer. - * On output, \c *buf is updated to point to the end of the - * data that has been read. On success, this is the first byte - * past the end of the ServerKeyExchange parameters. - * On error, this is the point at which an error has been - * detected, which is usually not useful except to debug - * failures. - * \param end The end of the input buffer. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. - * - */ -int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, - const unsigned char **buf, - const unsigned char *end ); - -/** - * \brief This function sets up an ECDH context from an EC key. - * - * It is used by clients and servers in place of the - * ServerKeyEchange for static ECDH, and imports ECDH - * parameters from the EC key information of a certificate. - * - * \see ecp.h - * - * \param ctx The ECDH context to set up. This must be initialized. - * \param key The EC key to use. This must be initialized. - * \param side Defines the source of the key. Possible values are: - * - #MBEDTLS_ECDH_OURS: The key is ours. - * - #MBEDTLS_ECDH_THEIRS: The key is that of the peer. - * - * \return \c 0 on success. - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. - * - */ -int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, - const mbedtls_ecp_keypair *key, - mbedtls_ecdh_side side ); - -/** - * \brief This function generates a public key and exports it - * as a TLS ClientKeyExchange payload. - * - * This is the second function used by a TLS client for ECDH(E) - * ciphersuites. - * - * \see ecp.h - * - * \param ctx The ECDH context to use. This must be initialized - * and bound to a group, the latter usually by - * mbedtls_ecdh_read_params(). - * \param olen The address at which to store the number of Bytes written. - * This must not be \c NULL. - * \param buf The destination buffer. This must be a writable buffer - * of length \p blen Bytes. - * \param blen The size of the destination buffer \p buf in Bytes. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL in case \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. - */ -int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function parses and processes the ECDHE payload of a - * TLS ClientKeyExchange message. - * - * This is the third function used by a TLS server for ECDH(E) - * ciphersuites. (It is called after mbedtls_ecdh_setup() and - * mbedtls_ecdh_make_params().) - * - * \see ecp.h - * - * \param ctx The ECDH context to use. This must be initialized - * and bound to a group, for example via mbedtls_ecdh_setup(). - * \param buf The pointer to the ClientKeyExchange payload. This must - * be a readable buffer of length \p blen Bytes. - * \param blen The length of the input buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. - */ -int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, - const unsigned char *buf, size_t blen ); - -/** - * \brief This function derives and exports the shared secret. - * - * This is the last function used by both TLS client - * and servers. - * - * \note If \p f_rng is not NULL, it is used to implement - * countermeasures against side-channel attacks. - * For more information, see mbedtls_ecp_mul(). - * - * \see ecp.h - - * \param ctx The ECDH context to use. This must be initialized - * and have its own private key generated and the peer's - * public key imported. - * \param olen The address at which to store the total number of - * Bytes written on success. This must not be \c NULL. - * \param buf The buffer to write the generated shared key to. This - * must be a writable buffer of size \p blen Bytes. - * \param blen The length of the destination buffer \p buf in Bytes. - * \param f_rng The RNG function, for blinding purposes. This may - * b \c NULL if blinding isn't needed. - * \param p_rng The RNG context. This may be \c NULL if \p f_rng - * doesn't need a context argument. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. - */ -int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief This function enables restartable EC computations for this - * context. (Default: disabled.) - * - * \see \c mbedtls_ecp_set_max_ops() - * - * \note It is not possible to safely disable restartable - * computations once enabled, except by free-ing the context, - * which cancels possible in-progress operations. - * - * \param ctx The ECDH context to use. This must be initialized. - */ -void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#ifdef __cplusplus -} -#endif - -#endif /* ecdh.h */ diff --git a/mbedtls/ecdsa.c b/mbedtls/ecdsa.c deleted file mode 100644 index d9fb9b189..000000000 --- a/mbedtls/ecdsa.c +++ /dev/null @@ -1,1037 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Elliptic curve DSA - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * References: - * - * SEC1 http://www.secg.org/index.php?action=secg,docs_secg - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ECDSA_C) - -#include "mbedtls/ecdsa.h" -#include "mbedtls/asn1write.h" - -#include - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -#include "mbedtls/hmac_drbg.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/platform_util.h" - -/* Parameter validation macros based on platform_util.h */ -#define ECDSA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECDSA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_ECP_RESTARTABLE) - -/* - * Sub-context for ecdsa_verify() - */ -struct mbedtls_ecdsa_restart_ver -{ - mbedtls_mpi u1, u2; /* intermediate values */ - enum { /* what to do next? */ - ecdsa_ver_init = 0, /* getting started */ - ecdsa_ver_muladd, /* muladd step */ - } state; -}; - -/* - * Init verify restart sub-context - */ -static void ecdsa_restart_ver_init( mbedtls_ecdsa_restart_ver_ctx *ctx ) -{ - mbedtls_mpi_init( &ctx->u1 ); - mbedtls_mpi_init( &ctx->u2 ); - ctx->state = ecdsa_ver_init; -} - -/* - * Free the components of a verify restart sub-context - */ -static void ecdsa_restart_ver_free( mbedtls_ecdsa_restart_ver_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_mpi_free( &ctx->u1 ); - mbedtls_mpi_free( &ctx->u2 ); - - ecdsa_restart_ver_init( ctx ); -} - -/* - * Sub-context for ecdsa_sign() - */ -struct mbedtls_ecdsa_restart_sig -{ - int sign_tries; - int key_tries; - mbedtls_mpi k; /* per-signature random */ - mbedtls_mpi r; /* r value */ - enum { /* what to do next? */ - ecdsa_sig_init = 0, /* getting started */ - ecdsa_sig_mul, /* doing ecp_mul() */ - ecdsa_sig_modn, /* mod N computations */ - } state; -}; - -/* - * Init verify sign sub-context - */ -static void ecdsa_restart_sig_init( mbedtls_ecdsa_restart_sig_ctx *ctx ) -{ - ctx->sign_tries = 0; - ctx->key_tries = 0; - mbedtls_mpi_init( &ctx->k ); - mbedtls_mpi_init( &ctx->r ); - ctx->state = ecdsa_sig_init; -} - -/* - * Free the components of a sign restart sub-context - */ -static void ecdsa_restart_sig_free( mbedtls_ecdsa_restart_sig_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_mpi_free( &ctx->k ); - mbedtls_mpi_free( &ctx->r ); -} - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/* - * Sub-context for ecdsa_sign_det() - */ -struct mbedtls_ecdsa_restart_det -{ - mbedtls_hmac_drbg_context rng_ctx; /* DRBG state */ - enum { /* what to do next? */ - ecdsa_det_init = 0, /* getting started */ - ecdsa_det_sign, /* make signature */ - } state; -}; - -/* - * Init verify sign_det sub-context - */ -static void ecdsa_restart_det_init( mbedtls_ecdsa_restart_det_ctx *ctx ) -{ - mbedtls_hmac_drbg_init( &ctx->rng_ctx ); - ctx->state = ecdsa_det_init; -} - -/* - * Free the components of a sign_det restart sub-context - */ -static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_hmac_drbg_free( &ctx->rng_ctx ); - - ecdsa_restart_det_init( ctx ); -} -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -#define ECDSA_RS_ECP ( rs_ctx == NULL ? NULL : &rs_ctx->ecp ) - -/* Utility macro for checking and updating ops budget */ -#define ECDSA_BUDGET( ops ) \ - MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, ECDSA_RS_ECP, ops ) ); - -/* Call this when entering a function that needs its own sub-context */ -#define ECDSA_RS_ENTER( SUB ) do { \ - /* reset ops count for this call if top-level */ \ - if( rs_ctx != NULL && rs_ctx->ecp.depth++ == 0 ) \ - rs_ctx->ecp.ops_done = 0; \ - \ - /* set up our own sub-context if needed */ \ - if( mbedtls_ecp_restart_is_enabled() && \ - rs_ctx != NULL && rs_ctx->SUB == NULL ) \ - { \ - rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) ); \ - if( rs_ctx->SUB == NULL ) \ - return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); \ - \ - ecdsa_restart_## SUB ##_init( rs_ctx->SUB ); \ - } \ -} while( 0 ) - -/* Call this when leaving a function that needs its own sub-context */ -#define ECDSA_RS_LEAVE( SUB ) do { \ - /* clear our sub-context when not in progress (done or error) */ \ - if( rs_ctx != NULL && rs_ctx->SUB != NULL && \ - ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) \ - { \ - ecdsa_restart_## SUB ##_free( rs_ctx->SUB ); \ - mbedtls_free( rs_ctx->SUB ); \ - rs_ctx->SUB = NULL; \ - } \ - \ - if( rs_ctx != NULL ) \ - rs_ctx->ecp.depth--; \ -} while( 0 ) - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define ECDSA_RS_ECP NULL - -#define ECDSA_BUDGET( ops ) /* no-op; for compatibility */ - -#define ECDSA_RS_ENTER( SUB ) (void) rs_ctx -#define ECDSA_RS_LEAVE( SUB ) (void) rs_ctx - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) || \ - !defined(MBEDTLS_ECDSA_SIGN_ALT) || \ - !defined(MBEDTLS_ECDSA_VERIFY_ALT) -/* - * Derive a suitable integer for group grp from a buffer of length len - * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 - */ -static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x, - const unsigned char *buf, size_t blen ) -{ - int ret; - size_t n_size = ( grp->nbits + 7 ) / 8; - size_t use_size = blen > n_size ? n_size : blen; - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) ); - if( use_size * 8 > grp->nbits ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) ); - - /* While at it, reduce modulo N */ - if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) ); - -cleanup: - return( ret ); -} -#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */ - -#if !defined(MBEDTLS_ECDSA_SIGN_ALT) -/* - * Compute ECDSA signature of a hashed message (SEC1 4.1.3) - * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) - */ -static int ecdsa_sign_restartable( mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - int (*f_rng_blind)(void *, unsigned char *, size_t), - void *p_rng_blind, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret, key_tries, sign_tries; - int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries; - mbedtls_ecp_point R; - mbedtls_mpi k, e, t; - mbedtls_mpi *pk = &k, *pr = r; - - /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ - if( grp->N.p == NULL ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* Make sure d is in range 1..n-1 */ - if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - mbedtls_ecp_point_init( &R ); - mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t ); - - ECDSA_RS_ENTER( sig ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->sig != NULL ) - { - /* redirect to our context */ - p_sign_tries = &rs_ctx->sig->sign_tries; - p_key_tries = &rs_ctx->sig->key_tries; - pk = &rs_ctx->sig->k; - pr = &rs_ctx->sig->r; - - /* jump to current step */ - if( rs_ctx->sig->state == ecdsa_sig_mul ) - goto mul; - if( rs_ctx->sig->state == ecdsa_sig_modn ) - goto modn; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - *p_sign_tries = 0; - do - { - if( (*p_sign_tries)++ > 10 ) - { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - goto cleanup; - } - - /* - * Steps 1-3: generate a suitable ephemeral keypair - * and set r = xR mod n - */ - *p_key_tries = 0; - do - { - if( (*p_key_tries)++ > 10 ) - { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, pk, f_rng, p_rng ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->sig != NULL ) - rs_ctx->sig->state = ecdsa_sig_mul; - -mul: -#endif - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &R, pk, &grp->G, - f_rng_blind, - p_rng_blind, - ECDSA_RS_ECP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) ); - } - while( mbedtls_mpi_cmp_int( pr, 0 ) == 0 ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->sig != NULL ) - rs_ctx->sig->state = ecdsa_sig_modn; - -modn: -#endif - /* - * Accounting for everything up to the end of the loop - * (step 6, but checking now avoids saving e and t) - */ - ECDSA_BUDGET( MBEDTLS_ECP_OPS_INV + 4 ); - - /* - * Step 5: derive MPI from hashed message - */ - MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); - - /* - * Generate a random value to blind inv_mod in next step, - * avoiding a potential timing leak. - */ - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng_blind, - p_rng_blind ) ); - - /* - * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, pr, d ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pk, pk, &grp->N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) ); - } - while( mbedtls_mpi_cmp_int( s, 0 ) == 0 ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->sig != NULL ) - mbedtls_mpi_copy( r, pr ); -#endif - -cleanup: - mbedtls_ecp_point_free( &R ); - mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t ); - - ECDSA_RS_LEAVE( sig ); - - return( ret ); -} - -/* - * Compute ECDSA signature of a hashed message - */ -int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - ECDSA_VALIDATE_RET( grp != NULL ); - ECDSA_VALIDATE_RET( r != NULL ); - ECDSA_VALIDATE_RET( s != NULL ); - ECDSA_VALIDATE_RET( d != NULL ); - ECDSA_VALIDATE_RET( f_rng != NULL ); - ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); - - /* Use the same RNG for both blinding and ephemeral key generation */ - return( ecdsa_sign_restartable( grp, r, s, d, buf, blen, - f_rng, p_rng, f_rng, p_rng, NULL ) ); -} -#endif /* !MBEDTLS_ECDSA_SIGN_ALT */ - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/* - * Deterministic signature wrapper - */ -static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - int (*f_rng_blind)(void *, unsigned char *, size_t), - void *p_rng_blind, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_hmac_drbg_context rng_ctx; - mbedtls_hmac_drbg_context *p_rng = &rng_ctx; - unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; - size_t grp_len = ( grp->nbits + 7 ) / 8; - const mbedtls_md_info_t *md_info; - mbedtls_mpi h; - - if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &h ); - mbedtls_hmac_drbg_init( &rng_ctx ); - - ECDSA_RS_ENTER( det ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->det != NULL ) - { - /* redirect to our context */ - p_rng = &rs_ctx->det->rng_ctx; - - /* jump to current step */ - if( rs_ctx->det->state == ecdsa_det_sign ) - goto sign; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); - MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); - mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->det != NULL ) - rs_ctx->det->state = ecdsa_det_sign; - -sign: -#endif -#if defined(MBEDTLS_ECDSA_SIGN_ALT) - ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, - mbedtls_hmac_drbg_random, p_rng ); -#else - if( f_rng_blind != NULL ) - ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen, - mbedtls_hmac_drbg_random, p_rng, - f_rng_blind, p_rng_blind, rs_ctx ); - else - { - mbedtls_hmac_drbg_context *p_rng_blind_det; - -#if !defined(MBEDTLS_ECP_RESTARTABLE) - /* - * To avoid reusing rng_ctx and risking incorrect behavior we seed a - * second HMAC-DRBG with the same seed. We also apply a label to avoid - * reusing the bits of the ephemeral key for blinding and eliminate the - * risk that they leak this way. - */ - const char* blind_label = "BLINDING CONTEXT"; - mbedtls_hmac_drbg_context rng_ctx_blind; - - mbedtls_hmac_drbg_init( &rng_ctx_blind ); - p_rng_blind_det = &rng_ctx_blind; - - mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info, - data, 2 * grp_len ); - ret = mbedtls_hmac_drbg_update_ret( p_rng_blind_det, - (const unsigned char*) blind_label, - strlen( blind_label ) ); - if( ret != 0 ) - { - mbedtls_hmac_drbg_free( &rng_ctx_blind ); - goto cleanup; - } -#else - /* - * In the case of restartable computations we would either need to store - * the second RNG in the restart context too or set it up at every - * restart. The first option would penalize the correct application of - * the function and the second would defeat the purpose of the - * restartable feature. - * - * Therefore in this case we reuse the original RNG. This comes with the - * price that the resulting signature might not be a valid deterministic - * ECDSA signature with a very low probability (same magnitude as - * successfully guessing the private key). However even then it is still - * a valid ECDSA signature. - */ - p_rng_blind_det = p_rng; -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - /* - * Since the output of the RNGs is always the same for the same key and - * message, this limits the efficiency of blinding and leaks information - * through side channels. After mbedtls_ecdsa_sign_det() is removed NULL - * won't be a valid value for f_rng_blind anymore. Therefore it should - * be checked by the caller and this branch and check can be removed. - */ - ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen, - mbedtls_hmac_drbg_random, p_rng, - mbedtls_hmac_drbg_random, p_rng_blind_det, - rs_ctx ); - -#if !defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_hmac_drbg_free( &rng_ctx_blind ); -#endif - } -#endif /* MBEDTLS_ECDSA_SIGN_ALT */ - -cleanup: - mbedtls_hmac_drbg_free( &rng_ctx ); - mbedtls_mpi_free( &h ); - - ECDSA_RS_LEAVE( det ); - - return( ret ); -} - -/* - * Deterministic signature wrappers - */ -int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, - mbedtls_mpi *s, const mbedtls_mpi *d, - const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg ) -{ - ECDSA_VALIDATE_RET( grp != NULL ); - ECDSA_VALIDATE_RET( r != NULL ); - ECDSA_VALIDATE_RET( s != NULL ); - ECDSA_VALIDATE_RET( d != NULL ); - ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); - - return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, - NULL, NULL, NULL ) ); -} - -int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r, - mbedtls_mpi *s, const mbedtls_mpi *d, - const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - int (*f_rng_blind)(void *, unsigned char *, - size_t), - void *p_rng_blind ) -{ - ECDSA_VALIDATE_RET( grp != NULL ); - ECDSA_VALIDATE_RET( r != NULL ); - ECDSA_VALIDATE_RET( s != NULL ); - ECDSA_VALIDATE_RET( d != NULL ); - ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); - ECDSA_VALIDATE_RET( f_rng_blind != NULL ); - - return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, - f_rng_blind, p_rng_blind, NULL ) ); -} -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -#if !defined(MBEDTLS_ECDSA_VERIFY_ALT) -/* - * Verify ECDSA signature of hashed message (SEC1 4.1.4) - * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) - */ -static int ecdsa_verify_restartable( mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, - const mbedtls_mpi *r, const mbedtls_mpi *s, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_mpi e, s_inv, u1, u2; - mbedtls_ecp_point R; - mbedtls_mpi *pu1 = &u1, *pu2 = &u2; - - mbedtls_ecp_point_init( &R ); - mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv ); - mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 ); - - /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ - if( grp->N.p == NULL ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - ECDSA_RS_ENTER( ver ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ver != NULL ) - { - /* redirect to our context */ - pu1 = &rs_ctx->ver->u1; - pu2 = &rs_ctx->ver->u2; - - /* jump to current step */ - if( rs_ctx->ver->state == ecdsa_ver_muladd ) - goto muladd; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - /* - * Step 1: make sure r and s are in range 1..n-1 - */ - if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 || - mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 ) - { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - - /* - * Step 3: derive MPI from hashed message - */ - MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); - - /* - * Step 4: u1 = e / s mod n, u2 = r / s mod n - */ - ECDSA_BUDGET( MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu1, &e, &s_inv ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu1, pu1, &grp->N ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu2, r, &s_inv ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu2, pu2, &grp->N ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ver != NULL ) - rs_ctx->ver->state = ecdsa_ver_muladd; - -muladd: -#endif - /* - * Step 5: R = u1 G + u2 Q - */ - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd_restartable( grp, - &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP ) ); - - if( mbedtls_ecp_is_zero( &R ) ) - { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - - /* - * Step 6: convert xR to an integer (no-op) - * Step 7: reduce xR mod n (gives v) - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) ); - - /* - * Step 8: check if v (that is, R.X) is equal to r - */ - if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 ) - { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free( &R ); - mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv ); - mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 ); - - ECDSA_RS_LEAVE( ver ); - - return( ret ); -} - -/* - * Verify ECDSA signature of hashed message - */ -int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, - const mbedtls_mpi *r, - const mbedtls_mpi *s) -{ - ECDSA_VALIDATE_RET( grp != NULL ); - ECDSA_VALIDATE_RET( Q != NULL ); - ECDSA_VALIDATE_RET( r != NULL ); - ECDSA_VALIDATE_RET( s != NULL ); - ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); - - return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) ); -} -#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ - -/* - * Convert a signature (given by context) to ASN.1 - */ -static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s, - unsigned char *sig, size_t *slen ) -{ - int ret; - unsigned char buf[MBEDTLS_ECDSA_MAX_LEN]; - unsigned char *p = buf + sizeof( buf ); - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - - memcpy( sig, p, len ); - *slen = len; - - return( 0 ); -} - -/* - * Compute and write signature - */ -int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_mpi r, s; - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - ECDSA_VALIDATE_RET( slen != NULL ); - - mbedtls_mpi_init( &r ); - mbedtls_mpi_init( &s ); - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - MBEDTLS_MPI_CHK( ecdsa_sign_det_restartable( &ctx->grp, &r, &s, &ctx->d, - hash, hlen, md_alg, f_rng, - p_rng, rs_ctx ) ); -#else - (void) md_alg; - -#if defined(MBEDTLS_ECDSA_SIGN_ALT) - (void) rs_ctx; - - MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d, - hash, hlen, f_rng, p_rng ) ); -#else - /* Use the same RNG for both blinding and ephemeral key generation */ - MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d, - hash, hlen, f_rng, p_rng, f_rng, - p_rng, rs_ctx ) ); -#endif /* MBEDTLS_ECDSA_SIGN_ALT */ -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - - MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) ); - -cleanup: - mbedtls_mpi_free( &r ); - mbedtls_mpi_free( &s ); - - return( ret ); -} - -/* - * Compute and write signature - */ -int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - ECDSA_VALIDATE_RET( slen != NULL ); - return( mbedtls_ecdsa_write_signature_restartable( - ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) && \ - defined(MBEDTLS_ECDSA_DETERMINISTIC) -int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - mbedtls_md_type_t md_alg ) -{ - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - ECDSA_VALIDATE_RET( slen != NULL ); - return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen, - NULL, NULL ) ); -} -#endif - -/* - * Read and check signature - */ -int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen ) -{ - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - return( mbedtls_ecdsa_read_signature_restartable( - ctx, hash, hlen, sig, slen, NULL ) ); -} - -/* - * Restartable read and check signature - */ -int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen, - mbedtls_ecdsa_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char *p = (unsigned char *) sig; - const unsigned char *end = sig + slen; - size_t len; - mbedtls_mpi r, s; - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( hash != NULL ); - ECDSA_VALIDATE_RET( sig != NULL ); - - mbedtls_mpi_init( &r ); - mbedtls_mpi_init( &s ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - if( p + len != end ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - goto cleanup; - } - - if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 ) - { - ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } -#if defined(MBEDTLS_ECDSA_VERIFY_ALT) - (void) rs_ctx; - - if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen, - &ctx->Q, &r, &s ) ) != 0 ) - goto cleanup; -#else - if( ( ret = ecdsa_verify_restartable( &ctx->grp, hash, hlen, - &ctx->Q, &r, &s, rs_ctx ) ) != 0 ) - goto cleanup; -#endif /* MBEDTLS_ECDSA_VERIFY_ALT */ - - /* At this point we know that the buffer starts with a valid signature. - * Return 0 if the buffer just contains the signature, and a specific - * error code if the valid signature is followed by more data. */ - if( p != end ) - ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; - -cleanup: - mbedtls_mpi_free( &r ); - mbedtls_mpi_free( &s ); - - return( ret ); -} - -#if !defined(MBEDTLS_ECDSA_GENKEY_ALT) -/* - * Generate key pair - */ -int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret = 0; - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( f_rng != NULL ); - - ret = mbedtls_ecp_group_load( &ctx->grp, gid ); - if( ret != 0 ) - return( ret ); - - return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, - &ctx->Q, f_rng, p_rng ) ); -} -#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */ - -/* - * Set context from an mbedtls_ecp_keypair - */ -int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ) -{ - int ret; - ECDSA_VALIDATE_RET( ctx != NULL ); - ECDSA_VALIDATE_RET( key != NULL ); - - if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 || - ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 || - ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ) - { - mbedtls_ecdsa_free( ctx ); - } - - return( ret ); -} - -/* - * Initialize context - */ -void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ) -{ - ECDSA_VALIDATE( ctx != NULL ); - - mbedtls_ecp_keypair_init( ctx ); -} - -/* - * Free context - */ -void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_ecp_keypair_free( ctx ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx ) -{ - ECDSA_VALIDATE( ctx != NULL ); - - mbedtls_ecp_restart_init( &ctx->ecp ); - - ctx->ver = NULL; - ctx->sig = NULL; -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - ctx->det = NULL; -#endif -} - -/* - * Free the components of a restart context - */ -void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_ecp_restart_free( &ctx->ecp ); - - ecdsa_restart_ver_free( ctx->ver ); - mbedtls_free( ctx->ver ); - ctx->ver = NULL; - - ecdsa_restart_sig_free( ctx->sig ); - mbedtls_free( ctx->sig ); - ctx->sig = NULL; - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - ecdsa_restart_det_free( ctx->det ); - mbedtls_free( ctx->det ); - ctx->det = NULL; -#endif -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#endif /* MBEDTLS_ECDSA_C */ diff --git a/mbedtls/ecdsa.h b/mbedtls/ecdsa.h deleted file mode 100644 index c8a819a2b..000000000 --- a/mbedtls/ecdsa.h +++ /dev/null @@ -1,630 +0,0 @@ -#pragma GCC system_header -/** - * \file ecdsa.h - * - * \brief This file contains ECDSA definitions and functions. - * - * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in - * Standards for Efficient Cryptography Group (SECG): - * SEC1 Elliptic Curve Cryptography. - * The use of ECDSA for TLS is defined in RFC-4492: Elliptic Curve - * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS). - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_ECDSA_H -#define MBEDTLS_ECDSA_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ecp.h" -#include "md.h" - -/* - * RFC-4492 page 20: - * - * Ecdsa-Sig-Value ::= SEQUENCE { - * r INTEGER, - * s INTEGER - * } - * - * Size is at most - * 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s, - * twice that + 1 (tag) + 2 (len) for the sequence - * (assuming ECP_MAX_BYTES is less than 126 for r and s, - * and less than 124 (total len <= 255) for the sequence) - */ -#if MBEDTLS_ECP_MAX_BYTES > 124 -#error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN" -#endif -/** The maximal size of an ECDSA signature in Bytes. */ -#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) ) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief The ECDSA context structure. - * - * \warning Performing multiple operations concurrently on the same - * ECDSA context is not supported; objects of this type - * should not be shared between multiple threads. - */ -typedef mbedtls_ecp_keypair mbedtls_ecdsa_context; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Internal restart context for ecdsa_verify() - * - * \note Opaque struct, defined in ecdsa.c - */ -typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx; - -/** - * \brief Internal restart context for ecdsa_sign() - * - * \note Opaque struct, defined in ecdsa.c - */ -typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx; - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/** - * \brief Internal restart context for ecdsa_sign_det() - * - * \note Opaque struct, defined in ecdsa.c - */ -typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx; -#endif - -/** - * \brief General context for resuming ECDSA operations - */ -typedef struct -{ - mbedtls_ecp_restart_ctx ecp; /*!< base context for ECP restart and - shared administrative info */ - mbedtls_ecdsa_restart_ver_ctx *ver; /*!< ecdsa_verify() sub-context */ - mbedtls_ecdsa_restart_sig_ctx *sig; /*!< ecdsa_sign() sub-context */ -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - mbedtls_ecdsa_restart_det_ctx *det; /*!< ecdsa_sign_det() sub-context */ -#endif -} mbedtls_ecdsa_restart_ctx; - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_ecdsa_restart_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief This function computes the ECDSA signature of a - * previously-hashed message. - * - * \note The deterministic version implemented in - * mbedtls_ecdsa_sign_det() is usually preferred. - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated - * as defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.3, step 5. - * - * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized. - * \param buf The content to be signed. This is usually the hash of - * the original data to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX - * or \c MBEDTLS_MPI_XXX error code on failure. - */ -int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/** - * \brief This function computes the ECDSA signature of a - * previously-hashed message, deterministic version. - * - * For more information, see RFC-6979: Deterministic - * Usage of the Digital Signature Algorithm (DSA) and Elliptic - * Curve Digital Signature Algorithm (ECDSA). - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.3, step 5. - * - * \warning Since the output of the internal RNG is always the same for - * the same key and message, this limits the efficiency of - * blinding and leaks information through side channels. For - * secure behavior use mbedtls_ecdsa_sign_det_ext() instead. - * - * (Optimally the blinding is a random value that is different - * on every execution. In this case the blinding is still - * random from the attackers perspective, but is the same on - * each execution. This means that this blinding does not - * prevent attackers from recovering secrets by combining - * several measurement traces, but may prevent some attacks - * that exploit relationships between secret data.) - * - * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized - * and setup, for example through mbedtls_ecp_gen_privkey(). - * \param buf The hashed content to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param md_alg The hash algorithm used to hash the original data. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX - * error code on failure. - */ -int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, - mbedtls_mpi *s, const mbedtls_mpi *d, - const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg ); -/** - * \brief This function computes the ECDSA signature of a - * previously-hashed message, deterministic version. - * - * For more information, see RFC-6979: Deterministic - * Usage of the Digital Signature Algorithm (DSA) and Elliptic - * Curve Digital Signature Algorithm (ECDSA). - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.3, step 5. - * - * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized - * and setup, for example through mbedtls_ecp_gen_privkey(). - * \param buf The hashed content to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param md_alg The hash algorithm used to hash the original data. - * \param f_rng_blind The RNG function used for blinding. This must not be - * \c NULL. - * \param p_rng_blind The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX - * error code on failure. - */ -int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r, - mbedtls_mpi *s, const mbedtls_mpi *d, - const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - int (*f_rng_blind)(void *, unsigned char *, - size_t), - void *p_rng_blind ); -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -/** - * \brief This function verifies the ECDSA signature of a - * previously-hashed message. - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.4, step 3. - * - * \see ecp.h - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param buf The hashed content that was signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param Q The public key to use for verification. This must be - * initialized and setup. - * \param r The first integer of the signature. - * This must be initialized. - * \param s The second integer of the signature. - * This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature - * is invalid. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX - * error code on failure for any other reason. - */ -int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, const mbedtls_mpi *r, - const mbedtls_mpi *s); - -/** - * \brief This function computes the ECDSA signature and writes it - * to a buffer, serialized as defined in RFC-4492: - * Elliptic Curve Cryptography (ECC) Cipher Suites for - * Transport Layer Security (TLS). - * - * \warning It is not thread-safe to use the same context in - * multiple threads. - * - * \note The deterministic version is used if - * #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more - * information, see RFC-6979: Deterministic Usage - * of the Digital Signature Algorithm (DSA) and Elliptic - * Curve Digital Signature Algorithm (ECDSA). - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.3, step 5. - * - * \see ecp.h - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and private key bound to it, for example - * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). - * \param md_alg The message digest that was used to hash the message. - * \param hash The message hash to be signed. This must be a readable - * buffer of length \p blen Bytes. - * \param hlen The length of the hash \p hash in Bytes. - * \param sig The buffer to which to write the signature. This must be a - * writable buffer of length at least twice as large as the - * size of the curve used, plus 9. For example, 73 Bytes if - * a 256-bit curve is used. A buffer length of - * #MBEDTLS_ECDSA_MAX_LEN is always safe. - * \param slen The address at which to store the actual length of - * the signature written. Must not be \c NULL. - * \param f_rng The RNG function. This must not be \c NULL if - * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, - * it is unused and may be set to \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't use a context. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or - * \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function computes the ECDSA signature and writes it - * to a buffer, in a restartable way. - * - * \see \c mbedtls_ecdsa_write_signature() - * - * \note This function is like \c mbedtls_ecdsa_write_signature() - * but it can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and private key bound to it, for example - * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). - * \param md_alg The message digest that was used to hash the message. - * \param hash The message hash to be signed. This must be a readable - * buffer of length \p blen Bytes. - * \param hlen The length of the hash \p hash in Bytes. - * \param sig The buffer to which to write the signature. This must be a - * writable buffer of length at least twice as large as the - * size of the curve used, plus 9. For example, 73 Bytes if - * a 256-bit curve is used. A buffer length of - * #MBEDTLS_ECDSA_MAX_LEN is always safe. - * \param slen The address at which to store the actual length of - * the signature written. Must not be \c NULL. - * \param f_rng The RNG function. This must not be \c NULL if - * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, - * it is unused and may be set to \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't use a context. - * \param rs_ctx The restart context to use. This may be \c NULL to disable - * restarting. If it is not \c NULL, it must point to an - * initialized restart context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or - * \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecdsa_restart_ctx *rs_ctx ); - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -#if ! defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function computes an ECDSA signature and writes - * it to a buffer, serialized as defined in RFC-4492: - * Elliptic Curve Cryptography (ECC) Cipher Suites for - * Transport Layer Security (TLS). - * - * The deterministic version is defined in RFC-6979: - * Deterministic Usage of the Digital Signature Algorithm (DSA) - * and Elliptic Curve Digital Signature Algorithm (ECDSA). - * - * \warning It is not thread-safe to use the same context in - * multiple threads. - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.3, step 5. - * - * \see ecp.h - * - * \disabled_deprecated Superseded by mbedtls_ecdsa_write_signature() in - * Mbed TLS version 2.0 and later. - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and private key bound to it, for example - * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). - * \param hash The message hash to be signed. This must be a readable - * buffer of length \p blen Bytes. - * \param hlen The length of the hash \p hash in Bytes. - * \param sig The buffer to which to write the signature. This must be a - * writable buffer of length at least twice as large as the - * size of the curve used, plus 9. For example, 73 Bytes if - * a 256-bit curve is used. A buffer length of - * #MBEDTLS_ECDSA_MAX_LEN is always safe. - * \param slen The address at which to store the actual length of - * the signature written. Must not be \c NULL. - * \param md_alg The message digest that was used to hash the message. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or - * \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t *slen, - mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED; -#undef MBEDTLS_DEPRECATED -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -/** - * \brief This function reads and verifies an ECDSA signature. - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.4, step 3. - * - * \see ecp.h - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and public key bound to it. - * \param hash The message hash that was signed. This must be a readable - * buffer of length \p size Bytes. - * \param hlen The size of the hash \p hash. - * \param sig The signature to read and verify. This must be a readable - * buffer of length \p slen Bytes. - * \param slen The size of \p sig in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. - * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid - * signature in \p sig, but its length is less than \p siglen. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX - * error code on failure for any other reason. - */ -int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen ); - -/** - * \brief This function reads and verifies an ECDSA signature, - * in a restartable way. - * - * \see \c mbedtls_ecdsa_read_signature() - * - * \note This function is like \c mbedtls_ecdsa_read_signature() - * but it can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and public key bound to it. - * \param hash The message hash that was signed. This must be a readable - * buffer of length \p size Bytes. - * \param hlen The size of the hash \p hash. - * \param sig The signature to read and verify. This must be a readable - * buffer of length \p slen Bytes. - * \param slen The size of \p sig in Bytes. - * \param rs_ctx The restart context to use. This may be \c NULL to disable - * restarting. If it is not \c NULL, it must point to an - * initialized restart context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. - * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid - * signature in \p sig, but its length is less than \p siglen. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX - * error code on failure for any other reason. - */ -int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen, - mbedtls_ecdsa_restart_ctx *rs_ctx ); - -/** - * \brief This function generates an ECDSA keypair on the given curve. - * - * \see ecp.h - * - * \param ctx The ECDSA context to store the keypair in. - * This must be initialized. - * \param gid The elliptic curve to use. One of the various - * \c MBEDTLS_ECP_DP_XXX macros depending on configuration. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. - */ -int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - -/** - * \brief This function sets up an ECDSA context from an EC key pair. - * - * \see ecp.h - * - * \param ctx The ECDSA context to setup. This must be initialized. - * \param key The EC key to use. This must be initialized and hold - * a private-public key pair or a public key. In the former - * case, the ECDSA context may be used for signature creation - * and verification after this call. In the latter case, it - * may be used for signature verification. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. - */ -int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, - const mbedtls_ecp_keypair *key ); - -/** - * \brief This function initializes an ECDSA context. - * - * \param ctx The ECDSA context to initialize. - * This must not be \c NULL. - */ -void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ); - -/** - * \brief This function frees an ECDSA context. - * - * \param ctx The ECDSA context to free. This may be \c NULL, - * in which case this function does nothing. If it - * is not \c NULL, it must be initialized. - */ -void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context. - * - * \param ctx The restart context to initialize. - * This must not be \c NULL. - */ -void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx ); - -/** - * \brief Free the components of a restart context. - * - * \param ctx The restart context to free. This may be \c NULL, - * in which case this function does nothing. If it - * is not \c NULL, it must be initialized. - */ -void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#ifdef __cplusplus -} -#endif - -#endif /* ecdsa.h */ diff --git a/mbedtls/ecjpake.c b/mbedtls/ecjpake.c deleted file mode 100644 index 4b200e45c..000000000 --- a/mbedtls/ecjpake.c +++ /dev/null @@ -1,1189 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Elliptic curve J-PAKE - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * References in the code are to the Thread v1.0 Specification, - * available to members of the Thread Group http://threadgroup.org/ - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ECJPAKE_C) - -#include "mbedtls/ecjpake.h" -#include "mbedtls/platform_util.h" - -#include - -#if !defined(MBEDTLS_ECJPAKE_ALT) - -/* Parameter validation macros based on platform_util.h */ -#define ECJPAKE_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECJPAKE_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * Convert a mbedtls_ecjpake_role to identifier string - */ -static const char * const ecjpake_id[] = { - "client", - "server" -}; - -#define ID_MINE ( ecjpake_id[ ctx->role ] ) -#define ID_PEER ( ecjpake_id[ 1 - ctx->role ] ) - -/* - * Initialize context - */ -void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ) -{ - ECJPAKE_VALIDATE( ctx != NULL ); - - ctx->md_info = NULL; - mbedtls_ecp_group_init( &ctx->grp ); - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; - - mbedtls_ecp_point_init( &ctx->Xm1 ); - mbedtls_ecp_point_init( &ctx->Xm2 ); - mbedtls_ecp_point_init( &ctx->Xp1 ); - mbedtls_ecp_point_init( &ctx->Xp2 ); - mbedtls_ecp_point_init( &ctx->Xp ); - - mbedtls_mpi_init( &ctx->xm1 ); - mbedtls_mpi_init( &ctx->xm2 ); - mbedtls_mpi_init( &ctx->s ); -} - -/* - * Free context - */ -void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ) -{ - if( ctx == NULL ) - return; - - ctx->md_info = NULL; - mbedtls_ecp_group_free( &ctx->grp ); - - mbedtls_ecp_point_free( &ctx->Xm1 ); - mbedtls_ecp_point_free( &ctx->Xm2 ); - mbedtls_ecp_point_free( &ctx->Xp1 ); - mbedtls_ecp_point_free( &ctx->Xp2 ); - mbedtls_ecp_point_free( &ctx->Xp ); - - mbedtls_mpi_free( &ctx->xm1 ); - mbedtls_mpi_free( &ctx->xm2 ); - mbedtls_mpi_free( &ctx->s ); -} - -/* - * Setup context - */ -int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, - mbedtls_ecjpake_role role, - mbedtls_md_type_t hash, - mbedtls_ecp_group_id curve, - const unsigned char *secret, - size_t len ) -{ - int ret; - - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT || - role == MBEDTLS_ECJPAKE_SERVER ); - ECJPAKE_VALIDATE_RET( secret != NULL || len == 0 ); - - ctx->role = role; - - if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL ) - return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) ); - -cleanup: - if( ret != 0 ) - mbedtls_ecjpake_free( ctx ); - - return( ret ); -} - -/* - * Check if context is ready for use - */ -int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx ) -{ - ECJPAKE_VALIDATE_RET( ctx != NULL ); - - if( ctx->md_info == NULL || - ctx->grp.id == MBEDTLS_ECP_DP_NONE || - ctx->s.p == NULL ) - { - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - - return( 0 ); -} - -/* - * Write a point plus its length to a buffer - */ -static int ecjpake_write_len_point( unsigned char **p, - const unsigned char *end, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *P ) -{ - int ret; - size_t len; - - /* Need at least 4 for length plus 1 for point */ - if( end < *p || end - *p < 5 ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - ret = mbedtls_ecp_point_write_binary( grp, P, pf, - &len, *p + 4, end - ( *p + 4 ) ); - if( ret != 0 ) - return( ret ); - - (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF ); - (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF ); - (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF ); - (*p)[3] = (unsigned char)( ( len ) & 0xFF ); - - *p += 4 + len; - - return( 0 ); -} - -/* - * Size of the temporary buffer for ecjpake_hash: - * 3 EC points plus their length, plus ID and its length (4 + 6 bytes) - */ -#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 ) - -/* - * Compute hash for ZKP (7.4.2.2.2.1) - */ -static int ecjpake_hash( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - const mbedtls_ecp_point *V, - const mbedtls_ecp_point *X, - const char *id, - mbedtls_mpi *h ) -{ - int ret; - unsigned char buf[ECJPAKE_HASH_BUF_LEN]; - unsigned char *p = buf; - const unsigned char *end = buf + sizeof( buf ); - const size_t id_len = strlen( id ); - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - - /* Write things to temporary buffer */ - MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) ); - MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) ); - MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) ); - - if( end - p < 4 ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF ); - *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF ); - *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( id_len ) & 0xFF ); - - if( end < p || (size_t)( end - p ) < id_len ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - memcpy( p, id, id_len ); - p += id_len; - - /* Compute hash */ - MBEDTLS_MPI_CHK( mbedtls_md( md_info, buf, p - buf, hash ) ); - - /* Turn it into an integer mod n */ - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash, - mbedtls_md_get_size( md_info ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) ); - -cleanup: - return( ret ); -} - -/* - * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3) - */ -static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - const mbedtls_ecp_point *X, - const char *id, - const unsigned char **p, - const unsigned char *end ) -{ - int ret; - mbedtls_ecp_point V, VV; - mbedtls_mpi r, h; - size_t r_len; - - mbedtls_ecp_point_init( &V ); - mbedtls_ecp_point_init( &VV ); - mbedtls_mpi_init( &r ); - mbedtls_mpi_init( &h ); - - /* - * struct { - * ECPoint V; - * opaque r<1..2^8-1>; - * } ECSchnorrZKP; - */ - if( end < *p ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) ); - - if( end < *p || (size_t)( end - *p ) < 1 ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - r_len = *(*p)++; - - if( end < *p || (size_t)( end - *p ) < r_len ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) ); - *p += r_len; - - /* - * Verification - */ - MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp, - &VV, &h, X, &r, G ) ); - - if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 ) - { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free( &V ); - mbedtls_ecp_point_free( &VV ); - mbedtls_mpi_free( &r ); - mbedtls_mpi_free( &h ); - - return( ret ); -} - -/* - * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2) - */ -static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - const mbedtls_mpi *x, - const mbedtls_ecp_point *X, - const char *id, - unsigned char **p, - const unsigned char *end, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_ecp_point V; - mbedtls_mpi v; - mbedtls_mpi h; /* later recycled to hold r */ - size_t len; - - if( end < *p ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - mbedtls_ecp_point_init( &V ); - mbedtls_mpi_init( &v ); - mbedtls_mpi_init( &h ); - - /* Compute signature */ - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, - G, &v, &V, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */ - - /* Write it out */ - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V, - pf, &len, *p, end - *p ) ); - *p += len; - - len = mbedtls_mpi_size( &h ); /* actually r */ - if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 ) - { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - - *(*p)++ = (unsigned char)( len & 0xFF ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */ - *p += len; - -cleanup: - mbedtls_ecp_point_free( &V ); - mbedtls_mpi_free( &v ); - mbedtls_mpi_free( &h ); - - return( ret ); -} - -/* - * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof - * Output: verified public key X - */ -static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_ecp_point *X, - const char *id, - const unsigned char **p, - const unsigned char *end ) -{ - int ret; - - if( end < *p ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * struct { - * ECPoint X; - * ECSchnorrZKP zkp; - * } ECJPAKEKeyKP; - */ - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) ); - if( mbedtls_ecp_is_zero( X ) ) - { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - - MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) ); - -cleanup: - return( ret ); -} - -/* - * Generate an ECJPAKEKeyKP - * Output: the serialized structure, plus private/public key pair - */ -static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_mpi *x, - mbedtls_ecp_point *X, - const char *id, - unsigned char **p, - const unsigned char *end, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - size_t len; - - if( end < *p ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - /* Generate key (7.4.2.3.1) and write it out */ - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X, - f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X, - pf, &len, *p, end - *p ) ); - *p += len; - - /* Generate and write proof */ - MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id, - p, end, f_rng, p_rng ) ); - -cleanup: - return( ret ); -} - -/* - * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs - * Ouputs: verified peer public keys Xa, Xb - */ -static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_ecp_point *Xa, - mbedtls_ecp_point *Xb, - const char *id, - const unsigned char *buf, - size_t len ) -{ - int ret; - const unsigned char *p = buf; - const unsigned char *end = buf + len; - - /* - * struct { - * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2]; - * } ECJPAKEKeyKPPairList; - */ - MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) ); - MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) ); - - if( p != end ) - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - -cleanup: - return( ret ); -} - -/* - * Generate a ECJPAKEKeyKPPairList - * Outputs: the serialized structure, plus two private/public key pairs - */ -static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_mpi *xm1, - mbedtls_ecp_point *Xa, - mbedtls_mpi *xm2, - mbedtls_ecp_point *Xb, - const char *id, - unsigned char *buf, - size_t len, - size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - unsigned char *p = buf; - const unsigned char *end = buf + len; - - MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id, - &p, end, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id, - &p, end, f_rng, p_rng ) ); - - *olen = p - buf; - -cleanup: - return( ret ); -} - -/* - * Read and process the first round message - */ -int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len ) -{ - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - - return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format, - &ctx->grp.G, - &ctx->Xp1, &ctx->Xp2, ID_PEER, - buf, len ) ); -} - -/* - * Generate and write the first round message - */ -int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - ECJPAKE_VALIDATE_RET( olen != NULL ); - ECJPAKE_VALIDATE_RET( f_rng != NULL ); - - return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format, - &ctx->grp.G, - &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2, - ID_MINE, buf, len, olen, f_rng, p_rng ) ); -} - -/* - * Compute the sum of three points R = A + B + C - */ -static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *A, - const mbedtls_ecp_point *B, - const mbedtls_ecp_point *C ) -{ - int ret; - mbedtls_mpi one; - - mbedtls_mpi_init( &one ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) ); - -cleanup: - mbedtls_mpi_free( &one ); - - return( ret ); -} - -/* - * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6) - */ -int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len ) -{ - int ret; - const unsigned char *p = buf; - const unsigned char *end = buf + len; - mbedtls_ecp_group grp; - mbedtls_ecp_point G; /* C: GB, S: GA */ - - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - - mbedtls_ecp_group_init( &grp ); - mbedtls_ecp_point_init( &G ); - - /* - * Server: GA = X3 + X4 + X1 (7.4.2.6.1) - * Client: GB = X1 + X2 + X3 (7.4.2.5.1) - * Unified: G = Xm1 + Xm2 + Xp1 - * We need that before parsing in order to check Xp as we read it - */ - MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, - &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) ); - - /* - * struct { - * ECParameters curve_params; // only client reading server msg - * ECJPAKEKeyKP ecjpake_key_kp; - * } Client/ServerECJPAKEParams; - */ - if( ctx->role == MBEDTLS_ECJPAKE_CLIENT ) - { - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) ); - if( grp.id != ctx->grp.id ) - { - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - goto cleanup; - } - } - - MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp, - ctx->point_format, - &G, &ctx->Xp, ID_PEER, &p, end ) ); - - if( p != end ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - -cleanup: - mbedtls_ecp_group_free( &grp ); - mbedtls_ecp_point_free( &G ); - - return( ret ); -} - -/* - * Compute R = +/- X * S mod N, taking care not to leak S - */ -static int ecjpake_mul_secret( mbedtls_mpi *R, int sign, - const mbedtls_mpi *X, - const mbedtls_mpi *S, - const mbedtls_mpi *N, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_mpi b; /* Blinding value, then s + N * blinding */ - - mbedtls_mpi_init( &b ); - - /* b = s + rnd-128-bit * N */ - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) ); - - /* R = sign * X * b mod N */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) ); - R->s *= sign; - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) ); - -cleanup: - mbedtls_mpi_free( &b ); - - return( ret ); -} - -/* - * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6) - */ -int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_ecp_point G; /* C: GA, S: GB */ - mbedtls_ecp_point Xm; /* C: Xc, S: Xs */ - mbedtls_mpi xm; /* C: xc, S: xs */ - unsigned char *p = buf; - const unsigned char *end = buf + len; - size_t ec_len; - - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - ECJPAKE_VALIDATE_RET( olen != NULL ); - ECJPAKE_VALIDATE_RET( f_rng != NULL ); - - mbedtls_ecp_point_init( &G ); - mbedtls_ecp_point_init( &Xm ); - mbedtls_mpi_init( &xm ); - - /* - * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1) - * - * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA - * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB - * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G - */ - MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, - &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) ); - MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s, - &ctx->grp.N, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) ); - - /* - * Now write things out - * - * struct { - * ECParameters curve_params; // only server writing its message - * ECJPAKEKeyKP ecjpake_key_kp; - * } Client/ServerECJPAKEParams; - */ - if( ctx->role == MBEDTLS_ECJPAKE_SERVER ) - { - if( end < p ) - { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len, - p, end - p ) ); - p += ec_len; - } - - if( end < p ) - { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm, - ctx->point_format, &ec_len, p, end - p ) ); - p += ec_len; - - MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp, - ctx->point_format, - &G, &xm, &Xm, ID_MINE, - &p, end, f_rng, p_rng ) ); - - *olen = p - buf; - -cleanup: - mbedtls_ecp_point_free( &G ); - mbedtls_ecp_point_free( &Xm ); - mbedtls_mpi_free( &xm ); - - return( ret ); -} - -/* - * Derive PMS (7.4.2.7 / 7.4.2.8) - */ -int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - mbedtls_ecp_point K; - mbedtls_mpi m_xm2_s, one; - unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; - size_t x_bytes; - - ECJPAKE_VALIDATE_RET( ctx != NULL ); - ECJPAKE_VALIDATE_RET( buf != NULL ); - ECJPAKE_VALIDATE_RET( olen != NULL ); - ECJPAKE_VALIDATE_RET( f_rng != NULL ); - - *olen = mbedtls_md_get_size( ctx->md_info ); - if( len < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - mbedtls_ecp_point_init( &K ); - mbedtls_mpi_init( &m_xm2_s ); - mbedtls_mpi_init( &one ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); - - /* - * Client: K = ( Xs - X4 * x2 * s ) * x2 - * Server: K = ( Xc - X2 * x4 * s ) * x4 - * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2 - */ - MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s, - &ctx->grp.N, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K, - &one, &ctx->Xp, - &m_xm2_s, &ctx->Xp2 ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K, - f_rng, p_rng ) ); - - /* PMS = SHA-256( K.X ) */ - x_bytes = ( ctx->grp.pbits + 7 ) / 8; - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) ); - MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) ); - -cleanup: - mbedtls_ecp_point_free( &K ); - mbedtls_mpi_free( &m_xm2_s ); - mbedtls_mpi_free( &one ); - - return( ret ); -} - -#undef ID_MINE -#undef ID_PEER - -#endif /* ! MBEDTLS_ECJPAKE_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif - -#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - !defined(MBEDTLS_SHA256_C) -int mbedtls_ecjpake_self_test( int verbose ) -{ - (void) verbose; - return( 0 ); -} -#else - -static const unsigned char ecjpake_test_password[] = { - 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74, - 0x65, 0x73, 0x74 -}; - -#if !defined(MBEDTLS_ECJPAKE_ALT) - -static const unsigned char ecjpake_test_x1[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, - 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21 -}; - -static const unsigned char ecjpake_test_x2[] = { - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 -}; - -static const unsigned char ecjpake_test_x3[] = { - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 -}; - -static const unsigned char ecjpake_test_x4[] = { - 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, - 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, - 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1 -}; - -static const unsigned char ecjpake_test_cli_one[] = { - 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19, - 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44, - 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad, - 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62, - 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9, - 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d, - 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e, - 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e, - 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73, - 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22, - 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce, - 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00, - 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b, - 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e, - 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62, - 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5, - 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb, - 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35, - 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0, - 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb, - 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47, - 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39, - 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97, - 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40, - 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d, - 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa, - 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d, - 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0 -}; - -static const unsigned char ecjpake_test_srv_one[] = { - 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, - 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, - 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, - 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, - 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, - 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d, - 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64, - 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36, - 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2, - 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec, - 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16, - 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96, - 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3, - 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19, - 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f, - 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8, - 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7, - 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea, - 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5, - 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6, - 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31, - 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d, - 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8, - 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee, - 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84, - 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f, - 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80, - 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12 -}; - -static const unsigned char ecjpake_test_srv_two[] = { - 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23, - 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c, - 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f, - 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca, - 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26, - 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55, - 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38, - 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6, - 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9, - 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4, - 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2, - 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8, - 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd, - 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c -}; - -static const unsigned char ecjpake_test_cli_two[] = { - 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46, - 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb, - 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72, - 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce, - 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98, - 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31, - 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15, - 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36, - 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8, - 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45, - 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d, - 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58, - 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82, - 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c -}; - -static const unsigned char ecjpake_test_pms[] = { - 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7, - 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9, - 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51 -}; - -/* Load my private keys and generate the corresponding public keys */ -static int ecjpake_test_load( mbedtls_ecjpake_context *ctx, - const unsigned char *xm1, size_t len1, - const unsigned char *xm2, size_t len2 ) -{ - int ret; - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1, - &ctx->grp.G, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2, - &ctx->grp.G, NULL, NULL ) ); - -cleanup: - return( ret ); -} - -#endif /* ! MBEDTLS_ECJPAKE_ALT */ - -/* For tests we don't need a secure RNG; - * use the LGC from Numerical Recipes for simplicity */ -static int ecjpake_lgc( void *p, unsigned char *out, size_t len ) -{ - static uint32_t x = 42; - (void) p; - - while( len > 0 ) - { - size_t use_len = len > 4 ? 4 : len; - x = 1664525 * x + 1013904223; - memcpy( out, &x, use_len ); - out += use_len; - len -= use_len; - } - - return( 0 ); -} - -#define TEST_ASSERT( x ) \ - do { \ - if( x ) \ - ret = 0; \ - else \ - { \ - ret = 1; \ - goto cleanup; \ - } \ - } while( 0 ) - -/* - * Checkup routine - */ -int mbedtls_ecjpake_self_test( int verbose ) -{ - int ret; - mbedtls_ecjpake_context cli; - mbedtls_ecjpake_context srv; - unsigned char buf[512], pms[32]; - size_t len, pmslen; - - mbedtls_ecjpake_init( &cli ); - mbedtls_ecjpake_init( &srv ); - - if( verbose != 0 ) - mbedtls_printf( " ECJPAKE test #0 (setup): " ); - - TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT, - MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, - ecjpake_test_password, - sizeof( ecjpake_test_password ) ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER, - MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, - ecjpake_test_password, - sizeof( ecjpake_test_password ) ) == 0 ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " ECJPAKE test #1 (random handshake): " ); - - TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, - pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( len == pmslen ); - TEST_ASSERT( memcmp( buf, pms, len ) == 0 ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -#if !defined(MBEDTLS_ECJPAKE_ALT) - /* 'reference handshake' tests can only be run against implementations - * for which we have 100% control over how the random ephemeral keys - * are generated. This is only the case for the internal mbed TLS - * implementation, so these tests are skipped in case the internal - * implementation is swapped out for an alternative one. */ - if( verbose != 0 ) - mbedtls_printf( " ECJPAKE test #2 (reference handshake): " ); - - /* Simulate generation of round one */ - MBEDTLS_MPI_CHK( ecjpake_test_load( &cli, - ecjpake_test_x1, sizeof( ecjpake_test_x1 ), - ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) ); - - MBEDTLS_MPI_CHK( ecjpake_test_load( &srv, - ecjpake_test_x3, sizeof( ecjpake_test_x3 ), - ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) ); - - /* Read round one */ - TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, - ecjpake_test_cli_one, - sizeof( ecjpake_test_cli_one ) ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, - ecjpake_test_srv_one, - sizeof( ecjpake_test_srv_one ) ) == 0 ); - - /* Skip generation of round two, read round two */ - TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, - ecjpake_test_srv_two, - sizeof( ecjpake_test_srv_two ) ) == 0 ); - - TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, - ecjpake_test_cli_two, - sizeof( ecjpake_test_cli_two ) ) == 0 ); - - /* Server derives PMS */ - TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); - TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); - - memset( buf, 0, len ); /* Avoid interferences with next step */ - - /* Client derives PMS */ - TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, - buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); - - TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); - TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); -#endif /* ! MBEDTLS_ECJPAKE_ALT */ - -cleanup: - mbedtls_ecjpake_free( &cli ); - mbedtls_ecjpake_free( &srv ); - - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( ret ); -} - -#undef TEST_ASSERT - -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */ - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ECJPAKE_C */ diff --git a/mbedtls/ecjpake.h b/mbedtls/ecjpake.h deleted file mode 100644 index 9522c20b6..000000000 --- a/mbedtls/ecjpake.h +++ /dev/null @@ -1,303 +0,0 @@ -#pragma GCC system_header -/** - * \file ecjpake.h - * - * \brief Elliptic curve J-PAKE - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_ECJPAKE_H -#define MBEDTLS_ECJPAKE_H - -/* - * J-PAKE is a password-authenticated key exchange that allows deriving a - * strong shared secret from a (potentially low entropy) pre-shared - * passphrase, with forward secrecy and mutual authentication. - * https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling - * - * This file implements the Elliptic Curve variant of J-PAKE, - * as defined in Chapter 7.4 of the Thread v1.0 Specification, - * available to members of the Thread Group http://threadgroup.org/ - * - * As the J-PAKE algorithm is inherently symmetric, so is our API. - * Each party needs to send its first round message, in any order, to the - * other party, then each sends its second round message, in any order. - * The payloads are serialized in a way suitable for use in TLS, but could - * also be use outside TLS. - */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ecp.h" -#include "md.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Roles in the EC J-PAKE exchange - */ -typedef enum { - MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */ - MBEDTLS_ECJPAKE_SERVER, /**< Server */ -} mbedtls_ecjpake_role; - -#if !defined(MBEDTLS_ECJPAKE_ALT) -/** - * EC J-PAKE context structure. - * - * J-PAKE is a symmetric protocol, except for the identifiers used in - * Zero-Knowledge Proofs, and the serialization of the second message - * (KeyExchange) as defined by the Thread spec. - * - * In order to benefit from this symmetry, we choose a different naming - * convetion from the Thread v1.0 spec. Correspondance is indicated in the - * description as a pair C: client name, S: server name - */ -typedef struct mbedtls_ecjpake_context -{ - const mbedtls_md_info_t *md_info; /**< Hash to use */ - mbedtls_ecp_group grp; /**< Elliptic curve */ - mbedtls_ecjpake_role role; /**< Are we client or server? */ - int point_format; /**< Format for point export */ - - mbedtls_ecp_point Xm1; /**< My public key 1 C: X1, S: X3 */ - mbedtls_ecp_point Xm2; /**< My public key 2 C: X2, S: X4 */ - mbedtls_ecp_point Xp1; /**< Peer public key 1 C: X3, S: X1 */ - mbedtls_ecp_point Xp2; /**< Peer public key 2 C: X4, S: X2 */ - mbedtls_ecp_point Xp; /**< Peer public key C: Xs, S: Xc */ - - mbedtls_mpi xm1; /**< My private key 1 C: x1, S: x3 */ - mbedtls_mpi xm2; /**< My private key 2 C: x2, S: x4 */ - - mbedtls_mpi s; /**< Pre-shared secret (passphrase) */ -} mbedtls_ecjpake_context; - -#else /* MBEDTLS_ECJPAKE_ALT */ -#include "ecjpake_alt.h" -#endif /* MBEDTLS_ECJPAKE_ALT */ - -/** - * \brief Initialize an ECJPAKE context. - * - * \param ctx The ECJPAKE context to initialize. - * This must not be \c NULL. - */ -void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ); - -/** - * \brief Set up an ECJPAKE context for use. - * - * \note Currently the only values for hash/curve allowed by the - * standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1. - * - * \param ctx The ECJPAKE context to set up. This must be initialized. - * \param role The role of the caller. This must be either - * #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER. - * \param hash The identifier of the hash function to use, - * for example #MBEDTLS_MD_SHA256. - * \param curve The identifier of the elliptic curve to use, - * for example #MBEDTLS_ECP_DP_SECP256R1. - * \param secret The pre-shared secret (passphrase). This must be - * a readable buffer of length \p len Bytes. It need - * only be valid for the duration of this call. - * \param len The length of the pre-shared secret \p secret. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, - mbedtls_ecjpake_role role, - mbedtls_md_type_t hash, - mbedtls_ecp_group_id curve, - const unsigned char *secret, - size_t len ); - -/** - * \brief Check if an ECJPAKE context is ready for use. - * - * \param ctx The ECJPAKE context to check. This must be - * initialized. - * - * \return \c 0 if the context is ready for use. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise. - */ -int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx ); - -/** - * \brief Generate and write the first round message - * (TLS: contents of the Client/ServerHello extension, - * excluding extension type and length bytes). - * - * \param ctx The ECJPAKE context to use. This must be - * initialized and set up. - * \param buf The buffer to write the contents to. This must be a - * writable buffer of length \p len Bytes. - * \param len The length of \p buf in Bytes. - * \param olen The address at which to store the total number - * of Bytes written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief Read and process the first round message - * (TLS: contents of the Client/ServerHello extension, - * excluding extension type and length bytes). - * - * \param ctx The ECJPAKE context to use. This must be initialized - * and set up. - * \param buf The buffer holding the first round message. This must - * be a readable buffer of length \p len Bytes. - * \param len The length in Bytes of \p buf. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len ); - -/** - * \brief Generate and write the second round message - * (TLS: contents of the Client/ServerKeyExchange). - * - * \param ctx The ECJPAKE context to use. This must be initialized, - * set up, and already have performed round one. - * \param buf The buffer to write the round two contents to. - * This must be a writable buffer of length \p len Bytes. - * \param len The size of \p buf in Bytes. - * \param olen The address at which to store the total number of Bytes - * written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief Read and process the second round message - * (TLS: contents of the Client/ServerKeyExchange). - * - * \param ctx The ECJPAKE context to use. This must be initialized - * and set up and already have performed round one. - * \param buf The buffer holding the second round message. This must - * be a readable buffer of length \p len Bytes. - * \param len The length in Bytes of \p buf. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len ); - -/** - * \brief Derive the shared secret - * (TLS: Pre-Master Secret). - * - * \param ctx The ECJPAKE context to use. This must be initialized, - * set up and have performed both round one and two. - * \param buf The buffer to write the derived secret to. This must - * be a writable buffer of length \p len Bytes. - * \param len The length of \p buf in Bytes. - * \param olen The address at which to store the total number of Bytes - * written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This clears an ECJPAKE context and frees any - * embedded data structure. - * - * \param ctx The ECJPAKE context to free. This may be \c NULL, - * in which case this function does nothing. If it is not - * \c NULL, it must point to an initialized ECJPAKE context. - */ -void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_ecjpake_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - - -#endif /* ecjpake.h */ diff --git a/mbedtls/ecp.c b/mbedtls/ecp.c deleted file mode 100644 index 605f33ce6..000000000 --- a/mbedtls/ecp.c +++ /dev/null @@ -1,3582 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Elliptic curves over GF(p): generic functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * References: - * - * SEC1 http://www.secg.org/index.php?action=secg,docs_secg - * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone - * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf - * RFC 4492 for the related TLS structures and constants - * RFC 7748 for the Curve448 and Curve25519 curve definitions - * - * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf - * - * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis - * for elliptic curve cryptosystems. In : Cryptographic Hardware and - * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. - * - * - * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to - * render ECC resistant against Side Channel Attacks. IACR Cryptology - * ePrint Archive, 2004, vol. 2004, p. 342. - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -/** - * \brief Function level alternative implementation. - * - * The MBEDTLS_ECP_INTERNAL_ALT macro enables alternative implementations to - * replace certain functions in this module. The alternative implementations are - * typically hardware accelerators and need to activate the hardware before the - * computation starts and deactivate it after it finishes. The - * mbedtls_internal_ecp_init() and mbedtls_internal_ecp_free() functions serve - * this purpose. - * - * To preserve the correct functionality the following conditions must hold: - * - * - The alternative implementation must be activated by - * mbedtls_internal_ecp_init() before any of the replaceable functions is - * called. - * - mbedtls_internal_ecp_free() must \b only be called when the alternative - * implementation is activated. - * - mbedtls_internal_ecp_init() must \b not be called when the alternative - * implementation is activated. - * - Public functions must not return while the alternative implementation is - * activated. - * - Replaceable functions are guarded by \c MBEDTLS_ECP_XXX_ALT macros and - * before calling them an \code if( mbedtls_internal_ecp_grp_capable( grp ) ) - * \endcode ensures that the alternative implementation supports the current - * group. - */ -#if defined(MBEDTLS_ECP_INTERNAL_ALT) -#endif - -#if defined(MBEDTLS_ECP_C) - -#include "mbedtls/ecp.h" -#include "mbedtls/threading.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/bn_mul.h" - -#include - -#if !defined(MBEDTLS_ECP_ALT) - -/* Parameter validation macros based on platform_util.h */ -#define ECP_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECP_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/ecp_internal.h" - -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) -#if defined(MBEDTLS_HMAC_DRBG_C) -#include "mbedtls/hmac_drbg.h" -#elif defined(MBEDTLS_CTR_DRBG_C) -#include "mbedtls/ctr_drbg.h" -#elif defined(MBEDTLS_SHA512_C) -#include "mbedtls/sha512.h" -#elif defined(MBEDTLS_SHA256_C) -#include "mbedtls/sha256.h" -#else -#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid." -#endif -#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */ - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * Counts of point addition and doubling, and field multiplications. - * Used to test resistance of point multiplication to simple timing attacks. - */ -static unsigned long add_count, dbl_count, mul_count; -#endif - -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) -/* - * Currently ecp_mul() takes a RNG function as an argument, used for - * side-channel protection, but it can be NULL. The initial reasoning was - * that people will pass non-NULL RNG when they care about side-channels, but - * unfortunately we have some APIs that call ecp_mul() with a NULL RNG, with - * no opportunity for the user to do anything about it. - * - * The obvious strategies for addressing that include: - * - change those APIs so that they take RNG arguments; - * - require a global RNG to be available to all crypto modules. - * - * Unfortunately those would break compatibility. So what we do instead is - * have our own internal DRBG instance, seeded from the secret scalar. - * - * The following is a light-weight abstraction layer for doing that with - * HMAC_DRBG (first choice) or CTR_DRBG. - */ - -#if defined(MBEDTLS_HMAC_DRBG_C) - -/* DRBG context type */ -typedef mbedtls_hmac_drbg_context ecp_drbg_context; - -/* DRBG context init */ -static inline void ecp_drbg_init( ecp_drbg_context *ctx ) -{ - mbedtls_hmac_drbg_init( ctx ); -} - -/* DRBG context free */ -static inline void ecp_drbg_free( ecp_drbg_context *ctx ) -{ - mbedtls_hmac_drbg_free( ctx ); -} - -/* DRBG function */ -static inline int ecp_drbg_random( void *p_rng, - unsigned char *output, size_t output_len ) -{ - return( mbedtls_hmac_drbg_random( p_rng, output, output_len ) ); -} - -/* DRBG context seeding */ -static int ecp_drbg_seed( ecp_drbg_context *ctx, - const mbedtls_mpi *secret, size_t secret_len ) -{ - int ret; - unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES]; - /* The list starts with strong hashes */ - const mbedtls_md_type_t md_type = mbedtls_md_list()[0]; - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_type ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret, - secret_bytes, secret_len ) ); - - ret = mbedtls_hmac_drbg_seed_buf( ctx, md_info, secret_bytes, secret_len ); - -cleanup: - mbedtls_platform_zeroize( secret_bytes, secret_len ); - - return( ret ); -} - -#elif defined(MBEDTLS_CTR_DRBG_C) - -/* DRBG context type */ -typedef mbedtls_ctr_drbg_context ecp_drbg_context; - -/* DRBG context init */ -static inline void ecp_drbg_init( ecp_drbg_context *ctx ) -{ - mbedtls_ctr_drbg_init( ctx ); -} - -/* DRBG context free */ -static inline void ecp_drbg_free( ecp_drbg_context *ctx ) -{ - mbedtls_ctr_drbg_free( ctx ); -} - -/* DRBG function */ -static inline int ecp_drbg_random( void *p_rng, - unsigned char *output, size_t output_len ) -{ - return( mbedtls_ctr_drbg_random( p_rng, output, output_len ) ); -} - -/* - * Since CTR_DRBG doesn't have a seed_buf() function the way HMAC_DRBG does, - * we need to pass an entropy function when seeding. So we use a dummy - * function for that, and pass the actual entropy as customisation string. - * (During seeding of CTR_DRBG the entropy input and customisation string are - * concatenated before being used to update the secret state.) - */ -static int ecp_ctr_drbg_null_entropy(void *ctx, unsigned char *out, size_t len) -{ - (void) ctx; - memset( out, 0, len ); - return( 0 ); -} - -/* DRBG context seeding */ -static int ecp_drbg_seed( ecp_drbg_context *ctx, - const mbedtls_mpi *secret, size_t secret_len ) -{ - int ret; - unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES]; - - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret, - secret_bytes, secret_len ) ); - - ret = mbedtls_ctr_drbg_seed( ctx, ecp_ctr_drbg_null_entropy, NULL, - secret_bytes, secret_len ); - -cleanup: - mbedtls_platform_zeroize( secret_bytes, secret_len ); - - return( ret ); -} - -#elif defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA256_C) - -/* This will be used in the self-test function */ -#define ECP_ONE_STEP_KDF - -/* - * We need to expand secret data (the scalar) into a longer stream of bytes. - * - * We'll use the One-Step KDF from NIST SP 800-56C, with option 1 (H is a hash - * function) and empty FixedInfo. (Though we'll make it fit the DRBG API for - * convenience, this is not a full-fledged DRBG, but we don't need one here.) - * - * We need a basic hash abstraction layer to use whatever SHA-2 is available. - */ -#if defined(MBEDTLS_SHA512_C) - -#define HASH_FUNC( in, ilen, out ) mbedtls_sha512_ret( in, ilen, out, 0 ); -#define HASH_BLOCK_BYTES ( 512 / 8 ) - -#elif defined(MBEDTLS_SHA256_C) - -#define HASH_FUNC( in, ilen, out ) mbedtls_sha256_ret( in, ilen, out, 0 ); -#define HASH_BLOCK_BYTES ( 256 / 8 ) - -#endif /* SHA512/SHA256 abstraction */ - -/* - * State consists of a 32-bit counter plus the secret value. - * - * We stored them concatenated in a single buffer as that's what will get - * passed to the hash function. - */ -typedef struct { - size_t total_len; - uint8_t buf[4 + MBEDTLS_ECP_MAX_BYTES]; -} ecp_drbg_context; - -static void ecp_drbg_init( ecp_drbg_context *ctx ) -{ - memset( ctx, 0, sizeof( ecp_drbg_context ) ); -} - -static void ecp_drbg_free( ecp_drbg_context *ctx ) -{ - mbedtls_platform_zeroize( ctx, sizeof( ecp_drbg_context ) ); -} - -static int ecp_drbg_seed( ecp_drbg_context *ctx, - const mbedtls_mpi *secret, size_t secret_len ) -{ - ctx->total_len = 4 + secret_len; - memset( ctx->buf, 0, 4); - return( mbedtls_mpi_write_binary( secret, ctx->buf + 4, secret_len ) ); -} - -static int ecp_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) -{ - ecp_drbg_context *ctx = p_rng; - int ret; - size_t len_done = 0; - uint8_t tmp[HASH_BLOCK_BYTES]; - - while( len_done < output_len ) - { - uint8_t use_len; - - /* This function is only called for coordinate randomisation, which - * happens only twice in a scalar multiplication. Each time needs a - * random value in the range [2, p-1], and gets it by drawing len(p) - * bytes from this function, and retrying up to 10 times if unlucky. - * - * So for the largest curve, each scalar multiplication draws at most - * 20 * 66 bytes. The minimum block size is 32 (SHA-256), so with - * rounding that means a most 20 * 3 blocks. - * - * Since we don't need to draw more that 255 blocks, don't bother - * with carry propagation and just return an error instead. We can - * change that it we even need to draw more blinding values. - */ - ctx->buf[3] += 1; - if( ctx->buf[3] == 0 ) - return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); - - ret = HASH_FUNC( ctx->buf, ctx->total_len, tmp ); - if( ret != 0 ) - return( ret ); - - if( output_len - len_done > HASH_BLOCK_BYTES ) - use_len = HASH_BLOCK_BYTES; - else - use_len = output_len - len_done; - - memcpy( output + len_done, tmp, use_len ); - len_done += use_len; - } - - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - - return( 0 ); -} - -#else /* DRBG/SHA modules */ -#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid." -#endif /* DRBG/SHA modules */ -#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Maximum number of "basic operations" to be done in a row. - * - * Default value 0 means that ECC operations will not yield. - * Note that regardless of the value of ecp_max_ops, always at - * least one step is performed before yielding. - * - * Setting ecp_max_ops=1 can be suitable for testing purposes - * as it will interrupt computation at all possible points. - */ -static unsigned ecp_max_ops = 0; - -/* - * Set ecp_max_ops - */ -void mbedtls_ecp_set_max_ops( unsigned max_ops ) -{ - ecp_max_ops = max_ops; -} - -/* - * Check if restart is enabled - */ -int mbedtls_ecp_restart_is_enabled( void ) -{ - return( ecp_max_ops != 0 ); -} - -/* - * Restart sub-context for ecp_mul_comb() - */ -struct mbedtls_ecp_restart_mul -{ - mbedtls_ecp_point R; /* current intermediate result */ - size_t i; /* current index in various loops, 0 outside */ - mbedtls_ecp_point *T; /* table for precomputed points */ - unsigned char T_size; /* number of points in table T */ - enum { /* what were we doing last time we returned? */ - ecp_rsm_init = 0, /* nothing so far, dummy initial state */ - ecp_rsm_pre_dbl, /* precompute 2^n multiples */ - ecp_rsm_pre_norm_dbl, /* normalize precomputed 2^n multiples */ - ecp_rsm_pre_add, /* precompute remaining points by adding */ - ecp_rsm_pre_norm_add, /* normalize all precomputed points */ - ecp_rsm_comb_core, /* ecp_mul_comb_core() */ - ecp_rsm_final_norm, /* do the final normalization */ - } state; -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - ecp_drbg_context drbg_ctx; - unsigned char drbg_seeded; -#endif -}; - -/* - * Init restart_mul sub-context - */ -static void ecp_restart_rsm_init( mbedtls_ecp_restart_mul_ctx *ctx ) -{ - mbedtls_ecp_point_init( &ctx->R ); - ctx->i = 0; - ctx->T = NULL; - ctx->T_size = 0; - ctx->state = ecp_rsm_init; -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - ecp_drbg_init( &ctx->drbg_ctx ); - ctx->drbg_seeded = 0; -#endif -} - -/* - * Free the components of a restart_mul sub-context - */ -static void ecp_restart_rsm_free( mbedtls_ecp_restart_mul_ctx *ctx ) -{ - unsigned char i; - - if( ctx == NULL ) - return; - - mbedtls_ecp_point_free( &ctx->R ); - - if( ctx->T != NULL ) - { - for( i = 0; i < ctx->T_size; i++ ) - mbedtls_ecp_point_free( ctx->T + i ); - mbedtls_free( ctx->T ); - } - -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - ecp_drbg_free( &ctx->drbg_ctx ); -#endif - - ecp_restart_rsm_init( ctx ); -} - -/* - * Restart context for ecp_muladd() - */ -struct mbedtls_ecp_restart_muladd -{ - mbedtls_ecp_point mP; /* mP value */ - mbedtls_ecp_point R; /* R intermediate result */ - enum { /* what should we do next? */ - ecp_rsma_mul1 = 0, /* first multiplication */ - ecp_rsma_mul2, /* second multiplication */ - ecp_rsma_add, /* addition */ - ecp_rsma_norm, /* normalization */ - } state; -}; - -/* - * Init restart_muladd sub-context - */ -static void ecp_restart_ma_init( mbedtls_ecp_restart_muladd_ctx *ctx ) -{ - mbedtls_ecp_point_init( &ctx->mP ); - mbedtls_ecp_point_init( &ctx->R ); - ctx->state = ecp_rsma_mul1; -} - -/* - * Free the components of a restart_muladd sub-context - */ -static void ecp_restart_ma_free( mbedtls_ecp_restart_muladd_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_ecp_point_free( &ctx->mP ); - mbedtls_ecp_point_free( &ctx->R ); - - ecp_restart_ma_init( ctx ); -} - -/* - * Initialize a restart context - */ -void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ) -{ - ECP_VALIDATE( ctx != NULL ); - ctx->ops_done = 0; - ctx->depth = 0; - ctx->rsm = NULL; - ctx->ma = NULL; -} - -/* - * Free the components of a restart context - */ -void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - ecp_restart_rsm_free( ctx->rsm ); - mbedtls_free( ctx->rsm ); - - ecp_restart_ma_free( ctx->ma ); - mbedtls_free( ctx->ma ); - - mbedtls_ecp_restart_init( ctx ); -} - -/* - * Check if we can do the next step - */ -int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, - mbedtls_ecp_restart_ctx *rs_ctx, - unsigned ops ) -{ - ECP_VALIDATE_RET( grp != NULL ); - - if( rs_ctx != NULL && ecp_max_ops != 0 ) - { - /* scale depending on curve size: the chosen reference is 256-bit, - * and multiplication is quadratic. Round to the closest integer. */ - if( grp->pbits >= 512 ) - ops *= 4; - else if( grp->pbits >= 384 ) - ops *= 2; - - /* Avoid infinite loops: always allow first step. - * Because of that, however, it's not generally true - * that ops_done <= ecp_max_ops, so the check - * ops_done > ecp_max_ops below is mandatory. */ - if( ( rs_ctx->ops_done != 0 ) && - ( rs_ctx->ops_done > ecp_max_ops || - ops > ecp_max_ops - rs_ctx->ops_done ) ) - { - return( MBEDTLS_ERR_ECP_IN_PROGRESS ); - } - - /* update running count */ - rs_ctx->ops_done += ops; - } - - return( 0 ); -} - -/* Call this when entering a function that needs its own sub-context */ -#define ECP_RS_ENTER( SUB ) do { \ - /* reset ops count for this call if top-level */ \ - if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) \ - rs_ctx->ops_done = 0; \ - \ - /* set up our own sub-context if needed */ \ - if( mbedtls_ecp_restart_is_enabled() && \ - rs_ctx != NULL && rs_ctx->SUB == NULL ) \ - { \ - rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) ); \ - if( rs_ctx->SUB == NULL ) \ - return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); \ - \ - ecp_restart_## SUB ##_init( rs_ctx->SUB ); \ - } \ -} while( 0 ) - -/* Call this when leaving a function that needs its own sub-context */ -#define ECP_RS_LEAVE( SUB ) do { \ - /* clear our sub-context when not in progress (done or error) */ \ - if( rs_ctx != NULL && rs_ctx->SUB != NULL && \ - ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) \ - { \ - ecp_restart_## SUB ##_free( rs_ctx->SUB ); \ - mbedtls_free( rs_ctx->SUB ); \ - rs_ctx->SUB = NULL; \ - } \ - \ - if( rs_ctx != NULL ) \ - rs_ctx->depth--; \ -} while( 0 ) - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define ECP_RS_ENTER( sub ) (void) rs_ctx; -#define ECP_RS_LEAVE( sub ) (void) rs_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -#define ECP_SHORTWEIERSTRASS -#endif - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ - defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -#define ECP_MONTGOMERY -#endif - -/* - * Curve types: internal for now, might be exposed later - */ -typedef enum -{ - ECP_TYPE_NONE = 0, - ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ - ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ -} ecp_curve_type; - -/* - * List of supported curves: - * - internal ID - * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2) - * - size in bits - * - readable name - * - * Curves are listed in order: largest curves first, and for a given size, - * fastest curves first. This provides the default order for the SSL module. - * - * Reminder: update profiles in x509_crt.c when adding a new curves! - */ -static const mbedtls_ecp_curve_info ecp_supported_curves[] = -{ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - { MBEDTLS_ECP_DP_SECP521R1, 25, 521, "secp521r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - { MBEDTLS_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - { MBEDTLS_ECP_DP_SECP384R1, 24, 384, "secp384r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - { MBEDTLS_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - { MBEDTLS_ECP_DP_SECP256R1, 23, 256, "secp256r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - { MBEDTLS_ECP_DP_SECP256K1, 22, 256, "secp256k1" }, -#endif -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - { MBEDTLS_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - { MBEDTLS_ECP_DP_SECP224R1, 21, 224, "secp224r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - { MBEDTLS_ECP_DP_SECP224K1, 20, 224, "secp224k1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - { MBEDTLS_ECP_DP_SECP192R1, 19, 192, "secp192r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, -#endif - { MBEDTLS_ECP_DP_NONE, 0, 0, NULL }, -}; - -#define ECP_NB_CURVES sizeof( ecp_supported_curves ) / \ - sizeof( ecp_supported_curves[0] ) - -static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES]; - -/* - * List of supported curves and associated info - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ) -{ - return( ecp_supported_curves ); -} - -/* - * List of supported curves, group ID only - */ -const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void ) -{ - static int init_done = 0; - - if( ! init_done ) - { - size_t i = 0; - const mbedtls_ecp_curve_info *curve_info; - - for( curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++ ) - { - ecp_supported_grp_id[i++] = curve_info->grp_id; - } - ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE; - - init_done = 1; - } - - return( ecp_supported_grp_id ); -} - -/* - * Get the curve info for the internal identifier - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id ) -{ - const mbedtls_ecp_curve_info *curve_info; - - for( curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++ ) - { - if( curve_info->grp_id == grp_id ) - return( curve_info ); - } - - return( NULL ); -} - -/* - * Get the curve info from the TLS identifier - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id ) -{ - const mbedtls_ecp_curve_info *curve_info; - - for( curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++ ) - { - if( curve_info->tls_id == tls_id ) - return( curve_info ); - } - - return( NULL ); -} - -/* - * Get the curve info from the name - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name ) -{ - const mbedtls_ecp_curve_info *curve_info; - - if( name == NULL ) - return( NULL ); - - for( curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++ ) - { - if( strcmp( curve_info->name, name ) == 0 ) - return( curve_info ); - } - - return( NULL ); -} - -/* - * Get the type of a curve - */ -static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp ) -{ - if( grp->G.X.p == NULL ) - return( ECP_TYPE_NONE ); - - if( grp->G.Y.p == NULL ) - return( ECP_TYPE_MONTGOMERY ); - else - return( ECP_TYPE_SHORT_WEIERSTRASS ); -} - -/* - * Initialize (the components of) a point - */ -void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ) -{ - ECP_VALIDATE( pt != NULL ); - - mbedtls_mpi_init( &pt->X ); - mbedtls_mpi_init( &pt->Y ); - mbedtls_mpi_init( &pt->Z ); -} - -/* - * Initialize (the components of) a group - */ -void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ) -{ - ECP_VALIDATE( grp != NULL ); - - grp->id = MBEDTLS_ECP_DP_NONE; - mbedtls_mpi_init( &grp->P ); - mbedtls_mpi_init( &grp->A ); - mbedtls_mpi_init( &grp->B ); - mbedtls_ecp_point_init( &grp->G ); - mbedtls_mpi_init( &grp->N ); - grp->pbits = 0; - grp->nbits = 0; - grp->h = 0; - grp->modp = NULL; - grp->t_pre = NULL; - grp->t_post = NULL; - grp->t_data = NULL; - grp->T = NULL; - grp->T_size = 0; -} - -/* - * Initialize (the components of) a key pair - */ -void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ) -{ - ECP_VALIDATE( key != NULL ); - - mbedtls_ecp_group_init( &key->grp ); - mbedtls_mpi_init( &key->d ); - mbedtls_ecp_point_init( &key->Q ); -} - -/* - * Unallocate (the components of) a point - */ -void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ) -{ - if( pt == NULL ) - return; - - mbedtls_mpi_free( &( pt->X ) ); - mbedtls_mpi_free( &( pt->Y ) ); - mbedtls_mpi_free( &( pt->Z ) ); -} - -/* - * Unallocate (the components of) a group - */ -void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ) -{ - size_t i; - - if( grp == NULL ) - return; - - if( grp->h != 1 ) - { - mbedtls_mpi_free( &grp->P ); - mbedtls_mpi_free( &grp->A ); - mbedtls_mpi_free( &grp->B ); - mbedtls_ecp_point_free( &grp->G ); - mbedtls_mpi_free( &grp->N ); - } - - if( grp->T != NULL ) - { - for( i = 0; i < grp->T_size; i++ ) - mbedtls_ecp_point_free( &grp->T[i] ); - mbedtls_free( grp->T ); - } - - mbedtls_platform_zeroize( grp, sizeof( mbedtls_ecp_group ) ); -} - -/* - * Unallocate (the components of) a key pair - */ -void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ) -{ - if( key == NULL ) - return; - - mbedtls_ecp_group_free( &key->grp ); - mbedtls_mpi_free( &key->d ); - mbedtls_ecp_point_free( &key->Q ); -} - -/* - * Copy the contents of a point - */ -int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) -{ - int ret; - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Z, &Q->Z ) ); - -cleanup: - return( ret ); -} - -/* - * Copy the contents of a group object - */ -int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ) -{ - ECP_VALIDATE_RET( dst != NULL ); - ECP_VALIDATE_RET( src != NULL ); - - return( mbedtls_ecp_group_load( dst, src->id ) ); -} - -/* - * Set point to zero - */ -int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ) -{ - int ret; - ECP_VALIDATE_RET( pt != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z , 0 ) ); - -cleanup: - return( ret ); -} - -/* - * Tell if a point is zero - */ -int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ) -{ - ECP_VALIDATE_RET( pt != NULL ); - - return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ); -} - -/* - * Compare two points lazily - */ -int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, - const mbedtls_ecp_point *Q ) -{ - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - - if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 && - mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 && - mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 ) - { - return( 0 ); - } - - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); -} - -/* - * Import a non-zero point from ASCII strings - */ -int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, - const char *x, const char *y ) -{ - int ret; - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( x != NULL ); - ECP_VALIDATE_RET( y != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); - -cleanup: - return( ret ); -} - -/* - * Export a point into unsigned binary data (SEC1 2.3.3) - */ -int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *P, - int format, size_t *olen, - unsigned char *buf, size_t buflen ) -{ - int ret = 0; - size_t plen; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( olen != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || - format == MBEDTLS_ECP_PF_COMPRESSED ); - - /* - * Common case: P == 0 - */ - if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) - { - if( buflen < 1 ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - buf[0] = 0x00; - *olen = 1; - - return( 0 ); - } - - plen = mbedtls_mpi_size( &grp->P ); - - if( format == MBEDTLS_ECP_PF_UNCOMPRESSED ) - { - *olen = 2 * plen + 1; - - if( buflen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - buf[0] = 0x04; - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); - } - else if( format == MBEDTLS_ECP_PF_COMPRESSED ) - { - *olen = plen + 1; - - if( buflen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); - } - -cleanup: - return( ret ); -} - -/* - * Import a point from unsigned binary data (SEC1 2.3.4) - */ -int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char *buf, size_t ilen ) -{ - int ret; - size_t plen; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - - if( ilen < 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - if( buf[0] == 0x00 ) - { - if( ilen == 1 ) - return( mbedtls_ecp_set_zero( pt ) ); - else - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - - plen = mbedtls_mpi_size( &grp->P ); - - if( buf[0] != 0x04 ) - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - - if( ilen != 2 * plen + 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); - -cleanup: - return( ret ); -} - -/* - * Import a point from a TLS ECPoint record (RFC 4492) - * struct { - * opaque point <1..2^8-1>; - * } ECPoint; - */ -int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char **buf, size_t buf_len ) -{ - unsigned char data_len; - const unsigned char *buf_start; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( *buf != NULL ); - - /* - * We must have at least two bytes (1 for length, at least one for data) - */ - if( buf_len < 2 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - data_len = *(*buf)++; - if( data_len < 1 || data_len > buf_len - 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * Save buffer start for read_binary and update buf - */ - buf_start = *buf; - *buf += data_len; - - return( mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ) ); -} - -/* - * Export a point as a TLS ECPoint record (RFC 4492) - * struct { - * opaque point <1..2^8-1>; - * } ECPoint; - */ -int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, - int format, size_t *olen, - unsigned char *buf, size_t blen ) -{ - int ret; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - ECP_VALIDATE_RET( olen != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || - format == MBEDTLS_ECP_PF_COMPRESSED ); - - /* - * buffer length must be at least one, for our length byte - */ - if( blen < 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_ecp_point_write_binary( grp, pt, format, - olen, buf + 1, blen - 1) ) != 0 ) - return( ret ); - - /* - * write length to the first byte and update total length - */ - buf[0] = (unsigned char) *olen; - ++*olen; - - return( 0 ); -} - -/* - * Set a group from an ECParameters record (RFC 4492) - */ -int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, - const unsigned char **buf, size_t len ) -{ - int ret; - mbedtls_ecp_group_id grp_id; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( *buf != NULL ); - - if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, len ) ) != 0 ) - return( ret ); - - return( mbedtls_ecp_group_load( grp, grp_id ) ); -} - -/* - * Read a group id from an ECParameters record (RFC 4492) and convert it to - * mbedtls_ecp_group_id. - */ -int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, - const unsigned char **buf, size_t len ) -{ - uint16_t tls_id; - const mbedtls_ecp_curve_info *curve_info; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( *buf != NULL ); - - /* - * We expect at least three bytes (see below) - */ - if( len < 3 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * First byte is curve_type; only named_curve is handled - */ - if( *(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * Next two bytes are the namedcurve value - */ - tls_id = *(*buf)++; - tls_id <<= 8; - tls_id |= *(*buf)++; - - if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL ) - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - - *grp = curve_info->grp_id; - - return( 0 ); -} - -/* - * Write the ECParameters record corresponding to a group (RFC 4492) - */ -int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, - unsigned char *buf, size_t blen ) -{ - const mbedtls_ecp_curve_info *curve_info; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( buf != NULL ); - ECP_VALIDATE_RET( olen != NULL ); - - if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* - * We are going to write 3 bytes (see below) - */ - *olen = 3; - if( blen < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - /* - * First byte is curve_type, always named_curve - */ - *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE; - - /* - * Next two bytes are the namedcurve value - */ - buf[0] = curve_info->tls_id >> 8; - buf[1] = curve_info->tls_id & 0xFF; - - return( 0 ); -} - -/* - * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi. - * See the documentation of struct mbedtls_ecp_group. - * - * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf. - */ -static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp ) -{ - int ret; - - if( grp->modp == NULL ) - return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) ); - - /* N->s < 0 is a much faster test, which fails only if N is 0 */ - if( ( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) || - mbedtls_mpi_bitlen( N ) > 2 * grp->pbits ) - { - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - - MBEDTLS_MPI_CHK( grp->modp( N ) ); - - /* N->s < 0 is a much faster test, which fails only if N is 0 */ - while( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &grp->P ) ); - - while( mbedtls_mpi_cmp_mpi( N, &grp->P ) >= 0 ) - /* we known P, N and the result are positive */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, N, &grp->P ) ); - -cleanup: - return( ret ); -} - -/* - * Fast mod-p functions expect their argument to be in the 0..p^2 range. - * - * In order to guarantee that, we need to ensure that operands of - * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will - * bring the result back to this range. - * - * The following macros are shortcuts for doing that. - */ - -/* - * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi - */ -#if defined(MBEDTLS_SELF_TEST) -#define INC_MUL_COUNT mul_count++; -#else -#define INC_MUL_COUNT -#endif - -#define MOD_MUL( N ) \ - do \ - { \ - MBEDTLS_MPI_CHK( ecp_modp( &(N), grp ) ); \ - INC_MUL_COUNT \ - } while( 0 ) - -/* - * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi - * N->s < 0 is a very fast test, which fails only if N is 0 - */ -#define MOD_SUB( N ) \ - while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 ) \ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) ) - -/* - * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int. - * We known P, N and the result are positive, so sub_abs is correct, and - * a bit faster. - */ -#define MOD_ADD( N ) \ - while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 ) \ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) ) - -#if defined(ECP_SHORTWEIERSTRASS) -/* - * For curves in short Weierstrass form, we do all the internal operations in - * Jacobian coordinates. - * - * For multiplication, we'll use a comb method with coutermeasueres against - * SPA, hence timing attacks. - */ - -/* - * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1) - * Cost: 1N := 1I + 3M + 1S - */ -static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt ) -{ - int ret; - mbedtls_mpi Zi, ZZi; - - if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ) - return( 0 ); - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_normalize_jac( grp, pt ) ); -#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ - - mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); - - /* - * X = X / Z^2 mod p - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi, &pt->Z, &grp->P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X ); - - /* - * Y = Y / Z^3 mod p - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y ); - - /* - * Z = 1 - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); - -cleanup: - - mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi ); - - return( ret ); -} - -/* - * Normalize jacobian coordinates of an array of (pointers to) points, - * using Montgomery's trick to perform only one inversion mod P. - * (See for example Cohen's "A Course in Computational Algebraic Number - * Theory", Algorithm 10.3.4.) - * - * Warning: fails (returning an error) if one of the points is zero! - * This should never happen, see choice of w in ecp_mul_comb(). - * - * Cost: 1N(t) := 1I + (6t - 3)M + 1S - */ -static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *T[], size_t T_size ) -{ - int ret; - size_t i; - mbedtls_mpi *c, u, Zi, ZZi; - - if( T_size < 2 ) - return( ecp_normalize_jac( grp, *T ) ); - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_normalize_jac_many( grp, T, T_size ) ); -#endif - - if( ( c = mbedtls_calloc( T_size, sizeof( mbedtls_mpi ) ) ) == NULL ) - return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); - - for( i = 0; i < T_size; i++ ) - mbedtls_mpi_init( &c[i] ); - - mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); - - /* - * c[i] = Z_0 * ... * Z_i - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) ); - for( i = 1; i < T_size; i++ ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) ); - MOD_MUL( c[i] ); - } - - /* - * u = 1 / (Z_0 * ... * Z_n) mod P - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[T_size-1], &grp->P ) ); - - for( i = T_size - 1; ; i-- ) - { - /* - * Zi = 1 / Z_i mod p - * u = 1 / (Z_0 * ... * Z_i) mod P - */ - if( i == 0 ) { - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Zi, &u ) ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u ); - } - - /* - * proceed as in normalize() - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y ); - - /* - * Post-precessing: reclaim some memory by shrinking coordinates - * - not storing Z (always 1) - * - shrinking other coordinates, but still keeping the same number of - * limbs as P, as otherwise it will too likely be regrown too fast. - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->X, grp->P.n ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->Y, grp->P.n ) ); - mbedtls_mpi_free( &T[i]->Z ); - - if( i == 0 ) - break; - } - -cleanup: - - mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi ); - for( i = 0; i < T_size; i++ ) - mbedtls_mpi_free( &c[i] ); - mbedtls_free( c ); - - return( ret ); -} - -/* - * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak. - * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid - */ -static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *Q, - unsigned char inv ) -{ - int ret; - unsigned char nonzero; - mbedtls_mpi mQY; - - mbedtls_mpi_init( &mQY ); - - /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) ); - nonzero = mbedtls_mpi_cmp_int( &Q->Y, 0 ) != 0; - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) ); - -cleanup: - mbedtls_mpi_free( &mQY ); - - return( ret ); -} - -/* - * Point doubling R = 2 P, Jacobian coordinates - * - * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 . - * - * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR - * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring. - * - * Standard optimizations are applied when curve parameter A is one of { 0, -3 }. - * - * Cost: 1D := 3M + 4S (A == 0) - * 4M + 4S (A == -3) - * 3M + 6S + 1a otherwise - */ -static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *P ) -{ - int ret; - mbedtls_mpi M, S, T, U; - -#if defined(MBEDTLS_SELF_TEST) - dbl_count++; -#endif - -#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_double_jac( grp, R, P ) ); -#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ - - mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U ); - - /* Special case for A = -3 */ - if( grp->A.p == NULL ) - { - /* M = 3(X + Z^2)(X - Z^2) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M ); - } - else - { - /* M = 3.X^2 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M ); - - /* Optimize away for "koblitz" curves with A = 0 */ - if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 ) - { - /* M += A.Z^4 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M ); - } - } - - /* S = 4.X.Y^2 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T, 1 ) ); MOD_ADD( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S, 1 ) ); MOD_ADD( S ); - - /* U = 8.Y^4 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U ); - - /* T = M^2 - 2.S */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T ); - - /* S = M(S - T) - U */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S ); - - /* U = 2.Y.Z */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &U ) ); - -cleanup: - mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U ); - - return( ret ); -} - -/* - * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22) - * - * The coordinates of Q must be normalized (= affine), - * but those of P don't need to. R is not normalized. - * - * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. - * None of these cases can happen as intermediate step in ecp_mul_comb(): - * - at each step, P, Q and R are multiples of the base point, the factor - * being less than its order, so none of them is zero; - * - Q is an odd multiple of the base point, P an even multiple, - * due to the choice of precomputed points in the modified comb method. - * So branches for these cases do not leak secret information. - * - * We accept Q->Z being unset (saving memory in tables) as meaning 1. - * - * Cost: 1A := 8M + 3S - */ -static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) -{ - int ret; - mbedtls_mpi T1, T2, T3, T4, X, Y, Z; - -#if defined(MBEDTLS_SELF_TEST) - add_count++; -#endif - -#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_add_mixed( grp, R, P, Q ) ); -#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ - - /* - * Trivial cases: P == 0 or Q == 0 (case 1) - */ - if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) - return( mbedtls_ecp_copy( R, Q ) ); - - if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 0 ) == 0 ) - return( mbedtls_ecp_copy( R, P ) ); - - /* - * Make sure Q coordinates are normalized - */ - if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 1 ) != 0 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 ); - mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 ); - - /* Special cases (2) and (3) */ - if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 ) - { - if( mbedtls_mpi_cmp_int( &T2, 0 ) == 0 ) - { - ret = ecp_double_jac( grp, R, P ); - goto cleanup; - } - else - { - ret = mbedtls_ecp_set_zero( R ); - goto cleanup; - } - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) ); - -cleanup: - - mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 ); - mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); - - return( ret ); -} - -/* - * Randomize jacobian coordinates: - * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l - * This is sort of the reverse operation of ecp_normalize_jac(). - * - * This countermeasure was first suggested in [2]. - */ -static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - mbedtls_mpi l, ll; - size_t p_size; - int count = 0; - -#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ) ); -#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ - - p_size = ( grp->pbits + 7 ) / 8; - mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll ); - - /* Generate l such that 1 < l < p */ - do - { - if( count++ > 30 ) - { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, ( p_size * 8 ) - grp->pbits ) ); - } - while( ( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ) || - ( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) ); - - /* Z = l * Z */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z ); - - /* X = l^2 * X */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X ); - - /* Y = l^3 * Y */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y ); - -cleanup: - mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll ); - - return( ret ); -} - -/* - * Check and define parameters used by the comb method (see below for details) - */ -#if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7 -#error "MBEDTLS_ECP_WINDOW_SIZE out of bounds" -#endif - -/* d = ceil( n / w ) */ -#define COMB_MAX_D ( MBEDTLS_ECP_MAX_BITS + 1 ) / 2 - -/* number of precomputed points */ -#define COMB_MAX_PRE ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) - -/* - * Compute the representation of m that will be used with our comb method. - * - * The basic comb method is described in GECC 3.44 for example. We use a - * modified version that provides resistance to SPA by avoiding zero - * digits in the representation as in [3]. We modify the method further by - * requiring that all K_i be odd, which has the small cost that our - * representation uses one more K_i, due to carries, but saves on the size of - * the precomputed table. - * - * Summary of the comb method and its modifications: - * - * - The goal is to compute m*P for some w*d-bit integer m. - * - * - The basic comb method splits m into the w-bit integers - * x[0] .. x[d-1] where x[i] consists of the bits in m whose - * index has residue i modulo d, and computes m * P as - * S[x[0]] + 2 * S[x[1]] + .. + 2^(d-1) S[x[d-1]], where - * S[i_{w-1} .. i_0] := i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + i_0 P. - * - * - If it happens that, say, x[i+1]=0 (=> S[x[i+1]]=0), one can replace the sum by - * .. + 2^{i-1} S[x[i-1]] - 2^i S[x[i]] + 2^{i+1} S[x[i]] + 2^{i+2} S[x[i+2]] .., - * thereby successively converting it into a form where all summands - * are nonzero, at the cost of negative summands. This is the basic idea of [3]. - * - * - More generally, even if x[i+1] != 0, we can first transform the sum as - * .. - 2^i S[x[i]] + 2^{i+1} ( S[x[i]] + S[x[i+1]] ) + 2^{i+2} S[x[i+2]] .., - * and then replace S[x[i]] + S[x[i+1]] = S[x[i] ^ x[i+1]] + 2 S[x[i] & x[i+1]]. - * Performing and iterating this procedure for those x[i] that are even - * (keeping track of carry), we can transform the original sum into one of the form - * S[x'[0]] +- 2 S[x'[1]] +- .. +- 2^{d-1} S[x'[d-1]] + 2^d S[x'[d]] - * with all x'[i] odd. It is therefore only necessary to know S at odd indices, - * which is why we are only computing half of it in the first place in - * ecp_precompute_comb and accessing it with index abs(i) / 2 in ecp_select_comb. - * - * - For the sake of compactness, only the seven low-order bits of x[i] - * are used to represent its absolute value (K_i in the paper), and the msb - * of x[i] encodes the sign (s_i in the paper): it is set if and only if - * if s_i == -1; - * - * Calling conventions: - * - x is an array of size d + 1 - * - w is the size, ie number of teeth, of the comb, and must be between - * 2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE) - * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d - * (the result will be incorrect if these assumptions are not satisfied) - */ -static void ecp_comb_recode_core( unsigned char x[], size_t d, - unsigned char w, const mbedtls_mpi *m ) -{ - size_t i, j; - unsigned char c, cc, adjust; - - memset( x, 0, d+1 ); - - /* First get the classical comb values (except for x_d = 0) */ - for( i = 0; i < d; i++ ) - for( j = 0; j < w; j++ ) - x[i] |= mbedtls_mpi_get_bit( m, i + d * j ) << j; - - /* Now make sure x_1 .. x_d are odd */ - c = 0; - for( i = 1; i <= d; i++ ) - { - /* Add carry and update it */ - cc = x[i] & c; - x[i] = x[i] ^ c; - c = cc; - - /* Adjust if needed, avoiding branches */ - adjust = 1 - ( x[i] & 0x01 ); - c |= x[i] & ( x[i-1] * adjust ); - x[i] = x[i] ^ ( x[i-1] * adjust ); - x[i-1] |= adjust << 7; - } -} - -/* - * Precompute points for the adapted comb method - * - * Assumption: T must be able to hold 2^{w - 1} elements. - * - * Operation: If i = i_{w-1} ... i_1 is the binary representation of i, - * sets T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P. - * - * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) - * - * Note: Even comb values (those where P would be omitted from the - * sum defining T[i] above) are not needed in our adaption - * the comb method. See ecp_comb_recode_core(). - * - * This function currently works in four steps: - * (1) [dbl] Computation of intermediate T[i] for 2-power values of i - * (2) [norm_dbl] Normalization of coordinates of these T[i] - * (3) [add] Computation of all T[i] - * (4) [norm_add] Normalization of all T[i] - * - * Step 1 can be interrupted but not the others; together with the final - * coordinate normalization they are the largest steps done at once, depending - * on the window size. Here are operation counts for P-256: - * - * step (2) (3) (4) - * w = 5 142 165 208 - * w = 4 136 77 160 - * w = 3 130 33 136 - * w = 2 124 11 124 - * - * So if ECC operations are blocking for too long even with a low max_ops - * value, it's useful to set MBEDTLS_ECP_WINDOW_SIZE to a lower value in order - * to minimize maximum blocking time. - */ -static int ecp_precompute_comb( const mbedtls_ecp_group *grp, - mbedtls_ecp_point T[], const mbedtls_ecp_point *P, - unsigned char w, size_t d, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char i; - size_t j = 0; - const unsigned char T_size = 1U << ( w - 1 ); - mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1]; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - { - if( rs_ctx->rsm->state == ecp_rsm_pre_dbl ) - goto dbl; - if( rs_ctx->rsm->state == ecp_rsm_pre_norm_dbl ) - goto norm_dbl; - if( rs_ctx->rsm->state == ecp_rsm_pre_add ) - goto add; - if( rs_ctx->rsm->state == ecp_rsm_pre_norm_add ) - goto norm_add; - } -#else - (void) rs_ctx; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - { - rs_ctx->rsm->state = ecp_rsm_pre_dbl; - - /* initial state for the loop */ - rs_ctx->rsm->i = 0; - } - -dbl: -#endif - /* - * Set T[0] = P and - * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) - */ - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &T[0], P ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 ) - j = rs_ctx->rsm->i; - else -#endif - j = 0; - - for( ; j < d * ( w - 1 ); j++ ) - { - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL ); - - i = 1U << ( j / d ); - cur = T + i; - - if( j % d == 0 ) - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) ); - - MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) ); - } - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_pre_norm_dbl; - -norm_dbl: -#endif - /* - * Normalize current elements in T. As T has holes, - * use an auxiliary array of pointers to elements in T. - */ - j = 0; - for( i = 1; i < T_size; i <<= 1 ) - TT[j++] = T + i; - - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 ); - - MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_pre_add; - -add: -#endif - /* - * Compute the remaining ones using the minimal number of additions - * Be careful to update T[2^l] only after using it! - */ - MBEDTLS_ECP_BUDGET( ( T_size - 1 ) * MBEDTLS_ECP_OPS_ADD ); - - for( i = 1; i < T_size; i <<= 1 ) - { - j = i; - while( j-- ) - MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) ); - } - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_pre_norm_add; - -norm_add: -#endif - /* - * Normalize final elements in T. Even though there are no holes now, we - * still need the auxiliary array for homogeneity with the previous - * call. Also, skip T[0] which is already normalised, being a copy of P. - */ - for( j = 0; j + 1 < T_size; j++ ) - TT[j] = T + j + 1; - - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 ); - - MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) ); - -cleanup: -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && - ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - if( rs_ctx->rsm->state == ecp_rsm_pre_dbl ) - rs_ctx->rsm->i = j; - } -#endif - - return( ret ); -} - -/* - * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] - * - * See ecp_comb_recode_core() for background - */ -static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point T[], unsigned char T_size, - unsigned char i ) -{ - int ret; - unsigned char ii, j; - - /* Ignore the "sign" bit and scale down */ - ii = ( i & 0x7Fu ) >> 1; - - /* Read the whole table to thwart cache-based timing attacks */ - for( j = 0; j < T_size; j++ ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) ); - } - - /* Safely invert result if i is "negative" */ - MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) ); - -cleanup: - return( ret ); -} - -/* - * Core multiplication algorithm for the (modified) comb method. - * This part is actually common with the basic comb method (GECC 3.44) - * - * Cost: d A + d D + 1 R - */ -static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point T[], unsigned char T_size, - const unsigned char x[], size_t d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_ecp_point Txi; - size_t i; - - mbedtls_ecp_point_init( &Txi ); - -#if !defined(MBEDTLS_ECP_RESTARTABLE) - (void) rs_ctx; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && - rs_ctx->rsm->state != ecp_rsm_comb_core ) - { - rs_ctx->rsm->i = 0; - rs_ctx->rsm->state = ecp_rsm_comb_core; - } - - /* new 'if' instead of nested for the sake of the 'else' branch */ - if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 ) - { - /* restore current index (R already pointing to rs_ctx->rsm->R) */ - i = rs_ctx->rsm->i; - } - else -#endif - { - /* Start with a non-zero point and randomize its coordinates */ - i = d; - MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) ); -#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng != 0 ) -#endif - MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); - } - - while( i != 0 ) - { - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD ); - --i; - - MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) ); - MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, T_size, x[i] ) ); - MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) ); - } - -cleanup: - - mbedtls_ecp_point_free( &Txi ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && - ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - rs_ctx->rsm->i = i; - /* no need to save R, already pointing to rs_ctx->rsm->R */ - } -#endif - - return( ret ); -} - -/* - * Recode the scalar to get constant-time comb multiplication - * - * As the actual scalar recoding needs an odd scalar as a starting point, - * this wrapper ensures that by replacing m by N - m if necessary, and - * informs the caller that the result of multiplication will be negated. - * - * This works because we only support large prime order for Short Weierstrass - * curves, so N is always odd hence either m or N - m is. - * - * See ecp_comb_recode_core() for background. - */ -static int ecp_comb_recode_scalar( const mbedtls_ecp_group *grp, - const mbedtls_mpi *m, - unsigned char k[COMB_MAX_D + 1], - size_t d, - unsigned char w, - unsigned char *parity_trick ) -{ - int ret; - mbedtls_mpi M, mm; - - mbedtls_mpi_init( &M ); - mbedtls_mpi_init( &mm ); - - /* N is always odd (see above), just make extra sure */ - if( mbedtls_mpi_get_bit( &grp->N, 0 ) != 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - /* do we need the parity trick? */ - *parity_trick = ( mbedtls_mpi_get_bit( m, 0 ) == 0 ); - - /* execute parity fix in constant time */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, *parity_trick ) ); - - /* actual scalar recoding */ - ecp_comb_recode_core( k, d, w, &M ); - -cleanup: - mbedtls_mpi_free( &mm ); - mbedtls_mpi_free( &M ); - - return( ret ); -} - -/* - * Perform comb multiplication (for short Weierstrass curves) - * once the auxiliary table has been pre-computed. - * - * Scalar recoding may use a parity trick that makes us compute -m * P, - * if that is the case we'll need to recover m * P at the end. - */ -static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, - const mbedtls_mpi *m, - const mbedtls_ecp_point *T, - unsigned char T_size, - unsigned char w, - size_t d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char parity_trick; - unsigned char k[COMB_MAX_D + 1]; - mbedtls_ecp_point *RR = R; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - { - RR = &rs_ctx->rsm->R; - - if( rs_ctx->rsm->state == ecp_rsm_final_norm ) - goto final_norm; - } -#endif - - MBEDTLS_MPI_CHK( ecp_comb_recode_scalar( grp, m, k, d, w, - &parity_trick ) ); - MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, RR, T, T_size, k, d, - f_rng, p_rng, rs_ctx ) ); - MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, RR, parity_trick ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->state = ecp_rsm_final_norm; - -final_norm: - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); -#endif - /* - * Knowledge of the jacobian coordinates may leak the last few bits of the - * scalar [1], and since our MPI implementation isn't constant-flow, - * inversion (used for coordinate normalization) may leak the full value - * of its input via side-channels [2]. - * - * [1] https://eprint.iacr.org/2003/191 - * [2] https://eprint.iacr.org/2020/055 - * - * Avoid the leak by randomizing coordinates before we normalize them. - */ -#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng != 0 ) -#endif - MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) ); - - MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, RR ) ); -#endif - -cleanup: - return( ret ); -} - -/* - * Pick window size based on curve size and whether we optimize for base point - */ -static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp, - unsigned char p_eq_g ) -{ - unsigned char w; - - /* - * Minimize the number of multiplications, that is minimize - * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) - * (see costs of the various parts, with 1S = 1M) - */ - w = grp->nbits >= 384 ? 5 : 4; - - /* - * If P == G, pre-compute a bit more, since this may be re-used later. - * Just adding one avoids upping the cost of the first mul too much, - * and the memory cost too. - */ - if( p_eq_g ) - w++; - - /* - * Make sure w is within bounds. - * (The last test is useful only for very small curves in the test suite.) - */ - if( w > MBEDTLS_ECP_WINDOW_SIZE ) - w = MBEDTLS_ECP_WINDOW_SIZE; - if( w >= grp->nbits ) - w = 2; - - return( w ); -} - -/* - * Multiplication using the comb method - for curves in short Weierstrass form - * - * This function is mainly responsible for administrative work: - * - managing the restart context if enabled - * - managing the table of precomputed points (passed between the below two - * functions): allocation, computation, ownership tranfer, freeing. - * - * It delegates the actual arithmetic work to: - * ecp_precompute_comb() and ecp_mul_comb_with_precomp() - * - * See comments on ecp_comb_recode_core() regarding the computation strategy. - */ -static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - unsigned char w, p_eq_g, i; - size_t d; - unsigned char T_size = 0, T_ok = 0; - mbedtls_ecp_point *T = NULL; -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - ecp_drbg_context drbg_ctx; - - ecp_drbg_init( &drbg_ctx ); -#endif - - ECP_RS_ENTER( rsm ); - -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng == NULL ) - { - /* Adjust pointers */ - f_rng = &ecp_drbg_random; -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - p_rng = &rs_ctx->rsm->drbg_ctx; - else -#endif - p_rng = &drbg_ctx; - - /* Initialize internal DRBG if necessary */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx == NULL || rs_ctx->rsm == NULL || - rs_ctx->rsm->drbg_seeded == 0 ) -#endif - { - const size_t m_len = ( grp->nbits + 7 ) / 8; - MBEDTLS_MPI_CHK( ecp_drbg_seed( p_rng, m, m_len ) ); - } -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL ) - rs_ctx->rsm->drbg_seeded = 1; -#endif - } -#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */ - - /* Is P the base point ? */ -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 - p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && - mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); -#else - p_eq_g = 0; -#endif - - /* Pick window size and deduce related sizes */ - w = ecp_pick_window_size( grp, p_eq_g ); - T_size = 1U << ( w - 1 ); - d = ( grp->nbits + w - 1 ) / w; - - /* Pre-computed table: do we have it already for the base point? */ - if( p_eq_g && grp->T != NULL ) - { - /* second pointer to the same table, will be deleted on exit */ - T = grp->T; - T_ok = 1; - } - else -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* Pre-computed table: do we have one in progress? complete? */ - if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->T != NULL ) - { - /* transfer ownership of T from rsm to local function */ - T = rs_ctx->rsm->T; - rs_ctx->rsm->T = NULL; - rs_ctx->rsm->T_size = 0; - - /* This effectively jumps to the call to mul_comb_after_precomp() */ - T_ok = rs_ctx->rsm->state >= ecp_rsm_comb_core; - } - else -#endif - /* Allocate table if we didn't have any */ - { - T = mbedtls_calloc( T_size, sizeof( mbedtls_ecp_point ) ); - if( T == NULL ) - { - ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; - goto cleanup; - } - - for( i = 0; i < T_size; i++ ) - mbedtls_ecp_point_init( &T[i] ); - - T_ok = 0; - } - - /* Compute table (or finish computing it) if not done already */ - if( !T_ok ) - { - MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d, rs_ctx ) ); - - if( p_eq_g ) - { - /* almost transfer ownership of T to the group, but keep a copy of - * the pointer to use for calling the next function more easily */ - grp->T = T; - grp->T_size = T_size; - } - } - - /* Actual comb multiplication using precomputed points */ - MBEDTLS_MPI_CHK( ecp_mul_comb_after_precomp( grp, R, m, - T, T_size, w, d, - f_rng, p_rng, rs_ctx ) ); - -cleanup: - -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - ecp_drbg_free( &drbg_ctx ); -#endif - - /* does T belong to the group? */ - if( T == grp->T ) - T = NULL; - - /* does T belong to the restart context? */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->rsm != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS && T != NULL ) - { - /* transfer ownership of T from local function to rsm */ - rs_ctx->rsm->T_size = T_size; - rs_ctx->rsm->T = T; - T = NULL; - } -#endif - - /* did T belong to us? then let's destroy it! */ - if( T != NULL ) - { - for( i = 0; i < T_size; i++ ) - mbedtls_ecp_point_free( &T[i] ); - mbedtls_free( T ); - } - - /* don't free R while in progress in case R == P */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) -#endif - /* prevent caller from using invalid value */ - if( ret != 0 ) - mbedtls_ecp_point_free( R ); - - ECP_RS_LEAVE( rsm ); - - return( ret ); -} - -#endif /* ECP_SHORTWEIERSTRASS */ - -#if defined(ECP_MONTGOMERY) -/* - * For Montgomery curves, we do all the internal arithmetic in projective - * coordinates. Import/export of points uses only the x coordinates, which is - * internaly represented as X / Z. - * - * For scalar multiplication, we'll use a Montgomery ladder. - */ - -/* - * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1 - * Cost: 1M + 1I - */ -static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P ) -{ - int ret; - -#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_normalize_mxz( grp, P ) ); -#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ - - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); - -cleanup: - return( ret ); -} - -/* - * Randomize projective x/z coordinates: - * (X, Z) -> (l X, l Z) for random l - * This is sort of the reverse operation of ecp_normalize_mxz(). - * - * This countermeasure was first suggested in [2]. - * Cost: 2M - */ -static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - mbedtls_mpi l; - size_t p_size; - int count = 0; - -#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ) ); -#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ - - p_size = ( grp->pbits + 7 ) / 8; - mbedtls_mpi_init( &l ); - - /* Generate l such that 1 < l < p */ - do - { - if( count++ > 30 ) - { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, ( p_size * 8 ) - grp->pbits ) ); - } - while( ( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ) || - ( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z ); - -cleanup: - mbedtls_mpi_free( &l ); - - return( ret ); -} - -/* - * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q), - * for Montgomery curves in x/z coordinates. - * - * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3 - * with - * d = X1 - * P = (X2, Z2) - * Q = (X3, Z3) - * R = (X4, Z4) - * S = (X5, Z5) - * and eliminating temporary variables tO, ..., t4. - * - * Cost: 5M + 4S - */ -static int ecp_double_add_mxz( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, mbedtls_ecp_point *S, - const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q, - const mbedtls_mpi *d ) -{ - int ret; - mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB; - -#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) - if( mbedtls_internal_ecp_grp_capable( grp ) ) - return( mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ) ); -#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ - - mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B ); - mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C ); - mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z ); - -cleanup: - mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B ); - mbedtls_mpi_free( &BB ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &C ); - mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB ); - - return( ret ); -} - -/* - * Multiplication with Montgomery ladder in x/z coordinates, - * for curves in Montgomery form - */ -static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - size_t i; - unsigned char b; - mbedtls_ecp_point RP; - mbedtls_mpi PX; -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - ecp_drbg_context drbg_ctx; - - ecp_drbg_init( &drbg_ctx ); -#endif - mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX ); - -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng == NULL ) - { - const size_t m_len = ( grp->nbits + 7 ) / 8; - MBEDTLS_MPI_CHK( ecp_drbg_seed( &drbg_ctx, m, m_len ) ); - f_rng = &ecp_drbg_random; - p_rng = &drbg_ctx; - } -#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */ - - /* Save PX and read from P before writing to R, in case P == R */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &RP, P ) ); - - /* Set R to zero in modified x/z coordinates */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->X, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) ); - mbedtls_mpi_free( &R->Y ); - - /* RP.X might be sligtly larger than P, so reduce it */ - MOD_ADD( RP.X ); - - /* Randomize coordinates of the starting point */ -#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng != NULL ) -#endif - MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) ); - - /* Loop invariant: R = result so far, RP = R + P */ - i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */ - while( i-- > 0 ) - { - b = mbedtls_mpi_get_bit( m, i ); - /* - * if (b) R = 2R + P else R = 2R, - * which is: - * if (b) double_add( RP, R, RP, R ) - * else double_add( R, RP, R, RP ) - * but using safe conditional swaps to avoid leaks - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); - MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); - } - - /* - * Knowledge of the projective coordinates may leak the last few bits of the - * scalar [1], and since our MPI implementation isn't constant-flow, - * inversion (used for coordinate normalization) may leak the full value - * of its input via side-channels [2]. - * - * [1] https://eprint.iacr.org/2003/191 - * [2] https://eprint.iacr.org/2020/055 - * - * Avoid the leak by randomizing coordinates before we normalize them. - */ -#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - if( f_rng != NULL ) -#endif - MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) ); - - MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) ); - -cleanup: -#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - ecp_drbg_free( &drbg_ctx ); -#endif - - mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX ); - - return( ret ); -} - -#endif /* ECP_MONTGOMERY */ - -/* - * Restartable multiplication R = m * P - */ -int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - char is_grp_capable = 0; -#endif - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* reset ops count for this call if top-level */ - if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) - rs_ctx->ops_done = 0; -#endif - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) ) - MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* skip argument check when restarting */ - if( rs_ctx == NULL || rs_ctx->rsm == NULL ) -#endif - { - /* check_privkey is free */ - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK ); - - /* Common sanity checks */ - MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( grp, m ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) ); - } - - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -#if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) - MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); -#endif -#if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) - MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) ); -#endif - -cleanup: - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( is_grp_capable ) - mbedtls_internal_ecp_free( grp ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL ) - rs_ctx->depth--; -#endif - - return( ret ); -} - -/* - * Multiplication R = m * P - */ -int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) ); -} - -#if defined(ECP_SHORTWEIERSTRASS) -/* - * Check that an affine point is valid as a public key, - * short weierstrass curves (SEC1 3.2.3.1) - */ -static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) -{ - int ret; - mbedtls_mpi YY, RHS; - - /* pt coordinates must be normalized for our checks */ - if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 || - mbedtls_mpi_cmp_int( &pt->Y, 0 ) < 0 || - mbedtls_mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 || - mbedtls_mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - mbedtls_mpi_init( &YY ); mbedtls_mpi_init( &RHS ); - - /* - * YY = Y^2 - * RHS = X (X^2 + A) + B = X^3 + A X + B - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS ); - - /* Special case for A = -3 */ - if( grp->A.p == NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS ); - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS ); - - if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 ) - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - -cleanup: - - mbedtls_mpi_free( &YY ); mbedtls_mpi_free( &RHS ); - - return( ret ); -} -#endif /* ECP_SHORTWEIERSTRASS */ - -/* - * R = m * P with shortcuts for m == 1 and m == -1 - * NOT constant-time - ONLY for short Weierstrass! - */ -static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, - const mbedtls_mpi *m, - const mbedtls_ecp_point *P, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - - if( mbedtls_mpi_cmp_int( m, 1 ) == 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); - } - else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 ) - { - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); - if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) ); - } - else - { - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P, - NULL, NULL, rs_ctx ) ); - } - -cleanup: - return( ret ); -} - -/* - * Restartable linear combination - * NOT constant-time - */ -int mbedtls_ecp_muladd_restartable( - mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q, - mbedtls_ecp_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_ecp_point mP; - mbedtls_ecp_point *pmP = &mP; - mbedtls_ecp_point *pR = R; -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - char is_grp_capable = 0; -#endif - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( n != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - - if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - - mbedtls_ecp_point_init( &mP ); - - ECP_RS_ENTER( ma ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - { - /* redirect intermediate results to restart context */ - pmP = &rs_ctx->ma->mP; - pR = &rs_ctx->ma->R; - - /* jump to next operation */ - if( rs_ctx->ma->state == ecp_rsma_mul2 ) - goto mul2; - if( rs_ctx->ma->state == ecp_rsma_add ) - goto add; - if( rs_ctx->ma->state == ecp_rsma_norm ) - goto norm; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pmP, m, P, rs_ctx ) ); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - rs_ctx->ma->state = ecp_rsma_mul2; - -mul2: -#endif - MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pR, n, Q, rs_ctx ) ); - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) ) - MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - rs_ctx->ma->state = ecp_rsma_add; - -add: -#endif - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_ADD ); - MBEDTLS_MPI_CHK( ecp_add_mixed( grp, pR, pmP, pR ) ); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - rs_ctx->ma->state = ecp_rsma_norm; - -norm: -#endif - MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); - MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, pR ) ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && rs_ctx->ma != NULL ) - MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, pR ) ); -#endif - -cleanup: -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if( is_grp_capable ) - mbedtls_internal_ecp_free( grp ); -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - - mbedtls_ecp_point_free( &mP ); - - ECP_RS_LEAVE( ma ); - - return( ret ); -} - -/* - * Linear combination - * NOT constant-time - */ -int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( R != NULL ); - ECP_VALIDATE_RET( m != NULL ); - ECP_VALIDATE_RET( P != NULL ); - ECP_VALIDATE_RET( n != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) ); -} - -#if defined(ECP_MONTGOMERY) -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)} -#define ECP_MPI_INIT_ARRAY(x) \ - ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x) -/* - * Constants for the two points other than 0, 1, -1 (mod p) in - * https://cr.yp.to/ecdh.html#validate - * See ecp_check_pubkey_x25519(). - */ -static const mbedtls_mpi_uint x25519_bad_point_1[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 ), -}; -static const mbedtls_mpi_uint x25519_bad_point_2[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 ), -}; -static const mbedtls_mpi ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY( - x25519_bad_point_1 ); -static const mbedtls_mpi ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY( - x25519_bad_point_2 ); -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -/* - * Check that the input point is not one of the low-order points. - * This is recommended by the "May the Fourth" paper: - * https://eprint.iacr.org/2017/806.pdf - * Those points are never sent by an honest peer. - */ -static int ecp_check_bad_points_mx( const mbedtls_mpi *X, const mbedtls_mpi *P, - const mbedtls_ecp_group_id grp_id ) -{ - int ret; - mbedtls_mpi XmP; - - mbedtls_mpi_init( &XmP ); - - /* Reduce X mod P so that we only need to check values less than P. - * We know X < 2^256 so we can proceed by subtraction. */ - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &XmP, X ) ); - while( mbedtls_mpi_cmp_mpi( &XmP, P ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &XmP, &XmP, P ) ); - - /* Check against the known bad values that are less than P. For Curve448 - * these are 0, 1 and -1. For Curve25519 we check the values less than P - * from the following list: https://cr.yp.to/ecdh.html#validate */ - if( mbedtls_mpi_cmp_int( &XmP, 1 ) <= 0 ) /* takes care of 0 and 1 */ - { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - if( grp_id == MBEDTLS_ECP_DP_CURVE25519 ) - { - if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_1 ) == 0 ) - { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - - if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_2 ) == 0 ) - { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - } -#else - (void) grp_id; -#endif - - /* Final check: check if XmP + 1 is P (final because it changes XmP!) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &XmP, &XmP, 1 ) ); - if( mbedtls_mpi_cmp_mpi( &XmP, P ) == 0 ) - { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - - ret = 0; - -cleanup: - mbedtls_mpi_free( &XmP ); - - return( ret ); -} - -/* - * Check validity of a public key for Montgomery curves with x-only schemes - */ -static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) -{ - /* [Curve25519 p. 5] Just check X is the correct number of bytes */ - /* Allow any public value, if it's too big then we'll just reduce it mod p - * (RFC 7748 sec. 5 para. 3). */ - if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - /* Implicit in all standards (as they don't consider negative numbers): - * X must be non-negative. This is normally ensured by the way it's - * encoded for transmission, but let's be extra sure. */ - if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - return( ecp_check_bad_points_mx( &pt->X, &grp->P, grp->id ) ); -} -#endif /* ECP_MONTGOMERY */ - -/* - * Check that a point is valid as a public key - */ -int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); - - /* Must use affine coordinates */ - if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - -#if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) - return( ecp_check_pubkey_mx( grp, pt ) ); -#endif -#if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) - return( ecp_check_pubkey_sw( grp, pt ) ); -#endif - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); -} - -/* - * Check that an mbedtls_mpi is valid as a private key - */ -int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, - const mbedtls_mpi *d ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - -#if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) - { - /* see RFC 7748 sec. 5 para. 5 */ - if( mbedtls_mpi_get_bit( d, 0 ) != 0 || - mbedtls_mpi_get_bit( d, 1 ) != 0 || - mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */ - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - /* see [Curve25519] page 5 */ - if( grp->nbits == 254 && mbedtls_mpi_get_bit( d, 2 ) != 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - - return( 0 ); - } -#endif /* ECP_MONTGOMERY */ -#if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) - { - /* see SEC1 3.2 */ - if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || - mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ) - return( MBEDTLS_ERR_ECP_INVALID_KEY ); - else - return( 0 ); - } -#endif /* ECP_SHORTWEIERSTRASS */ - - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); -} - -/* - * Generate a private key - */ -int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, - mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - size_t n_size; -#if defined(ECP_SHORTWEIERSTRASS) - mbedtls_mpi one; - - mbedtls_mpi_init( &one ); -#endif - - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - n_size = ( grp->nbits + 7 ) / 8; - -#if defined(ECP_MONTGOMERY) - if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) - { - /* [M225] page 5 */ - size_t b; - - do { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); - } while( mbedtls_mpi_bitlen( d ) == 0); - - /* Make sure the most significant bit is nbits */ - b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */ - if( b > grp->nbits ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) ); - else - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) ); - - /* Make sure the last two bits are unset for Curve448, three bits for - Curve25519 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) ); - if( grp->nbits == 254 ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) ); - } - } -#endif /* ECP_MONTGOMERY */ - -#if defined(ECP_SHORTWEIERSTRASS) - if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) - { - /* SEC1 3.2.1: Generate d such that 1 <= n < N */ - int count = 0; - unsigned lt_lower = 1, lt_upper = 0; - - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &one, grp->N.n ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); - - /* - * Match the procedure given in RFC 6979 (deterministic ECDSA): - * - use the same byte ordering; - * - keep the leftmost nbits bits of the generated octet string; - * - try until result is in the desired range. - * This also avoids any biais, which is especially important for ECDSA. - */ - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) ); - - /* - * Each try has at worst a probability 1/2 of failing (the msb has - * a probability 1/2 of being 0, and then the result will be < N), - * so after 30 tries failure probability is a most 2**(-30). - * - * For most curves, 1 try is enough with overwhelming probability, - * since N starts with a lot of 1s in binary, but some curves - * such as secp224k1 are actually very close to the worst case. - */ - if( ++count > 30 ) - { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &grp->N, <_upper ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &one, <_lower ) ); - } - while( lt_lower != 0 || lt_upper == 0 ); - } -#endif /* ECP_SHORTWEIERSTRASS */ - -cleanup: -#if defined(ECP_SHORTWEIERSTRASS) - mbedtls_mpi_free( &one ); -#endif - return( ret ); -} - -/* - * Generate a keypair with configurable base point - */ -int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, - const mbedtls_ecp_point *G, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - ECP_VALIDATE_RET( G != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) ); - -cleanup: - return( ret ); -} - -/* - * Generate key pair, wrapper for conventional base point - */ -int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( d != NULL ); - ECP_VALIDATE_RET( Q != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) ); -} - -/* - * Generate a keypair, prettier wrapper - */ -int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - ECP_VALIDATE_RET( key != NULL ); - ECP_VALIDATE_RET( f_rng != NULL ); - - if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 ) - return( ret ); - - return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); -} - -/* - * Check a public-private key pair - */ -int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ) -{ - int ret; - mbedtls_ecp_point Q; - mbedtls_ecp_group grp; - ECP_VALIDATE_RET( pub != NULL ); - ECP_VALIDATE_RET( prv != NULL ); - - if( pub->grp.id == MBEDTLS_ECP_DP_NONE || - pub->grp.id != prv->grp.id || - mbedtls_mpi_cmp_mpi( &pub->Q.X, &prv->Q.X ) || - mbedtls_mpi_cmp_mpi( &pub->Q.Y, &prv->Q.Y ) || - mbedtls_mpi_cmp_mpi( &pub->Q.Z, &prv->Q.Z ) ) - { - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - } - - mbedtls_ecp_point_init( &Q ); - mbedtls_ecp_group_init( &grp ); - - /* mbedtls_ecp_mul() needs a non-const group... */ - mbedtls_ecp_group_copy( &grp, &prv->grp ); - - /* Also checks d is valid */ - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) ); - - if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) || - mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) || - mbedtls_mpi_cmp_mpi( &Q.Z, &prv->Q.Z ) ) - { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free( &Q ); - mbedtls_ecp_group_free( &grp ); - - return( ret ); -} - -#if defined(MBEDTLS_SELF_TEST) - -#if defined(ECP_ONE_STEP_KDF) -/* - * There are no test vectors from NIST for the One-Step KDF in SP 800-56C, - * but unofficial ones can be found at: - * https://github.com/patrickfav/singlestep-kdf/wiki/NIST-SP-800-56C-Rev1:-Non-Official-Test-Vectors - * - * We only use the ones with empty fixedInfo, and for brevity's sake, only - * 40-bytes output (with SHA-256 that's more than one block, and with SHA-512 - * less than one block). - */ -#if defined(MBEDTLS_SHA512_C) - -static const uint8_t test_kdf_z[16] = { - 0x3b, 0xa9, 0x79, 0xe9, 0xbc, 0x5e, 0x3e, 0xc7, - 0x61, 0x30, 0x36, 0xb6, 0xf5, 0x1c, 0xd5, 0xaa, -}; -static const uint8_t test_kdf_out[40] = { - 0x3e, 0xf6, 0xda, 0xf9, 0x51, 0x60, 0x70, 0x5f, - 0xdf, 0x21, 0xcd, 0xab, 0xac, 0x25, 0x7b, 0x05, - 0xfe, 0xc1, 0xab, 0x7c, 0xc9, 0x68, 0x43, 0x25, - 0x8a, 0xfc, 0x40, 0x6e, 0x5b, 0xf7, 0x98, 0x27, - 0x10, 0xfa, 0x7b, 0x93, 0x52, 0xd4, 0x16, 0xaa, -}; - -#elif defined(MBEDTLS_SHA256_C) - -static const uint8_t test_kdf_z[16] = { - 0xc8, 0x3e, 0x35, 0x8e, 0x99, 0xa6, 0x89, 0xc6, - 0x7d, 0xb4, 0xfe, 0x39, 0xcf, 0x8f, 0x26, 0xe1, -}; -static const uint8_t test_kdf_out[40] = { - 0x7d, 0xf6, 0x41, 0xf8, 0x3c, 0x47, 0xdc, 0x28, - 0x5f, 0x7f, 0xaa, 0xde, 0x05, 0x64, 0xd6, 0x25, - 0x00, 0x6a, 0x47, 0xd9, 0x1e, 0xa4, 0xa0, 0x8c, - 0xd7, 0xf7, 0x0c, 0x99, 0xaa, 0xa0, 0x72, 0x66, - 0x69, 0x0e, 0x25, 0xaa, 0xa1, 0x63, 0x14, 0x79, -}; - -#endif - -static int ecp_kdf_self_test( void ) -{ - int ret; - ecp_drbg_context kdf_ctx; - mbedtls_mpi scalar; - uint8_t out[sizeof( test_kdf_out )]; - - ecp_drbg_init( &kdf_ctx ); - mbedtls_mpi_init( &scalar ); - memset( out, 0, sizeof( out ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &scalar, - test_kdf_z, sizeof( test_kdf_z ) ) ); - - MBEDTLS_MPI_CHK( ecp_drbg_seed( &kdf_ctx, - &scalar, sizeof( test_kdf_z ) ) ); - - MBEDTLS_MPI_CHK( ecp_drbg_random( &kdf_ctx, out, sizeof( out ) ) ); - - if( memcmp( out, test_kdf_out, sizeof( out ) ) != 0 ) - ret = -1; - -cleanup: - ecp_drbg_free( &kdf_ctx ); - mbedtls_mpi_free( &scalar ); - - return( ret ); -} -#endif /* ECP_ONE_STEP_KDF */ - -/* - * Checkup routine - */ -int mbedtls_ecp_self_test( int verbose ) -{ - int ret; - size_t i; - mbedtls_ecp_group grp; - mbedtls_ecp_point R, P; - mbedtls_mpi m; - unsigned long add_c_prev, dbl_c_prev, mul_c_prev; - /* exponents especially adapted for secp192r1 */ - const char *exponents[] = - { - "000000000000000000000000000000000000000000000001", /* one */ - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */ - "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ - "400000000000000000000000000000000000000000000000", /* one and zeros */ - "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ - "555555555555555555555555555555555555555555555555", /* 101010... */ - }; - - mbedtls_ecp_group_init( &grp ); - mbedtls_ecp_point_init( &R ); - mbedtls_ecp_point_init( &P ); - mbedtls_mpi_init( &m ); - - /* Use secp192r1 if available, or any available curve */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) ); -#else - MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, mbedtls_ecp_curve_list()->grp_id ) ); -#endif - - if( verbose != 0 ) - mbedtls_printf( " ECP test #1 (constant op_count, base point G): " ); - - /* Do a dummy multiplication first to trigger precomputation */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) ); - - add_count = 0; - dbl_count = 0; - mul_count = 0; - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); - - for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) - { - add_c_prev = add_count; - dbl_c_prev = dbl_count; - mul_c_prev = mul_count; - add_count = 0; - dbl_count = 0; - mul_count = 0; - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); - - if( add_count != add_c_prev || - dbl_count != dbl_c_prev || - mul_count != mul_c_prev ) - { - if( verbose != 0 ) - mbedtls_printf( "failed (%u)\n", (unsigned int) i ); - - ret = 1; - goto cleanup; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " ECP test #2 (constant op_count, other point): " ); - /* We computed P = 2G last time, use it */ - - add_count = 0; - dbl_count = 0; - mul_count = 0; - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); - - for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) - { - add_c_prev = add_count; - dbl_c_prev = dbl_count; - mul_c_prev = mul_count; - add_count = 0; - dbl_count = 0; - mul_count = 0; - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); - - if( add_count != add_c_prev || - dbl_count != dbl_c_prev || - mul_count != mul_c_prev ) - { - if( verbose != 0 ) - mbedtls_printf( "failed (%u)\n", (unsigned int) i ); - - ret = 1; - goto cleanup; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -#if defined(ECP_ONE_STEP_KDF) - if( verbose != 0 ) - mbedtls_printf( " ECP test #3 (internal KDF): " ); - - ret = ecp_kdf_self_test(); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); -#endif /* ECP_ONE_STEP_KDF */ - -cleanup: - - if( ret < 0 && verbose != 0 ) - mbedtls_printf( "Unexpected error, return code = %08X\n", ret ); - - mbedtls_ecp_group_free( &grp ); - mbedtls_ecp_point_free( &R ); - mbedtls_ecp_point_free( &P ); - mbedtls_mpi_free( &m ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* !MBEDTLS_ECP_ALT */ - -#endif /* MBEDTLS_ECP_C */ diff --git a/mbedtls/ecp.h b/mbedtls/ecp.h deleted file mode 100644 index a5829523c..000000000 --- a/mbedtls/ecp.h +++ /dev/null @@ -1,1201 +0,0 @@ -#pragma GCC system_header -/** - * \file ecp.h - * - * \brief This file provides an API for Elliptic Curves over GF(P) (ECP). - * - * The use of ECP in cryptography and TLS is defined in - * Standards for Efficient Cryptography Group (SECG): SEC1 - * Elliptic Curve Cryptography and - * RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites - * for Transport Layer Security (TLS). - * - * RFC-2409: The Internet Key Exchange (IKE) defines ECP - * group types. - * - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_ECP_H -#define MBEDTLS_ECP_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "bignum.h" - -/* - * ECP error codes - */ -#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA -0x4F80 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 /**< The buffer is too small to write to. */ -#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 /**< The requested feature is not available, for example, the requested curve is not supported. */ -#define MBEDTLS_ERR_ECP_VERIFY_FAILED -0x4E00 /**< The signature is not valid. */ -#define MBEDTLS_ERR_ECP_ALLOC_FAILED -0x4D80 /**< Memory allocation failed. */ -#define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as ephemeral key, failed. */ -#define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */ -#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< The buffer contains a valid signature followed by more data. */ - -/* MBEDTLS_ERR_ECP_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED -0x4B80 /**< The ECP hardware accelerator failed. */ - -#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00 /**< Operation in progress, call again with the same parameters to continue. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Domain-parameter identifiers: curve, subgroup, and generator. - * - * \note Only curves over prime fields are supported. - * - * \warning This library does not support validation of arbitrary domain - * parameters. Therefore, only standardized domain parameters from trusted - * sources should be used. See mbedtls_ecp_group_load(). - */ -typedef enum -{ - MBEDTLS_ECP_DP_NONE = 0, /*!< Curve not defined. */ - MBEDTLS_ECP_DP_SECP192R1, /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP224R1, /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP384R1, /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP521R1, /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_BP256R1, /*!< Domain parameters for 256-bit Brainpool curve. */ - MBEDTLS_ECP_DP_BP384R1, /*!< Domain parameters for 384-bit Brainpool curve. */ - MBEDTLS_ECP_DP_BP512R1, /*!< Domain parameters for 512-bit Brainpool curve. */ - MBEDTLS_ECP_DP_CURVE25519, /*!< Domain parameters for Curve25519. */ - MBEDTLS_ECP_DP_SECP192K1, /*!< Domain parameters for 192-bit "Koblitz" curve. */ - MBEDTLS_ECP_DP_SECP224K1, /*!< Domain parameters for 224-bit "Koblitz" curve. */ - MBEDTLS_ECP_DP_SECP256K1, /*!< Domain parameters for 256-bit "Koblitz" curve. */ - MBEDTLS_ECP_DP_CURVE448, /*!< Domain parameters for Curve448. */ -} mbedtls_ecp_group_id; - -/** - * The number of supported curves, plus one for #MBEDTLS_ECP_DP_NONE. - * - * \note Montgomery curves are currently excluded. - */ -#define MBEDTLS_ECP_DP_MAX 12 - -/** - * Curve information, for use by other modules. - */ -typedef struct mbedtls_ecp_curve_info -{ - mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */ - uint16_t tls_id; /*!< The TLS NamedCurve identifier. */ - uint16_t bit_size; /*!< The curve size in bits. */ - const char *name; /*!< A human-friendly name. */ -} mbedtls_ecp_curve_info; - -/** - * \brief The ECP point structure, in Jacobian coordinates. - * - * \note All functions expect and return points satisfying - * the following condition: Z == 0 or - * Z == 1. Other values of \p Z are - * used only by internal functions. - * The point is zero, or "at infinity", if Z == 0. - * Otherwise, \p X and \p Y are its standard (affine) - * coordinates. - */ -typedef struct mbedtls_ecp_point -{ - mbedtls_mpi X; /*!< The X coordinate of the ECP point. */ - mbedtls_mpi Y; /*!< The Y coordinate of the ECP point. */ - mbedtls_mpi Z; /*!< The Z coordinate of the ECP point. */ -} -mbedtls_ecp_point; - -/* Determine the minimum safe value of MBEDTLS_ECP_MAX_BITS. */ -#if !defined(MBEDTLS_ECP_C) -#define MBEDTLS_ECP_MAX_BITS_MIN 0 -/* Note: the curves must be listed in DECREASING size! */ -#elif defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 521 -#elif defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 512 -#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 448 -#elif defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 384 -#elif defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 384 -#elif defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 256 -#elif defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 256 -#elif defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 256 -#elif defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 255 -#elif defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 225 // n is slightly above 2^224 -#elif defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 224 -#elif defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 192 -#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS_MIN 192 -#else -#error "MBEDTLS_ECP_C enabled, but no curve?" -#endif - -#if !defined(MBEDTLS_ECP_ALT) -/* - * default mbed TLS elliptic curve arithmetic implementation - * - * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an - * alternative implementation for the whole module and it will replace this - * one.) - */ - -/** - * \brief The ECP group structure. - * - * We consider two types of curve equations: - *
    • Short Weierstrass: y^2 = x^3 + A x + B mod P - * (SEC1 + RFC-4492)
    • - *
    • Montgomery: y^2 = x^3 + A x^2 + x mod P (Curve25519, - * Curve448)
    - * In both cases, the generator (\p G) for a prime-order subgroup is fixed. - * - * For Short Weierstrass, this subgroup is the whole curve, and its - * cardinality is denoted by \p N. Our code requires that \p N is an - * odd prime as mbedtls_ecp_mul() requires an odd number, and - * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes. - * - * For Montgomery curves, we do not store \p A, but (A + 2) / 4, - * which is the quantity used in the formulas. Additionally, \p nbits is - * not the size of \p N but the required size for private keys. - * - * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm. - * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the - * range of 0..2^(2*pbits)-1, and transforms it in-place to an integer - * which is congruent mod \p P to the given MPI, and is close enough to \p pbits - * in size, so that it may be efficiently brought in the 0..P-1 range by a few - * additions or subtractions. Therefore, it is only an approximative modular - * reduction. It must return 0 on success and non-zero on failure. - * - * \note Alternative implementations must keep the group IDs distinct. If - * two group structures have the same ID, then they must be - * identical. - * - */ -typedef struct mbedtls_ecp_group -{ - mbedtls_ecp_group_id id; /*!< An internal group identifier. */ - mbedtls_mpi P; /*!< The prime modulus of the base field. */ - mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. For - Montgomery curves: (A + 2) / 4. */ - mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation. - For Montgomery curves: unused. */ - mbedtls_ecp_point G; /*!< The generator of the subgroup used. */ - mbedtls_mpi N; /*!< The order of \p G. */ - size_t pbits; /*!< The number of bits in \p P.*/ - size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P. - For Montgomery curves: the number of bits in the - private keys. */ - unsigned int h; /*!< \internal 1 if the constants are static. */ - int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction - mod \p P (see above).*/ - int (*t_pre)(mbedtls_ecp_point *, void *); /*!< Unused. */ - int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */ - void *t_data; /*!< Unused. */ - mbedtls_ecp_point *T; /*!< Pre-computed points for ecp_mul_comb(). */ - size_t T_size; /*!< The number of pre-computed points. */ -} -mbedtls_ecp_group; - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h, or define them using the compiler command line. - * \{ - */ - -#if defined(MBEDTLS_ECP_MAX_BITS) - -#if MBEDTLS_ECP_MAX_BITS < MBEDTLS_ECP_MAX_BITS_MIN -#error "MBEDTLS_ECP_MAX_BITS is smaller than the largest supported curve" -#endif - -#else -/** - * The maximum size of the groups, that is, of \c N and \c P. - */ -#define MBEDTLS_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */ -#endif - -#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 ) -#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 ) - -#if !defined(MBEDTLS_ECP_WINDOW_SIZE) -/* - * Maximum "window" size used for point multiplication. - * Default: 6. - * Minimum value: 2. Maximum value: 7. - * - * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) - * points used for point multiplication. This value is directly tied to EC - * peak memory usage, so decreasing it by one should roughly cut memory usage - * by two (if large curves are in use). - * - * Reduction in size may reduce speed, but larger curves are impacted first. - * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): - * w-size: 6 5 4 3 2 - * 521 145 141 135 120 97 - * 384 214 209 198 177 146 - * 256 320 320 303 262 226 - * 224 475 475 453 398 342 - * 192 640 640 633 587 476 - */ -#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */ -#endif /* MBEDTLS_ECP_WINDOW_SIZE */ - -#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) -/* - * Trade memory for speed on fixed-point multiplication. - * - * This speeds up repeated multiplication of the generator (that is, the - * multiplication in ECDSA signatures, and half of the multiplications in - * ECDSA verification and ECDHE) by a factor roughly 3 to 4. - * - * The cost is increasing EC peak memory usage by a factor roughly 2. - * - * Change this value to 0 to reduce peak memory usage. - */ -#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ -#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ - -/* \} name SECTION: Module settings */ - -#else /* MBEDTLS_ECP_ALT */ -#include "ecp_alt.h" -#endif /* MBEDTLS_ECP_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Internal restart context for multiplication - * - * \note Opaque struct - */ -typedef struct mbedtls_ecp_restart_mul mbedtls_ecp_restart_mul_ctx; - -/** - * \brief Internal restart context for ecp_muladd() - * - * \note Opaque struct - */ -typedef struct mbedtls_ecp_restart_muladd mbedtls_ecp_restart_muladd_ctx; - -/** - * \brief General context for resuming ECC operations - */ -typedef struct -{ - unsigned ops_done; /*!< current ops count */ - unsigned depth; /*!< call depth (0 = top-level) */ - mbedtls_ecp_restart_mul_ctx *rsm; /*!< ecp_mul_comb() sub-context */ - mbedtls_ecp_restart_muladd_ctx *ma; /*!< ecp_muladd() sub-context */ -} mbedtls_ecp_restart_ctx; - -/* - * Operation counts for restartable functions - */ -#define MBEDTLS_ECP_OPS_CHK 3 /*!< basic ops count for ecp_check_pubkey() */ -#define MBEDTLS_ECP_OPS_DBL 8 /*!< basic ops count for ecp_double_jac() */ -#define MBEDTLS_ECP_OPS_ADD 11 /*!< basic ops count for see ecp_add_mixed() */ -#define MBEDTLS_ECP_OPS_INV 120 /*!< empirical equivalent for mpi_mod_inv() */ - -/** - * \brief Internal; for restartable functions in other modules. - * Check and update basic ops budget. - * - * \param grp Group structure - * \param rs_ctx Restart context - * \param ops Number of basic ops to do - * - * \return \c 0 if doing \p ops basic ops is still allowed, - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS otherwise. - */ -int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, - mbedtls_ecp_restart_ctx *rs_ctx, - unsigned ops ); - -/* Utility macro for checking and updating ops budget */ -#define MBEDTLS_ECP_BUDGET( ops ) \ - MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, rs_ctx, \ - (unsigned) (ops) ) ); - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define MBEDTLS_ECP_BUDGET( ops ) /* no-op; for compatibility */ - -/* We want to declare restartable versions of existing functions anyway */ -typedef void mbedtls_ecp_restart_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief The ECP key-pair structure. - * - * A generic key-pair that may be used for ECDSA and fixed ECDH, for example. - * - * \note Members are deliberately in the same order as in the - * ::mbedtls_ecdsa_context structure. - */ -typedef struct mbedtls_ecp_keypair -{ - mbedtls_ecp_group grp; /*!< Elliptic curve and base point */ - mbedtls_mpi d; /*!< our secret value */ - mbedtls_ecp_point Q; /*!< our public value */ -} -mbedtls_ecp_keypair; - -/* - * Point formats, from RFC 4492's enum ECPointFormat - */ -#define MBEDTLS_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format. */ -#define MBEDTLS_ECP_PF_COMPRESSED 1 /**< Compressed point format. */ - -/* - * Some other constants from RFC 4492 - */ -#define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< The named_curve of ECCurveType. */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Set the maximum number of basic operations done in a row. - * - * If more operations are needed to complete a computation, - * #MBEDTLS_ERR_ECP_IN_PROGRESS will be returned by the - * function performing the computation. It is then the - * caller's responsibility to either call again with the same - * parameters until it returns 0 or an error code; or to free - * the restart context if the operation is to be aborted. - * - * It is strictly required that all input parameters and the - * restart context be the same on successive calls for the - * same operation, but output parameters need not be the - * same; they must not be used until the function finally - * returns 0. - * - * This only applies to functions whose documentation - * mentions they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS for functions in the - * SSL module). For functions that accept a "restart context" - * argument, passing NULL disables restart and makes the - * function equivalent to the function with the same name - * with \c _restartable removed. For functions in the ECDH - * module, restart is disabled unless the function accepts - * an "ECDH context" argument and - * mbedtls_ecdh_enable_restart() was previously called on - * that context. For function in the SSL module, restart is - * only enabled for specific sides and key exchanges - * (currently only for clients and ECDHE-ECDSA). - * - * \param max_ops Maximum number of basic operations done in a row. - * Default: 0 (unlimited). - * Lower (non-zero) values mean ECC functions will block for - * a lesser maximum amount of time. - * - * \note A "basic operation" is defined as a rough equivalent of a - * multiplication in GF(p) for the NIST P-256 curve. - * As an indication, with default settings, a scalar - * multiplication (full run of \c mbedtls_ecp_mul()) is: - * - about 3300 basic operations for P-256 - * - about 9400 basic operations for P-384 - * - * \note Very low values are not always respected: sometimes - * functions need to block for a minimum number of - * operations, and will do so even if max_ops is set to a - * lower value. That minimum depends on the curve size, and - * can be made lower by decreasing the value of - * \c MBEDTLS_ECP_WINDOW_SIZE. As an indication, here is the - * lowest effective value for various curves and values of - * that parameter (w for short): - * w=6 w=5 w=4 w=3 w=2 - * P-256 208 208 160 136 124 - * P-384 682 416 320 272 248 - * P-521 1364 832 640 544 496 - * - * \note This setting is currently ignored by Curve25519. - */ -void mbedtls_ecp_set_max_ops( unsigned max_ops ); - -/** - * \brief Check if restart is enabled (max_ops != 0) - * - * \return \c 0 if \c max_ops == 0 (restart disabled) - * \return \c 1 otherwise (restart enabled) - */ -int mbedtls_ecp_restart_is_enabled( void ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief This function retrieves the information defined in - * mbedtls_ecp_curve_info() for all supported curves in order - * of preference. - * - * \return A statically allocated array. The last entry is 0. - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ); - -/** - * \brief This function retrieves the list of internal group - * identifiers of all supported curves in the order of - * preference. - * - * \return A statically allocated array, - * terminated with MBEDTLS_ECP_DP_NONE. - */ -const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void ); - -/** - * \brief This function retrieves curve information from an internal - * group identifier. - * - * \param grp_id An \c MBEDTLS_ECP_DP_XXX value. - * - * \return The associated curve information on success. - * \return NULL on failure. - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id ); - -/** - * \brief This function retrieves curve information from a TLS - * NamedCurve value. - * - * \param tls_id An \c MBEDTLS_ECP_DP_XXX value. - * - * \return The associated curve information on success. - * \return NULL on failure. - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id ); - -/** - * \brief This function retrieves curve information from a - * human-readable name. - * - * \param name The human-readable name. - * - * \return The associated curve information on success. - * \return NULL on failure. - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name ); - -/** - * \brief This function initializes a point as zero. - * - * \param pt The point to initialize. - */ -void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ); - -/** - * \brief This function initializes an ECP group context - * without loading any domain parameters. - * - * \note After this function is called, domain parameters - * for various ECP groups can be loaded through the - * mbedtls_ecp_group_load() or mbedtls_ecp_tls_read_group() - * functions. - */ -void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ); - -/** - * \brief This function initializes a key pair as an invalid one. - * - * \param key The key pair to initialize. - */ -void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ); - -/** - * \brief This function frees the components of a point. - * - * \param pt The point to free. - */ -void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ); - -/** - * \brief This function frees the components of an ECP group. - * - * \param grp The group to free. This may be \c NULL, in which - * case this function returns immediately. If it is not - * \c NULL, it must point to an initialized ECP group. - */ -void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ); - -/** - * \brief This function frees the components of a key pair. - * - * \param key The key pair to free. This may be \c NULL, in which - * case this function returns immediately. If it is not - * \c NULL, it must point to an initialized ECP key pair. - */ -void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ); - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context. - * - * \param ctx The restart context to initialize. This must - * not be \c NULL. - */ -void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ); - -/** - * \brief Free the components of a restart context. - * - * \param ctx The restart context to free. This may be \c NULL, in which - * case this function returns immediately. If it is not - * \c NULL, it must point to an initialized restart context. - */ -void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief This function copies the contents of point \p Q into - * point \p P. - * - * \param P The destination point. This must be initialized. - * \param Q The source point. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code for other kinds of failure. - */ -int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); - -/** - * \brief This function copies the contents of group \p src into - * group \p dst. - * - * \param dst The destination group. This must be initialized. - * \param src The source group. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, - const mbedtls_ecp_group *src ); - -/** - * \brief This function sets a point to the point at infinity. - * - * \param pt The point to set. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ); - -/** - * \brief This function checks if a point is the point at infinity. - * - * \param pt The point to test. This must be initialized. - * - * \return \c 1 if the point is zero. - * \return \c 0 if the point is non-zero. - * \return A negative error code on failure. - */ -int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ); - -/** - * \brief This function compares two points. - * - * \note This assumes that the points are normalized. Otherwise, - * they may compare as "not equal" even if they are. - * - * \param P The first point to compare. This must be initialized. - * \param Q The second point to compare. This must be initialized. - * - * \return \c 0 if the points are equal. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal. - */ -int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, - const mbedtls_ecp_point *Q ); - -/** - * \brief This function imports a non-zero point from two ASCII - * strings. - * - * \param P The destination point. This must be initialized. - * \param radix The numeric base of the input. - * \param x The first affine coordinate, as a null-terminated string. - * \param y The second affine coordinate, as a null-terminated string. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_MPI_XXX error code on failure. - */ -int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, - const char *x, const char *y ); - -/** - * \brief This function exports a point into unsigned binary data. - * - * \param grp The group to which the point should belong. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param P The point to export. This must be initialized. - * \param format The point format. This must be either - * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. - * \param olen The address at which to store the length of - * the output in Bytes. This must not be \c NULL. - * \param buf The output buffer. This must be a writable buffer - * of length \p buflen Bytes. - * \param buflen The length of the output buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer - * is too small to hold the point. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P, - int format, size_t *olen, - unsigned char *buf, size_t buflen ); - -/** - * \brief This function imports a point from unsigned binary data. - * - * \note This function does not check that the point actually - * belongs to the given group, see mbedtls_ecp_check_pubkey() - * for that. - * - * \param grp The group to which the point should belong. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param P The destination context to import the point to. - * This must be initialized. - * \param buf The input buffer. This must be a readable buffer - * of length \p ilen Bytes. - * \param ilen The length of the input buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format - * is not implemented. - */ -int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *P, - const unsigned char *buf, size_t ilen ); - -/** - * \brief This function imports a point from a TLS ECPoint record. - * - * \note On function return, \p *buf is updated to point immediately - * after the ECPoint record. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param pt The destination point. - * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the buffer. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization - * failure. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. - */ -int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char **buf, size_t len ); - -/** - * \brief This function exports a point as a TLS ECPoint record - * defined in RFC 4492, Section 5.4. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param pt The point to be exported. This must be initialized. - * \param format The point format to use. This must be either - * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. - * \param olen The address at which to store the length in Bytes - * of the data written. - * \param buf The target buffer. This must be a writable buffer of - * length \p blen Bytes. - * \param blen The length of the target buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer - * is too small to hold the exported point. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt, - int format, size_t *olen, - unsigned char *buf, size_t blen ); - -/** - * \brief This function sets up an ECP group context - * from a standardized set of domain parameters. - * - * \note The index should be a value of the NamedCurve enum, - * as defined in RFC-4492: Elliptic Curve Cryptography - * (ECC) Cipher Suites for Transport Layer Security (TLS), - * usually in the form of an \c MBEDTLS_ECP_DP_XXX macro. - * - * \param grp The group context to setup. This must be initialized. - * \param id The identifier of the domain parameter set to load. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't - * correspond to a known group. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ); - -/** - * \brief This function sets up an ECP group context from a TLS - * ECParameters record as defined in RFC 4492, Section 5.4. - * - * \note The read pointer \p buf is updated to point right after - * the ECParameters record on exit. - * - * \param grp The group context to setup. This must be initialized. - * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the input buffer \c *buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not - * recognized. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, - const unsigned char **buf, size_t len ); - -/** - * \brief This function extracts an elliptic curve group ID from a - * TLS ECParameters record as defined in RFC 4492, Section 5.4. - * - * \note The read pointer \p buf is updated to point right after - * the ECParameters record on exit. - * - * \param grp The address at which to store the group id. - * This must not be \c NULL. - * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the input buffer \c *buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not - * recognized. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, - const unsigned char **buf, - size_t len ); -/** - * \brief This function exports an elliptic curve as a TLS - * ECParameters record as defined in RFC 4492, Section 5.4. - * - * \param grp The ECP group to be exported. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param olen The address at which to store the number of Bytes written. - * This must not be \c NULL. - * \param buf The buffer to write to. This must be a writable buffer - * of length \p blen Bytes. - * \param blen The length of the output buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output - * buffer is too small to hold the exported group. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, - size_t *olen, - unsigned char *buf, size_t blen ); - -/** - * \brief This function performs a scalar multiplication of a point - * by an integer: \p R = \p m * \p P. - * - * It is not thread-safe to use same group in multiple threads. - * - * \note To prevent timing attacks, this function - * executes the exact same sequence of base-field - * operations for any valid \p m. It avoids any if-branch or - * array index depending on the value of \p m. - * - * \note If \p f_rng is not NULL, it is used to randomize - * intermediate results to prevent potential timing attacks - * targeting these results. We recommend always providing - * a non-NULL \p f_rng. The overhead is negligible. - * Note: unless #MBEDTLS_ECP_NO_INTERNAL_RNG is defined, when - * \p f_rng is NULL, an internal RNG (seeded from the value - * of \p m) will be used instead. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply. This must be initialized. - * \param P The point to multiply. This must be initialized. - * \param f_rng The RNG function. This may be \c NULL if randomization - * of intermediate results isn't desired (discouraged). - * \param p_rng The RNG context to be passed to \p p_rng. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private - * key, or \p P is not a valid public key. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - -/** - * \brief This function performs multiplication of a point by - * an integer: \p R = \p m * \p P in a restartable way. - * - * \see mbedtls_ecp_mul() - * - * \note This function does the same as \c mbedtls_ecp_mul(), but - * it can return early and restart according to the limit set - * with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply. This must be initialized. - * \param P The point to multiply. This must be initialized. - * \param f_rng The RNG function. This may be \c NULL if randomization - * of intermediate results isn't desired (discouraged). - * \param p_rng The RNG context to be passed to \p p_rng. - * \param rs_ctx The restart context (NULL disables restart). - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private - * key, or \p P is not a valid public key. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx ); - -/** - * \brief This function performs multiplication and addition of two - * points by integers: \p R = \p m * \p P + \p n * \p Q - * - * It is not thread-safe to use same group in multiple threads. - * - * \note In contrast to mbedtls_ecp_mul(), this function does not - * guarantee a constant execution flow and timing. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply \p P. - * This must be initialized. - * \param P The point to multiply by \p m. This must be initialized. - * \param n The integer by which to multiply \p Q. - * This must be initialized. - * \param Q The point to be multiplied by \p n. - * This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not - * valid private keys, or \p P or \p Q are not valid public - * keys. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q ); - -/** - * \brief This function performs multiplication and addition of two - * points by integers: \p R = \p m * \p P + \p n * \p Q in a - * restartable way. - * - * \see \c mbedtls_ecp_muladd() - * - * \note This function works the same as \c mbedtls_ecp_muladd(), - * but it can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply \p P. - * This must be initialized. - * \param P The point to multiply by \p m. This must be initialized. - * \param n The integer by which to multiply \p Q. - * This must be initialized. - * \param Q The point to be multiplied by \p n. - * This must be initialized. - * \param rs_ctx The restart context (NULL disables restart). - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not - * valid private keys, or \p P or \p Q are not valid public - * keys. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_muladd_restartable( - mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q, - mbedtls_ecp_restart_ctx *rs_ctx ); - -/** - * \brief This function checks that a point is a valid public key - * on this curve. - * - * It only checks that the point is non-zero, has - * valid coordinates and lies on the curve. It does not verify - * that it is indeed a multiple of \p G. This additional - * check is computationally more expensive, is not required - * by standards, and should not be necessary if the group - * used has a small cofactor. In particular, it is useless for - * the NIST groups which all have a cofactor of 1. - * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure, to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. - * - * \param grp The ECP group the point should belong to. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param pt The point to check. This must be initialized. - * - * \return \c 0 if the point is a valid public key. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not - * a valid public key for the given curve. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt ); - -/** - * \brief This function checks that an \p mbedtls_mpi is a - * valid private key for this curve. - * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. - * - * \param grp The ECP group the private key should belong to. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param d The integer to check. This must be initialized. - * - * \return \c 0 if the point is a valid private key. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid - * private key for the given curve. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, - const mbedtls_mpi *d ); - -/** - * \brief This function generates a private key. - * - * \param grp The ECP group to generate a private key for. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param d The destination MPI (secret part). This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, - mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function generates a keypair with a configurable base - * point. - * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. - * - * \param grp The ECP group to generate a key pair for. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param G The base point to use. This must be initialized - * and belong to \p grp. It replaces the default base - * point \c grp->G used by mbedtls_ecp_gen_keypair(). - * \param d The destination MPI (secret part). - * This must be initialized. - * \param Q The destination point (public part). - * This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, - const mbedtls_ecp_point *G, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function generates an ECP keypair. - * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. - * - * \param grp The ECP group to generate a key pair for. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param d The destination MPI (secret part). - * This must be initialized. - * \param Q The destination point (public part). - * This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, - mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function generates an ECP key. - * - * \param grp_id The ECP group identifier. - * \param key The destination key. This must be initialized. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief This function checks that the keypair objects - * \p pub and \p prv have the same group and the - * same public point, and that the private key in - * \p prv is consistent with the public key. - * - * \param pub The keypair structure holding the public key. This - * must be initialized. If it contains a private key, that - * part is ignored. - * \param prv The keypair structure holding the full keypair. - * This must be initialized. - * - * \return \c 0 on success, meaning that the keys are valid and match. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match. - * \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX - * error code on calculation failure. - */ -int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, - const mbedtls_ecp_keypair *prv ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The ECP checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_ecp_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* ecp.h */ diff --git a/mbedtls/ecp_curves.c b/mbedtls/ecp_curves.c deleted file mode 100644 index 00e6bbc93..000000000 --- a/mbedtls/ecp_curves.c +++ /dev/null @@ -1,1497 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Elliptic curves over GF(p): curve-specific data and functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ECP_C) - -#include "mbedtls/ecp.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/bn_mul.h" - -#include - -#if !defined(MBEDTLS_ECP_ALT) - -/* Parameter validation macros based on platform_util.h */ -#define ECP_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECP_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)} - -#define ECP_MPI_INIT_ARRAY(x) \ - ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x) - -/* - * Note: the constants are in little-endian order - * to be directly usable in MPIs - */ - -/* - * Domain parameters for secp192r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static const mbedtls_mpi_uint secp192r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp192r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ), -}; -static const mbedtls_mpi_uint secp192r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ), -}; -static const mbedtls_mpi_uint secp192r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ), -}; -static const mbedtls_mpi_uint secp192r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -/* - * Domain parameters for secp224r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static const mbedtls_mpi_uint secp224r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), -}; -static const mbedtls_mpi_uint secp224r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ), - MBEDTLS_BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ), -}; -static const mbedtls_mpi_uint secp224r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ), - MBEDTLS_BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ), -}; -static const mbedtls_mpi_uint secp224r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ), - MBEDTLS_BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ), -}; -static const mbedtls_mpi_uint secp224r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -/* - * Domain parameters for secp256r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static const mbedtls_mpi_uint secp256r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp256r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ), -}; -static const mbedtls_mpi_uint secp256r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ), -}; -static const mbedtls_mpi_uint secp256r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ), -}; -static const mbedtls_mpi_uint secp256r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -/* - * Domain parameters for secp384r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static const mbedtls_mpi_uint secp384r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp384r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ), -}; -static const mbedtls_mpi_uint secp384r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ), -}; -static const mbedtls_mpi_uint secp384r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ), -}; -static const mbedtls_mpi_uint secp384r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* - * Domain parameters for secp521r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static const mbedtls_mpi_uint secp521r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 0x01 ), -}; -static const mbedtls_mpi_uint secp521r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ), - MBEDTLS_BYTES_TO_T_UINT_2( 0x51, 0x00 ), -}; -static const mbedtls_mpi_uint secp521r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ), - MBEDTLS_BYTES_TO_T_UINT_2( 0xC6, 0x00 ), -}; -static const mbedtls_mpi_uint secp521r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ), - MBEDTLS_BYTES_TO_T_UINT_2( 0x18, 0x01 ), -}; -static const mbedtls_mpi_uint secp521r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 0x01 ), -}; -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static const mbedtls_mpi_uint secp192k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp192k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ), -}; -static const mbedtls_mpi_uint secp192k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2( 0x03, 0x00 ), -}; -static const mbedtls_mpi_uint secp192k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ), -}; -static const mbedtls_mpi_uint secp192k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ), -}; -static const mbedtls_mpi_uint secp192k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static const mbedtls_mpi_uint secp224k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp224k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ), -}; -static const mbedtls_mpi_uint secp224k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2( 0x05, 0x00 ), -}; -static const mbedtls_mpi_uint secp224k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ), - MBEDTLS_BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ), -}; -static const mbedtls_mpi_uint secp224k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ), - MBEDTLS_BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ), -}; -static const mbedtls_mpi_uint secp224k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ), -}; -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static const mbedtls_mpi_uint secp256k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -static const mbedtls_mpi_uint secp256k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ), -}; -static const mbedtls_mpi_uint secp256k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2( 0x07, 0x00 ), -}; -static const mbedtls_mpi_uint secp256k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ), -}; -static const mbedtls_mpi_uint secp256k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ), -}; -static const mbedtls_mpi_uint secp256k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), -}; -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -/* - * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) - */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP256r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ), -}; -static const mbedtls_mpi_uint brainpoolP256r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), -}; -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -/* - * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) - */ -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP384r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ), -}; -static const mbedtls_mpi_uint brainpoolP384r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), -}; -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -/* - * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) - */ -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP512r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ), -}; -static const mbedtls_mpi_uint brainpoolP512r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), - MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), -}; -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - -/* - * Create an MPI from embedded constants - * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint) - */ -static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len ) -{ - X->s = 1; - X->n = len / sizeof( mbedtls_mpi_uint ); - X->p = (mbedtls_mpi_uint *) p; -} - -/* - * Set an MPI to static value 1 - */ -static inline void ecp_mpi_set1( mbedtls_mpi *X ) -{ - static mbedtls_mpi_uint one[] = { 1 }; - X->s = 1; - X->n = 1; - X->p = one; -} - -/* - * Make group available from embedded constants - */ -static int ecp_group_load( mbedtls_ecp_group *grp, - const mbedtls_mpi_uint *p, size_t plen, - const mbedtls_mpi_uint *a, size_t alen, - const mbedtls_mpi_uint *b, size_t blen, - const mbedtls_mpi_uint *gx, size_t gxlen, - const mbedtls_mpi_uint *gy, size_t gylen, - const mbedtls_mpi_uint *n, size_t nlen) -{ - ecp_mpi_load( &grp->P, p, plen ); - if( a != NULL ) - ecp_mpi_load( &grp->A, a, alen ); - ecp_mpi_load( &grp->B, b, blen ); - ecp_mpi_load( &grp->N, n, nlen ); - - ecp_mpi_load( &grp->G.X, gx, gxlen ); - ecp_mpi_load( &grp->G.Y, gy, gylen ); - ecp_mpi_set1( &grp->G.Z ); - - grp->pbits = mbedtls_mpi_bitlen( &grp->P ); - grp->nbits = mbedtls_mpi_bitlen( &grp->N ); - - grp->h = 1; - - return( 0 ); -} - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* Forward declarations */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static int ecp_mod_p192( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static int ecp_mod_p224( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static int ecp_mod_p256( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static int ecp_mod_p384( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static int ecp_mod_p521( mbedtls_mpi * ); -#endif - -#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P; -#else -#define NIST_MODP( P ) -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -/* Additional forward declarations */ -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -static int ecp_mod_p255( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -static int ecp_mod_p448( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static int ecp_mod_p192k1( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static int ecp_mod_p224k1( mbedtls_mpi * ); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static int ecp_mod_p256k1( mbedtls_mpi * ); -#endif - -#define LOAD_GROUP_A( G ) ecp_group_load( grp, \ - G ## _p, sizeof( G ## _p ), \ - G ## _a, sizeof( G ## _a ), \ - G ## _b, sizeof( G ## _b ), \ - G ## _gx, sizeof( G ## _gx ), \ - G ## _gy, sizeof( G ## _gy ), \ - G ## _n, sizeof( G ## _n ) ) - -#define LOAD_GROUP( G ) ecp_group_load( grp, \ - G ## _p, sizeof( G ## _p ), \ - NULL, 0, \ - G ## _b, sizeof( G ## _b ), \ - G ## _gx, sizeof( G ## _gx ), \ - G ## _gy, sizeof( G ## _gy ), \ - G ## _n, sizeof( G ## _n ) ) - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -/* Constants used by ecp_use_curve25519() */ -static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42; -static const unsigned char curve25519_part_of_n[] = { - 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, - 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED, -}; - -/* - * Specialized function for creating the Curve25519 group - */ -static int ecp_use_curve25519( mbedtls_ecp_group *grp ) -{ - int ret; - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve25519_a24 ) ); - - /* P = 2^255 - 19 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) ); - grp->pbits = mbedtls_mpi_bitlen( &grp->P ); - - /* N = 2^252 + 27742317777372353535851937790883648493 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->N, - curve25519_part_of_n, sizeof( curve25519_part_of_n ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) ); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) ); - mbedtls_mpi_free( &grp->G.Y ); - - /* Actually, the required msb for private keys */ - grp->nbits = 254; - -cleanup: - if( ret != 0 ) - mbedtls_ecp_group_free( grp ); - - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -/* Constants used by ecp_use_curve448() */ -static const mbedtls_mpi_sint curve448_a24 = 0x98AA; -static const unsigned char curve448_part_of_n[] = { - 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24, - 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93, - 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC, - 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D, -}; - -/* - * Specialized function for creating the Curve448 group - */ -static int ecp_use_curve448( mbedtls_ecp_group *grp ) -{ - mbedtls_mpi Ns; - int ret; - - mbedtls_mpi_init( &Ns ); - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve448_a24 ) ); - - /* P = 2^448 - 2^224 - 1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) ); - grp->pbits = mbedtls_mpi_bitlen( &grp->P ); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) ); - mbedtls_mpi_free( &grp->G.Y ); - - /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns, - curve448_part_of_n, sizeof( curve448_part_of_n ) ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) ); - - /* Actually, the required msb for private keys */ - grp->nbits = 447; - -cleanup: - mbedtls_mpi_free( &Ns ); - if( ret != 0 ) - mbedtls_ecp_group_free( grp ); - - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -/* - * Set a group using well-known domain parameters - */ -int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ) -{ - ECP_VALIDATE_RET( grp != NULL ); - mbedtls_ecp_group_free( grp ); - - grp->id = id; - - switch( id ) - { -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - case MBEDTLS_ECP_DP_SECP192R1: - NIST_MODP( p192 ); - return( LOAD_GROUP( secp192r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - case MBEDTLS_ECP_DP_SECP224R1: - NIST_MODP( p224 ); - return( LOAD_GROUP( secp224r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - case MBEDTLS_ECP_DP_SECP256R1: - NIST_MODP( p256 ); - return( LOAD_GROUP( secp256r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - case MBEDTLS_ECP_DP_SECP384R1: - NIST_MODP( p384 ); - return( LOAD_GROUP( secp384r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - case MBEDTLS_ECP_DP_SECP521R1: - NIST_MODP( p521 ); - return( LOAD_GROUP( secp521r1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - case MBEDTLS_ECP_DP_SECP192K1: - grp->modp = ecp_mod_p192k1; - return( LOAD_GROUP_A( secp192k1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - case MBEDTLS_ECP_DP_SECP224K1: - grp->modp = ecp_mod_p224k1; - return( LOAD_GROUP_A( secp224k1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - case MBEDTLS_ECP_DP_SECP256K1: - grp->modp = ecp_mod_p256k1; - return( LOAD_GROUP_A( secp256k1 ) ); -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - case MBEDTLS_ECP_DP_BP256R1: - return( LOAD_GROUP_A( brainpoolP256r1 ) ); -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - case MBEDTLS_ECP_DP_BP384R1: - return( LOAD_GROUP_A( brainpoolP384r1 ) ); -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - case MBEDTLS_ECP_DP_BP512R1: - return( LOAD_GROUP_A( brainpoolP512r1 ) ); -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - case MBEDTLS_ECP_DP_CURVE25519: - grp->modp = ecp_mod_p255; - return( ecp_use_curve25519( grp ) ); -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - case MBEDTLS_ECP_DP_CURVE448: - grp->modp = ecp_mod_p448; - return( ecp_use_curve448( grp ) ); -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - - default: - mbedtls_ecp_group_free( grp ); - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - } -} - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* - * Fast reduction modulo the primes used by the NIST curves. - * - * These functions are critical for speed, but not needed for correct - * operations. So, we make the choice to heavily rely on the internals of our - * bignum library, which creates a tight coupling between these functions and - * our MPI implementation. However, the coupling between the ECP module and - * MPI remains loose, since these functions can be deactivated at will. - */ - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -/* - * Compared to the way things are presented in FIPS 186-3 D.2, - * we proceed in columns, from right (least significant chunk) to left, - * adding chunks to N in place, and keeping a carry for the next chunk. - * This avoids moving things around in memory, and uselessly adding zeros, - * compared to the more straightforward, line-oriented approach. - * - * For this prime we need to handle data in chunks of 64 bits. - * Since this is always a multiple of our basic mbedtls_mpi_uint, we can - * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it. - */ - -/* Add 64-bit chunks (dst += src) and update carry */ -static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry ) -{ - unsigned char i; - mbedtls_mpi_uint c = 0; - for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ ) - { - *dst += c; c = ( *dst < c ); - *dst += *src; c += ( *dst < *src ); - } - *carry += c; -} - -/* Add carry to a 64-bit chunk and update carry */ -static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry ) -{ - unsigned char i; - for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ ) - { - *dst += *carry; - *carry = ( *dst < *carry ); - } -} - -#define WIDTH 8 / sizeof( mbedtls_mpi_uint ) -#define A( i ) N->p + (i) * WIDTH -#define ADD( i ) add64( p, A( i ), &c ) -#define NEXT p += WIDTH; carry64( p, &c ) -#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 - -/* - * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) - */ -static int ecp_mod_p192( mbedtls_mpi *N ) -{ - int ret; - mbedtls_mpi_uint c = 0; - mbedtls_mpi_uint *p, *end; - - /* Make sure we have enough blocks so that A(5) is legal */ - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) ); - - p = N->p; - end = p + N->n; - - ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 - ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 - ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 - -cleanup: - return( ret ); -} - -#undef WIDTH -#undef A -#undef ADD -#undef NEXT -#undef LAST -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -/* - * The reader is advised to first understand ecp_mod_p192() since the same - * general structure is used here, but with additional complications: - * (1) chunks of 32 bits, and (2) subtractions. - */ - -/* - * For these primes, we need to handle data in chunks of 32 bits. - * This makes it more complicated if we use 64 bits limbs in MPI, - * which prevents us from using a uniform access method as for p192. - * - * So, we define a mini abstraction layer to access 32 bit chunks, - * load them in 'cur' for work, and store them back from 'cur' when done. - * - * While at it, also define the size of N in terms of 32-bit chunks. - */ -#define LOAD32 cur = A( i ); - -#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ - -#define MAX32 N->n -#define A( j ) N->p[j] -#define STORE32 N->p[i] = cur; - -#else /* 64-bit */ - -#define MAX32 N->n * 2 -#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \ - (uint32_t)( N->p[(j)/2] ) -#define STORE32 \ - if( i % 2 ) { \ - N->p[i/2] &= 0x00000000FFFFFFFF; \ - N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \ - } else { \ - N->p[i/2] &= 0xFFFFFFFF00000000; \ - N->p[i/2] |= (mbedtls_mpi_uint) cur; \ - } - -#endif /* sizeof( mbedtls_mpi_uint ) */ - -/* - * Helpers for addition and subtraction of chunks, with signed carry. - */ -static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) -{ - *dst += src; - *carry += ( *dst < src ); -} - -static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) -{ - *carry -= ( *dst < src ); - *dst -= src; -} - -#define ADD( j ) add32( &cur, A( j ), &c ); -#define SUB( j ) sub32( &cur, A( j ), &c ); - -/* - * Helpers for the main 'loop' - * (see fix_negative for the motivation of C) - */ -#define INIT( b ) \ - int ret; \ - signed char c = 0, cc; \ - uint32_t cur; \ - size_t i = 0, bits = (b); \ - mbedtls_mpi C; \ - mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \ - \ - C.s = 1; \ - C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \ - C.p = Cp; \ - memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \ - \ - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \ - sizeof( mbedtls_mpi_uint ) ) ); \ - LOAD32; - -#define NEXT \ - STORE32; i++; LOAD32; \ - cc = c; c = 0; \ - if( cc < 0 ) \ - sub32( &cur, -cc, &c ); \ - else \ - add32( &cur, cc, &c ); \ - -#define LAST \ - STORE32; i++; \ - cur = c > 0 ? c : 0; STORE32; \ - cur = 0; while( ++i < MAX32 ) { STORE32; } \ - if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) ); - -/* - * If the result is negative, we get it in the form - * c * 2^bits + N, with c negative and N positive shorter than 'bits' - */ -static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits ) -{ - int ret; - - /* C = - c * 2^bits */ -#if !defined(MBEDTLS_HAVE_INT64) - ((void) bits); -#else - if( bits == 224 ) - C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32; - else -#endif - C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c; - - /* N = - ( C - N ) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) ); - N->s = -1; - -cleanup: - - return( ret ); -} - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -/* - * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) - */ -static int ecp_mod_p224( mbedtls_mpi *N ) -{ - INIT( 224 ); - - SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 - SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 - SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 - SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 - SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 - SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 - SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -/* - * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) - */ -static int ecp_mod_p256( mbedtls_mpi *N ) -{ - INIT( 256 ); - - ADD( 8 ); ADD( 9 ); - SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 - - ADD( 9 ); ADD( 10 ); - SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 - - ADD( 10 ); ADD( 11 ); - SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 - - ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); - SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 - - ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); - SUB( 9 ); SUB( 10 ); NEXT; // A4 - - ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); - SUB( 10 ); SUB( 11 ); NEXT; // A5 - - ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); - SUB( 8 ); SUB( 9 ); NEXT; // A6 - - ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); - SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -/* - * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) - */ -static int ecp_mod_p384( mbedtls_mpi *N ) -{ - INIT( 384 ); - - ADD( 12 ); ADD( 21 ); ADD( 20 ); - SUB( 23 ); NEXT; // A0 - - ADD( 13 ); ADD( 22 ); ADD( 23 ); - SUB( 12 ); SUB( 20 ); NEXT; // A2 - - ADD( 14 ); ADD( 23 ); - SUB( 13 ); SUB( 21 ); NEXT; // A2 - - ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); - SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 - - ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); - SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 - - ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); - SUB( 16 ); NEXT; // A5 - - ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); - SUB( 17 ); NEXT; // A6 - - ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); - SUB( 18 ); NEXT; // A7 - - ADD( 20 ); ADD( 17 ); ADD( 16 ); - SUB( 19 ); NEXT; // A8 - - ADD( 21 ); ADD( 18 ); ADD( 17 ); - SUB( 20 ); NEXT; // A9 - - ADD( 22 ); ADD( 19 ); ADD( 18 ); - SUB( 21 ); NEXT; // A10 - - ADD( 23 ); ADD( 20 ); ADD( 19 ); - SUB( 22 ); LAST; // A11 - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#undef A -#undef LOAD32 -#undef STORE32 -#undef MAX32 -#undef INIT -#undef NEXT -#undef LAST - -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || - MBEDTLS_ECP_DP_SECP256R1_ENABLED || - MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -/* - * Here we have an actual Mersenne prime, so things are more straightforward. - * However, chunks are aligned on a 'weird' boundary (521 bits). - */ - -/* Size of p521 in terms of mbedtls_mpi_uint */ -#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) - -/* Bits to keep in the most significant mbedtls_mpi_uint */ -#define P521_MASK 0x01FF - -/* - * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) - * Write N as A1 + 2^521 A0, return A0 + A1 - */ -static int ecp_mod_p521( mbedtls_mpi *N ) -{ - int ret; - size_t i; - mbedtls_mpi M; - mbedtls_mpi_uint Mp[P521_WIDTH + 1]; - /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits: - * we need to hold bits 513 to 1056, which is 34 limbs, that is - * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ - - if( N->n < P521_WIDTH ) - return( 0 ); - - /* M = A1 */ - M.s = 1; - M.n = N->n - ( P521_WIDTH - 1 ); - if( M.n > P521_WIDTH + 1 ) - M.n = P521_WIDTH + 1; - M.p = Mp; - memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); - - /* N = A0 */ - N->p[P521_WIDTH - 1] &= P521_MASK; - for( i = P521_WIDTH; i < N->n; i++ ) - N->p[i] = 0; - - /* N = A0 + A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); - -cleanup: - return( ret ); -} - -#undef P521_WIDTH -#undef P521_MASK -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - -/* Size of p255 in terms of mbedtls_mpi_uint */ -#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) - -/* - * Fast quasi-reduction modulo p255 = 2^255 - 19 - * Write N as A0 + 2^255 A1, return A0 + 19 * A1 - */ -static int ecp_mod_p255( mbedtls_mpi *N ) -{ - int ret; - size_t i; - mbedtls_mpi M; - mbedtls_mpi_uint Mp[P255_WIDTH + 2]; - - if( N->n < P255_WIDTH ) - return( 0 ); - - /* M = A1 */ - M.s = 1; - M.n = N->n - ( P255_WIDTH - 1 ); - if( M.n > P255_WIDTH + 1 ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - M.p = Mp; - memset( Mp, 0, sizeof Mp ); - memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); - M.n++; /* Make room for multiplication by 19 */ - - /* N = A0 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) ); - for( i = P255_WIDTH; i < N->n; i++ ) - N->p[i] = 0; - - /* N = A0 + 19 * A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - -/* Size of p448 in terms of mbedtls_mpi_uint */ -#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) ) - -/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */ -#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) ) -#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) ) -#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) ) -#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 ) - -/* - * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1 - * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return - * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference - * implementation of Curve448, which uses its own special 56-bit limbs rather - * than a generic bignum library. We could squeeze some extra speed out on - * 32-bit machines by splitting N up into 32-bit limbs and doing the - * arithmetic using the limbs directly as we do for the NIST primes above, - * but for 64-bit targets it should use half the number of operations if we do - * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds. - */ -static int ecp_mod_p448( mbedtls_mpi *N ) -{ - int ret; - size_t i; - mbedtls_mpi M, Q; - mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH]; - - if( N->n <= P448_WIDTH ) - return( 0 ); - - /* M = A1 */ - M.s = 1; - M.n = N->n - ( P448_WIDTH ); - if( M.n > P448_WIDTH ) - /* Shouldn't be called with N larger than 2^896! */ - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - M.p = Mp; - memset( Mp, 0, sizeof( Mp ) ); - memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) ); - - /* N = A0 */ - for( i = P448_WIDTH; i < N->n; i++ ) - N->p[i] = 0; - - /* N += A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) ); - - /* Q = B1, N += B1 */ - Q = M; - Q.p = Qp; - memcpy( Qp, Mp, sizeof( Qp ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) ); - - /* M = (B0 + B1) * 2^224, N += M */ - if( sizeof( mbedtls_mpi_uint ) > 4 ) - Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS ); - for( i = P224_WIDTH_MAX; i < M.n; ++i ) - Mp[i] = 0; - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) ); - M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */ - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) ); - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -/* - * Fast quasi-reduction modulo P = 2^s - R, - * with R about 33 bits, used by the Koblitz curves. - * - * Write N as A0 + 2^224 A1, return A0 + R * A1. - * Actually do two passes, since R is big. - */ -#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P -#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R -static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs, - size_t adjust, size_t shift, mbedtls_mpi_uint mask ) -{ - int ret; - size_t i; - mbedtls_mpi M, R; - mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1]; - - if( N->n < p_limbs ) - return( 0 ); - - /* Init R */ - R.s = 1; - R.p = Rp; - R.n = P_KOBLITZ_R; - - /* Common setup for M */ - M.s = 1; - M.p = Mp; - - /* M = A1 */ - M.n = N->n - ( p_limbs - adjust ); - if( M.n > p_limbs + adjust ) - M.n = p_limbs + adjust; - memset( Mp, 0, sizeof Mp ); - memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); - if( shift != 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); - M.n += R.n; /* Make room for multiplication by R */ - - /* N = A0 */ - if( mask != 0 ) - N->p[p_limbs - 1] &= mask; - for( i = p_limbs; i < N->n; i++ ) - N->p[i] = 0; - - /* N = A0 + R * A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); - - /* Second pass */ - - /* M = A1 */ - M.n = N->n - ( p_limbs - adjust ); - if( M.n > p_limbs + adjust ) - M.n = p_limbs + adjust; - memset( Mp, 0, sizeof Mp ); - memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); - if( shift != 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); - M.n += R.n; /* Make room for multiplication by R */ - - /* N = A0 */ - if( mask != 0 ) - N->p[p_limbs - 1] &= mask; - for( i = p_limbs; i < N->n; i++ ) - N->p[i] = 0; - - /* N = A0 + R * A1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) || - MBEDTLS_ECP_DP_SECP224K1_ENABLED) || - MBEDTLS_ECP_DP_SECP256K1_ENABLED) */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -/* - * Fast quasi-reduction modulo p192k1 = 2^192 - R, - * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119 - */ -static int ecp_mod_p192k1( mbedtls_mpi *N ) -{ - static mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00 ) }; - - return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, - 0 ) ); -} -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -/* - * Fast quasi-reduction modulo p224k1 = 2^224 - R, - * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 - */ -static int ecp_mod_p224k1( mbedtls_mpi *N ) -{ - static mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00 ) }; - -#if defined(MBEDTLS_HAVE_INT64) - return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) ); -#else - return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, - 0 ) ); -#endif -} - -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -/* - * Fast quasi-reduction modulo p256k1 = 2^256 - R, - * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 - */ -static int ecp_mod_p256k1( mbedtls_mpi *N ) -{ - static mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00 ) }; - return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, - 0 ) ); -} -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#endif /* !MBEDTLS_ECP_ALT */ - -#endif /* MBEDTLS_ECP_C */ diff --git a/mbedtls/ecp_internal.h b/mbedtls/ecp_internal.h deleted file mode 100644 index 5c13a56a3..000000000 --- a/mbedtls/ecp_internal.h +++ /dev/null @@ -1,325 +0,0 @@ -#pragma GCC system_header -/** - * \file ecp_internal.h - * - * \brief Function declarations for alternative implementation of elliptic curve - * point arithmetic. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * References: - * - * [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records. - * - * - * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis - * for elliptic curve cryptosystems. In : Cryptographic Hardware and - * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. - * - * - * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to - * render ECC resistant against Side Channel Attacks. IACR Cryptology - * ePrint Archive, 2004, vol. 2004, p. 342. - * - * - * [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters. - * - * - * [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic - * Curve Cryptography. - * - * [6] Digital Signature Standard (DSS), FIPS 186-4. - * - * - * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer - * Security (TLS), RFC 4492. - * - * - * [8] - * - * [9] COHEN, Henri. A Course in Computational Algebraic Number Theory. - * Springer Science & Business Media, 1 Aug 2000 - */ - -#ifndef MBEDTLS_ECP_INTERNAL_H -#define MBEDTLS_ECP_INTERNAL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - -/** - * \brief Indicate if the Elliptic Curve Point module extension can - * handle the group. - * - * \param grp The pointer to the elliptic curve group that will be the - * basis of the cryptographic computations. - * - * \return Non-zero if successful. - */ -unsigned char mbedtls_internal_ecp_grp_capable( const mbedtls_ecp_group *grp ); - -/** - * \brief Initialise the Elliptic Curve Point module extension. - * - * If mbedtls_internal_ecp_grp_capable returns true for a - * group, this function has to be able to initialise the - * module for it. - * - * This module can be a driver to a crypto hardware - * accelerator, for which this could be an initialise function. - * - * \param grp The pointer to the group the module needs to be - * initialised for. - * - * \return 0 if successful. - */ -int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ); - -/** - * \brief Frees and deallocates the Elliptic Curve Point module - * extension. - * - * \param grp The pointer to the group the module was initialised for. - */ -void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ); - -#if defined(ECP_SHORTWEIERSTRASS) - -#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) -/** - * \brief Randomize jacobian coordinates: - * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l. - * - * \param grp Pointer to the group representing the curve. - * - * \param pt The point on the curve to be randomised, given with Jacobian - * coordinates. - * - * \param f_rng A function pointer to the random number generator. - * - * \param p_rng A pointer to the random number generator state. - * - * \return 0 if successful. - */ -int mbedtls_internal_ecp_randomize_jac( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -#endif - -#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) -/** - * \brief Addition: R = P + Q, mixed affine-Jacobian coordinates. - * - * The coordinates of Q must be normalized (= affine), - * but those of P don't need to. R is not normalized. - * - * This function is used only as a subrutine of - * ecp_mul_comb(). - * - * Special cases: (1) P or Q is zero, (2) R is zero, - * (3) P == Q. - * None of these cases can happen as intermediate step in - * ecp_mul_comb(): - * - at each step, P, Q and R are multiples of the base - * point, the factor being less than its order, so none of - * them is zero; - * - Q is an odd multiple of the base point, P an even - * multiple, due to the choice of precomputed points in the - * modified comb method. - * So branches for these cases do not leak secret information. - * - * We accept Q->Z being unset (saving memory in tables) as - * meaning 1. - * - * Cost in field operations if done by [5] 3.22: - * 1A := 8M + 3S - * - * \param grp Pointer to the group representing the curve. - * - * \param R Pointer to a point structure to hold the result. - * - * \param P Pointer to the first summand, given with Jacobian - * coordinates - * - * \param Q Pointer to the second summand, given with affine - * coordinates. - * - * \return 0 if successful. - */ -int mbedtls_internal_ecp_add_mixed( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, const mbedtls_ecp_point *P, - const mbedtls_ecp_point *Q ); -#endif - -/** - * \brief Point doubling R = 2 P, Jacobian coordinates. - * - * Cost: 1D := 3M + 4S (A == 0) - * 4M + 4S (A == -3) - * 3M + 6S + 1a otherwise - * when the implementation is based on the "dbl-1998-cmo-2" - * doubling formulas in [8] and standard optimizations are - * applied when curve parameter A is one of { 0, -3 }. - * - * \param grp Pointer to the group representing the curve. - * - * \param R Pointer to a point structure to hold the result. - * - * \param P Pointer to the point that has to be doubled, given with - * Jacobian coordinates. - * - * \return 0 if successful. - */ -#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) -int mbedtls_internal_ecp_double_jac( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, const mbedtls_ecp_point *P ); -#endif - -/** - * \brief Normalize jacobian coordinates of an array of (pointers to) - * points. - * - * Using Montgomery's trick to perform only one inversion mod P - * the cost is: - * 1N(t) := 1I + (6t - 3)M + 1S - * (See for example Algorithm 10.3.4. in [9]) - * - * This function is used only as a subrutine of - * ecp_mul_comb(). - * - * Warning: fails (returning an error) if one of the points is - * zero! - * This should never happen, see choice of w in ecp_mul_comb(). - * - * \param grp Pointer to the group representing the curve. - * - * \param T Array of pointers to the points to normalise. - * - * \param t_len Number of elements in the array. - * - * \return 0 if successful, - * an error if one of the points is zero. - */ -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) -int mbedtls_internal_ecp_normalize_jac_many( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *T[], size_t t_len ); -#endif - -/** - * \brief Normalize jacobian coordinates so that Z == 0 || Z == 1. - * - * Cost in field operations if done by [5] 3.2.1: - * 1N := 1I + 3M + 1S - * - * \param grp Pointer to the group representing the curve. - * - * \param pt pointer to the point to be normalised. This is an - * input/output parameter. - * - * \return 0 if successful. - */ -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) -int mbedtls_internal_ecp_normalize_jac( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt ); -#endif - -#endif /* ECP_SHORTWEIERSTRASS */ - -#if defined(ECP_MONTGOMERY) - -#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) -int mbedtls_internal_ecp_double_add_mxz( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, mbedtls_ecp_point *S, const mbedtls_ecp_point *P, - const mbedtls_ecp_point *Q, const mbedtls_mpi *d ); -#endif - -/** - * \brief Randomize projective x/z coordinates: - * (X, Z) -> (l X, l Z) for random l - * - * \param grp pointer to the group representing the curve - * - * \param P the point on the curve to be randomised given with - * projective coordinates. This is an input/output parameter. - * - * \param f_rng a function pointer to the random number generator - * - * \param p_rng a pointer to the random number generator state - * - * \return 0 if successful - */ -#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) -int mbedtls_internal_ecp_randomize_mxz( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -#endif - -/** - * \brief Normalize Montgomery x/z coordinates: X = X/Z, Z = 1. - * - * \param grp pointer to the group representing the curve - * - * \param P pointer to the point to be normalised. This is an - * input/output parameter. - * - * \return 0 if successful - */ -#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) -int mbedtls_internal_ecp_normalize_mxz( const mbedtls_ecp_group *grp, - mbedtls_ecp_point *P ); -#endif - -#endif /* ECP_MONTGOMERY */ - -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#endif /* ecp_internal.h */ - diff --git a/mbedtls/entropy.c b/mbedtls/entropy.c deleted file mode 100644 index 01e35f737..000000000 --- a/mbedtls/entropy.c +++ /dev/null @@ -1,772 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Entropy accumulator implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ENTROPY_C) - -#if defined(MBEDTLS_TEST_NULL_ENTROPY) -#warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! " -#warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES " -#warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE " -#endif - -#include "mbedtls/entropy.h" -#include "mbedtls/entropy_poll.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#include "mbedtls/platform.h" -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if defined(MBEDTLS_HAVEGE_C) -#include "mbedtls/havege.h" -#endif - -#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ - -void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) -{ - ctx->source_count = 0; - memset( ctx->source, 0, sizeof( ctx->source ) ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif - - ctx->accumulator_started = 0; -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - mbedtls_sha512_init( &ctx->accumulator ); -#else - mbedtls_sha256_init( &ctx->accumulator ); -#endif -#if defined(MBEDTLS_HAVEGE_C) - mbedtls_havege_init( &ctx->havege_data ); -#endif - - /* Reminder: Update ENTROPY_HAVE_STRONG in the test files - * when adding more strong entropy sources here. */ - -#if defined(MBEDTLS_TEST_NULL_ENTROPY) - mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL, - 1, MBEDTLS_ENTROPY_SOURCE_STRONG ); -#endif - -#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) -#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) - mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL, - MBEDTLS_ENTROPY_MIN_PLATFORM, - MBEDTLS_ENTROPY_SOURCE_STRONG ); -#endif -#if defined(MBEDTLS_TIMING_C) - mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, - MBEDTLS_ENTROPY_MIN_HARDCLOCK, - MBEDTLS_ENTROPY_SOURCE_WEAK ); -#endif -#if defined(MBEDTLS_HAVEGE_C) - mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data, - MBEDTLS_ENTROPY_MIN_HAVEGE, - MBEDTLS_ENTROPY_SOURCE_STRONG ); -#endif -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL, - MBEDTLS_ENTROPY_MIN_HARDWARE, - MBEDTLS_ENTROPY_SOURCE_STRONG ); -#endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) - mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, - MBEDTLS_ENTROPY_BLOCK_SIZE, - MBEDTLS_ENTROPY_SOURCE_STRONG ); - ctx->initial_entropy_run = 0; -#endif -#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ -} - -void mbedtls_entropy_free( mbedtls_entropy_context *ctx ) -{ - /* If the context was already free, don't call free() again. - * This is important for mutexes which don't allow double-free. */ - if( ctx->accumulator_started == -1 ) - return; - -#if defined(MBEDTLS_HAVEGE_C) - mbedtls_havege_free( &ctx->havege_data ); -#endif -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &ctx->mutex ); -#endif -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - mbedtls_sha512_free( &ctx->accumulator ); -#else - mbedtls_sha256_free( &ctx->accumulator ); -#endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) - ctx->initial_entropy_run = 0; -#endif - ctx->source_count = 0; - mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) ); - ctx->accumulator_started = -1; -} - -int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, - mbedtls_entropy_f_source_ptr f_source, void *p_source, - size_t threshold, int strong ) -{ - int idx, ret = 0; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - idx = ctx->source_count; - if( idx >= MBEDTLS_ENTROPY_MAX_SOURCES ) - { - ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES; - goto exit; - } - - ctx->source[idx].f_source = f_source; - ctx->source[idx].p_source = p_source; - ctx->source[idx].threshold = threshold; - ctx->source[idx].strong = strong; - - ctx->source_count++; - -exit: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -/* - * Entropy accumulator update - */ -static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id, - const unsigned char *data, size_t len ) -{ - unsigned char header[2]; - unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE]; - size_t use_len = len; - const unsigned char *p = data; - int ret = 0; - - if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE ) - { -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - if( ( ret = mbedtls_sha512_ret( data, len, tmp, 0 ) ) != 0 ) - goto cleanup; -#else - if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 ) - goto cleanup; -#endif - p = tmp; - use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; - } - - header[0] = source_id; - header[1] = use_len & 0xFF; - - /* - * Start the accumulator if this has not already happened. Note that - * it is sufficient to start the accumulator here only because all calls to - * gather entropy eventually execute this code. - */ -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - if( ctx->accumulator_started == 0 && - ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) - goto cleanup; - else - ctx->accumulator_started = 1; - if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 ) - goto cleanup; - ret = mbedtls_sha512_update_ret( &ctx->accumulator, p, use_len ); -#else - if( ctx->accumulator_started == 0 && - ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) - goto cleanup; - else - ctx->accumulator_started = 1; - if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 ) - goto cleanup; - ret = mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len ); -#endif - -cleanup: - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - - return( ret ); -} - -int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, - const unsigned char *data, size_t len ) -{ - int ret; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -/* - * Run through the different sources to add entropy to our accumulator - */ -static int entropy_gather_internal( mbedtls_entropy_context *ctx ) -{ - int ret = 0, i, have_one_strong = 0; - unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER]; - size_t olen; - - if( ctx->source_count == 0 ) - return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED ); - - /* - * Run through our entropy sources - */ - for( i = 0; i < ctx->source_count; i++ ) - { - if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG ) - have_one_strong = 1; - - olen = 0; - if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, - buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 ) - { - goto cleanup; - } - - /* - * Add if we actually gathered something - */ - if( olen > 0 ) - { - if( ( ret = entropy_update( ctx, (unsigned char) i, - buf, olen ) ) != 0 ) - return( ret ); - ctx->source[i].size += olen; - } - } - - if( have_one_strong == 0 ) - ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE; - -cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - return( ret ); -} - -/* - * Thread-safe wrapper for entropy_gather_internal() - */ -int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ) -{ - int ret; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - ret = entropy_gather_internal( ctx ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) -{ - int ret, count = 0, i, done; - mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - - if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - -#if defined(MBEDTLS_ENTROPY_NV_SEED) - /* Update the NV entropy seed before generating any entropy for outside - * use. - */ - if( ctx->initial_entropy_run == 0 ) - { - ctx->initial_entropy_run = 1; - if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 ) - return( ret ); - } -#endif - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - /* - * Always gather extra entropy before a call - */ - do - { - if( count++ > ENTROPY_MAX_LOOP ) - { - ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - goto exit; - } - - if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) - goto exit; - - done = 1; - for( i = 0; i < ctx->source_count; i++ ) - if( ctx->source[i].size < ctx->source[i].threshold ) - done = 0; - } - while( ! done ); - - memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); - -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - /* - * Note that at this stage it is assumed that the accumulator was started - * in a previous call to entropy_update(). If this is not guaranteed, the - * code below will fail. - */ - if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 ) - goto exit; - - /* - * Reset accumulator and counters and recycle existing entropy - */ - mbedtls_sha512_free( &ctx->accumulator ); - mbedtls_sha512_init( &ctx->accumulator ); - if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf, - MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) - goto exit; - - /* - * Perform second SHA-512 on entropy - */ - if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, - buf, 0 ) ) != 0 ) - goto exit; -#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ - if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 ) - goto exit; - - /* - * Reset accumulator and counters and recycle existing entropy - */ - mbedtls_sha256_free( &ctx->accumulator ); - mbedtls_sha256_init( &ctx->accumulator ); - if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf, - MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) - goto exit; - - /* - * Perform second SHA-256 on entropy - */ - if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, - buf, 0 ) ) != 0 ) - goto exit; -#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ - - for( i = 0; i < ctx->source_count; i++ ) - ctx->source[i].size = 0; - - memcpy( output, buf, len ); - - ret = 0; - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ) -{ - int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - - /* Read new seed and write it to NV */ - if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) - return( ret ); - - if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) - return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); - - /* Manually update the remaining stream with a separator value to diverge */ - memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); - ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); - - return( ret ); -} -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if defined(MBEDTLS_FS_IO) -int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ) -{ - int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - FILE *f = NULL; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - - if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) - { - ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - goto exit; - } - - if( ( f = fopen( path, "wb" ) ) == NULL ) - { - ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - goto exit; - } - - if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE ) - { - ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - goto exit; - } - - ret = 0; - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - if( f != NULL ) - fclose( f ); - - return( ret ); -} - -int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path ) -{ - int ret = 0; - FILE *f; - size_t n; - unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); - - fseek( f, 0, SEEK_END ); - n = (size_t) ftell( f ); - fseek( f, 0, SEEK_SET ); - - if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) - n = MBEDTLS_ENTROPY_MAX_SEED_SIZE; - - if( fread( buf, 1, n, f ) != n ) - ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - else - ret = mbedtls_entropy_update_manual( ctx, buf, n ); - - fclose( f ); - - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - if( ret != 0 ) - return( ret ); - - return( mbedtls_entropy_write_seed_file( ctx, path ) ); -} -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) -#if !defined(MBEDTLS_TEST_NULL_ENTROPY) -/* - * Dummy source function - */ -static int entropy_dummy_source( void *data, unsigned char *output, - size_t len, size_t *olen ) -{ - ((void) data); - - memset( output, 0x2a, len ); - *olen = len; - - return( 0 ); -} -#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - -static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len ) -{ - int ret = 0; - size_t entropy_len = 0; - size_t olen = 0; - size_t attempts = buf_len; - - while( attempts > 0 && entropy_len < buf_len ) - { - if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len, - buf_len - entropy_len, &olen ) ) != 0 ) - return( ret ); - - entropy_len += olen; - attempts--; - } - - if( entropy_len < buf_len ) - { - ret = 1; - } - - return( ret ); -} - - -static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf, - size_t buf_len ) -{ - unsigned char set= 0xFF; - unsigned char unset = 0x00; - size_t i; - - for( i = 0; i < buf_len; i++ ) - { - set &= buf[i]; - unset |= buf[i]; - } - - return( set == 0xFF || unset == 0x00 ); -} - -/* - * A test to ensure hat the entropy sources are functioning correctly - * and there is no obvious failure. The test performs the following checks: - * - The entropy source is not providing only 0s (all bits unset) or 1s (all - * bits set). - * - The entropy source is not providing values in a pattern. Because the - * hardware could be providing data in an arbitrary length, this check polls - * the hardware entropy source twice and compares the result to ensure they - * are not equal. - * - The error code returned by the entropy source is not an error. - */ -int mbedtls_entropy_source_self_test( int verbose ) -{ - int ret = 0; - unsigned char buf0[2 * sizeof( unsigned long long int )]; - unsigned char buf1[2 * sizeof( unsigned long long int )]; - - if( verbose != 0 ) - mbedtls_printf( " ENTROPY_BIAS test: " ); - - memset( buf0, 0x00, sizeof( buf0 ) ); - memset( buf1, 0x00, sizeof( buf1 ) ); - - if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 ) - goto cleanup; - if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 ) - goto cleanup; - - /* Make sure that the returned values are not all 0 or 1 */ - if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 ) - goto cleanup; - if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 ) - goto cleanup; - - /* Make sure that the entropy source is not returning values in a - * pattern */ - ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0; - -cleanup: - if( verbose != 0 ) - { - if( ret != 0 ) - mbedtls_printf( "failed\n" ); - else - mbedtls_printf( "passed\n" ); - - mbedtls_printf( "\n" ); - } - - return( ret != 0 ); -} - -#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ - -/* - * The actual entropy quality is hard to test, but we can at least - * test that the functions don't cause errors and write the correct - * amount of data to buffers. - */ -int mbedtls_entropy_self_test( int verbose ) -{ - int ret = 1; -#if !defined(MBEDTLS_TEST_NULL_ENTROPY) - mbedtls_entropy_context ctx; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; - unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; - size_t i, j; -#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ - - if( verbose != 0 ) - mbedtls_printf( " ENTROPY test: " ); - -#if !defined(MBEDTLS_TEST_NULL_ENTROPY) - mbedtls_entropy_init( &ctx ); - - /* First do a gather to make sure we have default sources */ - if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 ) - goto cleanup; - - ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16, - MBEDTLS_ENTROPY_SOURCE_WEAK ); - if( ret != 0 ) - goto cleanup; - - if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 ) - goto cleanup; - - /* - * To test that mbedtls_entropy_func writes correct number of bytes: - * - use the whole buffer and rely on ASan to detect overruns - * - collect entropy 8 times and OR the result in an accumulator: - * any byte should then be 0 with probably 2^(-64), so requiring - * each of the 32 or 64 bytes to be non-zero has a false failure rate - * of at most 2^(-58) which is acceptable. - */ - for( i = 0; i < 8; i++ ) - { - if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 ) - goto cleanup; - - for( j = 0; j < sizeof( buf ); j++ ) - acc[j] |= buf[j]; - } - - for( j = 0; j < sizeof( buf ); j++ ) - { - if( acc[j] == 0 ) - { - ret = 1; - goto cleanup; - } - } - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 ) - goto cleanup; -#endif - -cleanup: - mbedtls_entropy_free( &ctx ); -#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ - - if( verbose != 0 ) - { - if( ret != 0 ) - mbedtls_printf( "failed\n" ); - else - mbedtls_printf( "passed\n" ); - - mbedtls_printf( "\n" ); - } - - return( ret != 0 ); -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ENTROPY_C */ diff --git a/mbedtls/entropy.h b/mbedtls/entropy.h deleted file mode 100644 index a00c4edd4..000000000 --- a/mbedtls/entropy.h +++ /dev/null @@ -1,317 +0,0 @@ -#pragma GCC system_header -/** - * \file entropy.h - * - * \brief Entropy accumulator implementation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_ENTROPY_H -#define MBEDTLS_ENTROPY_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) -#include "sha512.h" -#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR -#else -#if defined(MBEDTLS_SHA256_C) -#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR -#include "sha256.h" -#endif -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -#if defined(MBEDTLS_HAVEGE_C) -#include "havege.h" -#endif - -#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */ -#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */ -#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */ -#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D /**< No strong sources have been added to poll. */ -#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F /**< Read/write error in file. */ - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES) -#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -#endif - -#if !defined(MBEDTLS_ENTROPY_MAX_GATHER) -#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -#endif - -/* \} name SECTION: Module settings */ - -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) -#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */ -#else -#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */ -#endif - -#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ -#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES - -#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */ -#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Entropy poll callback pointer - * - * \param data Callback-specific data pointer - * \param output Data to fill - * \param len Maximum size to provide - * \param olen The actual amount of bytes put into the buffer (Can be 0) - * - * \return 0 if no critical failures occurred, - * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise - */ -typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len, - size_t *olen); - -/** - * \brief Entropy source state - */ -typedef struct mbedtls_entropy_source_state -{ - mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */ - void * p_source; /**< The callback data pointer */ - size_t size; /**< Amount received in bytes */ - size_t threshold; /**< Minimum bytes required before release */ - int strong; /**< Is the source strong? */ -} -mbedtls_entropy_source_state; - -/** - * \brief Entropy context structure - */ -typedef struct mbedtls_entropy_context -{ - int accumulator_started; /* 0 after init. - * 1 after the first update. - * -1 after free. */ -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) - mbedtls_sha512_context accumulator; -#else - mbedtls_sha256_context accumulator; -#endif - int source_count; /* Number of entries used in source. */ - mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES]; -#if defined(MBEDTLS_HAVEGE_C) - mbedtls_havege_state havege_data; -#endif -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; /*!< mutex */ -#endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) - int initial_entropy_run; -#endif -} -mbedtls_entropy_context; - -/** - * \brief Initialize the context - * - * \param ctx Entropy context to initialize - */ -void mbedtls_entropy_init( mbedtls_entropy_context *ctx ); - -/** - * \brief Free the data in the context - * - * \param ctx Entropy context to free - */ -void mbedtls_entropy_free( mbedtls_entropy_context *ctx ); - -/** - * \brief Adds an entropy source to poll - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param ctx Entropy context - * \param f_source Entropy function - * \param p_source Function data - * \param threshold Minimum required from source before entropy is released - * ( with mbedtls_entropy_func() ) (in bytes) - * \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or - * MBEDTLS_ENTROPY_SOURCE_WEAK. - * At least one strong source needs to be added. - * Weaker sources (such as the cycle counter) can be used as - * a complement. - * - * \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES - */ -int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, - mbedtls_entropy_f_source_ptr f_source, void *p_source, - size_t threshold, int strong ); - -/** - * \brief Trigger an extra gather poll for the accumulator - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param ctx Entropy context - * - * \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED - */ -int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ); - -/** - * \brief Retrieve entropy from the accumulator - * (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE) - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param data Entropy context - * \param output Buffer to fill - * \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE - * - * \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED - */ -int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ); - -/** - * \brief Add data to the accumulator manually - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param ctx Entropy context - * \param data Data to add - * \param len Length of data - * - * \return 0 if successful - */ -int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, - const unsigned char *data, size_t len ); - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -/** - * \brief Trigger an update of the seed file in NV by using the - * current entropy pool. - * - * \param ctx Entropy context - * - * \return 0 if successful - */ -int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ); -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Write a seed file - * - * \param ctx Entropy context - * \param path Name of the file - * - * \return 0 if successful, - * MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or - * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED - */ -int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ); - -/** - * \brief Read and update a seed file. Seed is added to this - * instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are - * read from the seed file. The rest is ignored. - * - * \param ctx Entropy context - * \param path Name of the file - * - * \return 0 if successful, - * MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, - * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED - */ -int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path ); -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine - * - * This module self-test also calls the entropy self-test, - * mbedtls_entropy_source_self_test(); - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_entropy_self_test( int verbose ); - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) -/** - * \brief Checkup routine - * - * Verifies the integrity of the hardware entropy source - * provided by the function 'mbedtls_hardware_poll()'. - * - * Note this is the only hardware entropy source that is known - * at link time, and other entropy sources configured - * dynamically at runtime by the function - * mbedtls_entropy_add_source() will not be tested. - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_entropy_source_self_test( int verbose ); -#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* entropy.h */ diff --git a/mbedtls/entropy_poll.c b/mbedtls/entropy_poll.c deleted file mode 100644 index 8a2b1f698..000000000 --- a/mbedtls/entropy_poll.c +++ /dev/null @@ -1,274 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Platform-specific and custom entropy polling functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if defined(__linux__) && !defined(_GNU_SOURCE) -/* Ensure that syscall() is available even when compiling with -std=c99 */ -#define _GNU_SOURCE -#endif - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#if defined(MBEDTLS_ENTROPY_C) - -#include "mbedtls/entropy.h" -#include "mbedtls/entropy_poll.h" - -#if defined(MBEDTLS_TIMING_C) -#include "mbedtls/timing.h" -#endif -#if defined(MBEDTLS_HAVEGE_C) -#include "mbedtls/havege.h" -#endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#include "mbedtls/platform.h" -#endif - -#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) - -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) -#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h" -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - -#if !defined(_WIN32_WINNT) -#define _WIN32_WINNT 0x0400 -#endif -#include -#include - -int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, - size_t *olen ) -{ - HCRYPTPROV provider; - ((void) data); - *olen = 0; - - if( CryptAcquireContext( &provider, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) - { - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - } - - if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) - { - CryptReleaseContext( provider, 0 ); - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - } - - CryptReleaseContext( provider, 0 ); - *olen = len; - - return( 0 ); -} -#else /* _WIN32 && !EFIX64 && !EFI32 */ - -/* - * Test for Linux getrandom() support. - * Since there is no wrapper in the libc yet, use the generic syscall wrapper - * available in GNU libc and compatible libc's (eg uClibc). - */ -#if defined(__linux__) && defined(__GLIBC__) -#include -#include -#if defined(SYS_getrandom) -#define HAVE_GETRANDOM -#include - -static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) -{ - /* MemSan cannot understand that the syscall writes to the buffer */ -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) - memset( buf, 0, buflen ); -#endif -#endif - return( syscall( SYS_getrandom, buf, buflen, flags ) ); -} -#endif /* SYS_getrandom */ -#endif /* __linux__ */ - -#include - -int mbedtls_platform_entropy_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - FILE *file; - size_t read_len; - int ret; - ((void) data); - -#if defined(HAVE_GETRANDOM) - ret = getrandom_wrapper( output, len, 0 ); - if( ret >= 0 ) - { - *olen = ret; - return( 0 ); - } - else if( errno != ENOSYS ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - /* Fall through if the system call isn't known. */ -#else - ((void) ret); -#endif /* HAVE_GETRANDOM */ - - *olen = 0; - - file = fopen( "/dev/urandom", "rb" ); - if( file == NULL ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - - read_len = fread( output, 1, len, file ); - if( read_len != len ) - { - fclose( file ); - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - } - - fclose( file ); - *olen = len; - - return( 0 ); -} -#endif /* _WIN32 && !EFIX64 && !EFI32 */ -#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ - -#if defined(MBEDTLS_TEST_NULL_ENTROPY) -int mbedtls_null_entropy_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - ((void) data); - ((void) output); - *olen = 0; - - if( len < sizeof(unsigned char) ) - return( 0 ); - - *olen = sizeof(unsigned char); - - return( 0 ); -} -#endif - -#if defined(MBEDTLS_TIMING_C) -int mbedtls_hardclock_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - unsigned long timer = mbedtls_timing_hardclock(); - ((void) data); - *olen = 0; - - if( len < sizeof(unsigned long) ) - return( 0 ); - - memcpy( output, &timer, sizeof(unsigned long) ); - *olen = sizeof(unsigned long); - - return( 0 ); -} -#endif /* MBEDTLS_TIMING_C */ - -#if defined(MBEDTLS_HAVEGE_C) -int mbedtls_havege_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - mbedtls_havege_state *hs = (mbedtls_havege_state *) data; - *olen = 0; - - if( mbedtls_havege_random( hs, output, len ) != 0 ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - - *olen = len; - - return( 0 ); -} -#endif /* MBEDTLS_HAVEGE_C */ - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -int mbedtls_nv_seed_poll( void *data, - unsigned char *output, size_t len, size_t *olen ) -{ - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; - ((void) data); - - memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); - - if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) - return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); - - if( len < use_len ) - use_len = len; - - memcpy( output, buf, use_len ); - *olen = use_len; - - return( 0 ); -} -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#endif /* MBEDTLS_ENTROPY_C */ diff --git a/mbedtls/entropy_poll.h b/mbedtls/entropy_poll.h deleted file mode 100644 index 9b65fc4f4..000000000 --- a/mbedtls/entropy_poll.h +++ /dev/null @@ -1,136 +0,0 @@ -#pragma GCC system_header -/** - * \file entropy_poll.h - * - * \brief Platform-specific and custom entropy polling functions - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_ENTROPY_POLL_H -#define MBEDTLS_ENTROPY_POLL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Default thresholds for built-in sources, in bytes - */ -#define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */ -#define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */ -#define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */ -#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE) -#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */ -#endif - -/** - * \brief Entropy poll callback that provides 0 entropy. - */ -#if defined(MBEDTLS_TEST_NULL_ENTROPY) - int mbedtls_null_entropy_poll( void *data, - unsigned char *output, size_t len, size_t *olen ); -#endif - -#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) -/** - * \brief Platform-specific entropy poll callback - */ -int mbedtls_platform_entropy_poll( void *data, - unsigned char *output, size_t len, size_t *olen ); -#endif - -#if defined(MBEDTLS_HAVEGE_C) -/** - * \brief HAVEGE based entropy poll callback - * - * Requires an HAVEGE state as its data pointer. - */ -int mbedtls_havege_poll( void *data, - unsigned char *output, size_t len, size_t *olen ); -#endif - -#if defined(MBEDTLS_TIMING_C) -/** - * \brief mbedtls_timing_hardclock-based entropy poll callback - */ -int mbedtls_hardclock_poll( void *data, - unsigned char *output, size_t len, size_t *olen ); -#endif - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) -/** - * \brief Entropy poll callback for a hardware source - * - * \warning This is not provided by mbed TLS! - * See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h. - * - * \note This must accept NULL as its first argument. - */ -int mbedtls_hardware_poll( void *data, - unsigned char *output, size_t len, size_t *olen ); -#endif - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -/** - * \brief Entropy poll callback for a non-volatile seed file - * - * \note This must accept NULL as its first argument. - */ -int mbedtls_nv_seed_poll( void *data, - unsigned char *output, size_t len, size_t *olen ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* entropy_poll.h */ diff --git a/mbedtls/error.c b/mbedtls/error.c deleted file mode 100644 index c972301d2..000000000 --- a/mbedtls/error.c +++ /dev/null @@ -1,957 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Error message information - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) - -#include "mbedtls/error.h" - -#if defined(MBEDTLS_ERROR_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#define mbedtls_snprintf snprintf -#endif - -#include -#include - -#if defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#endif - -#if defined(MBEDTLS_ARC4_C) -#include "mbedtls/arc4.h" -#endif - -#if defined(MBEDTLS_ARIA_C) -#include "mbedtls/aria.h" -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" -#endif - -#if defined(MBEDTLS_BASE64_C) -#include "mbedtls/base64.h" -#endif - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -#if defined(MBEDTLS_BLOWFISH_C) -#include "mbedtls/blowfish.h" -#endif - -#if defined(MBEDTLS_CAMELLIA_C) -#include "mbedtls/camellia.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_CIPHER_C) -#include "mbedtls/cipher.h" -#endif - -#if defined(MBEDTLS_CMAC_C) -#include "mbedtls/cmac.h" -#endif - -#if defined(MBEDTLS_CTR_DRBG_C) -#include "mbedtls/ctr_drbg.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_DHM_C) -#include "mbedtls/dhm.h" -#endif - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_ENTROPY_C) -#include "mbedtls/entropy.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_HKDF_C) -#include "mbedtls/hkdf.h" -#endif - -#if defined(MBEDTLS_HMAC_DRBG_C) -#include "mbedtls/hmac_drbg.h" -#endif - -#if defined(MBEDTLS_MD_C) -#include "mbedtls/md.h" -#endif - -#if defined(MBEDTLS_MD2_C) -#include "mbedtls/md2.h" -#endif - -#if defined(MBEDTLS_MD4_C) -#include "mbedtls/md4.h" -#endif - -#if defined(MBEDTLS_MD5_C) -#include "mbedtls/md5.h" -#endif - -#if defined(MBEDTLS_NET_C) -#include "mbedtls/net_sockets.h" -#endif - -#if defined(MBEDTLS_OID_C) -#include "mbedtls/oid.h" -#endif - -#if defined(MBEDTLS_PADLOCK_C) -#include "mbedtls/padlock.h" -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PK_C) -#include "mbedtls/pk.h" -#endif - -#if defined(MBEDTLS_PKCS12_C) -#include "mbedtls/pkcs12.h" -#endif - -#if defined(MBEDTLS_PKCS5_C) -#include "mbedtls/pkcs5.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#endif - -#if defined(MBEDTLS_POLY1305_C) -#include "mbedtls/poly1305.h" -#endif - -#if defined(MBEDTLS_RIPEMD160_C) -#include "mbedtls/ripemd160.h" -#endif - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif - -#if defined(MBEDTLS_SHA1_C) -#include "mbedtls/sha1.h" -#endif - -#if defined(MBEDTLS_SHA256_C) -#include "mbedtls/sha256.h" -#endif - -#if defined(MBEDTLS_SHA512_C) -#include "mbedtls/sha512.h" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) -#include "mbedtls/ssl.h" -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) -#include "mbedtls/x509.h" -#endif - -#if defined(MBEDTLS_XTEA_C) -#include "mbedtls/xtea.h" -#endif - - -void mbedtls_strerror( int ret, char *buf, size_t buflen ) -{ - size_t len; - int use_ret; - - if( buflen == 0 ) - return; - - memset( buf, 0x00, buflen ); - - if( ret < 0 ) - ret = -ret; - - if( ret & 0xFF80 ) - { - use_ret = ret & 0xFF80; - - // High level error codes - // - // BEGIN generated code -#if defined(MBEDTLS_CIPHER_C) - if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" ); - if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" ); - if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" ); - if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) ) - mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" ); - if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) ) - mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" ); - if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) ) - mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" ); - if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) ) - mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" ); - if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" ); -#endif /* MBEDTLS_CIPHER_C */ - -#if defined(MBEDTLS_DHM_C) - if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" ); - if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) ) - mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" ); - if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) ) - mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" ); - if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) ) - mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" ); - if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) ) - mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" ); - if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) ) - mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" ); - if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) ) - mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" ); - if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" ); - if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) ) - mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" ); - if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" ); - if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) ) - mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" ); -#endif /* MBEDTLS_DHM_C */ - -#if defined(MBEDTLS_ECP_C) - if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" ); - if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "ECP - The requested feature is not available, for example, the requested curve is not supported" ); - if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) ) - mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" ); - if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" ); - if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) ) - mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as ephemeral key, failed" ); - if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) ) - mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" ); - if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" ); - if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "ECP - The ECP hardware accelerator failed" ); - if( use_ret == -(MBEDTLS_ERR_ECP_IN_PROGRESS) ) - mbedtls_snprintf( buf, buflen, "ECP - Operation in progress, call again with the same parameters to continue" ); -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_MD_C) - if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" ); - if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" ); - if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) ) - mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" ); - if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" ); -#endif /* MBEDTLS_MD_C */ - -#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) - if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) ) - mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" ); - if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) ) - mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" ); - if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" ); - if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) ) - mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" ); - if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) ) - mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" ); - if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" ); - if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" ); - if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" ); - if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" ); -#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ - -#if defined(MBEDTLS_PK_C) - if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" ); - if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" ); - if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) ) - mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" ); - if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) ) - mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" ); - if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) ) - mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" ); - if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) ) - mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" ); - if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" ); - if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" ); - if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) ) - mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" ); - if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) ) - mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) ) - mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" ); - if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); - if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" ); - if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" ); -#endif /* MBEDTLS_PK_C */ - -#if defined(MBEDTLS_PKCS12_C) - if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" ); - if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) ) - mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" ); - if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" ); -#endif /* MBEDTLS_PKCS12_C */ - -#if defined(MBEDTLS_PKCS5_C) - if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) ) - mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" ); - if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" ); - if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" ); -#endif /* MBEDTLS_PKCS5_C */ - -#if defined(MBEDTLS_RSA_C) - if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) ) - mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" ); - if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) ) - mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" ); - if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) ) - mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" ); - if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) ) - mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" ); - if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) ) - mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" ); - if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) ) - mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" ); - if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) ) - mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" ); - if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) ) - mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" ); - if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) ) - mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" ); - if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" ); -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_SSL_TLS_C) - if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) ) - mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) ) - mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) ) - mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" ); - if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) ) - mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) ) - mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) ) - mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) ) - mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) ) - mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" ); - if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" ); - if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) ) - mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" ); - if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) ) - { - mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" ); - return; - } - if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) ) - mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) ) - mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" ); - if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) ) - mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" ); - if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) ) - mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" ); - if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) ) - mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) ) - mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) ) - mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) ) - mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" ); - if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) ) - mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) ) - mbedtls_snprintf( buf, buflen, "SSL - No data of requested type currently available on underlying transport" ); - if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) ) - mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" ); - if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) ) - mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) ) - mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" ); - if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) ) - mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) ) - mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" ); - if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) ) - mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) ) - mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" ); - if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) ) - mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" ); - if( use_ret == -(MBEDTLS_ERR_SSL_EARLY_MESSAGE) ) - mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) ) - mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_CONFIG) ) - mbedtls_snprintf( buf, buflen, "SSL - Invalid value in SSL config" ); -#endif /* MBEDTLS_SSL_TLS_C */ - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) - if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" ); - if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) ) - mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) ) - mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) ) - mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) ) - mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) ) - mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) ) - mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) ) - mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) ) - mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) ) - mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) ) - mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" ); - if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) ) - mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" ); - if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" ); - if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) ) - mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" ); - if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) ) - mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" ); - if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "X509 - Input invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" ); - if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) ) - mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" ); - if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" ); - if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) ) - mbedtls_snprintf( buf, buflen, "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" ); -#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ - // END generated code - - if( strlen( buf ) == 0 ) - mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); - } - - use_ret = ret & ~0xFF80; - - if( use_ret == 0 ) - return; - - // If high level code is present, make a concatenation between both - // error strings. - // - len = strlen( buf ); - - if( len > 0 ) - { - if( buflen - len < 5 ) - return; - - mbedtls_snprintf( buf + len, buflen - len, " : " ); - - buf += len + 3; - buflen -= len + 3; - } - - // Low level error codes - // - // BEGIN generated code -#if defined(MBEDTLS_AES_C) - if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) ) - mbedtls_snprintf( buf, buflen, "AES - Invalid key length" ); - if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) ) - mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" ); - if( use_ret == -(MBEDTLS_ERR_AES_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "AES - Invalid input data" ); - if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" ); - if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "AES - AES hardware accelerator failed" ); -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_ARC4_C) - if( use_ret == -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" ); -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_ARIA_C) - if( use_ret == -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "ARIA - Bad input data" ); - if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH) ) - mbedtls_snprintf( buf, buflen, "ARIA - Invalid data input length" ); - if( use_ret == -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "ARIA - Feature not available. For example, an unsupported ARIA key size" ); - if( use_ret == -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "ARIA - ARIA hardware accelerator failed" ); -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_ASN1_PARSE_C) - if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) ) - mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" ); - if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) ) - mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" ); - if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) ) - mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" ); - if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" ); - if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) ) - mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" ); - if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" ); - if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" ); -#endif /* MBEDTLS_ASN1_PARSE_C */ - -#if defined(MBEDTLS_BASE64_C) - if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" ); - if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) ) - mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" ); -#endif /* MBEDTLS_BASE64_C */ - -#if defined(MBEDTLS_BIGNUM_C) - if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) ) - mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" ); - if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) ) - mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" ); - if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" ); - if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) ) - mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" ); - if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) ) - mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" ); - if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) ) - mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" ); - if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" ); -#endif /* MBEDTLS_BIGNUM_C */ - -#if defined(MBEDTLS_BLOWFISH_C) - if( use_ret == -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "BLOWFISH - Bad input data" ); - if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) ) - mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" ); - if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" ); -#endif /* MBEDTLS_BLOWFISH_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - if( use_ret == -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "CAMELLIA - Bad input data" ); - if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) ) - mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" ); - if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" ); -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_CCM_C) - if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) ) - mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" ); - if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) ) - mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" ); - if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" ); -#endif /* MBEDTLS_CCM_C */ - -#if defined(MBEDTLS_CHACHA20_C) - if( use_ret == -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" ); - if( use_ret == -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "CHACHA20 - Feature not available. For example, s part of the API is not implemented" ); - if( use_ret == -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "CHACHA20 - Chacha20 hardware accelerator failed" ); -#endif /* MBEDTLS_CHACHA20_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE) ) - mbedtls_snprintf( buf, buflen, "CHACHAPOLY - The requested operation is not permitted in the current state" ); - if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) ) - mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Authenticated decryption failed: data was not authentic" ); -#endif /* MBEDTLS_CHACHAPOLY_C */ - -#if defined(MBEDTLS_CMAC_C) - if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" ); -#endif /* MBEDTLS_CMAC_C */ - -#if defined(MBEDTLS_CTR_DRBG_C) - if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) ) - mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" ); - if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) ) - mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" ); - if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) ) - mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" ); - if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) ) - mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" ); -#endif /* MBEDTLS_CTR_DRBG_C */ - -#if defined(MBEDTLS_DES_C) - if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) ) - mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" ); - if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" ); -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ENTROPY_C) - if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) ) - mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" ); - if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) ) - mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" ); - if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) ) - mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" ); - if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) ) - mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" ); - if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) ) - mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" ); -#endif /* MBEDTLS_ENTROPY_C */ - -#if defined(MBEDTLS_GCM_C) - if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) ) - mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" ); - if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" ); - if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) ) - mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" ); -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_HKDF_C) - if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" ); -#endif /* MBEDTLS_HKDF_C */ - -#if defined(MBEDTLS_HMAC_DRBG_C) - if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) ) - mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" ); - if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) ) - mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" ); - if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) ) - mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" ); - if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) ) - mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" ); -#endif /* MBEDTLS_HMAC_DRBG_C */ - -#if defined(MBEDTLS_MD2_C) - if( use_ret == -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "MD2 - MD2 hardware accelerator failed" ); -#endif /* MBEDTLS_MD2_C */ - -#if defined(MBEDTLS_MD4_C) - if( use_ret == -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "MD4 - MD4 hardware accelerator failed" ); -#endif /* MBEDTLS_MD4_C */ - -#if defined(MBEDTLS_MD5_C) - if( use_ret == -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" ); -#endif /* MBEDTLS_MD5_C */ - -#if defined(MBEDTLS_NET_C) - if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" ); - if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" ); - if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" ); - if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) ) - mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" ); - if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) ) - mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" ); - if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" ); - if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) ) - mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" ); - if( use_ret == -(MBEDTLS_ERR_NET_POLL_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Polling the net context failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "NET - Input invalid" ); -#endif /* MBEDTLS_NET_C */ - -#if defined(MBEDTLS_OID_C) - if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) ) - mbedtls_snprintf( buf, buflen, "OID - OID is not found" ); - if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" ); -#endif /* MBEDTLS_OID_C */ - -#if defined(MBEDTLS_PADLOCK_C) - if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) ) - mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" ); -#endif /* MBEDTLS_PADLOCK_C */ - -#if defined(MBEDTLS_PLATFORM_C) - if( use_ret == -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "PLATFORM - Hardware accelerator failed" ); - if( use_ret == -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED) ) - mbedtls_snprintf( buf, buflen, "PLATFORM - The requested feature is not supported by the platform" ); -#endif /* MBEDTLS_PLATFORM_C */ - -#if defined(MBEDTLS_POLY1305_C) - if( use_ret == -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "POLY1305 - Invalid input parameter(s)" ); - if( use_ret == -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "POLY1305 - Feature not available. For example, s part of the API is not implemented" ); - if( use_ret == -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "POLY1305 - Poly1305 hardware accelerator failed" ); -#endif /* MBEDTLS_POLY1305_C */ - -#if defined(MBEDTLS_RIPEMD160_C) - if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" ); -#endif /* MBEDTLS_RIPEMD160_C */ - -#if defined(MBEDTLS_SHA1_C) - if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" ); - if( use_ret == -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 input data was malformed" ); -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - if( use_ret == -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 hardware accelerator failed" ); - if( use_ret == -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 input data was malformed" ); -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - if( use_ret == -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 hardware accelerator failed" ); - if( use_ret == -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 input data was malformed" ); -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_THREADING_C) - if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" ); - if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) ) - mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" ); -#endif /* MBEDTLS_THREADING_C */ - -#if defined(MBEDTLS_XTEA_C) - if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) ) - mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" ); - if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" ); -#endif /* MBEDTLS_XTEA_C */ - // END generated code - - if( strlen( buf ) != 0 ) - return; - - mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); -} - -#else /* MBEDTLS_ERROR_C */ - -/* - * Provide an non-function in case MBEDTLS_ERROR_C is not defined - */ -void mbedtls_strerror( int ret, char *buf, size_t buflen ) -{ - ((void) ret); - - if( buflen > 0 ) - buf[0] = '\0'; -} - -#endif /* MBEDTLS_ERROR_C */ - -#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */ diff --git a/mbedtls/error.h b/mbedtls/error.h deleted file mode 100644 index 17acbf31d..000000000 --- a/mbedtls/error.h +++ /dev/null @@ -1,156 +0,0 @@ -#pragma GCC system_header -/** - * \file error.h - * - * \brief Error to string translation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_ERROR_H -#define MBEDTLS_ERROR_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -/** - * Error code layout. - * - * Currently we try to keep all error codes within the negative space of 16 - * bits signed integers to support all platforms (-0x0001 - -0x7FFF). In - * addition we'd like to give two layers of information on the error if - * possible. - * - * For that purpose the error codes are segmented in the following manner: - * - * 16 bit error code bit-segmentation - * - * 1 bit - Unused (sign bit) - * 3 bits - High level module ID - * 5 bits - Module-dependent error code - * 7 bits - Low level module errors - * - * For historical reasons, low-level error codes are divided in even and odd, - * even codes were assigned first, and -1 is reserved for other errors. - * - * Low-level module errors (0x0002-0x007E, 0x0003-0x007F) - * - * Module Nr Codes assigned - * MPI 7 0x0002-0x0010 - * GCM 3 0x0012-0x0014 0x0013-0x0013 - * BLOWFISH 3 0x0016-0x0018 0x0017-0x0017 - * THREADING 3 0x001A-0x001E - * AES 5 0x0020-0x0022 0x0021-0x0025 - * CAMELLIA 3 0x0024-0x0026 0x0027-0x0027 - * XTEA 2 0x0028-0x0028 0x0029-0x0029 - * BASE64 2 0x002A-0x002C - * OID 1 0x002E-0x002E 0x000B-0x000B - * PADLOCK 1 0x0030-0x0030 - * DES 2 0x0032-0x0032 0x0033-0x0033 - * CTR_DBRG 4 0x0034-0x003A - * ENTROPY 3 0x003C-0x0040 0x003D-0x003F - * NET 13 0x0042-0x0052 0x0043-0x0049 - * ARIA 4 0x0058-0x005E - * ASN1 7 0x0060-0x006C - * CMAC 1 0x007A-0x007A - * PBKDF2 1 0x007C-0x007C - * HMAC_DRBG 4 0x0003-0x0009 - * CCM 3 0x000D-0x0011 - * ARC4 1 0x0019-0x0019 - * MD2 1 0x002B-0x002B - * MD4 1 0x002D-0x002D - * MD5 1 0x002F-0x002F - * RIPEMD160 1 0x0031-0x0031 - * SHA1 1 0x0035-0x0035 0x0073-0x0073 - * SHA256 1 0x0037-0x0037 0x0074-0x0074 - * SHA512 1 0x0039-0x0039 0x0075-0x0075 - * CHACHA20 3 0x0051-0x0055 - * POLY1305 3 0x0057-0x005B - * CHACHAPOLY 2 0x0054-0x0056 - * PLATFORM 1 0x0070-0x0072 - * - * High-level module nr (3 bits - 0x0...-0x7...) - * Name ID Nr of Errors - * PEM 1 9 - * PKCS#12 1 4 (Started from top) - * X509 2 20 - * PKCS5 2 4 (Started from top) - * DHM 3 11 - * PK 3 15 (Started from top) - * RSA 4 11 - * ECP 4 10 (Started from top) - * MD 5 5 - * HKDF 5 1 (Started from top) - * SSL 5 1 (Started from 0x5E80) - * CIPHER 6 8 - * SSL 6 23 (Started from top) - * SSL 7 32 - * - * Module dependent error code (5 bits 0x.00.-0x.F8.) - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Translate a mbed TLS error code into a string representation, - * Result is truncated if necessary and always includes a terminating - * null byte. - * - * \param errnum error code - * \param buffer buffer to place representation in - * \param buflen length of the buffer - */ -void mbedtls_strerror( int errnum, char *buffer, size_t buflen ); - -#ifdef __cplusplus -} -#endif - -#endif /* error.h */ diff --git a/mbedtls/gcm.c b/mbedtls/gcm.c deleted file mode 100644 index 8a812706e..000000000 --- a/mbedtls/gcm.c +++ /dev/null @@ -1,1032 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * NIST SP800-38D compliant GCM implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf - * - * See also: - * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf - * - * We use the algorithm described as Shoup's method with 4-bit tables in - * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_GCM_C) - -#include "mbedtls/gcm.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_AESNI_C) -#include "mbedtls/aesni.h" -#endif - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#include "mbedtls/platform.h" -#if !defined(MBEDTLS_PLATFORM_C) -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#if !defined(MBEDTLS_GCM_ALT) - -/* Parameter validation macros */ -#define GCM_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT ) -#define GCM_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * Initialize a context - */ -void mbedtls_gcm_init( mbedtls_gcm_context *ctx ) -{ - GCM_VALIDATE( ctx != NULL ); - memset( ctx, 0, sizeof( mbedtls_gcm_context ) ); -} - -/* - * Precompute small multiples of H, that is set - * HH[i] || HL[i] = H times i, - * where i is seen as a field element as in [MGV], ie high-order bits - * correspond to low powers of P. The result is stored in the same way, that - * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL - * corresponds to P^127. - */ -static int gcm_gen_table( mbedtls_gcm_context *ctx ) -{ - int ret, i, j; - uint64_t hi, lo; - uint64_t vl, vh; - unsigned char h[16]; - size_t olen = 0; - - memset( h, 0, 16 ); - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) - return( ret ); - - /* pack h as two 64-bits ints, big-endian */ - GET_UINT32_BE( hi, h, 0 ); - GET_UINT32_BE( lo, h, 4 ); - vh = (uint64_t) hi << 32 | lo; - - GET_UINT32_BE( hi, h, 8 ); - GET_UINT32_BE( lo, h, 12 ); - vl = (uint64_t) hi << 32 | lo; - - /* 8 = 1000 corresponds to 1 in GF(2^128) */ - ctx->HL[8] = vl; - ctx->HH[8] = vh; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - /* With CLMUL support, we need only h, not the rest of the table */ - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) - return( 0 ); -#endif - - /* 0 corresponds to 0 in GF(2^128) */ - ctx->HH[0] = 0; - ctx->HL[0] = 0; - - for( i = 4; i > 0; i >>= 1 ) - { - uint32_t T = ( vl & 1 ) * 0xe1000000U; - vl = ( vh << 63 ) | ( vl >> 1 ); - vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32); - - ctx->HL[i] = vl; - ctx->HH[i] = vh; - } - - for( i = 2; i <= 8; i *= 2 ) - { - uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; - vh = *HiH; - vl = *HiL; - for( j = 1; j < i; j++ ) - { - HiH[j] = vh ^ ctx->HH[j]; - HiL[j] = vl ^ ctx->HL[j]; - } - } - - return( 0 ); -} - -int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( key != NULL ); - GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 ); - - cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - if( cipher_info->block_size != 16 ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - mbedtls_cipher_free( &ctx->cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = gcm_gen_table( ctx ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * Shoup's method for multiplication use this table with - * last4[x] = x times P^128 - * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] - */ -static const uint64_t last4[16] = -{ - 0x0000, 0x1c20, 0x3840, 0x2460, - 0x7080, 0x6ca0, 0x48c0, 0x54e0, - 0xe100, 0xfd20, 0xd940, 0xc560, - 0x9180, 0x8da0, 0xa9c0, 0xb5e0 -}; - -/* - * Sets output to x times H using the precomputed tables. - * x and output are seen as elements of GF(2^128) as in [MGV]. - */ -static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], - unsigned char output[16] ) -{ - int i = 0; - unsigned char lo, hi, rem; - uint64_t zh, zl; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) { - unsigned char h[16]; - - PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); - PUT_UINT32_BE( ctx->HH[8], h, 4 ); - PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); - PUT_UINT32_BE( ctx->HL[8], h, 12 ); - - mbedtls_aesni_gcm_mult( output, x, h ); - return; - } -#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */ - - lo = x[15] & 0xf; - - zh = ctx->HH[lo]; - zl = ctx->HL[lo]; - - for( i = 15; i >= 0; i-- ) - { - lo = x[i] & 0xf; - hi = x[i] >> 4; - - if( i != 15 ) - { - rem = (unsigned char) zl & 0xf; - zl = ( zh << 60 ) | ( zl >> 4 ); - zh = ( zh >> 4 ); - zh ^= (uint64_t) last4[rem] << 48; - zh ^= ctx->HH[lo]; - zl ^= ctx->HL[lo]; - - } - - rem = (unsigned char) zl & 0xf; - zl = ( zh << 60 ) | ( zl >> 4 ); - zh = ( zh >> 4 ); - zh ^= (uint64_t) last4[rem] << 48; - zh ^= ctx->HH[hi]; - zl ^= ctx->HL[hi]; - } - - PUT_UINT32_BE( zh >> 32, output, 0 ); - PUT_UINT32_BE( zh, output, 4 ); - PUT_UINT32_BE( zl >> 32, output, 8 ); - PUT_UINT32_BE( zl, output, 12 ); -} - -int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, - int mode, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len ) -{ - int ret; - unsigned char work_buf[16]; - size_t i; - const unsigned char *p; - size_t use_len, olen = 0; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( iv != NULL ); - GCM_VALIDATE_RET( add_len == 0 || add != NULL ); - - /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ - /* IV is not allowed to be zero length */ - if( iv_len == 0 || - ( (uint64_t) iv_len ) >> 61 != 0 || - ( (uint64_t) add_len ) >> 61 != 0 ) - { - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - } - - memset( ctx->y, 0x00, sizeof(ctx->y) ); - memset( ctx->buf, 0x00, sizeof(ctx->buf) ); - - ctx->mode = mode; - ctx->len = 0; - ctx->add_len = 0; - - if( iv_len == 12 ) - { - memcpy( ctx->y, iv, iv_len ); - ctx->y[15] = 1; - } - else - { - memset( work_buf, 0x00, 16 ); - PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); - - p = iv; - while( iv_len > 0 ) - { - use_len = ( iv_len < 16 ) ? iv_len : 16; - - for( i = 0; i < use_len; i++ ) - ctx->y[i] ^= p[i]; - - gcm_mult( ctx, ctx->y, ctx->y ); - - iv_len -= use_len; - p += use_len; - } - - for( i = 0; i < 16; i++ ) - ctx->y[i] ^= work_buf[i]; - - gcm_mult( ctx, ctx->y, ctx->y ); - } - - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, - &olen ) ) != 0 ) - { - return( ret ); - } - - ctx->add_len = add_len; - p = add; - while( add_len > 0 ) - { - use_len = ( add_len < 16 ) ? add_len : 16; - - for( i = 0; i < use_len; i++ ) - ctx->buf[i] ^= p[i]; - - gcm_mult( ctx, ctx->buf, ctx->buf ); - - add_len -= use_len; - p += use_len; - } - - return( 0 ); -} - -int mbedtls_gcm_update( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - unsigned char ectr[16]; - size_t i; - const unsigned char *p; - unsigned char *out_p = output; - size_t use_len, olen = 0; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( length == 0 || input != NULL ); - GCM_VALIDATE_RET( length == 0 || output != NULL ); - - if( output > input && (size_t) ( output - input ) < length ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes - * Also check for possible overflow */ - if( ctx->len + length < ctx->len || - (uint64_t) ctx->len + length > 0xFFFFFFFE0ull ) - { - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - } - - ctx->len += length; - - p = input; - while( length > 0 ) - { - use_len = ( length < 16 ) ? length : 16; - - for( i = 16; i > 12; i-- ) - if( ++ctx->y[i - 1] != 0 ) - break; - - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, - &olen ) ) != 0 ) - { - return( ret ); - } - - for( i = 0; i < use_len; i++ ) - { - if( ctx->mode == MBEDTLS_GCM_DECRYPT ) - ctx->buf[i] ^= p[i]; - out_p[i] = ectr[i] ^ p[i]; - if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) - ctx->buf[i] ^= out_p[i]; - } - - gcm_mult( ctx, ctx->buf, ctx->buf ); - - length -= use_len; - p += use_len; - out_p += use_len; - } - - return( 0 ); -} - -int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, - unsigned char *tag, - size_t tag_len ) -{ - unsigned char work_buf[16]; - size_t i; - uint64_t orig_len; - uint64_t orig_add_len; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( tag != NULL ); - - orig_len = ctx->len * 8; - orig_add_len = ctx->add_len * 8; - - if( tag_len > 16 || tag_len < 4 ) - return( MBEDTLS_ERR_GCM_BAD_INPUT ); - - memcpy( tag, ctx->base_ectr, tag_len ); - - if( orig_len || orig_add_len ) - { - memset( work_buf, 0x00, 16 ); - - PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); - PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); - PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); - PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); - - for( i = 0; i < 16; i++ ) - ctx->buf[i] ^= work_buf[i]; - - gcm_mult( ctx, ctx->buf, ctx->buf ); - - for( i = 0; i < tag_len; i++ ) - tag[i] ^= ctx->buf[i]; - } - - return( 0 ); -} - -int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, - int mode, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *input, - unsigned char *output, - size_t tag_len, - unsigned char *tag ) -{ - int ret; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( iv != NULL ); - GCM_VALIDATE_RET( add_len == 0 || add != NULL ); - GCM_VALIDATE_RET( length == 0 || input != NULL ); - GCM_VALIDATE_RET( length == 0 || output != NULL ); - GCM_VALIDATE_RET( tag != NULL ); - - if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *tag, - size_t tag_len, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - unsigned char check_tag[16]; - size_t i; - int diff; - - GCM_VALIDATE_RET( ctx != NULL ); - GCM_VALIDATE_RET( iv != NULL ); - GCM_VALIDATE_RET( add_len == 0 || add != NULL ); - GCM_VALIDATE_RET( tag != NULL ); - GCM_VALIDATE_RET( length == 0 || input != NULL ); - GCM_VALIDATE_RET( length == 0 || output != NULL ); - - if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length, - iv, iv_len, add, add_len, - input, output, tag_len, check_tag ) ) != 0 ) - { - return( ret ); - } - - /* Check tag in "constant-time" */ - for( diff = 0, i = 0; i < tag_len; i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) - { - mbedtls_platform_zeroize( output, length ); - return( MBEDTLS_ERR_GCM_AUTH_FAILED ); - } - - return( 0 ); -} - -void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) -{ - if( ctx == NULL ) - return; - mbedtls_cipher_free( &ctx->cipher_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); -} - -#endif /* !MBEDTLS_GCM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/* - * AES-GCM test vectors from: - * - * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip - */ -#define MAX_TESTS 6 - -static const int key_index[MAX_TESTS] = - { 0, 0, 1, 1, 1, 1 }; - -static const unsigned char key[MAX_TESTS][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, -}; - -static const size_t iv_len[MAX_TESTS] = - { 12, 12, 12, 12, 8, 60 }; - -static const int iv_index[MAX_TESTS] = - { 0, 0, 1, 1, 1, 2 }; - -static const unsigned char iv[MAX_TESTS][64] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, - 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, - 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, - 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, - 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, - 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, - 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, - 0xa6, 0x37, 0xb3, 0x9b }, -}; - -static const size_t add_len[MAX_TESTS] = - { 0, 0, 0, 20, 20, 20 }; - -static const int add_index[MAX_TESTS] = - { 0, 0, 0, 1, 1, 1 }; - -static const unsigned char additional[MAX_TESTS][64] = -{ - { 0x00 }, - { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xab, 0xad, 0xda, 0xd2 }, -}; - -static const size_t pt_len[MAX_TESTS] = - { 0, 16, 64, 60, 60, 60 }; - -static const int pt_index[MAX_TESTS] = - { 0, 0, 1, 1, 1, 1 }; - -static const unsigned char pt[MAX_TESTS][64] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, -}; - -static const unsigned char ct[MAX_TESTS * 3][64] = -{ - { 0x00 }, - { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, - 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, - { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, - { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91 }, - { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, - 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, - 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, - 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, - 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, - 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, - 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, - 0xc2, 0x3f, 0x45, 0x98 }, - { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, - 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, - 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, - 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, - 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, - 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, - 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, - 0x4c, 0x34, 0xae, 0xe5 }, - { 0x00 }, - { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, - 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, - { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, - { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10 }, - { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, - 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, - 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, - 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, - 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, - 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, - 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, - 0xa0, 0xf0, 0x62, 0xf7 }, - { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, - 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, - 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, - 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, - 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, - 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, - 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, - 0xe9, 0xb7, 0x37, 0x3b }, - { 0x00 }, - { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, - 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, - { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, - { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62 }, - { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, - 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, - 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, - 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, - 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, - 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, - 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, - 0xf4, 0x7c, 0x9b, 0x1f }, - { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, - 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, - 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, - 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, - 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, - 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, - 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, - 0x44, 0xae, 0x7e, 0x3f }, -}; - -static const unsigned char tag[MAX_TESTS * 3][16] = -{ - { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, - 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, - { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, - 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, - { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, - 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, - { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, - 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, - { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, - 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, - { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, - 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, - { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, - 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, - { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, - 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, - { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, - 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, - { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, - 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, - { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, - 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, - { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, - 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, - { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, - 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, - { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, - 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, - { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, - 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, - { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, - 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, - { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, - 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, - { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, - 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, -}; - -int mbedtls_gcm_self_test( int verbose ) -{ - mbedtls_gcm_context ctx; - unsigned char buf[64]; - unsigned char tag_buf[16]; - int i, j, ret; - mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; - - for( j = 0; j < 3; j++ ) - { - int key_len = 128 + 64 * j; - - for( i = 0; i < MAX_TESTS; i++ ) - { - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d (%s): ", - key_len, i, "enc" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], - key_len ); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 ) - { - mbedtls_printf( "skipped\n" ); - break; - } - else if( ret != 0 ) - { - goto exit; - } - - ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, - pt_len[i], - iv[iv_index[i]], iv_len[i], - additional[add_index[i]], add_len[i], - pt[pt_index[i]], buf, 16, tag_buf ); - if( ret != 0 ) - goto exit; - - if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || - memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d (%s): ", - key_len, i, "dec" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], - key_len ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, - pt_len[i], - iv[iv_index[i]], iv_len[i], - additional[add_index[i]], add_len[i], - ct[j * 6 + i], buf, 16, tag_buf ); - - if( ret != 0 ) - goto exit; - - if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || - memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", - key_len, i, "enc" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], - key_len ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, - iv[iv_index[i]], iv_len[i], - additional[add_index[i]], add_len[i] ); - if( ret != 0 ) - goto exit; - - if( pt_len[i] > 32 ) - { - size_t rest_len = pt_len[i] - 32; - ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, - buf + 32 ); - if( ret != 0 ) - goto exit; - } - else - { - ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); - if( ret != 0 ) - goto exit; - } - - ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || - memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - mbedtls_gcm_init( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", - key_len, i, "dec" ); - - ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], - key_len ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, - iv[iv_index[i]], iv_len[i], - additional[add_index[i]], add_len[i] ); - if( ret != 0 ) - goto exit; - - if( pt_len[i] > 32 ) - { - size_t rest_len = pt_len[i] - 32; - ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, - buf + 32 ); - if( ret != 0 ) - goto exit; - } - else - { - ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], - buf ); - if( ret != 0 ) - goto exit; - } - - ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); - if( ret != 0 ) - goto exit; - - if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || - memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) - { - ret = 1; - goto exit; - } - - mbedtls_gcm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - ret = 0; - -exit: - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - mbedtls_gcm_free( &ctx ); - } - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_GCM_C */ diff --git a/mbedtls/gcm.h b/mbedtls/gcm.h deleted file mode 100644 index a9c90a194..000000000 --- a/mbedtls/gcm.h +++ /dev/null @@ -1,352 +0,0 @@ -#pragma GCC system_header -/** - * \file gcm.h - * - * \brief This file contains GCM definitions and functions. - * - * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined - * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation - * (GCM), Natl. Inst. Stand. Technol. - * - * For more information on GCM, see NIST SP 800-38D: Recommendation for - * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_GCM_H -#define MBEDTLS_GCM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "cipher.h" - -#include - -#define MBEDTLS_GCM_ENCRYPT 1 -#define MBEDTLS_GCM_DECRYPT 0 - -#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */ - -/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */ - -#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_GCM_ALT) - -/** - * \brief The GCM context structure. - */ -typedef struct mbedtls_gcm_context -{ - mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ - uint64_t HL[16]; /*!< Precalculated HTable low. */ - uint64_t HH[16]; /*!< Precalculated HTable high. */ - uint64_t len; /*!< The total length of the encrypted data. */ - uint64_t add_len; /*!< The total length of the additional data. */ - unsigned char base_ectr[16]; /*!< The first ECTR for tag. */ - unsigned char y[16]; /*!< The Y working value. */ - unsigned char buf[16]; /*!< The buf working value. */ - int mode; /*!< The operation to perform: - #MBEDTLS_GCM_ENCRYPT or - #MBEDTLS_GCM_DECRYPT. */ -} -mbedtls_gcm_context; - -#else /* !MBEDTLS_GCM_ALT */ -#include "gcm_alt.h" -#endif /* !MBEDTLS_GCM_ALT */ - -/** - * \brief This function initializes the specified GCM context, - * to make references valid, and prepares the context - * for mbedtls_gcm_setkey() or mbedtls_gcm_free(). - * - * The function does not bind the GCM context to a particular - * cipher, nor set the key. For this purpose, use - * mbedtls_gcm_setkey(). - * - * \param ctx The GCM context to initialize. This must not be \c NULL. - */ -void mbedtls_gcm_init( mbedtls_gcm_context *ctx ); - -/** - * \brief This function associates a GCM context with a - * cipher algorithm and a key. - * - * \param ctx The GCM context. This must be initialized. - * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. This must be a readable buffer of at - * least \p keybits bits. - * \param keybits The key size in bits. Valid options are: - *
    • 128 bits
    • - *
    • 192 bits
    • - *
    • 256 bits
    - * - * \return \c 0 on success. - * \return A cipher-specific error code on failure. - */ -int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief This function performs GCM encryption or decryption of a buffer. - * - * \note For encryption, the output buffer can be the same as the - * input buffer. For decryption, the output buffer cannot be - * the same as input buffer. If the buffers overlap, the output - * buffer must trail at least 8 Bytes behind the input buffer. - * - * \warning When this function performs a decryption, it outputs the - * authentication tag and does not verify that the data is - * authentic. You should use this function to perform encryption - * only. For decryption, use mbedtls_gcm_auth_decrypt() instead. - * - * \param ctx The GCM context to use for encryption or decryption. This - * must be initialized. - * \param mode The operation to perform: - * - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption. - * The ciphertext is written to \p output and the - * authentication tag is written to \p tag. - * - #MBEDTLS_GCM_DECRYPT to perform decryption. - * The plaintext is written to \p output and the - * authentication tag is written to \p tag. - * Note that this mode is not recommended, because it does - * not verify the authenticity of the data. For this reason, - * you should use mbedtls_gcm_auth_decrypt() instead of - * calling this function in decryption mode. - * \param length The length of the input data, which is equal to the length - * of the output data. - * \param iv The initialization vector. This must be a readable buffer of - * at least \p iv_len Bytes. - * \param iv_len The length of the IV. - * \param add The buffer holding the additional data. This must be of at - * least that size in Bytes. - * \param add_len The length of the additional data. - * \param input The buffer holding the input data. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size in Bytes. - * \param output The buffer for holding the output data. If \p length is greater - * than zero, this must be a writable buffer of at least that - * size in Bytes. - * \param tag_len The length of the tag to generate. - * \param tag The buffer for holding the tag. This must be a writable - * buffer of at least \p tag_len Bytes. - * - * \return \c 0 if the encryption or decryption was performed - * successfully. Note that in #MBEDTLS_GCM_DECRYPT mode, - * this does not indicate that the data is authentic. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are - * not valid or a cipher-specific error code if the encryption - * or decryption failed. - */ -int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, - int mode, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *input, - unsigned char *output, - size_t tag_len, - unsigned char *tag ); - -/** - * \brief This function performs a GCM authenticated decryption of a - * buffer. - * - * \note For decryption, the output buffer cannot be the same as - * input buffer. If the buffers overlap, the output buffer - * must trail at least 8 Bytes behind the input buffer. - * - * \param ctx The GCM context. This must be initialized. - * \param length The length of the ciphertext to decrypt, which is also - * the length of the decrypted plaintext. - * \param iv The initialization vector. This must be a readable buffer - * of at least \p iv_len Bytes. - * \param iv_len The length of the IV. - * \param add The buffer holding the additional data. This must be of at - * least that size in Bytes. - * \param add_len The length of the additional data. - * \param tag The buffer holding the tag to verify. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to verify. - * \param input The buffer holding the ciphertext. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size. - * \param output The buffer for holding the decrypted plaintext. If \p length - * is greater than zero, this must be a writable buffer of at - * least that size. - * - * \return \c 0 if successful and authenticated. - * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are - * not valid or a cipher-specific error code if the decryption - * failed. - */ -int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *tag, - size_t tag_len, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function starts a GCM encryption or decryption - * operation. - * - * \param ctx The GCM context. This must be initialized. - * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or - * #MBEDTLS_GCM_DECRYPT. - * \param iv The initialization vector. This must be a readable buffer of - * at least \p iv_len Bytes. - * \param iv_len The length of the IV. - * \param add The buffer holding the additional data, or \c NULL - * if \p add_len is \c 0. - * \param add_len The length of the additional data. If \c 0, - * \p add may be \c NULL. - * - * \return \c 0 on success. - */ -int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, - int mode, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len ); - -/** - * \brief This function feeds an input buffer into an ongoing GCM - * encryption or decryption operation. - * - * ` The function expects input to be a multiple of 16 - * Bytes. Only the last call before calling - * mbedtls_gcm_finish() can be less than 16 Bytes. - * - * \note For decryption, the output buffer cannot be the same as - * input buffer. If the buffers overlap, the output buffer - * must trail at least 8 Bytes behind the input buffer. - * - * \param ctx The GCM context. This must be initialized. - * \param length The length of the input data. This must be a multiple of - * 16 except in the last call before mbedtls_gcm_finish(). - * \param input The buffer holding the input data. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size in Bytes. - * \param output The buffer for holding the output data. If \p length is - * greater than zero, this must be a writable buffer of at - * least that size in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. - */ -int mbedtls_gcm_update( mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function finishes the GCM operation and generates - * the authentication tag. - * - * It wraps up the GCM stream, and generates the - * tag. The tag can have a maximum length of 16 Bytes. - * - * \param ctx The GCM context. This must be initialized. - * \param tag The buffer for holding the tag. This must be a writable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to generate. This must be at least - * four. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. - */ -int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, - unsigned char *tag, - size_t tag_len ); - -/** - * \brief This function clears a GCM context and the underlying - * cipher sub-context. - * - * \param ctx The GCM context to clear. If this is \c NULL, the call has - * no effect. Otherwise, this must be initialized. - */ -void mbedtls_gcm_free( mbedtls_gcm_context *ctx ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The GCM checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_gcm_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - - -#endif /* gcm.h */ diff --git a/mbedtls/havege.c b/mbedtls/havege.c deleted file mode 100644 index 8746dbe0d..000000000 --- a/mbedtls/havege.c +++ /dev/null @@ -1,291 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The HAVEGE RNG was designed by Andre Seznec in 2002. - * - * http://www.irisa.fr/caps/projects/hipsor/publi.php - * - * Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_HAVEGE_C) - -#include "mbedtls/havege.h" -#include "mbedtls/timing.h" -#include "mbedtls/platform_util.h" - -#include -#include - -/* If int isn't capable of storing 2^32 distinct values, the code of this - * module may cause a processor trap or a miscalculation. If int is more - * than 32 bits, the code may not calculate the intended values. */ -#if INT_MIN + 1 != -0x7fffffff -#error "The HAVEGE module requires int to be exactly 32 bits, with INT_MIN = -2^31." -#endif -#if UINT_MAX != 0xffffffff -#error "The HAVEGE module requires unsigned to be exactly 32 bits." -#endif - -/* ------------------------------------------------------------------------ - * On average, one iteration accesses two 8-word blocks in the havege WALK - * table, and generates 16 words in the RES array. - * - * The data read in the WALK table is updated and permuted after each use. - * The result of the hardware clock counter read is used for this update. - * - * 25 conditional tests are present. The conditional tests are grouped in - * two nested groups of 12 conditional tests and 1 test that controls the - * permutation; on average, there should be 6 tests executed and 3 of them - * should be mispredicted. - * ------------------------------------------------------------------------ - */ - -#define SWAP(X,Y) { unsigned *T = (X); (X) = (Y); (Y) = T; } - -#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; -#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; - -#define TST1_LEAVE U1++; } -#define TST2_LEAVE U2++; } - -#define ONE_ITERATION \ - \ - PTEST = PT1 >> 20; \ - \ - TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ - TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ - TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ - \ - TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ - TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ - TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ - \ - PTX = (PT1 >> 18) & 7; \ - PT1 &= 0x1FFF; \ - PT2 &= 0x1FFF; \ - CLK = (unsigned) mbedtls_timing_hardclock(); \ - \ - i = 0; \ - A = &WALK[PT1 ]; RES[i++] ^= *A; \ - B = &WALK[PT2 ]; RES[i++] ^= *B; \ - C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \ - D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \ - \ - IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \ - *A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \ - *B = IN ^ U1; \ - *C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \ - *D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \ - \ - A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \ - B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \ - C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \ - D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \ - \ - if( PTEST & 1 ) SWAP( A, C ); \ - \ - IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \ - *A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \ - *B = IN; CLK = (unsigned) mbedtls_timing_hardclock(); \ - *C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \ - *D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \ - \ - A = &WALK[PT1 ^ 4]; \ - B = &WALK[PT2 ^ 1]; \ - \ - PTEST = PT2 >> 1; \ - \ - PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \ - PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \ - PTY = (PT2 >> 10) & 7; \ - \ - TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ - TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ - TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ - \ - TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ - TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ - TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ - \ - C = &WALK[PT1 ^ 5]; \ - D = &WALK[PT2 ^ 5]; \ - \ - RES[i++] ^= *A; \ - RES[i++] ^= *B; \ - RES[i++] ^= *C; \ - RES[i++] ^= *D; \ - \ - IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \ - *A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \ - *B = IN ^ U2; \ - *C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \ - *D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \ - \ - A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \ - B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \ - C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \ - D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \ - \ - IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \ - *A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \ - *B = IN; \ - *C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \ - *D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \ - \ - PT1 = ( RES[( i - 8 ) ^ PTX] ^ \ - WALK[PT1 ^ PTX ^ 7] ) & (~1); \ - PT1 ^= (PT2 ^ 0x10) & 0x10; \ - \ - for( n++, i = 0; i < 16; i++ ) \ - POOL[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i]; - -/* - * Entropy gathering function - */ -static void havege_fill( mbedtls_havege_state *hs ) -{ - unsigned i, n = 0; - unsigned U1, U2, *A, *B, *C, *D; - unsigned PT1, PT2, *WALK, *POOL, RES[16]; - unsigned PTX, PTY, CLK, PTEST, IN; - - WALK = (unsigned *) hs->WALK; - POOL = (unsigned *) hs->pool; - PT1 = hs->PT1; - PT2 = hs->PT2; - - PTX = U1 = 0; - PTY = U2 = 0; - - (void)PTX; - - memset( RES, 0, sizeof( RES ) ); - - while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 ) - { - ONE_ITERATION - ONE_ITERATION - ONE_ITERATION - ONE_ITERATION - } - - hs->PT1 = PT1; - hs->PT2 = PT2; - - hs->offset[0] = 0; - hs->offset[1] = MBEDTLS_HAVEGE_COLLECT_SIZE / 2; -} - -/* - * HAVEGE initialization - */ -void mbedtls_havege_init( mbedtls_havege_state *hs ) -{ - memset( hs, 0, sizeof( mbedtls_havege_state ) ); - - havege_fill( hs ); -} - -void mbedtls_havege_free( mbedtls_havege_state *hs ) -{ - if( hs == NULL ) - return; - - mbedtls_platform_zeroize( hs, sizeof( mbedtls_havege_state ) ); -} - -/* - * HAVEGE rand function - */ -int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len ) -{ - int val; - size_t use_len; - mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng; - unsigned char *p = buf; - - while( len > 0 ) - { - use_len = len; - if( use_len > sizeof(int) ) - use_len = sizeof(int); - - if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE ) - havege_fill( hs ); - - val = hs->pool[hs->offset[0]++]; - val ^= hs->pool[hs->offset[1]++]; - - memcpy( p, &val, use_len ); - - len -= use_len; - p += use_len; - } - - return( 0 ); -} - -#endif /* MBEDTLS_HAVEGE_C */ diff --git a/mbedtls/havege.h b/mbedtls/havege.h deleted file mode 100644 index 09ec5820d..000000000 --- a/mbedtls/havege.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma GCC system_header -/** - * \file havege.h - * - * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_HAVEGE_H -#define MBEDTLS_HAVEGE_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#define MBEDTLS_HAVEGE_COLLECT_SIZE 1024 - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief HAVEGE state structure - */ -typedef struct mbedtls_havege_state -{ - int PT1, PT2, offset[2]; - int pool[MBEDTLS_HAVEGE_COLLECT_SIZE]; - int WALK[8192]; -} -mbedtls_havege_state; - -/** - * \brief HAVEGE initialization - * - * \param hs HAVEGE state to be initialized - */ -void mbedtls_havege_init( mbedtls_havege_state *hs ); - -/** - * \brief Clear HAVEGE state - * - * \param hs HAVEGE state to be cleared - */ -void mbedtls_havege_free( mbedtls_havege_state *hs ); - -/** - * \brief HAVEGE rand function - * - * \param p_rng A HAVEGE state - * \param output Buffer to fill - * \param len Length of buffer - * - * \return 0 - */ -int mbedtls_havege_random( void *p_rng, unsigned char *output, size_t len ); - -#ifdef __cplusplus -} -#endif - -#endif /* havege.h */ diff --git a/mbedtls/hkdf.c b/mbedtls/hkdf.c deleted file mode 100644 index 807510d65..000000000 --- a/mbedtls/hkdf.c +++ /dev/null @@ -1,230 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * HKDF implementation -- RFC 5869 - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_HKDF_C) - -#include -#include "mbedtls/hkdf.h" -#include "mbedtls/platform_util.h" - -int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt, - size_t salt_len, const unsigned char *ikm, size_t ikm_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len ) -{ - int ret; - unsigned char prk[MBEDTLS_MD_MAX_SIZE]; - - ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk ); - - if( ret == 0 ) - { - ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ), - info, info_len, okm, okm_len ); - } - - mbedtls_platform_zeroize( prk, sizeof( prk ) ); - - return( ret ); -} - -int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, - const unsigned char *salt, size_t salt_len, - const unsigned char *ikm, size_t ikm_len, - unsigned char *prk ) -{ - unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' }; - - if( salt == NULL ) - { - size_t hash_len; - - if( salt_len != 0 ) - { - return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; - } - - hash_len = mbedtls_md_get_size( md ); - - if( hash_len == 0 ) - { - return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; - } - - salt = null_salt; - salt_len = hash_len; - } - - return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) ); -} - -int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk, - size_t prk_len, const unsigned char *info, - size_t info_len, unsigned char *okm, size_t okm_len ) -{ - size_t hash_len; - size_t where = 0; - size_t n; - size_t t_len = 0; - size_t i; - int ret = 0; - mbedtls_md_context_t ctx; - unsigned char t[MBEDTLS_MD_MAX_SIZE]; - - if( okm == NULL ) - { - return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); - } - - hash_len = mbedtls_md_get_size( md ); - - if( prk_len < hash_len || hash_len == 0 ) - { - return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); - } - - if( info == NULL ) - { - info = (const unsigned char *) ""; - info_len = 0; - } - - n = okm_len / hash_len; - - if( (okm_len % hash_len) != 0 ) - { - n++; - } - - /* - * Per RFC 5869 Section 2.3, okm_len must not exceed - * 255 times the hash length - */ - if( n > 255 ) - { - return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); - } - - mbedtls_md_init( &ctx ); - - if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 ) - { - goto exit; - } - - /* - * Compute T = T(1) | T(2) | T(3) | ... | T(N) - * Where T(N) is defined in RFC 5869 Section 2.3 - */ - for( i = 1; i <= n; i++ ) - { - size_t num_to_copy; - unsigned char c = i & 0xff; - - ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len ); - if( ret != 0 ) - { - goto exit; - } - - ret = mbedtls_md_hmac_update( &ctx, t, t_len ); - if( ret != 0 ) - { - goto exit; - } - - ret = mbedtls_md_hmac_update( &ctx, info, info_len ); - if( ret != 0 ) - { - goto exit; - } - - /* The constant concatenated to the end of each T(n) is a single octet. - * */ - ret = mbedtls_md_hmac_update( &ctx, &c, 1 ); - if( ret != 0 ) - { - goto exit; - } - - ret = mbedtls_md_hmac_finish( &ctx, t ); - if( ret != 0 ) - { - goto exit; - } - - num_to_copy = i != n ? hash_len : okm_len - where; - memcpy( okm + where, t, num_to_copy ); - where += hash_len; - t_len = hash_len; - } - -exit: - mbedtls_md_free( &ctx ); - mbedtls_platform_zeroize( t, sizeof( t ) ); - - return( ret ); -} - -#endif /* MBEDTLS_HKDF_C */ diff --git a/mbedtls/hkdf.h b/mbedtls/hkdf.h deleted file mode 100644 index 06d99ed46..000000000 --- a/mbedtls/hkdf.h +++ /dev/null @@ -1,167 +0,0 @@ -#pragma GCC system_header -/** - * \file hkdf.h - * - * \brief This file contains the HKDF interface. - * - * The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is - * specified by RFC 5869. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_HKDF_H -#define MBEDTLS_HKDF_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "md.h" - -/** - * \name HKDF Error codes - * \{ - */ -#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */ -/* \} name */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief This is the HMAC-based Extract-and-Expand Key Derivation Function - * (HKDF). - * - * \param md A hash function; md.size denotes the length of the hash - * function output in bytes. - * \param salt An optional salt value (a non-secret random value); - * if the salt is not provided, a string of all zeros of - * md.size length is used as the salt. - * \param salt_len The length in bytes of the optional \p salt. - * \param ikm The input keying material. - * \param ikm_len The length in bytes of \p ikm. - * \param info An optional context and application specific information - * string. This can be a zero-length string. - * \param info_len The length of \p info in bytes. - * \param okm The output keying material of \p okm_len bytes. - * \param okm_len The length of the output keying material in bytes. This - * must be less than or equal to 255 * md.size bytes. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. - * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying - * MD layer. - */ -int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt, - size_t salt_len, const unsigned char *ikm, size_t ikm_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len ); - -/** - * \brief Take the input keying material \p ikm and extract from it a - * fixed-length pseudorandom key \p prk. - * - * \warning This function should only be used if the security of it has been - * studied and established in that particular context (eg. TLS 1.3 - * key schedule). For standard HKDF security guarantees use - * \c mbedtls_hkdf instead. - * - * \param md A hash function; md.size denotes the length of the - * hash function output in bytes. - * \param salt An optional salt value (a non-secret random value); - * if the salt is not provided, a string of all zeros - * of md.size length is used as the salt. - * \param salt_len The length in bytes of the optional \p salt. - * \param ikm The input keying material. - * \param ikm_len The length in bytes of \p ikm. - * \param[out] prk A pseudorandom key of at least md.size bytes. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. - * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying - * MD layer. - */ -int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, - const unsigned char *salt, size_t salt_len, - const unsigned char *ikm, size_t ikm_len, - unsigned char *prk ); - -/** - * \brief Expand the supplied \p prk into several additional pseudorandom - * keys, which is the output of the HKDF. - * - * \warning This function should only be used if the security of it has been - * studied and established in that particular context (eg. TLS 1.3 - * key schedule). For standard HKDF security guarantees use - * \c mbedtls_hkdf instead. - * - * \param md A hash function; md.size denotes the length of the hash - * function output in bytes. - * \param prk A pseudorandom key of at least md.size bytes. \p prk is - * usually the output from the HKDF extract step. - * \param prk_len The length in bytes of \p prk. - * \param info An optional context and application specific information - * string. This can be a zero-length string. - * \param info_len The length of \p info in bytes. - * \param okm The output keying material of \p okm_len bytes. - * \param okm_len The length of the output keying material in bytes. This - * must be less than or equal to 255 * md.size bytes. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. - * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying - * MD layer. - */ -int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk, - size_t prk_len, const unsigned char *info, - size_t info_len, unsigned char *okm, size_t okm_len ); - -#ifdef __cplusplus -} -#endif - -#endif /* hkdf.h */ diff --git a/mbedtls/hmac_drbg.c b/mbedtls/hmac_drbg.c deleted file mode 100644 index 1e8a325f4..000000000 --- a/mbedtls/hmac_drbg.c +++ /dev/null @@ -1,672 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * HMAC_DRBG implementation (NIST SP 800-90) - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * The NIST SP 800-90A DRBGs are described in the following publication. - * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf - * References below are based on rev. 1 (January 2012). - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_HMAC_DRBG_C) - -#include "mbedtls/hmac_drbg.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_SELF_TEST */ -#endif /* MBEDTLS_PLATFORM_C */ - -/* - * HMAC_DRBG context initialization - */ -void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); - - ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; -} - -/* - * HMAC_DRBG update, using optional additional data (10.1.2.2) - */ -int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ) -{ - size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); - unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; - unsigned char sep[1]; - unsigned char K[MBEDTLS_MD_MAX_SIZE]; - int ret = 0; - - for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) - { - /* Step 1 or 4 */ - if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - ctx->V, md_len ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - sep, 1 ) ) != 0 ) - goto exit; - if( rounds == 2 ) - { - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - additional, add_len ) ) != 0 ) - goto exit; - } - if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 ) - goto exit; - - /* Step 2 or 5 */ - if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - ctx->V, md_len ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) - goto exit; - } - -exit: - mbedtls_platform_zeroize( K, sizeof( K ) ); - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, - size_t add_len ) -{ - (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len ); -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/* - * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) - */ -int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t * md_info, - const unsigned char *data, size_t data_len ) -{ - int ret; - - if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif - - /* - * Set initial working state. - * Use the V memory location, which is currently all 0, to initialize the - * MD context with an all-zero key. Then set V to its initial value. - */ - if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, - mbedtls_md_get_size( md_info ) ) ) != 0 ) - return( ret ); - memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) ); - - if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * Internal function used both for seeding and reseeding the DRBG. - * Comments starting with arabic numbers refer to section 10.1.2.4 - * of SP800-90A, while roman numbers refer to section 9.2. - */ -static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t len, - int use_nonce ) -{ - unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; - size_t seedlen = 0; - int ret; - - { - size_t total_entropy_len; - - if( use_nonce == 0 ) - total_entropy_len = ctx->entropy_len; - else - total_entropy_len = ctx->entropy_len * 3 / 2; - - /* III. Check input length */ - if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT || - total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ) - { - return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); - } - } - - memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ); - - /* IV. Gather entropy_len bytes of entropy for the seed */ - if( ( ret = ctx->f_entropy( ctx->p_entropy, - seed, ctx->entropy_len ) ) != 0 ) - { - return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); - } - seedlen += ctx->entropy_len; - - /* For initial seeding, allow adding of nonce generated - * from the entropy source. See Sect 8.6.7 in SP800-90A. */ - if( use_nonce ) - { - /* Note: We don't merge the two calls to f_entropy() in order - * to avoid requesting too much entropy from f_entropy() - * at once. Specifically, if the underlying digest is not - * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which - * is larger than the maximum of 32 Bytes that our own - * entropy source implementation can emit in a single - * call in configurations disabling SHA-512. */ - if( ( ret = ctx->f_entropy( ctx->p_entropy, - seed + seedlen, - ctx->entropy_len / 2 ) ) != 0 ) - { - return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); - } - - seedlen += ctx->entropy_len / 2; - } - - - /* 1. Concatenate entropy and additional data if any */ - if( additional != NULL && len != 0 ) - { - memcpy( seed + seedlen, additional, len ); - seedlen += len; - } - - /* 2. Update state */ - if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 ) - goto exit; - - /* 3. Reset reseed_counter */ - ctx->reseed_counter = 1; - -exit: - /* 4. Done */ - mbedtls_platform_zeroize( seed, seedlen ); - return( ret ); -} - -/* - * HMAC_DRBG reseeding: 10.1.2.4 + 9.2 - */ -int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t len ) -{ - return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) ); -} - -/* - * HMAC_DRBG initialisation (10.1.2.3 + 9.1) - * - * The nonce is not passed as a separate parameter but extracted - * from the entropy source as suggested in 8.6.7. - */ -int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t * md_info, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len ) -{ - int ret; - size_t md_size; - - if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - - /* The mutex is initialized iff the md context is set up. */ -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif - - md_size = mbedtls_md_get_size( md_info ); - - /* - * Set initial working state. - * Use the V memory location, which is currently all 0, to initialize the - * MD context with an all-zero key. Then set V to its initial value. - */ - if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 ) - return( ret ); - memset( ctx->V, 0x01, md_size ); - - ctx->f_entropy = f_entropy; - ctx->p_entropy = p_entropy; - - if( ctx->entropy_len == 0 ) - { - /* - * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by - * each hash function, then according to SP800-90A rev1 10.1 table 2, - * min_entropy_len (in bits) is security_strength. - * - * (This also matches the sizes used in the NIST test vectors.) - */ - ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ - md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ - 32; /* better (256+) -> 256 bits */ - } - - if( ( ret = hmac_drbg_reseed_core( ctx, custom, len, - 1 /* add nonce */ ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Set prediction resistance - */ -void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, - int resistance ) -{ - ctx->prediction_resistance = resistance; -} - -/* - * Set entropy length grabbed for seeding - */ -void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ) -{ - ctx->entropy_len = len; -} - -/* - * Set reseed interval - */ -void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ) -{ - ctx->reseed_interval = interval; -} - -/* - * HMAC_DRBG random function with optional additional data: - * 10.1.2.5 (arabic) + 9.3 (Roman) - */ -int mbedtls_hmac_drbg_random_with_add( void *p_rng, - unsigned char *output, size_t out_len, - const unsigned char *additional, size_t add_len ) -{ - int ret; - mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; - size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); - size_t left = out_len; - unsigned char *out = output; - - /* II. Check request length */ - if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST ) - return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); - - /* III. Check input length */ - if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT ) - return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); - - /* 1. (aka VII and IX) Check reseed counter and PR */ - if( ctx->f_entropy != NULL && /* For no-reseeding instances */ - ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || - ctx->reseed_counter > ctx->reseed_interval ) ) - { - if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) - return( ret ); - - add_len = 0; /* VII.4 */ - } - - /* 2. Use additional data if any */ - if( additional != NULL && add_len != 0 ) - { - if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, - additional, add_len ) ) != 0 ) - goto exit; - } - - /* 3, 4, 5. Generate bytes */ - while( left != 0 ) - { - size_t use_len = left > md_len ? md_len : left; - - if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, - ctx->V, md_len ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) - goto exit; - - memcpy( out, ctx->V, use_len ); - out += use_len; - left -= use_len; - } - - /* 6. Update */ - if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, - additional, add_len ) ) != 0 ) - goto exit; - - /* 7. Update reseed counter */ - ctx->reseed_counter++; - -exit: - /* 8. Done */ - return( ret ); -} - -/* - * HMAC_DRBG random function - */ -int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) -{ - int ret; - mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -/* - * This function resets HMAC_DRBG context to the state immediately - * after initial call of mbedtls_hmac_drbg_init(). - */ -void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_THREADING_C) - /* The mutex is initialized iff the md context is set up. */ - if( ctx->md_ctx.md_info != NULL ) - mbedtls_mutex_free( &ctx->mutex ); -#endif - mbedtls_md_free( &ctx->md_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); - ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; -} - -#if defined(MBEDTLS_FS_IO) -int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) -{ - int ret; - FILE *f; - unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; - - if( ( f = fopen( path, "wb" ) ) == NULL ) - return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); - - if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) - goto exit; - - if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) - { - ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; - goto exit; - } - - ret = 0; - -exit: - fclose( f ); - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - return( ret ); -} - -int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) -{ - int ret = 0; - FILE *f = NULL; - size_t n; - unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; - unsigned char c; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); - - n = fread( buf, 1, sizeof( buf ), f ); - if( fread( &c, 1, 1, f ) != 0 ) - { - ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG; - goto exit; - } - if( n == 0 || ferror( f ) ) - { - ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; - goto exit; - } - fclose( f ); - f = NULL; - - ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n ); - -exit: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - if( f != NULL ) - fclose( f ); - if( ret != 0 ) - return( ret ); - return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) ); -} -#endif /* MBEDTLS_FS_IO */ - - -#if defined(MBEDTLS_SELF_TEST) - -#if !defined(MBEDTLS_SHA1_C) -/* Dummy checkup routine */ -int mbedtls_hmac_drbg_self_test( int verbose ) -{ - (void) verbose; - return( 0 ); -} -#else - -#define OUTPUT_LEN 80 - -/* From a NIST PR=true test vector */ -static const unsigned char entropy_pr[] = { - 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, - 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, - 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, - 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, - 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; -static const unsigned char result_pr[OUTPUT_LEN] = { - 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, - 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, - 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, - 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, - 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, - 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, - 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; - -/* From a NIST PR=false test vector */ -static const unsigned char entropy_nopr[] = { - 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, - 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, - 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, - 0xe9, 0x9d, 0xfe, 0xdf }; -static const unsigned char result_nopr[OUTPUT_LEN] = { - 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, - 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, - 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, - 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, - 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, - 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, - 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; - -/* "Entropy" from buffer */ -static size_t test_offset; -static int hmac_drbg_self_test_entropy( void *data, - unsigned char *buf, size_t len ) -{ - const unsigned char *p = data; - memcpy( buf, p + test_offset, len ); - test_offset += len; - return( 0 ); -} - -#define CHK( c ) if( (c) != 0 ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf( "failed\n" ); \ - return( 1 ); \ - } - -/* - * Checkup routine for HMAC_DRBG with SHA-1 - */ -int mbedtls_hmac_drbg_self_test( int verbose ) -{ - mbedtls_hmac_drbg_context ctx; - unsigned char buf[OUTPUT_LEN]; - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); - - mbedtls_hmac_drbg_init( &ctx ); - - /* - * PR = True - */ - if( verbose != 0 ) - mbedtls_printf( " HMAC_DRBG (PR = True) : " ); - - test_offset = 0; - CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, - hmac_drbg_self_test_entropy, (void *) entropy_pr, - NULL, 0 ) ); - mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); - CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); - CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); - CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); - mbedtls_hmac_drbg_free( &ctx ); - - mbedtls_hmac_drbg_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - /* - * PR = False - */ - if( verbose != 0 ) - mbedtls_printf( " HMAC_DRBG (PR = False) : " ); - - mbedtls_hmac_drbg_init( &ctx ); - - test_offset = 0; - CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, - hmac_drbg_self_test_entropy, (void *) entropy_nopr, - NULL, 0 ) ); - CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) ); - CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); - CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); - CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); - mbedtls_hmac_drbg_free( &ctx ); - - mbedtls_hmac_drbg_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_HMAC_DRBG_C */ diff --git a/mbedtls/hmac_drbg.h b/mbedtls/hmac_drbg.h deleted file mode 100644 index 6f207a8b0..000000000 --- a/mbedtls/hmac_drbg.h +++ /dev/null @@ -1,498 +0,0 @@ -#pragma GCC system_header -/** - * \file hmac_drbg.h - * - * \brief The HMAC_DRBG pseudorandom generator. - * - * This module implements the HMAC_DRBG pseudorandom generator described - * in NIST SP 800-90A: Recommendation for Random Number Generation Using - * Deterministic Random Bit Generators. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_HMAC_DRBG_H -#define MBEDTLS_HMAC_DRBG_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "md.h" - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -/* - * Error codes - */ -#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 /**< Too many random requested in single call. */ -#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 /**< Input too large (Entropy + additional). */ -#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 /**< Read/write error in file. */ -#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 /**< The entropy source failed. */ - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) -#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -#endif - -#if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT) -#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -#endif - -#if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST) -#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -#endif - -#if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) -#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ -#endif - -/* \} name SECTION: Module settings */ - -#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */ -#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * HMAC_DRBG context. - */ -typedef struct mbedtls_hmac_drbg_context -{ - /* Working state: the key K is not stored explicitly, - * but is implied by the HMAC context */ - mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */ - unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */ - int reseed_counter; /*!< reseed counter */ - - /* Administrative state */ - size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */ - int prediction_resistance; /*!< enable prediction resistance (Automatic - reseed before every random generation) */ - int reseed_interval; /*!< reseed interval */ - - /* Callbacks */ - int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */ - void *p_entropy; /*!< context for the entropy function */ - -#if defined(MBEDTLS_THREADING_C) - /* Invariant: the mutex is initialized if and only if - * md_ctx->md_info != NULL. This means that the mutex is initialized - * during the initial seeding in mbedtls_hmac_drbg_seed() or - * mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free(). - * - * Note that this invariant may change without notice. Do not rely on it - * and do not access the mutex directly in application code. - */ - mbedtls_threading_mutex_t mutex; -#endif -} mbedtls_hmac_drbg_context; - -/** - * \brief HMAC_DRBG context initialization. - * - * This function makes the context ready for mbedtls_hmac_drbg_seed(), - * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free(). - * - * \note The reseed interval is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL - * by default. Override this value by calling - * mbedtls_hmac_drbg_set_reseed_interval(). - * - * \param ctx HMAC_DRBG context to be initialized. - */ -void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); - -/** - * \brief HMAC_DRBG initial seeding. - * - * Set the initial seed and set up the entropy source for future reseeds. - * - * A typical choice for the \p f_entropy and \p p_entropy parameters is - * to use the entropy module: - * - \p f_entropy is mbedtls_entropy_func(); - * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized - * with mbedtls_entropy_init() (which registers the platform's default - * entropy sources). - * - * You can provide a personalization string in addition to the - * entropy source, to make this instantiation as unique as possible. - * - * \note By default, the security strength as defined by NIST is: - * - 128 bits if \p md_info is SHA-1; - * - 192 bits if \p md_info is SHA-224; - * - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512. - * Note that SHA-256 is just as efficient as SHA-224. - * The security strength can be reduced if a smaller - * entropy length is set with - * mbedtls_hmac_drbg_set_entropy_len(). - * - * \note The default entropy length is the security strength - * (converted from bits to bytes). You can override - * it by calling mbedtls_hmac_drbg_set_entropy_len(). - * - * \note During the initial seeding, this function calls - * the entropy source to obtain a nonce - * whose length is half the entropy length. - */ -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * after this function returns successfully, - * it is safe to call mbedtls_hmac_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * \param ctx HMAC_DRBG context to be seeded. - * \param md_info MD algorithm to use for HMAC_DRBG. - * \param f_entropy The entropy callback, taking as arguments the - * \p p_entropy context, the buffer to fill, and the - * length of the buffer. - * \p f_entropy is always called with a length that is - * less than or equal to the entropy length. - * \param p_entropy The entropy context to pass to \p f_entropy. - * \param custom The personalization string. - * This can be \c NULL, in which case the personalization - * string is empty regardless of the value of \p len. - * \param len The length of the personalization string. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT - * and also at most - * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2 - * where \p entropy_len is the entropy length - * described above. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is - * invalid. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough - * memory to allocate context data. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if the call to \p f_entropy failed. - */ -int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t * md_info, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len ); - -/** - * \brief Initilisation of simpified HMAC_DRBG (never reseeds). - * - * This function is meant for use in algorithms that need a pseudorandom - * input such as deterministic ECDSA. - */ -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * after this function returns successfully, - * it is safe to call mbedtls_hmac_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * \param ctx HMAC_DRBG context to be initialised. - * \param md_info MD algorithm to use for HMAC_DRBG. - * \param data Concatenation of the initial entropy string and - * the additional data. - * \param data_len Length of \p data in bytes. - * - * \return \c 0 if successful. or - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is - * invalid. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough - * memory to allocate context data. - */ -int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t * md_info, - const unsigned char *data, size_t data_len ); - -/** - * \brief This function turns prediction resistance on or off. - * The default value is off. - * - * \note If enabled, entropy is gathered at the beginning of - * every call to mbedtls_hmac_drbg_random_with_add() - * or mbedtls_hmac_drbg_random(). - * Only use this if your entropy source has sufficient - * throughput. - * - * \param ctx The HMAC_DRBG context. - * \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF. - */ -void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, - int resistance ); - -/** - * \brief This function sets the amount of entropy grabbed on each - * seed or reseed. - * - * See the documentation of mbedtls_hmac_drbg_seed() for the default value. - * - * \param ctx The HMAC_DRBG context. - * \param len The amount of entropy to grab, in bytes. - */ -void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, - size_t len ); - -/** - * \brief Set the reseed interval. - * - * The reseed interval is the number of calls to mbedtls_hmac_drbg_random() - * or mbedtls_hmac_drbg_random_with_add() after which the entropy function - * is called again. - * - * The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL. - * - * \param ctx The HMAC_DRBG context. - * \param interval The reseed interval. - */ -void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, - int interval ); - -/** - * \brief This function updates the state of the HMAC_DRBG context. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param ctx The HMAC_DRBG context. - * \param additional The data to update the state with. - * If this is \c NULL, there is no additional data. - * \param add_len Length of \p additional in bytes. - * Unused if \p additional is \c NULL. - * - * \return \c 0 on success, or an error from the underlying - * hash calculation. - */ -int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t add_len ); - -/** - * \brief This function reseeds the HMAC_DRBG context, that is - * extracts data from the entropy source. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param ctx The HMAC_DRBG context. - * \param additional Additional data to add to the state. - * If this is \c NULL, there is no additional data - * and \p len should be \c 0. - * \param len The length of the additional data. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT - * and also at most - * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len - * where \p entropy_len is the entropy length - * (see mbedtls_hmac_drbg_set_entropy_len()). - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if a call to the entropy function failed. - */ -int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t len ); - -/** - * \brief This function updates an HMAC_DRBG instance with additional - * data and uses it to generate random data. - * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param p_rng The HMAC_DRBG context. This must be a pointer to a - * #mbedtls_hmac_drbg_context structure. - * \param output The buffer to fill. - * \param output_len The length of the buffer in bytes. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - * \param additional Additional data to update with. - * If this is \c NULL, there is no additional data - * and \p add_len should be \c 0. - * \param add_len The length of the additional data. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if a call to the entropy source failed. - * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if - * \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if - * \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT. - */ -int mbedtls_hmac_drbg_random_with_add( void *p_rng, - unsigned char *output, size_t output_len, - const unsigned char *additional, - size_t add_len ); - -/** - * \brief This function uses HMAC_DRBG to generate random data. - * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. - */ -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * it is safe to call mbedtls_ctr_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * \param p_rng The HMAC_DRBG context. This must be a pointer to a - * #mbedtls_hmac_drbg_context structure. - * \param output The buffer to fill. - * \param out_len The length of the buffer in bytes. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if a call to the entropy source failed. - * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if - * \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - */ -int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); - -/** - * \brief This function resets HMAC_DRBG context to the state immediately - * after initial call of mbedtls_hmac_drbg_init(). - * - * \param ctx The HMAC_DRBG context to free. - */ -void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); - -#if ! defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function updates the state of the HMAC_DRBG context. - * - * \disabled_deprecated Superseded by mbedtls_hmac_drbg_update_ret() - * in 2.16.0. - * - * \param ctx The HMAC_DRBG context. - * \param additional The data to update the state with. - * If this is \c NULL, there is no additional data. - * \param add_len Length of \p additional in bytes. - * Unused if \p additional is \c NULL. - */ -MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( - mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t add_len ); -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_FS_IO) -/** - * \brief This function writes a seed file. - * - * \param ctx The HMAC_DRBG context. - * \param path The name of the file. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed - * failure. - */ -int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); - -/** - * \brief This function reads and updates a seed file. The seed - * is added to this instance. - * - * \param ctx The HMAC_DRBG context. - * \param path The name of the file. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on - * reseed failure. - * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing - * seed file is too large. - */ -int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); -#endif /* MBEDTLS_FS_IO */ - - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The HMAC_DRBG Checkup routine. - * - * \return \c 0 if successful. - * \return \c 1 if the test failed. - */ -int mbedtls_hmac_drbg_self_test( int verbose ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* hmac_drbg.h */ diff --git a/mbedtls/md.c b/mbedtls/md.c deleted file mode 100644 index 508dd6dce..000000000 --- a/mbedtls/md.c +++ /dev/null @@ -1,513 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file mbedtls_md.c - * - * \brief Generic message digest wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD_C) - -#include "mbedtls/md.h" -#include "mbedtls/md_internal.h" -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -/* - * Reminder: update profiles in x509_crt.c when adding a new hash! - */ -static const int supported_digests[] = { - -#if defined(MBEDTLS_SHA512_C) - MBEDTLS_MD_SHA512, - MBEDTLS_MD_SHA384, -#endif - -#if defined(MBEDTLS_SHA256_C) - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA224, -#endif - -#if defined(MBEDTLS_SHA1_C) - MBEDTLS_MD_SHA1, -#endif - -#if defined(MBEDTLS_RIPEMD160_C) - MBEDTLS_MD_RIPEMD160, -#endif - -#if defined(MBEDTLS_MD5_C) - MBEDTLS_MD_MD5, -#endif - -#if defined(MBEDTLS_MD4_C) - MBEDTLS_MD_MD4, -#endif - -#if defined(MBEDTLS_MD2_C) - MBEDTLS_MD_MD2, -#endif - - MBEDTLS_MD_NONE -}; - -const int *mbedtls_md_list( void ) -{ - return( supported_digests ); -} - -const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) -{ - if( NULL == md_name ) - return( NULL ); - - /* Get the appropriate digest information */ -#if defined(MBEDTLS_MD2_C) - if( !strcmp( "MD2", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); -#endif -#if defined(MBEDTLS_MD4_C) - if( !strcmp( "MD4", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); -#endif -#if defined(MBEDTLS_MD5_C) - if( !strcmp( "MD5", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); -#endif -#if defined(MBEDTLS_RIPEMD160_C) - if( !strcmp( "RIPEMD160", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); -#endif -#if defined(MBEDTLS_SHA1_C) - if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); -#endif -#if defined(MBEDTLS_SHA256_C) - if( !strcmp( "SHA224", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); - if( !strcmp( "SHA256", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); -#endif -#if defined(MBEDTLS_SHA512_C) - if( !strcmp( "SHA384", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); - if( !strcmp( "SHA512", md_name ) ) - return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); -#endif - return( NULL ); -} - -const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) -{ - switch( md_type ) - { -#if defined(MBEDTLS_MD2_C) - case MBEDTLS_MD_MD2: - return( &mbedtls_md2_info ); -#endif -#if defined(MBEDTLS_MD4_C) - case MBEDTLS_MD_MD4: - return( &mbedtls_md4_info ); -#endif -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - return( &mbedtls_md5_info ); -#endif -#if defined(MBEDTLS_RIPEMD160_C) - case MBEDTLS_MD_RIPEMD160: - return( &mbedtls_ripemd160_info ); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - return( &mbedtls_sha1_info ); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA224: - return( &mbedtls_sha224_info ); - case MBEDTLS_MD_SHA256: - return( &mbedtls_sha256_info ); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA384: - return( &mbedtls_sha384_info ); - case MBEDTLS_MD_SHA512: - return( &mbedtls_sha512_info ); -#endif - default: - return( NULL ); - } -} - -void mbedtls_md_init( mbedtls_md_context_t *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); -} - -void mbedtls_md_free( mbedtls_md_context_t *ctx ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return; - - if( ctx->md_ctx != NULL ) - ctx->md_info->ctx_free_func( ctx->md_ctx ); - - if( ctx->hmac_ctx != NULL ) - { - mbedtls_platform_zeroize( ctx->hmac_ctx, - 2 * ctx->md_info->block_size ); - mbedtls_free( ctx->hmac_ctx ); - } - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); -} - -int mbedtls_md_clone( mbedtls_md_context_t *dst, - const mbedtls_md_context_t *src ) -{ - if( dst == NULL || dst->md_info == NULL || - src == NULL || src->md_info == NULL || - dst->md_info != src->md_info ) - { - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - } - - dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); - - return( 0 ); -} - -#if ! defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) -{ - return mbedtls_md_setup( ctx, md_info, 1 ); -} -#endif - -int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) -{ - if( md_info == NULL || ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_MD_ALLOC_FAILED ); - - if( hmac != 0 ) - { - ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); - if( ctx->hmac_ctx == NULL ) - { - md_info->ctx_free_func( ctx->md_ctx ); - return( MBEDTLS_ERR_MD_ALLOC_FAILED ); - } - } - - ctx->md_info = md_info; - - return( 0 ); -} - -int mbedtls_md_starts( mbedtls_md_context_t *ctx ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->starts_func( ctx->md_ctx ) ); -} - -int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); -} - -int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); -} - -int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - if( md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( md_info->digest_func( input, ilen, output ) ); -} - -#if defined(MBEDTLS_FS_IO) -int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) -{ - int ret; - FILE *f; - size_t n; - mbedtls_md_context_t ctx; - unsigned char buf[1024]; - - if( md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); - - mbedtls_md_init( &ctx ); - - if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) - goto cleanup; - - if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) - goto cleanup; - - while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) - goto cleanup; - - if( ferror( f ) != 0 ) - ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; - else - ret = md_info->finish_func( ctx.md_ctx, output ); - -cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - fclose( f ); - mbedtls_md_free( &ctx ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) -{ - int ret; - unsigned char sum[MBEDTLS_MD_MAX_SIZE]; - unsigned char *ipad, *opad; - size_t i; - - if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - if( keylen > (size_t) ctx->md_info->block_size ) - { - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) - goto cleanup; - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 ) - goto cleanup; - if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 ) - goto cleanup; - - keylen = ctx->md_info->size; - key = sum; - } - - ipad = (unsigned char *) ctx->hmac_ctx; - opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; - - memset( ipad, 0x36, ctx->md_info->block_size ); - memset( opad, 0x5C, ctx->md_info->block_size ); - - for( i = 0; i < keylen; i++ ) - { - ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); - opad[i] = (unsigned char)( opad[i] ^ key[i] ); - } - - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) - goto cleanup; - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, - ctx->md_info->block_size ) ) != 0 ) - goto cleanup; - -cleanup: - mbedtls_platform_zeroize( sum, sizeof( sum ) ); - - return( ret ); -} - -int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) -{ - if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); -} - -int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) -{ - int ret; - unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; - unsigned char *opad; - - if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; - - if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) - return( ret ); - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) - return( ret ); - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, - ctx->md_info->block_size ) ) != 0 ) - return( ret ); - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, - ctx->md_info->size ) ) != 0 ) - return( ret ); - return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); -} - -int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) -{ - int ret; - unsigned char *ipad; - - if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - ipad = (unsigned char *) ctx->hmac_ctx; - - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) - return( ret ); - return( ctx->md_info->update_func( ctx->md_ctx, ipad, - ctx->md_info->block_size ) ); -} - -int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, - const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - mbedtls_md_context_t ctx; - int ret; - - if( md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - mbedtls_md_init( &ctx ); - - if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) - goto cleanup; - - if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 ) - goto cleanup; - if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 ) - goto cleanup; - if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 ) - goto cleanup; - -cleanup: - mbedtls_md_free( &ctx ); - - return( ret ); -} - -int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) -{ - if( ctx == NULL || ctx->md_info == NULL ) - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - - return( ctx->md_info->process_func( ctx->md_ctx, data ) ); -} - -unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) -{ - if( md_info == NULL ) - return( 0 ); - - return md_info->size; -} - -mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) -{ - if( md_info == NULL ) - return( MBEDTLS_MD_NONE ); - - return md_info->type; -} - -const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) -{ - if( md_info == NULL ) - return( NULL ); - - return md_info->name; -} - -#endif /* MBEDTLS_MD_C */ diff --git a/mbedtls/md.h b/mbedtls/md.h deleted file mode 100644 index b2fdd99c2..000000000 --- a/mbedtls/md.h +++ /dev/null @@ -1,496 +0,0 @@ -#pragma GCC system_header - /** - * \file md.h - * - * \brief This file contains the generic message-digest wrapper. - * - * \author Adriaan de Jong - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_MD_H -#define MBEDTLS_MD_H - -#include - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */ -#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */ -#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */ - -/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Supported message digests. - * - * \warning MD2, MD4, MD5 and SHA-1 are considered weak message digests and - * their use constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -typedef enum { - MBEDTLS_MD_NONE=0, /**< None. */ - MBEDTLS_MD_MD2, /**< The MD2 message digest. */ - MBEDTLS_MD_MD4, /**< The MD4 message digest. */ - MBEDTLS_MD_MD5, /**< The MD5 message digest. */ - MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */ - MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */ - MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */ - MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */ - MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */ - MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */ -} mbedtls_md_type_t; - -#if defined(MBEDTLS_SHA512_C) -#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */ -#else -#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */ -#endif - -/** - * Opaque struct defined in md_internal.h. - */ -typedef struct mbedtls_md_info_t mbedtls_md_info_t; - -/** - * The generic message-digest context. - */ -typedef struct mbedtls_md_context_t -{ - /** Information about the associated message digest. */ - const mbedtls_md_info_t *md_info; - - /** The digest-specific context. */ - void *md_ctx; - - /** The HMAC part of the context. */ - void *hmac_ctx; -} mbedtls_md_context_t; - -/** - * \brief This function returns the list of digests supported by the - * generic digest module. - * - * \note The list starts with the strongest available hashes. - * - * \return A statically allocated array of digests. Each element - * in the returned list is an integer belonging to the - * message-digest enumeration #mbedtls_md_type_t. - * The last entry is 0. - */ -const int *mbedtls_md_list( void ); - -/** - * \brief This function returns the message-digest information - * associated with the given digest name. - * - * \param md_name The name of the digest to search for. - * - * \return The message-digest information associated with \p md_name. - * \return NULL if the associated message-digest information is not found. - */ -const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ); - -/** - * \brief This function returns the message-digest information - * associated with the given digest type. - * - * \param md_type The type of digest to search for. - * - * \return The message-digest information associated with \p md_type. - * \return NULL if the associated message-digest information is not found. - */ -const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ); - -/** - * \brief This function initializes a message-digest context without - * binding it to a particular message-digest algorithm. - * - * This function should always be called first. It prepares the - * context for mbedtls_md_setup() for binding it to a - * message-digest algorithm. - */ -void mbedtls_md_init( mbedtls_md_context_t *ctx ); - -/** - * \brief This function clears the internal structure of \p ctx and - * frees any embedded internal structure, but does not free - * \p ctx itself. - * - * If you have called mbedtls_md_setup() on \p ctx, you must - * call mbedtls_md_free() when you are no longer using the - * context. - * Calling this function if you have previously - * called mbedtls_md_init() and nothing else is optional. - * You must not call this function if you have not called - * mbedtls_md_init(). - */ -void mbedtls_md_free( mbedtls_md_context_t *ctx ); - -#if ! defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function selects the message digest algorithm to use, - * and allocates internal structures. - * - * It should be called after mbedtls_md_init() or mbedtls_md_free(). - * Makes it necessary to call mbedtls_md_free() later. - * - * \disabled_deprecated Superseded by mbedtls_md_setup() in 2.0.0 - * - * \param ctx The context to set up. - * \param md_info The information structure of the message-digest algorithm - * to use. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. - */ -int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED; -#undef MBEDTLS_DEPRECATED -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief This function selects the message digest algorithm to use, - * and allocates internal structures. - * - * It should be called after mbedtls_md_init() or - * mbedtls_md_free(). Makes it necessary to call - * mbedtls_md_free() later. - * - * \param ctx The context to set up. - * \param md_info The information structure of the message-digest algorithm - * to use. - * \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory), - * or non-zero: HMAC is used with this context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. - */ -int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ); - -/** - * \brief This function clones the state of an message-digest - * context. - * - * \note You must call mbedtls_md_setup() on \c dst before calling - * this function. - * - * \note The two contexts must have the same type, - * for example, both are SHA-256. - * - * \warning This function clones the message-digest state, not the - * HMAC state. - * - * \param dst The destination context. - * \param src The context to be cloned. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure. - */ -int mbedtls_md_clone( mbedtls_md_context_t *dst, - const mbedtls_md_context_t *src ); - -/** - * \brief This function extracts the message-digest size from the - * message-digest information structure. - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * - * \return The size of the message-digest output in Bytes. - */ -unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ); - -/** - * \brief This function extracts the message-digest type from the - * message-digest information structure. - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * - * \return The type of the message digest. - */ -mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ); - -/** - * \brief This function extracts the message-digest name from the - * message-digest information structure. - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * - * \return The name of the message digest. - */ -const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ); - -/** - * \brief This function starts a message-digest computation. - * - * You must call this function after setting up the context - * with mbedtls_md_setup(), and before passing data with - * mbedtls_md_update(). - * - * \param ctx The generic message-digest context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -int mbedtls_md_starts( mbedtls_md_context_t *ctx ); - -/** - * \brief This function feeds an input buffer into an ongoing - * message-digest computation. - * - * You must call mbedtls_md_starts() before calling this - * function. You may call this function multiple times. - * Afterwards, call mbedtls_md_finish(). - * - * \param ctx The generic message-digest context. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ); - -/** - * \brief This function finishes the digest operation, - * and writes the result to the output buffer. - * - * Call this function after a call to mbedtls_md_starts(), - * followed by any number of calls to mbedtls_md_update(). - * Afterwards, you may either clear the context with - * mbedtls_md_free(), or call mbedtls_md_starts() to reuse - * the context for another digest operation with the same - * algorithm. - * - * \param ctx The generic message-digest context. - * \param output The buffer for the generic message-digest checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ); - -/** - * \brief This function calculates the message-digest of a buffer, - * with respect to a configurable message-digest algorithm - * in a single call. - * - * The result is calculated as - * Output = message_digest(input buffer). - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * \param input The buffer holding the data. - * \param ilen The length of the input data. - * \param output The generic message-digest checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, - unsigned char *output ); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief This function calculates the message-digest checksum - * result of the contents of the provided file. - * - * The result is calculated as - * Output = message_digest(file contents). - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * \param path The input file name. - * \param output The generic message-digest checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing - * the file pointed by \p path. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL. - */ -int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, - unsigned char *output ); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief This function sets the HMAC key and prepares to - * authenticate a new message. - * - * Call this function after mbedtls_md_setup(), to use - * the MD context for an HMAC calculation, then call - * mbedtls_md_hmac_update() to provide the input data, and - * mbedtls_md_hmac_finish() to get the HMAC value. - * - * \param ctx The message digest context containing an embedded HMAC - * context. - * \param key The HMAC secret key. - * \param keylen The length of the HMAC key in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, - size_t keylen ); - -/** - * \brief This function feeds an input buffer into an ongoing HMAC - * computation. - * - * Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset() - * before calling this function. - * You may call this function multiple times to pass the - * input piecewise. - * Afterwards, call mbedtls_md_hmac_finish(). - * - * \param ctx The message digest context containing an embedded HMAC - * context. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, - size_t ilen ); - -/** - * \brief This function finishes the HMAC operation, and writes - * the result to the output buffer. - * - * Call this function after mbedtls_md_hmac_starts() and - * mbedtls_md_hmac_update() to get the HMAC value. Afterwards - * you may either call mbedtls_md_free() to clear the context, - * or call mbedtls_md_hmac_reset() to reuse the context with - * the same HMAC key. - * - * \param ctx The message digest context containing an embedded HMAC - * context. - * \param output The generic HMAC checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output); - -/** - * \brief This function prepares to authenticate a new message with - * the same key as the previous HMAC operation. - * - * You may call this function after mbedtls_md_hmac_finish(). - * Afterwards call mbedtls_md_hmac_update() to pass the new - * input. - * - * \param ctx The message digest context containing an embedded HMAC - * context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ); - -/** - * \brief This function calculates the full generic HMAC - * on the input buffer with the provided key. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The HMAC result is calculated as - * output = generic HMAC(hmac key, input buffer). - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * \param key The HMAC secret key. - * \param keylen The length of the HMAC secret key in Bytes. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * \param output The generic HMAC result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output ); - -/* Internal use */ -int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_MD_H */ diff --git a/mbedtls/md2.c b/mbedtls/md2.c deleted file mode 100644 index 0722106ca..000000000 --- a/mbedtls/md2.c +++ /dev/null @@ -1,404 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * RFC 1115/1319 compliant MD2 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The MD2 algorithm was designed by Ron Rivest in 1989. - * - * http://www.ietf.org/rfc/rfc1115.txt - * http://www.ietf.org/rfc/rfc1319.txt - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD2_C) - -#include "mbedtls/md2.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_MD2_ALT) - -static const unsigned char PI_SUBST[256] = -{ - 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, - 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, - 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, - 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, - 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E, - 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, - 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, - 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, - 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, - 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3, - 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, - 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, - 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, - 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, - 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, - 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, - 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, - 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, - 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, - 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, - 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, - 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, - 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, - 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, - 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, - 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 -}; - -void mbedtls_md2_init( mbedtls_md2_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_md2_context ) ); -} - -void mbedtls_md2_free( mbedtls_md2_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md2_context ) ); -} - -void mbedtls_md2_clone( mbedtls_md2_context *dst, - const mbedtls_md2_context *src ) -{ - *dst = *src; -} - -/* - * MD2 context setup - */ -int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx ) -{ - memset( ctx->cksum, 0, 16 ); - memset( ctx->state, 0, 46 ); - memset( ctx->buffer, 0, 16 ); - ctx->left = 0; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2_starts( mbedtls_md2_context *ctx ) -{ - mbedtls_md2_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_MD2_PROCESS_ALT) -int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ) -{ - int i, j; - unsigned char t = 0; - - for( i = 0; i < 16; i++ ) - { - ctx->state[i + 16] = ctx->buffer[i]; - ctx->state[i + 32] = - (unsigned char)( ctx->buffer[i] ^ ctx->state[i]); - } - - for( i = 0; i < 18; i++ ) - { - for( j = 0; j < 48; j++ ) - { - ctx->state[j] = (unsigned char) - ( ctx->state[j] ^ PI_SUBST[t] ); - t = ctx->state[j]; - } - - t = (unsigned char)( t + i ); - } - - t = ctx->cksum[15]; - - for( i = 0; i < 16; i++ ) - { - ctx->cksum[i] = (unsigned char) - ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] ); - t = ctx->cksum[i]; - } - - /* Zeroise variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize( &t, sizeof( t ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2_process( mbedtls_md2_context *ctx ) -{ - mbedtls_internal_md2_process( ctx ); -} -#endif -#endif /* !MBEDTLS_MD2_PROCESS_ALT */ - -/* - * MD2 process buffer - */ -int mbedtls_md2_update_ret( mbedtls_md2_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - - while( ilen > 0 ) - { - if( ilen > 16 - ctx->left ) - fill = 16 - ctx->left; - else - fill = ilen; - - memcpy( ctx->buffer + ctx->left, input, fill ); - - ctx->left += fill; - input += fill; - ilen -= fill; - - if( ctx->left == 16 ) - { - ctx->left = 0; - if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) - return( ret ); - } - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2_update( mbedtls_md2_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md2_update_ret( ctx, input, ilen ); -} -#endif - -/* - * MD2 final digest - */ -int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx, - unsigned char output[16] ) -{ - int ret; - size_t i; - unsigned char x; - - x = (unsigned char)( 16 - ctx->left ); - - for( i = ctx->left; i < 16; i++ ) - ctx->buffer[i] = x; - - if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) - return( ret ); - - memcpy( ctx->buffer, ctx->cksum, 16 ); - if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) - return( ret ); - - memcpy( output, ctx->state, 16 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2_finish( mbedtls_md2_context *ctx, - unsigned char output[16] ) -{ - mbedtls_md2_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_MD2_ALT */ - -/* - * output = MD2( input buffer ) - */ -int mbedtls_md2_ret( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - int ret; - mbedtls_md2_context ctx; - - mbedtls_md2_init( &ctx ); - - if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_md2_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md2( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - mbedtls_md2_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) - -/* - * RFC 1319 test vectors - */ -static const unsigned char md2_test_str[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" } -}; - -static const size_t md2_test_strlen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md2_test_sum[7][16] = -{ - { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D, - 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 }, - { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72, - 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 }, - { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B, - 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB }, - { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B, - 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 }, - { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB, - 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B }, - { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39, - 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD }, - { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D, - 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 } -}; - -/* - * Checkup routine - */ -int mbedtls_md2_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char md2sum[16]; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " MD2 test #%d: ", i + 1 ); - - ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum ); - if( ret != 0 ) - goto fail; - - if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MD2_C */ diff --git a/mbedtls/md2.h b/mbedtls/md2.h deleted file mode 100644 index 8d6c9e3c4..000000000 --- a/mbedtls/md2.h +++ /dev/null @@ -1,332 +0,0 @@ -#pragma GCC system_header -/** - * \file md2.h - * - * \brief MD2 message digest algorithm (hash function) - * - * \warning MD2 is considered a weak message digest and its use constitutes a - * security risk. We recommend considering stronger message digests - * instead. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - * - */ -#ifndef MBEDTLS_MD2_H -#define MBEDTLS_MD2_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -/* MBEDTLS_ERR_MD2_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED -0x002B /**< MD2 hardware accelerator failed */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_MD2_ALT) -// Regular implementation -// - -/** - * \brief MD2 context structure - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -typedef struct mbedtls_md2_context -{ - unsigned char cksum[16]; /*!< checksum of the data block */ - unsigned char state[48]; /*!< intermediate digest state */ - unsigned char buffer[16]; /*!< data block being processed */ - size_t left; /*!< amount of data in buffer */ -} -mbedtls_md2_context; - -#else /* MBEDTLS_MD2_ALT */ -#include "md2_alt.h" -#endif /* MBEDTLS_MD2_ALT */ - -/** - * \brief Initialize MD2 context - * - * \param ctx MD2 context to be initialized - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md2_init( mbedtls_md2_context *ctx ); - -/** - * \brief Clear MD2 context - * - * \param ctx MD2 context to be cleared - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md2_free( mbedtls_md2_context *ctx ); - -/** - * \brief Clone (the state of) an MD2 context - * - * \param dst The destination context - * \param src The context to be cloned - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md2_clone( mbedtls_md2_context *dst, - const mbedtls_md2_context *src ); - -/** - * \brief MD2 context setup - * - * \param ctx context to be initialized - * - * \return 0 if successful - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx ); - -/** - * \brief MD2 process buffer - * - * \param ctx MD2 context - * \param input buffer holding the data - * \param ilen length of the input data - * - * \return 0 if successful - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md2_update_ret( mbedtls_md2_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief MD2 final digest - * - * \param ctx MD2 context - * \param output MD2 checksum result - * - * \return 0 if successful - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx, - unsigned char output[16] ); - -/** - * \brief MD2 process data block (internal use only) - * - * \param ctx MD2 context - * - * \return 0 if successful - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief MD2 context setup - * - * \disabled_deprecated Superseded by mbedtls_md2_starts_ret() in 2.7.0 - * - * \param ctx context to be initialized - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md2_starts( mbedtls_md2_context *ctx ); - -/** - * \brief MD2 process buffer - * - * \disabled_deprecated Superseded by mbedtls_md2_update_ret() in 2.7.0 - * - * \param ctx MD2 context - * \param input buffer holding the data - * \param ilen length of the input data - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md2_update( mbedtls_md2_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief MD2 final digest - * - * \disabled_deprecated Superseded by mbedtls_md2_finish_ret() in 2.7.0 - * - * \param ctx MD2 context - * \param output MD2 checksum result - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md2_finish( mbedtls_md2_context *ctx, - unsigned char output[16] ); - -/** - * \brief MD2 process data block (internal use only) - * - * \disabled_deprecated Superseded by mbedtls_internal_md2_process() in 2.7.0 - * - * \param ctx MD2 context - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Output = MD2( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD2 checksum result - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md2_ret( const unsigned char *input, - size_t ilen, - unsigned char output[16] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief Output = MD2( input buffer ) - * - * \disabled_deprecated Superseded by mbedtls_md2_ret() in 2.7.0 - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD2 checksum result - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input, - size_t ilen, - unsigned char output[16] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - * - * \warning MD2 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md2_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_md2.h */ diff --git a/mbedtls/md4.c b/mbedtls/md4.c deleted file mode 100644 index 8e018b803..000000000 --- a/mbedtls/md4.c +++ /dev/null @@ -1,528 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * RFC 1186/1320 compliant MD4 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The MD4 algorithm was designed by Ron Rivest in 1990. - * - * http://www.ietf.org/rfc/rfc1186.txt - * http://www.ietf.org/rfc/rfc1320.txt - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD4_C) - -#include "mbedtls/md4.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_MD4_ALT) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -void mbedtls_md4_init( mbedtls_md4_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_md4_context ) ); -} - -void mbedtls_md4_free( mbedtls_md4_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) ); -} - -void mbedtls_md4_clone( mbedtls_md4_context *dst, - const mbedtls_md4_context *src ) -{ - *dst = *src; -} - -/* - * MD4 context setup - */ -int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4_starts( mbedtls_md4_context *ctx ) -{ - mbedtls_md4_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_MD4_PROCESS_ALT) -int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, - const unsigned char data[64] ) -{ - struct - { - uint32_t X[16], A, B, C, D; - } local; - - GET_UINT32_LE( local.X[ 0], data, 0 ); - GET_UINT32_LE( local.X[ 1], data, 4 ); - GET_UINT32_LE( local.X[ 2], data, 8 ); - GET_UINT32_LE( local.X[ 3], data, 12 ); - GET_UINT32_LE( local.X[ 4], data, 16 ); - GET_UINT32_LE( local.X[ 5], data, 20 ); - GET_UINT32_LE( local.X[ 6], data, 24 ); - GET_UINT32_LE( local.X[ 7], data, 28 ); - GET_UINT32_LE( local.X[ 8], data, 32 ); - GET_UINT32_LE( local.X[ 9], data, 36 ); - GET_UINT32_LE( local.X[10], data, 40 ); - GET_UINT32_LE( local.X[11], data, 44 ); - GET_UINT32_LE( local.X[12], data, 48 ); - GET_UINT32_LE( local.X[13], data, 52 ); - GET_UINT32_LE( local.X[14], data, 56 ); - GET_UINT32_LE( local.X[15], data, 60 ); - -#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) - - local.A = ctx->state[0]; - local.B = ctx->state[1]; - local.C = ctx->state[2]; - local.D = ctx->state[3]; - -#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z))) -#define P(a,b,c,d,x,s) \ - do \ - { \ - (a) += F((b),(c),(d)) + (x); \ - (a) = S((a),(s)); \ - } while( 0 ) - - - P( local.A, local.B, local.C, local.D, local.X[ 0], 3 ); - P( local.D, local.A, local.B, local.C, local.X[ 1], 7 ); - P( local.C, local.D, local.A, local.B, local.X[ 2], 11 ); - P( local.B, local.C, local.D, local.A, local.X[ 3], 19 ); - P( local.A, local.B, local.C, local.D, local.X[ 4], 3 ); - P( local.D, local.A, local.B, local.C, local.X[ 5], 7 ); - P( local.C, local.D, local.A, local.B, local.X[ 6], 11 ); - P( local.B, local.C, local.D, local.A, local.X[ 7], 19 ); - P( local.A, local.B, local.C, local.D, local.X[ 8], 3 ); - P( local.D, local.A, local.B, local.C, local.X[ 9], 7 ); - P( local.C, local.D, local.A, local.B, local.X[10], 11 ); - P( local.B, local.C, local.D, local.A, local.X[11], 19 ); - P( local.A, local.B, local.C, local.D, local.X[12], 3 ); - P( local.D, local.A, local.B, local.C, local.X[13], 7 ); - P( local.C, local.D, local.A, local.B, local.X[14], 11 ); - P( local.B, local.C, local.D, local.A, local.X[15], 19 ); - -#undef P -#undef F - -#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) -#define P(a,b,c,d,x,s) \ - do \ - { \ - (a) += F((b),(c),(d)) + (x) + 0x5A827999; \ - (a) = S((a),(s)); \ - } while( 0 ) - - P( local.A, local.B, local.C, local.D, local.X[ 0], 3 ); - P( local.D, local.A, local.B, local.C, local.X[ 4], 5 ); - P( local.C, local.D, local.A, local.B, local.X[ 8], 9 ); - P( local.B, local.C, local.D, local.A, local.X[12], 13 ); - P( local.A, local.B, local.C, local.D, local.X[ 1], 3 ); - P( local.D, local.A, local.B, local.C, local.X[ 5], 5 ); - P( local.C, local.D, local.A, local.B, local.X[ 9], 9 ); - P( local.B, local.C, local.D, local.A, local.X[13], 13 ); - P( local.A, local.B, local.C, local.D, local.X[ 2], 3 ); - P( local.D, local.A, local.B, local.C, local.X[ 6], 5 ); - P( local.C, local.D, local.A, local.B, local.X[10], 9 ); - P( local.B, local.C, local.D, local.A, local.X[14], 13 ); - P( local.A, local.B, local.C, local.D, local.X[ 3], 3 ); - P( local.D, local.A, local.B, local.C, local.X[ 7], 5 ); - P( local.C, local.D, local.A, local.B, local.X[11], 9 ); - P( local.B, local.C, local.D, local.A, local.X[15], 13 ); - -#undef P -#undef F - -#define F(x,y,z) ((x) ^ (y) ^ (z)) -#define P(a,b,c,d,x,s) \ - do \ - { \ - (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \ - (a) = S((a),(s)); \ - } while( 0 ) - - P( local.A, local.B, local.C, local.D, local.X[ 0], 3 ); - P( local.D, local.A, local.B, local.C, local.X[ 8], 9 ); - P( local.C, local.D, local.A, local.B, local.X[ 4], 11 ); - P( local.B, local.C, local.D, local.A, local.X[12], 15 ); - P( local.A, local.B, local.C, local.D, local.X[ 2], 3 ); - P( local.D, local.A, local.B, local.C, local.X[10], 9 ); - P( local.C, local.D, local.A, local.B, local.X[ 6], 11 ); - P( local.B, local.C, local.D, local.A, local.X[14], 15 ); - P( local.A, local.B, local.C, local.D, local.X[ 1], 3 ); - P( local.D, local.A, local.B, local.C, local.X[ 9], 9 ); - P( local.C, local.D, local.A, local.B, local.X[ 5], 11 ); - P( local.B, local.C, local.D, local.A, local.X[13], 15 ); - P( local.A, local.B, local.C, local.D, local.X[ 3], 3 ); - P( local.D, local.A, local.B, local.C, local.X[11], 9 ); - P( local.C, local.D, local.A, local.B, local.X[ 7], 11 ); - P( local.B, local.C, local.D, local.A, local.X[15], 15 ); - -#undef F -#undef P - - ctx->state[0] += local.A; - ctx->state[1] += local.B; - ctx->state[2] += local.C; - ctx->state[3] += local.D; - - /* Zeroise variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize( &local, sizeof( local ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4_process( mbedtls_md4_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_md4_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_MD4_PROCESS_ALT */ - -/* - * MD4 process buffer - */ -int mbedtls_md4_update_ret( mbedtls_md4_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - - if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, ilen ); - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4_update( mbedtls_md4_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md4_update_ret( ctx, input, ilen ); -} -#endif - -static const unsigned char md4_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD4 final digest - */ -int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx, - unsigned char output[16] ) -{ - int ret; - uint32_t last, padn; - uint32_t high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_LE( low, msglen, 0 ); - PUT_UINT32_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn ); - if( ret != 0 ) - return( ret ); - - if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 ) - return( ret ); - - - PUT_UINT32_LE( ctx->state[0], output, 0 ); - PUT_UINT32_LE( ctx->state[1], output, 4 ); - PUT_UINT32_LE( ctx->state[2], output, 8 ); - PUT_UINT32_LE( ctx->state[3], output, 12 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4_finish( mbedtls_md4_context *ctx, - unsigned char output[16] ) -{ - mbedtls_md4_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_MD4_ALT */ - -/* - * output = MD4( input buffer ) - */ -int mbedtls_md4_ret( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - int ret; - mbedtls_md4_context ctx; - - mbedtls_md4_init( &ctx ); - - if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_md4_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md4( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - mbedtls_md4_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) - -/* - * RFC 1320 test vectors - */ -static const unsigned char md4_test_str[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" } -}; - -static const size_t md4_test_strlen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md4_test_sum[7][16] = -{ - { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, - 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, - { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, - 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, - { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, - 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, - { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, - 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, - { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, - 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, - { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, - 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, - { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, - 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } -}; - -/* - * Checkup routine - */ -int mbedtls_md4_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char md4sum[16]; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " MD4 test #%d: ", i + 1 ); - - ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum ); - if( ret != 0 ) - goto fail; - - if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MD4_C */ diff --git a/mbedtls/md4.h b/mbedtls/md4.h deleted file mode 100644 index ac558161c..000000000 --- a/mbedtls/md4.h +++ /dev/null @@ -1,337 +0,0 @@ -#pragma GCC system_header -/** - * \file md4.h - * - * \brief MD4 message digest algorithm (hash function) - * - * \warning MD4 is considered a weak message digest and its use constitutes a - * security risk. We recommend considering stronger message digests - * instead. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - * - */ -#ifndef MBEDTLS_MD4_H -#define MBEDTLS_MD4_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -/* MBEDTLS_ERR_MD4_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED -0x002D /**< MD4 hardware accelerator failed */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_MD4_ALT) -// Regular implementation -// - -/** - * \brief MD4 context structure - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -typedef struct mbedtls_md4_context -{ - uint32_t total[2]; /*!< number of bytes processed */ - uint32_t state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -mbedtls_md4_context; - -#else /* MBEDTLS_MD4_ALT */ -#include "md4_alt.h" -#endif /* MBEDTLS_MD4_ALT */ - -/** - * \brief Initialize MD4 context - * - * \param ctx MD4 context to be initialized - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md4_init( mbedtls_md4_context *ctx ); - -/** - * \brief Clear MD4 context - * - * \param ctx MD4 context to be cleared - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md4_free( mbedtls_md4_context *ctx ); - -/** - * \brief Clone (the state of) an MD4 context - * - * \param dst The destination context - * \param src The context to be cloned - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md4_clone( mbedtls_md4_context *dst, - const mbedtls_md4_context *src ); - -/** - * \brief MD4 context setup - * - * \param ctx context to be initialized - * - * \return 0 if successful - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - */ -int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx ); - -/** - * \brief MD4 process buffer - * - * \param ctx MD4 context - * \param input buffer holding the data - * \param ilen length of the input data - * - * \return 0 if successful - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md4_update_ret( mbedtls_md4_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief MD4 final digest - * - * \param ctx MD4 context - * \param output MD4 checksum result - * - * \return 0 if successful - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx, - unsigned char output[16] ); - -/** - * \brief MD4 process data block (internal use only) - * - * \param ctx MD4 context - * \param data buffer holding one block of data - * - * \return 0 if successful - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, - const unsigned char data[64] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief MD4 context setup - * - * \disabled_deprecated Superseded by mbedtls_md4_starts_ret() in 2.7.0 - * - * \param ctx context to be initialized - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md4_starts( mbedtls_md4_context *ctx ); - -/** - * \brief MD4 process buffer - * - * \disabled_deprecated Superseded by mbedtls_md4_update_ret() in 2.7.0 - * - * \param ctx MD4 context - * \param input buffer holding the data - * \param ilen length of the input data - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md4_update( mbedtls_md4_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief MD4 final digest - * - * \disabled_deprecated Superseded by mbedtls_md4_finish_ret() in 2.7.0 - * - * \param ctx MD4 context - * \param output MD4 checksum result - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md4_finish( mbedtls_md4_context *ctx, - unsigned char output[16] ); - -/** - * \brief MD4 process data block (internal use only) - * - * \disabled_deprecated Superseded by mbedtls_internal_md4_process() in 2.7.0 - * - * \param ctx MD4 context - * \param data buffer holding one block of data - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx, - const unsigned char data[64] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Output = MD4( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD4 checksum result - * - * \return 0 if successful - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md4_ret( const unsigned char *input, - size_t ilen, - unsigned char output[16] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief Output = MD4( input buffer ) - * - * \disabled_deprecated Superseded by mbedtls_md4_ret() in 2.7.0 - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD4 checksum result - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input, - size_t ilen, - unsigned char output[16] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - * - * \warning MD4 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md4_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_md4.h */ diff --git a/mbedtls/md5.c b/mbedtls/md5.c deleted file mode 100644 index 59e87c2b5..000000000 --- a/mbedtls/md5.c +++ /dev/null @@ -1,541 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * RFC 1321 compliant MD5 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The MD5 algorithm was designed by Ron Rivest in 1991. - * - * http://www.ietf.org/rfc/rfc1321.txt - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD5_C) - -#include "mbedtls/md5.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_MD5_ALT) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -void mbedtls_md5_init( mbedtls_md5_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_md5_context ) ); -} - -void mbedtls_md5_free( mbedtls_md5_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) ); -} - -void mbedtls_md5_clone( mbedtls_md5_context *dst, - const mbedtls_md5_context *src ) -{ - *dst = *src; -} - -/* - * MD5 context setup - */ -int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5_starts( mbedtls_md5_context *ctx ) -{ - mbedtls_md5_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_MD5_PROCESS_ALT) -int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, - const unsigned char data[64] ) -{ - struct - { - uint32_t X[16], A, B, C, D; - } local; - - GET_UINT32_LE( local.X[ 0], data, 0 ); - GET_UINT32_LE( local.X[ 1], data, 4 ); - GET_UINT32_LE( local.X[ 2], data, 8 ); - GET_UINT32_LE( local.X[ 3], data, 12 ); - GET_UINT32_LE( local.X[ 4], data, 16 ); - GET_UINT32_LE( local.X[ 5], data, 20 ); - GET_UINT32_LE( local.X[ 6], data, 24 ); - GET_UINT32_LE( local.X[ 7], data, 28 ); - GET_UINT32_LE( local.X[ 8], data, 32 ); - GET_UINT32_LE( local.X[ 9], data, 36 ); - GET_UINT32_LE( local.X[10], data, 40 ); - GET_UINT32_LE( local.X[11], data, 44 ); - GET_UINT32_LE( local.X[12], data, 48 ); - GET_UINT32_LE( local.X[13], data, 52 ); - GET_UINT32_LE( local.X[14], data, 56 ); - GET_UINT32_LE( local.X[15], data, 60 ); - -#define S(x,n) \ - ( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) ) - -#define P(a,b,c,d,k,s,t) \ - do \ - { \ - (a) += F((b),(c),(d)) + local.X[(k)] + (t); \ - (a) = S((a),(s)) + (b); \ - } while( 0 ) - - local.A = ctx->state[0]; - local.B = ctx->state[1]; - local.C = ctx->state[2]; - local.D = ctx->state[3]; - -#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) - - P( local.A, local.B, local.C, local.D, 0, 7, 0xD76AA478 ); - P( local.D, local.A, local.B, local.C, 1, 12, 0xE8C7B756 ); - P( local.C, local.D, local.A, local.B, 2, 17, 0x242070DB ); - P( local.B, local.C, local.D, local.A, 3, 22, 0xC1BDCEEE ); - P( local.A, local.B, local.C, local.D, 4, 7, 0xF57C0FAF ); - P( local.D, local.A, local.B, local.C, 5, 12, 0x4787C62A ); - P( local.C, local.D, local.A, local.B, 6, 17, 0xA8304613 ); - P( local.B, local.C, local.D, local.A, 7, 22, 0xFD469501 ); - P( local.A, local.B, local.C, local.D, 8, 7, 0x698098D8 ); - P( local.D, local.A, local.B, local.C, 9, 12, 0x8B44F7AF ); - P( local.C, local.D, local.A, local.B, 10, 17, 0xFFFF5BB1 ); - P( local.B, local.C, local.D, local.A, 11, 22, 0x895CD7BE ); - P( local.A, local.B, local.C, local.D, 12, 7, 0x6B901122 ); - P( local.D, local.A, local.B, local.C, 13, 12, 0xFD987193 ); - P( local.C, local.D, local.A, local.B, 14, 17, 0xA679438E ); - P( local.B, local.C, local.D, local.A, 15, 22, 0x49B40821 ); - -#undef F - -#define F(x,y,z) ((y) ^ ((z) & ((x) ^ (y)))) - - P( local.A, local.B, local.C, local.D, 1, 5, 0xF61E2562 ); - P( local.D, local.A, local.B, local.C, 6, 9, 0xC040B340 ); - P( local.C, local.D, local.A, local.B, 11, 14, 0x265E5A51 ); - P( local.B, local.C, local.D, local.A, 0, 20, 0xE9B6C7AA ); - P( local.A, local.B, local.C, local.D, 5, 5, 0xD62F105D ); - P( local.D, local.A, local.B, local.C, 10, 9, 0x02441453 ); - P( local.C, local.D, local.A, local.B, 15, 14, 0xD8A1E681 ); - P( local.B, local.C, local.D, local.A, 4, 20, 0xE7D3FBC8 ); - P( local.A, local.B, local.C, local.D, 9, 5, 0x21E1CDE6 ); - P( local.D, local.A, local.B, local.C, 14, 9, 0xC33707D6 ); - P( local.C, local.D, local.A, local.B, 3, 14, 0xF4D50D87 ); - P( local.B, local.C, local.D, local.A, 8, 20, 0x455A14ED ); - P( local.A, local.B, local.C, local.D, 13, 5, 0xA9E3E905 ); - P( local.D, local.A, local.B, local.C, 2, 9, 0xFCEFA3F8 ); - P( local.C, local.D, local.A, local.B, 7, 14, 0x676F02D9 ); - P( local.B, local.C, local.D, local.A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) ((x) ^ (y) ^ (z)) - - P( local.A, local.B, local.C, local.D, 5, 4, 0xFFFA3942 ); - P( local.D, local.A, local.B, local.C, 8, 11, 0x8771F681 ); - P( local.C, local.D, local.A, local.B, 11, 16, 0x6D9D6122 ); - P( local.B, local.C, local.D, local.A, 14, 23, 0xFDE5380C ); - P( local.A, local.B, local.C, local.D, 1, 4, 0xA4BEEA44 ); - P( local.D, local.A, local.B, local.C, 4, 11, 0x4BDECFA9 ); - P( local.C, local.D, local.A, local.B, 7, 16, 0xF6BB4B60 ); - P( local.B, local.C, local.D, local.A, 10, 23, 0xBEBFBC70 ); - P( local.A, local.B, local.C, local.D, 13, 4, 0x289B7EC6 ); - P( local.D, local.A, local.B, local.C, 0, 11, 0xEAA127FA ); - P( local.C, local.D, local.A, local.B, 3, 16, 0xD4EF3085 ); - P( local.B, local.C, local.D, local.A, 6, 23, 0x04881D05 ); - P( local.A, local.B, local.C, local.D, 9, 4, 0xD9D4D039 ); - P( local.D, local.A, local.B, local.C, 12, 11, 0xE6DB99E5 ); - P( local.C, local.D, local.A, local.B, 15, 16, 0x1FA27CF8 ); - P( local.B, local.C, local.D, local.A, 2, 23, 0xC4AC5665 ); - -#undef F - -#define F(x,y,z) ((y) ^ ((x) | ~(z))) - - P( local.A, local.B, local.C, local.D, 0, 6, 0xF4292244 ); - P( local.D, local.A, local.B, local.C, 7, 10, 0x432AFF97 ); - P( local.C, local.D, local.A, local.B, 14, 15, 0xAB9423A7 ); - P( local.B, local.C, local.D, local.A, 5, 21, 0xFC93A039 ); - P( local.A, local.B, local.C, local.D, 12, 6, 0x655B59C3 ); - P( local.D, local.A, local.B, local.C, 3, 10, 0x8F0CCC92 ); - P( local.C, local.D, local.A, local.B, 10, 15, 0xFFEFF47D ); - P( local.B, local.C, local.D, local.A, 1, 21, 0x85845DD1 ); - P( local.A, local.B, local.C, local.D, 8, 6, 0x6FA87E4F ); - P( local.D, local.A, local.B, local.C, 15, 10, 0xFE2CE6E0 ); - P( local.C, local.D, local.A, local.B, 6, 15, 0xA3014314 ); - P( local.B, local.C, local.D, local.A, 13, 21, 0x4E0811A1 ); - P( local.A, local.B, local.C, local.D, 4, 6, 0xF7537E82 ); - P( local.D, local.A, local.B, local.C, 11, 10, 0xBD3AF235 ); - P( local.C, local.D, local.A, local.B, 2, 15, 0x2AD7D2BB ); - P( local.B, local.C, local.D, local.A, 9, 21, 0xEB86D391 ); - -#undef F - - ctx->state[0] += local.A; - ctx->state[1] += local.B; - ctx->state[2] += local.C; - ctx->state[3] += local.D; - - /* Zeroise variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize( &local, sizeof( local ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5_process( mbedtls_md5_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_md5_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_MD5_PROCESS_ALT */ - -/* - * MD5 process buffer - */ -int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), input, ilen ); - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5_update( mbedtls_md5_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md5_update_ret( ctx, input, ilen ); -} -#endif - -/* - * MD5 final digest - */ -int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, - unsigned char output[16] ) -{ - int ret; - uint32_t used; - uint32_t high, low; - - /* - * Add padding: 0x80 then 0x00 until 8 bytes remain for the length - */ - used = ctx->total[0] & 0x3F; - - ctx->buffer[used++] = 0x80; - - if( used <= 56 ) - { - /* Enough room for padding + length in current block */ - memset( ctx->buffer + used, 0, 56 - used ); - } - else - { - /* We'll need an extra block */ - memset( ctx->buffer + used, 0, 64 - used ); - - if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - memset( ctx->buffer, 0, 56 ); - } - - /* - * Add message length - */ - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_LE( low, ctx->buffer, 56 ); - PUT_UINT32_LE( high, ctx->buffer, 60 ); - - if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - /* - * Output final state - */ - PUT_UINT32_LE( ctx->state[0], output, 0 ); - PUT_UINT32_LE( ctx->state[1], output, 4 ); - PUT_UINT32_LE( ctx->state[2], output, 8 ); - PUT_UINT32_LE( ctx->state[3], output, 12 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5_finish( mbedtls_md5_context *ctx, - unsigned char output[16] ) -{ - mbedtls_md5_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_MD5_ALT */ - -/* - * output = MD5( input buffer ) - */ -int mbedtls_md5_ret( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - int ret; - mbedtls_md5_context ctx; - - mbedtls_md5_init( &ctx ); - - if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_md5_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_md5( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - mbedtls_md5_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * RFC 1321 test vectors - */ -static const unsigned char md5_test_buf[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" } -}; - -static const size_t md5_test_buflen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md5_test_sum[7][16] = -{ - { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, - 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, - { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, - 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, - { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, - 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, - { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, - 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, - { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, - 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, - { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, - 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, - { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, - 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } -}; - -/* - * Checkup routine - */ -int mbedtls_md5_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char md5sum[16]; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " MD5 test #%d: ", i + 1 ); - - ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum ); - if( ret != 0 ) - goto fail; - - if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MD5_C */ diff --git a/mbedtls/md5.h b/mbedtls/md5.h deleted file mode 100644 index 5e6068c5a..000000000 --- a/mbedtls/md5.h +++ /dev/null @@ -1,337 +0,0 @@ -#pragma GCC system_header -/** - * \file md5.h - * - * \brief MD5 message digest algorithm (hash function) - * - * \warning MD5 is considered a weak message digest and its use constitutes a - * security risk. We recommend considering stronger message - * digests instead. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_MD5_H -#define MBEDTLS_MD5_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -/* MBEDTLS_ERR_MD5_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED -0x002F /**< MD5 hardware accelerator failed */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_MD5_ALT) -// Regular implementation -// - -/** - * \brief MD5 context structure - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -typedef struct mbedtls_md5_context -{ - uint32_t total[2]; /*!< number of bytes processed */ - uint32_t state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -mbedtls_md5_context; - -#else /* MBEDTLS_MD5_ALT */ -#include "md5_alt.h" -#endif /* MBEDTLS_MD5_ALT */ - -/** - * \brief Initialize MD5 context - * - * \param ctx MD5 context to be initialized - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md5_init( mbedtls_md5_context *ctx ); - -/** - * \brief Clear MD5 context - * - * \param ctx MD5 context to be cleared - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md5_free( mbedtls_md5_context *ctx ); - -/** - * \brief Clone (the state of) an MD5 context - * - * \param dst The destination context - * \param src The context to be cloned - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md5_clone( mbedtls_md5_context *dst, - const mbedtls_md5_context *src ); - -/** - * \brief MD5 context setup - * - * \param ctx context to be initialized - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx ); - -/** - * \brief MD5 process buffer - * - * \param ctx MD5 context - * \param input buffer holding the data - * \param ilen length of the input data - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief MD5 final digest - * - * \param ctx MD5 context - * \param output MD5 checksum result - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, - unsigned char output[16] ); - -/** - * \brief MD5 process data block (internal use only) - * - * \param ctx MD5 context - * \param data buffer holding one block of data - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, - const unsigned char data[64] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief MD5 context setup - * - * \disabled_deprecated Superseded by mbedtls_md5_starts_ret() in 2.7.0 - * - * \param ctx context to be initialized - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md5_starts( mbedtls_md5_context *ctx ); - -/** - * \brief MD5 process buffer - * - * \disabled_deprecated Superseded by mbedtls_md5_update_ret() in 2.7.0 - * - * \param ctx MD5 context - * \param input buffer holding the data - * \param ilen length of the input data - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md5_update( mbedtls_md5_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief MD5 final digest - * - * \disabled_deprecated Superseded by mbedtls_md5_finish_ret() in 2.7.0 - * - * \param ctx MD5 context - * \param output MD5 checksum result - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md5_finish( mbedtls_md5_context *ctx, - unsigned char output[16] ); - -/** - * \brief MD5 process data block (internal use only) - * - * \disabled_deprecated Superseded by mbedtls_internal_md5_process() in 2.7.0 - * - * \param ctx MD5 context - * \param data buffer holding one block of data - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx, - const unsigned char data[64] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Output = MD5( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD5 checksum result - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5_ret( const unsigned char *input, - size_t ilen, - unsigned char output[16] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief Output = MD5( input buffer ) - * - * \disabled_deprecated Superseded by mbedtls_md5_ret() in 2.7.0 - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD5 checksum result - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input, - size_t ilen, - unsigned char output[16] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_md5.h */ diff --git a/mbedtls/md_internal.h b/mbedtls/md_internal.h deleted file mode 100644 index fee42a74c..000000000 --- a/mbedtls/md_internal.h +++ /dev/null @@ -1,141 +0,0 @@ -#pragma GCC system_header -/** - * \file md_internal.h - * - * \brief Message digest wrappers. - * - * \warning This in an internal header. Do not include directly. - * - * \author Adriaan de Jong - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_MD_WRAP_H -#define MBEDTLS_MD_WRAP_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "md.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Message digest information. - * Allows message digest functions to be called in a generic way. - */ -struct mbedtls_md_info_t -{ - /** Digest identifier */ - mbedtls_md_type_t type; - - /** Name of the message digest */ - const char * name; - - /** Output length of the digest function in bytes */ - int size; - - /** Block length of the digest function in bytes */ - int block_size; - - /** Digest initialisation function */ - int (*starts_func)( void *ctx ); - - /** Digest update function */ - int (*update_func)( void *ctx, const unsigned char *input, size_t ilen ); - - /** Digest finalisation function */ - int (*finish_func)( void *ctx, unsigned char *output ); - - /** Generic digest function */ - int (*digest_func)( const unsigned char *input, size_t ilen, - unsigned char *output ); - - /** Allocate a new context */ - void * (*ctx_alloc_func)( void ); - - /** Free the given context */ - void (*ctx_free_func)( void *ctx ); - - /** Clone state from a context */ - void (*clone_func)( void *dst, const void *src ); - - /** Internal use only */ - int (*process_func)( void *ctx, const unsigned char *input ); -}; - -#if defined(MBEDTLS_MD2_C) -extern const mbedtls_md_info_t mbedtls_md2_info; -#endif -#if defined(MBEDTLS_MD4_C) -extern const mbedtls_md_info_t mbedtls_md4_info; -#endif -#if defined(MBEDTLS_MD5_C) -extern const mbedtls_md_info_t mbedtls_md5_info; -#endif -#if defined(MBEDTLS_RIPEMD160_C) -extern const mbedtls_md_info_t mbedtls_ripemd160_info; -#endif -#if defined(MBEDTLS_SHA1_C) -extern const mbedtls_md_info_t mbedtls_sha1_info; -#endif -#if defined(MBEDTLS_SHA256_C) -extern const mbedtls_md_info_t mbedtls_sha224_info; -extern const mbedtls_md_info_t mbedtls_sha256_info; -#endif -#if defined(MBEDTLS_SHA512_C) -extern const mbedtls_md_info_t mbedtls_sha384_info; -extern const mbedtls_md_info_t mbedtls_sha512_info; -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_MD_WRAP_H */ diff --git a/mbedtls/md_wrap.c b/mbedtls/md_wrap.c deleted file mode 100644 index 47566aa2d..000000000 --- a/mbedtls/md_wrap.c +++ /dev/null @@ -1,624 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file md_wrap.c - * - * \brief Generic message digest wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD_C) - -#include "mbedtls/md_internal.h" - -#if defined(MBEDTLS_MD2_C) -#include "mbedtls/md2.h" -#endif - -#if defined(MBEDTLS_MD4_C) -#include "mbedtls/md4.h" -#endif - -#if defined(MBEDTLS_MD5_C) -#include "mbedtls/md5.h" -#endif - -#if defined(MBEDTLS_RIPEMD160_C) -#include "mbedtls/ripemd160.h" -#endif - -#if defined(MBEDTLS_SHA1_C) -#include "mbedtls/sha1.h" -#endif - -#if defined(MBEDTLS_SHA256_C) -#include "mbedtls/sha256.h" -#endif - -#if defined(MBEDTLS_SHA512_C) -#include "mbedtls/sha512.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_MD2_C) - -static int md2_starts_wrap( void *ctx ) -{ - return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) ); -} - -static int md2_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) ); -} - -static int md2_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) ); -} - -static void *md2_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) ); - - if( ctx != NULL ) - mbedtls_md2_init( (mbedtls_md2_context *) ctx ); - - return( ctx ); -} - -static void md2_ctx_free( void *ctx ) -{ - mbedtls_md2_free( (mbedtls_md2_context *) ctx ); - mbedtls_free( ctx ); -} - -static void md2_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md2_clone( (mbedtls_md2_context *) dst, - (const mbedtls_md2_context *) src ); -} - -static int md2_process_wrap( void *ctx, const unsigned char *data ) -{ - ((void) data); - - return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) ); -} - -const mbedtls_md_info_t mbedtls_md2_info = { - MBEDTLS_MD_MD2, - "MD2", - 16, - 16, - md2_starts_wrap, - md2_update_wrap, - md2_finish_wrap, - mbedtls_md2_ret, - md2_ctx_alloc, - md2_ctx_free, - md2_clone_wrap, - md2_process_wrap, -}; - -#endif /* MBEDTLS_MD2_C */ - -#if defined(MBEDTLS_MD4_C) - -static int md4_starts_wrap( void *ctx ) -{ - return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) ); -} - -static int md4_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) ); -} - -static int md4_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) ); -} - -static void *md4_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) ); - - if( ctx != NULL ) - mbedtls_md4_init( (mbedtls_md4_context *) ctx ); - - return( ctx ); -} - -static void md4_ctx_free( void *ctx ) -{ - mbedtls_md4_free( (mbedtls_md4_context *) ctx ); - mbedtls_free( ctx ); -} - -static void md4_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md4_clone( (mbedtls_md4_context *) dst, - (const mbedtls_md4_context *) src ); -} - -static int md4_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) ); -} - -const mbedtls_md_info_t mbedtls_md4_info = { - MBEDTLS_MD_MD4, - "MD4", - 16, - 64, - md4_starts_wrap, - md4_update_wrap, - md4_finish_wrap, - mbedtls_md4_ret, - md4_ctx_alloc, - md4_ctx_free, - md4_clone_wrap, - md4_process_wrap, -}; - -#endif /* MBEDTLS_MD4_C */ - -#if defined(MBEDTLS_MD5_C) - -static int md5_starts_wrap( void *ctx ) -{ - return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) ); -} - -static int md5_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) ); -} - -static int md5_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) ); -} - -static void *md5_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) ); - - if( ctx != NULL ) - mbedtls_md5_init( (mbedtls_md5_context *) ctx ); - - return( ctx ); -} - -static void md5_ctx_free( void *ctx ) -{ - mbedtls_md5_free( (mbedtls_md5_context *) ctx ); - mbedtls_free( ctx ); -} - -static void md5_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md5_clone( (mbedtls_md5_context *) dst, - (const mbedtls_md5_context *) src ); -} - -static int md5_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) ); -} - -const mbedtls_md_info_t mbedtls_md5_info = { - MBEDTLS_MD_MD5, - "MD5", - 16, - 64, - md5_starts_wrap, - md5_update_wrap, - md5_finish_wrap, - mbedtls_md5_ret, - md5_ctx_alloc, - md5_ctx_free, - md5_clone_wrap, - md5_process_wrap, -}; - -#endif /* MBEDTLS_MD5_C */ - -#if defined(MBEDTLS_RIPEMD160_C) - -static int ripemd160_starts_wrap( void *ctx ) -{ - return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) ); -} - -static int ripemd160_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx, - input, ilen ) ); -} - -static int ripemd160_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx, - output ) ); -} - -static void *ripemd160_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) ); - - if( ctx != NULL ) - mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx ); - - return( ctx ); -} - -static void ripemd160_ctx_free( void *ctx ) -{ - mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx ); - mbedtls_free( ctx ); -} - -static void ripemd160_clone_wrap( void *dst, const void *src ) -{ - mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst, - (const mbedtls_ripemd160_context *) src ); -} - -static int ripemd160_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_ripemd160_process( - (mbedtls_ripemd160_context *) ctx, data ) ); -} - -const mbedtls_md_info_t mbedtls_ripemd160_info = { - MBEDTLS_MD_RIPEMD160, - "RIPEMD160", - 20, - 64, - ripemd160_starts_wrap, - ripemd160_update_wrap, - ripemd160_finish_wrap, - mbedtls_ripemd160_ret, - ripemd160_ctx_alloc, - ripemd160_ctx_free, - ripemd160_clone_wrap, - ripemd160_process_wrap, -}; - -#endif /* MBEDTLS_RIPEMD160_C */ - -#if defined(MBEDTLS_SHA1_C) - -static int sha1_starts_wrap( void *ctx ) -{ - return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) ); -} - -static int sha1_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx, - input, ilen ) ); -} - -static int sha1_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) ); -} - -static void *sha1_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) ); - - if( ctx != NULL ) - mbedtls_sha1_init( (mbedtls_sha1_context *) ctx ); - - return( ctx ); -} - -static void sha1_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha1_clone( (mbedtls_sha1_context *) dst, - (const mbedtls_sha1_context *) src ); -} - -static void sha1_ctx_free( void *ctx ) -{ - mbedtls_sha1_free( (mbedtls_sha1_context *) ctx ); - mbedtls_free( ctx ); -} - -static int sha1_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx, - data ) ); -} - -const mbedtls_md_info_t mbedtls_sha1_info = { - MBEDTLS_MD_SHA1, - "SHA1", - 20, - 64, - sha1_starts_wrap, - sha1_update_wrap, - sha1_finish_wrap, - mbedtls_sha1_ret, - sha1_ctx_alloc, - sha1_ctx_free, - sha1_clone_wrap, - sha1_process_wrap, -}; - -#endif /* MBEDTLS_SHA1_C */ - -/* - * Wrappers for generic message digests - */ -#if defined(MBEDTLS_SHA256_C) - -static int sha224_starts_wrap( void *ctx ) -{ - return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) ); -} - -static int sha224_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx, - input, ilen ) ); -} - -static int sha224_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx, - output ) ); -} - -static int sha224_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha256_ret( input, ilen, output, 1 ) ); -} - -static void *sha224_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) ); - - if( ctx != NULL ) - mbedtls_sha256_init( (mbedtls_sha256_context *) ctx ); - - return( ctx ); -} - -static void sha224_ctx_free( void *ctx ) -{ - mbedtls_sha256_free( (mbedtls_sha256_context *) ctx ); - mbedtls_free( ctx ); -} - -static void sha224_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha256_clone( (mbedtls_sha256_context *) dst, - (const mbedtls_sha256_context *) src ); -} - -static int sha224_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx, - data ) ); -} - -const mbedtls_md_info_t mbedtls_sha224_info = { - MBEDTLS_MD_SHA224, - "SHA224", - 28, - 64, - sha224_starts_wrap, - sha224_update_wrap, - sha224_finish_wrap, - sha224_wrap, - sha224_ctx_alloc, - sha224_ctx_free, - sha224_clone_wrap, - sha224_process_wrap, -}; - -static int sha256_starts_wrap( void *ctx ) -{ - return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) ); -} - -static int sha256_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha256_ret( input, ilen, output, 0 ) ); -} - -const mbedtls_md_info_t mbedtls_sha256_info = { - MBEDTLS_MD_SHA256, - "SHA256", - 32, - 64, - sha256_starts_wrap, - sha224_update_wrap, - sha224_finish_wrap, - sha256_wrap, - sha224_ctx_alloc, - sha224_ctx_free, - sha224_clone_wrap, - sha224_process_wrap, -}; - -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - -static int sha384_starts_wrap( void *ctx ) -{ - return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) ); -} - -static int sha384_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx, - input, ilen ) ); -} - -static int sha384_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx, - output ) ); -} - -static int sha384_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha512_ret( input, ilen, output, 1 ) ); -} - -static void *sha384_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) ); - - if( ctx != NULL ) - mbedtls_sha512_init( (mbedtls_sha512_context *) ctx ); - - return( ctx ); -} - -static void sha384_ctx_free( void *ctx ) -{ - mbedtls_sha512_free( (mbedtls_sha512_context *) ctx ); - mbedtls_free( ctx ); -} - -static void sha384_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha512_clone( (mbedtls_sha512_context *) dst, - (const mbedtls_sha512_context *) src ); -} - -static int sha384_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx, - data ) ); -} - -const mbedtls_md_info_t mbedtls_sha384_info = { - MBEDTLS_MD_SHA384, - "SHA384", - 48, - 128, - sha384_starts_wrap, - sha384_update_wrap, - sha384_finish_wrap, - sha384_wrap, - sha384_ctx_alloc, - sha384_ctx_free, - sha384_clone_wrap, - sha384_process_wrap, -}; - -static int sha512_starts_wrap( void *ctx ) -{ - return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) ); -} - -static int sha512_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha512_ret( input, ilen, output, 0 ) ); -} - -const mbedtls_md_info_t mbedtls_sha512_info = { - MBEDTLS_MD_SHA512, - "SHA512", - 64, - 128, - sha512_starts_wrap, - sha384_update_wrap, - sha384_finish_wrap, - sha512_wrap, - sha384_ctx_alloc, - sha384_ctx_free, - sha384_clone_wrap, - sha384_process_wrap, -}; - -#endif /* MBEDTLS_SHA512_C */ - -#endif /* MBEDTLS_MD_C */ diff --git a/mbedtls/memory_buffer_alloc.c b/mbedtls/memory_buffer_alloc.c deleted file mode 100644 index e0b6c9b08..000000000 --- a/mbedtls/memory_buffer_alloc.c +++ /dev/null @@ -1,788 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Buffer-based memory allocator - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#include "mbedtls/memory_buffer_alloc.h" - -/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C - is dependent upon MBEDTLS_PLATFORM_C */ -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_MEMORY_BACKTRACE) -#include -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#define MAGIC1 0xFF00AA55 -#define MAGIC2 0xEE119966 -#define MAX_BT 20 - -typedef struct _memory_header memory_header; -struct _memory_header -{ - size_t magic1; - size_t size; - size_t alloc; - memory_header *prev; - memory_header *next; - memory_header *prev_free; - memory_header *next_free; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - char **trace; - size_t trace_count; -#endif - size_t magic2; -}; - -typedef struct -{ - unsigned char *buf; - size_t len; - memory_header *first; - memory_header *first_free; - int verify; -#if defined(MBEDTLS_MEMORY_DEBUG) - size_t alloc_count; - size_t free_count; - size_t total_used; - size_t maximum_used; - size_t header_count; - size_t maximum_header_count; -#endif -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; -#endif -} -buffer_alloc_ctx; - -static buffer_alloc_ctx heap; - -#if defined(MBEDTLS_MEMORY_DEBUG) -static void debug_header( memory_header *hdr ) -{ -#if defined(MBEDTLS_MEMORY_BACKTRACE) - size_t i; -#endif - - mbedtls_fprintf( stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), " - "ALLOC(%zu), SIZE(%10zu)\n", - (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, - hdr->alloc, hdr->size ); - mbedtls_fprintf( stderr, " FPREV(%10zu), FNEXT(%10zu)\n", - (size_t) hdr->prev_free, (size_t) hdr->next_free ); - -#if defined(MBEDTLS_MEMORY_BACKTRACE) - mbedtls_fprintf( stderr, "TRACE: \n" ); - for( i = 0; i < hdr->trace_count; i++ ) - mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] ); - mbedtls_fprintf( stderr, "\n" ); -#endif -} - -static void debug_chain( void ) -{ - memory_header *cur = heap.first; - - mbedtls_fprintf( stderr, "\nBlock list\n" ); - while( cur != NULL ) - { - debug_header( cur ); - cur = cur->next; - } - - mbedtls_fprintf( stderr, "Free list\n" ); - cur = heap.first_free; - - while( cur != NULL ) - { - debug_header( cur ); - cur = cur->next_free; - } -} -#endif /* MBEDTLS_MEMORY_DEBUG */ - -static int verify_header( memory_header *hdr ) -{ - if( hdr->magic1 != MAGIC1 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" ); -#endif - return( 1 ); - } - - if( hdr->magic2 != MAGIC2 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" ); -#endif - return( 1 ); - } - - if( hdr->alloc > 1 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" ); -#endif - return( 1 ); - } - - if( hdr->prev != NULL && hdr->prev == hdr->next ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: prev == next\n" ); -#endif - return( 1 ); - } - - if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" ); -#endif - return( 1 ); - } - - return( 0 ); -} - -static int verify_chain( void ) -{ - memory_header *prv = heap.first, *cur; - - if( prv == NULL || verify_header( prv ) != 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: verification of first header " - "failed\n" ); -#endif - return( 1 ); - } - - if( heap.first->prev != NULL ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: verification failed: " - "first->prev != NULL\n" ); -#endif - return( 1 ); - } - - cur = heap.first->next; - - while( cur != NULL ) - { - if( verify_header( cur ) != 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: verification of header " - "failed\n" ); -#endif - return( 1 ); - } - - if( cur->prev != prv ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: verification failed: " - "cur->prev != prv\n" ); -#endif - return( 1 ); - } - - prv = cur; - cur = cur->next; - } - - return( 0 ); -} - -static void *buffer_alloc_calloc( size_t n, size_t size ) -{ - memory_header *new, *cur = heap.first_free; - unsigned char *p; - void *ret; - size_t original_len, len; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - void *trace_buffer[MAX_BT]; - size_t trace_cnt; -#endif - - if( heap.buf == NULL || heap.first == NULL ) - return( NULL ); - - original_len = len = n * size; - - if( n == 0 || size == 0 || len / n != size ) - return( NULL ); - else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - return( NULL ); - - if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - { - len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - len += MBEDTLS_MEMORY_ALIGN_MULTIPLE; - } - - // Find block that fits - // - while( cur != NULL ) - { - if( cur->size >= len ) - break; - - cur = cur->next_free; - } - - if( cur == NULL ) - return( NULL ); - - if( cur->alloc != 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated " - "data\n" ); -#endif - mbedtls_exit( 1 ); - } - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.alloc_count++; -#endif - - // Found location, split block if > memory_header + 4 room left - // - if( cur->size - len < sizeof(memory_header) + - MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - { - cur->alloc = 1; - - // Remove from free_list - // - if( cur->prev_free != NULL ) - cur->prev_free->next_free = cur->next_free; - else - heap.first_free = cur->next_free; - - if( cur->next_free != NULL ) - cur->next_free->prev_free = cur->prev_free; - - cur->prev_free = NULL; - cur->next_free = NULL; - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.total_used += cur->size; - if( heap.total_used > heap.maximum_used ) - heap.maximum_used = heap.total_used; -#endif -#if defined(MBEDTLS_MEMORY_BACKTRACE) - trace_cnt = backtrace( trace_buffer, MAX_BT ); - cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); - cur->trace_count = trace_cnt; -#endif - - if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) - mbedtls_exit( 1 ); - - ret = (unsigned char *) cur + sizeof( memory_header ); - memset( ret, 0, original_len ); - - return( ret ); - } - - p = ( (unsigned char *) cur ) + sizeof(memory_header) + len; - new = (memory_header *) p; - - new->size = cur->size - len - sizeof(memory_header); - new->alloc = 0; - new->prev = cur; - new->next = cur->next; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - new->trace = NULL; - new->trace_count = 0; -#endif - new->magic1 = MAGIC1; - new->magic2 = MAGIC2; - - if( new->next != NULL ) - new->next->prev = new; - - // Replace cur with new in free_list - // - new->prev_free = cur->prev_free; - new->next_free = cur->next_free; - if( new->prev_free != NULL ) - new->prev_free->next_free = new; - else - heap.first_free = new; - - if( new->next_free != NULL ) - new->next_free->prev_free = new; - - cur->alloc = 1; - cur->size = len; - cur->next = new; - cur->prev_free = NULL; - cur->next_free = NULL; - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.header_count++; - if( heap.header_count > heap.maximum_header_count ) - heap.maximum_header_count = heap.header_count; - heap.total_used += cur->size; - if( heap.total_used > heap.maximum_used ) - heap.maximum_used = heap.total_used; -#endif -#if defined(MBEDTLS_MEMORY_BACKTRACE) - trace_cnt = backtrace( trace_buffer, MAX_BT ); - cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); - cur->trace_count = trace_cnt; -#endif - - if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) - mbedtls_exit( 1 ); - - ret = (unsigned char *) cur + sizeof( memory_header ); - memset( ret, 0, original_len ); - - return( ret ); -} - -static void buffer_alloc_free( void *ptr ) -{ - memory_header *hdr, *old = NULL; - unsigned char *p = (unsigned char *) ptr; - - if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) - return; - - if( p < heap.buf || p >= heap.buf + heap.len ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed " - "space\n" ); -#endif - mbedtls_exit( 1 ); - } - - p -= sizeof(memory_header); - hdr = (memory_header *) p; - - if( verify_header( hdr ) != 0 ) - mbedtls_exit( 1 ); - - if( hdr->alloc != 1 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated " - "data\n" ); -#endif - mbedtls_exit( 1 ); - } - - hdr->alloc = 0; - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.free_count++; - heap.total_used -= hdr->size; -#endif - -#if defined(MBEDTLS_MEMORY_BACKTRACE) - free( hdr->trace ); - hdr->trace = NULL; - hdr->trace_count = 0; -#endif - - // Regroup with block before - // - if( hdr->prev != NULL && hdr->prev->alloc == 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.header_count--; -#endif - hdr->prev->size += sizeof(memory_header) + hdr->size; - hdr->prev->next = hdr->next; - old = hdr; - hdr = hdr->prev; - - if( hdr->next != NULL ) - hdr->next->prev = hdr; - - memset( old, 0, sizeof(memory_header) ); - } - - // Regroup with block after - // - if( hdr->next != NULL && hdr->next->alloc == 0 ) - { -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.header_count--; -#endif - hdr->size += sizeof(memory_header) + hdr->next->size; - old = hdr->next; - hdr->next = hdr->next->next; - - if( hdr->prev_free != NULL || hdr->next_free != NULL ) - { - if( hdr->prev_free != NULL ) - hdr->prev_free->next_free = hdr->next_free; - else - heap.first_free = hdr->next_free; - - if( hdr->next_free != NULL ) - hdr->next_free->prev_free = hdr->prev_free; - } - - hdr->prev_free = old->prev_free; - hdr->next_free = old->next_free; - - if( hdr->prev_free != NULL ) - hdr->prev_free->next_free = hdr; - else - heap.first_free = hdr; - - if( hdr->next_free != NULL ) - hdr->next_free->prev_free = hdr; - - if( hdr->next != NULL ) - hdr->next->prev = hdr; - - memset( old, 0, sizeof(memory_header) ); - } - - // Prepend to free_list if we have not merged - // (Does not have to stay in same order as prev / next list) - // - if( old == NULL ) - { - hdr->next_free = heap.first_free; - if( heap.first_free != NULL ) - heap.first_free->prev_free = hdr; - heap.first_free = hdr; - } - - if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 ) - mbedtls_exit( 1 ); -} - -void mbedtls_memory_buffer_set_verify( int verify ) -{ - heap.verify = verify; -} - -int mbedtls_memory_buffer_alloc_verify( void ) -{ - return verify_chain(); -} - -#if defined(MBEDTLS_MEMORY_DEBUG) -void mbedtls_memory_buffer_alloc_status( void ) -{ - mbedtls_fprintf( stderr, - "Current use: %zu blocks / %zu bytes, max: %zu blocks / " - "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n", - heap.header_count, heap.total_used, - heap.maximum_header_count, heap.maximum_used, - heap.maximum_header_count * sizeof( memory_header ) - + heap.maximum_used, - heap.alloc_count, heap.free_count ); - - if( heap.first->next == NULL ) - { - mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); - } - else - { - mbedtls_fprintf( stderr, "Memory currently allocated:\n" ); - debug_chain(); - } -} - -void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks ) -{ - *max_used = heap.maximum_used; - *max_blocks = heap.maximum_header_count; -} - -void mbedtls_memory_buffer_alloc_max_reset( void ) -{ - heap.maximum_used = 0; - heap.maximum_header_count = 0; -} - -void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks ) -{ - *cur_used = heap.total_used; - *cur_blocks = heap.header_count; -} -#endif /* MBEDTLS_MEMORY_DEBUG */ - -#if defined(MBEDTLS_THREADING_C) -static void *buffer_alloc_calloc_mutexed( size_t n, size_t size ) -{ - void *buf; - if( mbedtls_mutex_lock( &heap.mutex ) != 0 ) - return( NULL ); - buf = buffer_alloc_calloc( n, size ); - if( mbedtls_mutex_unlock( &heap.mutex ) ) - return( NULL ); - return( buf ); -} - -static void buffer_alloc_free_mutexed( void *ptr ) -{ - /* We have to good option here, but corrupting the heap seems - * worse than loosing memory. */ - if( mbedtls_mutex_lock( &heap.mutex ) ) - return; - buffer_alloc_free( ptr ); - (void) mbedtls_mutex_unlock( &heap.mutex ); -} -#endif /* MBEDTLS_THREADING_C */ - -void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) -{ - memset( &heap, 0, sizeof( buffer_alloc_ctx ) ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &heap.mutex ); - mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed, - buffer_alloc_free_mutexed ); -#else - mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free ); -#endif - - if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - return; - else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) - { - /* Adjust len first since buf is used in the computation */ - len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE - - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE - - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - } - - memset( buf, 0, len ); - - heap.buf = buf; - heap.len = len; - - heap.first = (memory_header *)buf; - heap.first->size = len - sizeof( memory_header ); - heap.first->magic1 = MAGIC1; - heap.first->magic2 = MAGIC2; - heap.first_free = heap.first; -} - -void mbedtls_memory_buffer_alloc_free( void ) -{ -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &heap.mutex ); -#endif - mbedtls_platform_zeroize( &heap, sizeof(buffer_alloc_ctx) ); -} - -#if defined(MBEDTLS_SELF_TEST) -static int check_pointer( void *p ) -{ - if( p == NULL ) - return( -1 ); - - if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 ) - return( -1 ); - - return( 0 ); -} - -static int check_all_free( void ) -{ - if( -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.total_used != 0 || -#endif - heap.first != heap.first_free || - (void *) heap.first != (void *) heap.buf ) - { - return( -1 ); - } - - return( 0 ); -} - -#define TEST_ASSERT( condition ) \ - if( ! (condition) ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf( "failed\n" ); \ - \ - ret = 1; \ - goto cleanup; \ - } - -int mbedtls_memory_buffer_alloc_self_test( int verbose ) -{ - unsigned char buf[1024]; - unsigned char *p, *q, *r, *end; - int ret = 0; - - if( verbose != 0 ) - mbedtls_printf( " MBA test #1 (basic alloc-free cycle): " ); - - mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); - - p = mbedtls_calloc( 1, 1 ); - q = mbedtls_calloc( 1, 128 ); - r = mbedtls_calloc( 1, 16 ); - - TEST_ASSERT( check_pointer( p ) == 0 && - check_pointer( q ) == 0 && - check_pointer( r ) == 0 ); - - mbedtls_free( r ); - mbedtls_free( q ); - mbedtls_free( p ); - - TEST_ASSERT( check_all_free( ) == 0 ); - - /* Memorize end to compare with the next test */ - end = heap.buf + heap.len; - - mbedtls_memory_buffer_alloc_free( ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " MBA test #2 (buf not aligned): " ); - - mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 ); - - TEST_ASSERT( heap.buf + heap.len == end ); - - p = mbedtls_calloc( 1, 1 ); - q = mbedtls_calloc( 1, 128 ); - r = mbedtls_calloc( 1, 16 ); - - TEST_ASSERT( check_pointer( p ) == 0 && - check_pointer( q ) == 0 && - check_pointer( r ) == 0 ); - - mbedtls_free( r ); - mbedtls_free( q ); - mbedtls_free( p ); - - TEST_ASSERT( check_all_free( ) == 0 ); - - mbedtls_memory_buffer_alloc_free( ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " MBA test #3 (full): " ); - - mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); - - p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) ); - - TEST_ASSERT( check_pointer( p ) == 0 ); - TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); - - mbedtls_free( p ); - - p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 ); - q = mbedtls_calloc( 1, 16 ); - - TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 ); - TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); - - mbedtls_free( q ); - - TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL ); - - mbedtls_free( p ); - - TEST_ASSERT( check_all_free( ) == 0 ); - - mbedtls_memory_buffer_alloc_free( ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -cleanup: - mbedtls_memory_buffer_alloc_free( ); - - return( ret ); -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ diff --git a/mbedtls/memory_buffer_alloc.h b/mbedtls/memory_buffer_alloc.h deleted file mode 100644 index 62aac2f8e..000000000 --- a/mbedtls/memory_buffer_alloc.h +++ /dev/null @@ -1,177 +0,0 @@ -#pragma GCC system_header -/** - * \file memory_buffer_alloc.h - * - * \brief Buffer-based memory allocator - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H -#define MBEDTLS_MEMORY_BUFFER_ALLOC_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_MEMORY_ALIGN_MULTIPLE) -#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ -#endif - -/* \} name SECTION: Module settings */ - -#define MBEDTLS_MEMORY_VERIFY_NONE 0 -#define MBEDTLS_MEMORY_VERIFY_ALLOC (1 << 0) -#define MBEDTLS_MEMORY_VERIFY_FREE (1 << 1) -#define MBEDTLS_MEMORY_VERIFY_ALWAYS (MBEDTLS_MEMORY_VERIFY_ALLOC | MBEDTLS_MEMORY_VERIFY_FREE) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Initialize use of stack-based memory allocator. - * The stack-based allocator does memory management inside the - * presented buffer and does not call calloc() and free(). - * It sets the global mbedtls_calloc() and mbedtls_free() pointers - * to its own functions. - * (Provided mbedtls_calloc() and mbedtls_free() are thread-safe if - * MBEDTLS_THREADING_C is defined) - * - * \note This code is not optimized and provides a straight-forward - * implementation of a stack-based memory allocator. - * - * \param buf buffer to use as heap - * \param len size of the buffer - */ -void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ); - -/** - * \brief Free the mutex for thread-safety and clear remaining memory - */ -void mbedtls_memory_buffer_alloc_free( void ); - -/** - * \brief Determine when the allocator should automatically verify the state - * of the entire chain of headers / meta-data. - * (Default: MBEDTLS_MEMORY_VERIFY_NONE) - * - * \param verify One of MBEDTLS_MEMORY_VERIFY_NONE, MBEDTLS_MEMORY_VERIFY_ALLOC, - * MBEDTLS_MEMORY_VERIFY_FREE or MBEDTLS_MEMORY_VERIFY_ALWAYS - */ -void mbedtls_memory_buffer_set_verify( int verify ); - -#if defined(MBEDTLS_MEMORY_DEBUG) -/** - * \brief Print out the status of the allocated memory (primarily for use - * after a program should have de-allocated all memory) - * Prints out a list of 'still allocated' blocks and their stack - * trace if MBEDTLS_MEMORY_BACKTRACE is defined. - */ -void mbedtls_memory_buffer_alloc_status( void ); - -/** - * \brief Get the peak heap usage so far - * - * \param max_used Peak number of bytes in use or committed. This - * includes bytes in allocated blocks too small to split - * into smaller blocks but larger than the requested size. - * \param max_blocks Peak number of blocks in use, including free and used - */ -void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks ); - -/** - * \brief Reset peak statistics - */ -void mbedtls_memory_buffer_alloc_max_reset( void ); - -/** - * \brief Get the current heap usage - * - * \param cur_used Current number of bytes in use or committed. This - * includes bytes in allocated blocks too small to split - * into smaller blocks but larger than the requested size. - * \param cur_blocks Current number of blocks in use, including free and used - */ -void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks ); -#endif /* MBEDTLS_MEMORY_DEBUG */ - -/** - * \brief Verifies that all headers in the memory buffer are correct - * and contain sane values. Helps debug buffer-overflow errors. - * - * Prints out first failure if MBEDTLS_MEMORY_DEBUG is defined. - * Prints out full header information if MBEDTLS_MEMORY_DEBUG - * is defined. (Includes stack trace information for each block if - * MBEDTLS_MEMORY_BACKTRACE is defined as well). - * - * \return 0 if verified, 1 otherwise - */ -int mbedtls_memory_buffer_alloc_verify( void ); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_memory_buffer_alloc_self_test( int verbose ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* memory_buffer_alloc.h */ diff --git a/mbedtls/net.h b/mbedtls/net.h deleted file mode 100644 index fee7c43f5..000000000 --- a/mbedtls/net.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma GCC system_header -/** - * \file net.h - * - * \brief Deprecated header file that includes net_sockets.h - * - * \disabled_deprecated Superseded by mbedtls/net_sockets.h - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#include "net_sockets.h" -#if defined(MBEDTLS_DEPRECATED_WARNING) -#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/mbedtls/net_sockets.c b/mbedtls/net_sockets.c deleted file mode 100644 index 706cee5f1..000000000 --- a/mbedtls/net_sockets.c +++ /dev/null @@ -1,744 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * TCP/IP or UDP/IP networking functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must - * be set before config.h, which pulls in glibc's features.h indirectly. - * Harmless on other platforms. */ -#ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200112L -#endif - -#if defined(__NetBSD__) -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 /* sockaddr_storage */ -#endif -#endif - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_NET_C) - -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) -#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#endif - -#include "mbedtls/net_sockets.h" - -#include - -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - -#define IS_EINTR( ret ) ( ( ret ) == WSAEINTR ) - -#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) -#undef _WIN32_WINNT -/* Enables getaddrinfo() & Co */ -#define _WIN32_WINNT 0x0501 -#endif - -#include - -#include -#include - -#if defined(_MSC_VER) -#if defined(_WIN32_WCE) -#pragma comment( lib, "ws2.lib" ) -#else -#pragma comment( lib, "ws2_32.lib" ) -#endif -#endif /* _MSC_VER */ - -#define read(fd,buf,len) recv( fd, (char*)( buf ), (int)( len ), 0 ) -#define write(fd,buf,len) send( fd, (char*)( buf ), (int)( len ), 0 ) -#define close(fd) closesocket(fd) - -static int wsa_init_done = 0; - -#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IS_EINTR( ret ) ( ( ret ) == EINTR ) - -#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ - -/* Some MS functions want int and MSVC warns if we pass size_t, - * but the standard functions use socklen_t, so cast only for MSVC */ -#if defined(_MSC_VER) -#define MSVC_INT_CAST (int) -#else -#define MSVC_INT_CAST -#endif - -#include - -#include - -#include - -/* - * Prepare for using the sockets interface - */ -static int net_prepare( void ) -{ -#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) - WSADATA wsaData; - - if( wsa_init_done == 0 ) - { - if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 ) - return( MBEDTLS_ERR_NET_SOCKET_FAILED ); - - wsa_init_done = 1; - } -#else -#if !defined(EFIX64) && !defined(EFI32) - signal( SIGPIPE, SIG_IGN ); -#endif -#endif - return( 0 ); -} - -/* - * Return 0 if the file descriptor is valid, an error otherwise. - * If for_select != 0, check whether the file descriptor is within the range - * allowed for fd_set used for the FD_xxx macros and the select() function. - */ -static int check_fd( int fd, int for_select ) -{ - if( fd < 0 ) - return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); - -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - (void) for_select; -#else - /* A limitation of select() is that it only works with file descriptors - * that are strictly less than FD_SETSIZE. This is a limitation of the - * fd_set type. Error out early, because attempting to call FD_SET on a - * large file descriptor is a buffer overflow on typical platforms. */ - if( for_select && fd >= FD_SETSIZE ) - return( MBEDTLS_ERR_NET_POLL_FAILED ); -#endif - - return( 0 ); -} - -/* - * Initialize a context - */ -void mbedtls_net_init( mbedtls_net_context *ctx ) -{ - ctx->fd = -1; -} - -/* - * Initiate a TCP connection with host:port and the given protocol - */ -int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, - const char *port, int proto ) -{ - int ret; - struct addrinfo hints, *addr_list, *cur; - - if( ( ret = net_prepare() ) != 0 ) - return( ret ); - - /* Do name resolution with both IPv6 and IPv4 */ - memset( &hints, 0, sizeof( hints ) ); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; - - if( getaddrinfo( host, port, &hints, &addr_list ) != 0 ) - return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); - - /* Try the sockaddrs until a connection succeeds */ - ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; - for( cur = addr_list; cur != NULL; cur = cur->ai_next ) - { - ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, - cur->ai_protocol ); - if( ctx->fd < 0 ) - { - ret = MBEDTLS_ERR_NET_SOCKET_FAILED; - continue; - } - - if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 ) - { - ret = 0; - break; - } - - close( ctx->fd ); - ret = MBEDTLS_ERR_NET_CONNECT_FAILED; - } - - freeaddrinfo( addr_list ); - - return( ret ); -} - -/* - * Create a listening socket on bind_ip:port - */ -int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ) -{ - int n, ret; - struct addrinfo hints, *addr_list, *cur; - - if( ( ret = net_prepare() ) != 0 ) - return( ret ); - - /* Bind to IPv6 and/or IPv4, but only in the desired protocol */ - memset( &hints, 0, sizeof( hints ) ); - hints.ai_family = AF_INET6; - hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; - if( bind_ip == NULL ) - hints.ai_flags = AI_PASSIVE; - - if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) - return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); - - /* Try the sockaddrs until a binding succeeds */ - ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; - for( cur = addr_list; cur != NULL; cur = cur->ai_next ) - { - ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, - cur->ai_protocol ); - if( ctx->fd < 0 ) - { - ret = MBEDTLS_ERR_NET_SOCKET_FAILED; - continue; - } - - n = 1; - if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR, - (const char *) &n, sizeof( n ) ) != 0 ) - { - close( ctx->fd ); - ret = MBEDTLS_ERR_NET_SOCKET_FAILED; - continue; - } - - if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 ) - { - close( ctx->fd ); - ret = MBEDTLS_ERR_NET_BIND_FAILED; - continue; - } - - /* Listen only makes sense for TCP */ - if( proto == MBEDTLS_NET_PROTO_TCP ) - { - if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 ) - { - close( ctx->fd ); - ret = MBEDTLS_ERR_NET_LISTEN_FAILED; - continue; - } - } - - /* Bind was successful */ - ret = 0; - break; - } - - freeaddrinfo( addr_list ); - - return( ret ); - -} - -#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) -/* - * Check if the requested operation would be blocking on a non-blocking socket - * and thus 'failed' with a negative return value. - */ -static int net_would_block( const mbedtls_net_context *ctx ) -{ - ((void) ctx); - return( WSAGetLastError() == WSAEWOULDBLOCK ); -} -#else -/* - * Check if the requested operation would be blocking on a non-blocking socket - * and thus 'failed' with a negative return value. - * - * Note: on a blocking socket this function always returns 0! - */ -static int net_would_block( const mbedtls_net_context *ctx ) -{ - int err = errno; - - /* - * Never return 'WOULD BLOCK' on a blocking socket - */ - if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK ) - { - errno = err; - return( 0 ); - } - - switch( errno = err ) - { -#if defined EAGAIN - case EAGAIN: -#endif -#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - return( 1 ); - } - return( 0 ); -} -#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ - -/* - * Accept a connection from a remote client - */ -int mbedtls_net_accept( mbedtls_net_context *bind_ctx, - mbedtls_net_context *client_ctx, - void *client_ip, size_t buf_size, size_t *ip_len ) -{ - int ret; - int type; - - struct sockaddr_storage client_addr; - -#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ - defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \ - ( defined(__NetBSD__) && defined(socklen_t) ) - socklen_t n = (socklen_t) sizeof( client_addr ); - socklen_t type_len = (socklen_t) sizeof( type ); -#else - int n = (int) sizeof( client_addr ); - int type_len = (int) sizeof( type ); -#endif - - /* Is this a TCP or UDP socket? */ - if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE, - (void *) &type, &type_len ) != 0 || - ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) - { - return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); - } - - if( type == SOCK_STREAM ) - { - /* TCP: actual accept() */ - ret = client_ctx->fd = (int) accept( bind_ctx->fd, - (struct sockaddr *) &client_addr, &n ); - } - else - { - /* UDP: wait for a message, but keep it in the queue */ - char buf[1] = { 0 }; - - ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK, - (struct sockaddr *) &client_addr, &n ); - -#if defined(_WIN32) - if( ret == SOCKET_ERROR && - WSAGetLastError() == WSAEMSGSIZE ) - { - /* We know buf is too small, thanks, just peeking here */ - ret = 0; - } -#endif - } - - if( ret < 0 ) - { - if( net_would_block( bind_ctx ) != 0 ) - return( MBEDTLS_ERR_SSL_WANT_READ ); - - return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); - } - - /* UDP: hijack the listening socket to communicate with the client, - * then bind a new socket to accept new connections */ - if( type != SOCK_STREAM ) - { - struct sockaddr_storage local_addr; - int one = 1; - - if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) - return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); - - client_ctx->fd = bind_ctx->fd; - bind_ctx->fd = -1; /* In case we exit early */ - - n = sizeof( struct sockaddr_storage ); - if( getsockname( client_ctx->fd, - (struct sockaddr *) &local_addr, &n ) != 0 || - ( bind_ctx->fd = (int) socket( local_addr.ss_family, - SOCK_DGRAM, IPPROTO_UDP ) ) < 0 || - setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR, - (const char *) &one, sizeof( one ) ) != 0 ) - { - return( MBEDTLS_ERR_NET_SOCKET_FAILED ); - } - - if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) - { - return( MBEDTLS_ERR_NET_BIND_FAILED ); - } - } - - if( client_ip != NULL ) - { - if( client_addr.ss_family == AF_INET ) - { - struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; - *ip_len = sizeof( addr4->sin_addr.s_addr ); - - if( buf_size < *ip_len ) - return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); - - memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); - } - else - { - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; - *ip_len = sizeof( addr6->sin6_addr.s6_addr ); - - if( buf_size < *ip_len ) - return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); - - memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len); - } - } - - return( 0 ); -} - -/* - * Set the socket blocking or non-blocking - */ -int mbedtls_net_set_block( mbedtls_net_context *ctx ) -{ -#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) - u_long n = 0; - return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); -#else - return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) ); -#endif -} - -int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ) -{ -#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) - u_long n = 1; - return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); -#else - return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) ); -#endif -} - -/* - * Check if data is available on the socket - */ - -int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout ) -{ - int ret; - struct timeval tv; - - fd_set read_fds; - fd_set write_fds; - - int fd = ctx->fd; - - ret = check_fd( fd, 1 ); - if( ret != 0 ) - return( ret ); - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) - /* Ensure that memory sanitizers consider read_fds and write_fds as - * initialized even on platforms such as Glibc/x86_64 where FD_ZERO - * is implemented in assembly. */ - memset( &read_fds, 0, sizeof( read_fds ) ); - memset( &write_fds, 0, sizeof( write_fds ) ); -#endif -#endif - - FD_ZERO( &read_fds ); - if( rw & MBEDTLS_NET_POLL_READ ) - { - rw &= ~MBEDTLS_NET_POLL_READ; - FD_SET( fd, &read_fds ); - } - - FD_ZERO( &write_fds ); - if( rw & MBEDTLS_NET_POLL_WRITE ) - { - rw &= ~MBEDTLS_NET_POLL_WRITE; - FD_SET( fd, &write_fds ); - } - - if( rw != 0 ) - return( MBEDTLS_ERR_NET_BAD_INPUT_DATA ); - - tv.tv_sec = timeout / 1000; - tv.tv_usec = ( timeout % 1000 ) * 1000; - - do - { - ret = select( fd + 1, &read_fds, &write_fds, NULL, - timeout == (uint32_t) -1 ? NULL : &tv ); - } - while( IS_EINTR( ret ) ); - - if( ret < 0 ) - return( MBEDTLS_ERR_NET_POLL_FAILED ); - - ret = 0; - if( FD_ISSET( fd, &read_fds ) ) - ret |= MBEDTLS_NET_POLL_READ; - if( FD_ISSET( fd, &write_fds ) ) - ret |= MBEDTLS_NET_POLL_WRITE; - - return( ret ); -} - -/* - * Portable usleep helper - */ -void mbedtls_net_usleep( unsigned long usec ) -{ -#if defined(_WIN32) - Sleep( ( usec + 999 ) / 1000 ); -#else - struct timeval tv; - tv.tv_sec = usec / 1000000; -#if defined(__unix__) || defined(__unix) || \ - ( defined(__APPLE__) && defined(__MACH__) ) - tv.tv_usec = (suseconds_t) usec % 1000000; -#else - tv.tv_usec = usec % 1000000; -#endif - select( 0, NULL, NULL, NULL, &tv ); -#endif -} - -/* - * Read at most 'len' characters - */ -int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ) -{ - int ret; - int fd = ((mbedtls_net_context *) ctx)->fd; - - ret = check_fd( fd, 0 ); - if( ret != 0 ) - return( ret ); - - ret = (int) read( fd, buf, len ); - - if( ret < 0 ) - { - if( net_would_block( ctx ) != 0 ) - return( MBEDTLS_ERR_SSL_WANT_READ ); - -#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) - if( WSAGetLastError() == WSAECONNRESET ) - return( MBEDTLS_ERR_NET_CONN_RESET ); -#else - if( errno == EPIPE || errno == ECONNRESET ) - return( MBEDTLS_ERR_NET_CONN_RESET ); - - if( errno == EINTR ) - return( MBEDTLS_ERR_SSL_WANT_READ ); -#endif - - return( MBEDTLS_ERR_NET_RECV_FAILED ); - } - - return( ret ); -} - -/* - * Read at most 'len' characters, blocking for at most 'timeout' ms - */ -int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, - size_t len, uint32_t timeout ) -{ - int ret; - struct timeval tv; - fd_set read_fds; - int fd = ((mbedtls_net_context *) ctx)->fd; - - ret = check_fd( fd, 1 ); - if( ret != 0 ) - return( ret ); - - FD_ZERO( &read_fds ); - FD_SET( fd, &read_fds ); - - tv.tv_sec = timeout / 1000; - tv.tv_usec = ( timeout % 1000 ) * 1000; - - ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv ); - - /* Zero fds ready means we timed out */ - if( ret == 0 ) - return( MBEDTLS_ERR_SSL_TIMEOUT ); - - if( ret < 0 ) - { -#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) - if( WSAGetLastError() == WSAEINTR ) - return( MBEDTLS_ERR_SSL_WANT_READ ); -#else - if( errno == EINTR ) - return( MBEDTLS_ERR_SSL_WANT_READ ); -#endif - - return( MBEDTLS_ERR_NET_RECV_FAILED ); - } - - /* This call will not block */ - return( mbedtls_net_recv( ctx, buf, len ) ); -} - -/* - * Write at most 'len' characters - */ -int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ) -{ - int ret; - int fd = ((mbedtls_net_context *) ctx)->fd; - - ret = check_fd( fd, 0 ); - if( ret != 0 ) - return( ret ); - - ret = (int) write( fd, buf, len ); - - if( ret < 0 ) - { - if( net_would_block( ctx ) != 0 ) - return( MBEDTLS_ERR_SSL_WANT_WRITE ); - -#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) - if( WSAGetLastError() == WSAECONNRESET ) - return( MBEDTLS_ERR_NET_CONN_RESET ); -#else - if( errno == EPIPE || errno == ECONNRESET ) - return( MBEDTLS_ERR_NET_CONN_RESET ); - - if( errno == EINTR ) - return( MBEDTLS_ERR_SSL_WANT_WRITE ); -#endif - - return( MBEDTLS_ERR_NET_SEND_FAILED ); - } - - return( ret ); -} - -/* - * Gracefully close the connection - */ -void mbedtls_net_free( mbedtls_net_context *ctx ) -{ - if( ctx->fd == -1 ) - return; - - shutdown( ctx->fd, 2 ); - close( ctx->fd ); - - ctx->fd = -1; -} - -#endif /* MBEDTLS_NET_C */ diff --git a/mbedtls/net_sockets.h b/mbedtls/net_sockets.h deleted file mode 100644 index 6b3cb216a..000000000 --- a/mbedtls/net_sockets.h +++ /dev/null @@ -1,309 +0,0 @@ -#pragma GCC system_header -/** - * \file net_sockets.h - * - * \brief Network sockets abstraction layer to integrate Mbed TLS into a - * BSD-style sockets API. - * - * The network sockets module provides an example integration of the - * Mbed TLS library into a BSD sockets implementation. The module is - * intended to be an example of how Mbed TLS can be integrated into a - * networking stack, as well as to be Mbed TLS's network integration - * for its supported platforms. - * - * The module is intended only to be used with the Mbed TLS library and - * is not intended to be used by third party application software - * directly. - * - * The supported platforms are as follows: - * * Microsoft Windows and Windows CE - * * POSIX/Unix platforms including Linux, OS X - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_NET_SOCKETS_H -#define MBEDTLS_NET_SOCKETS_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#include -#include - -#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */ -#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */ -#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */ -#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */ -#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */ -#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */ -#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */ -#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */ -#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */ -#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */ -#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */ -#define MBEDTLS_ERR_NET_POLL_FAILED -0x0047 /**< Polling the net context failed. */ -#define MBEDTLS_ERR_NET_BAD_INPUT_DATA -0x0049 /**< Input invalid. */ - -#define MBEDTLS_NET_LISTEN_BACKLOG 100 /**< The backlog that listen() should use. */ - -#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */ -#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */ - -#define MBEDTLS_NET_POLL_READ 1 /**< Used in \c mbedtls_net_poll to check for pending data */ -#define MBEDTLS_NET_POLL_WRITE 2 /**< Used in \c mbedtls_net_poll to check if write possible */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Wrapper type for sockets. - * - * Currently backed by just a file descriptor, but might be more in the future - * (eg two file descriptors for combined IPv4 + IPv6 support, or additional - * structures for hand-made UDP demultiplexing). - */ -typedef struct mbedtls_net_context -{ - int fd; /**< The underlying file descriptor */ -} -mbedtls_net_context; - -/** - * \brief Initialize a context - * Just makes the context ready to be used or freed safely. - * - * \param ctx Context to initialize - */ -void mbedtls_net_init( mbedtls_net_context *ctx ); - -/** - * \brief Initiate a connection with host:port in the given protocol - * - * \param ctx Socket to use - * \param host Host to connect to - * \param port Port to connect to - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_UNKNOWN_HOST, - * MBEDTLS_ERR_NET_CONNECT_FAILED - * - * \note Sets the socket in connected mode even with UDP. - */ -int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto ); - -/** - * \brief Create a receiving socket on bind_ip:port in the chosen - * protocol. If bind_ip == NULL, all interfaces are bound. - * - * \param ctx Socket to use - * \param bind_ip IP to bind to, can be NULL - * \param port Port number to use - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_UNKNOWN_HOST, - * MBEDTLS_ERR_NET_BIND_FAILED, - * MBEDTLS_ERR_NET_LISTEN_FAILED - * - * \note Regardless of the protocol, opens the sockets and binds it. - * In addition, make the socket listening if protocol is TCP. - */ -int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ); - -/** - * \brief Accept a connection from a remote client - * - * \param bind_ctx Relevant socket - * \param client_ctx Will contain the connected client socket - * \param client_ip Will contain the client IP address, can be NULL - * \param buf_size Size of the client_ip buffer - * \param ip_len Will receive the size of the client IP written, - * can be NULL if client_ip is null - * - * \return 0 if successful, or - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_BIND_FAILED, - * MBEDTLS_ERR_NET_ACCEPT_FAILED, or - * MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small, - * MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to - * non-blocking and accept() would block. - */ -int mbedtls_net_accept( mbedtls_net_context *bind_ctx, - mbedtls_net_context *client_ctx, - void *client_ip, size_t buf_size, size_t *ip_len ); - -/** - * \brief Check and wait for the context to be ready for read/write - * - * \note The current implementation of this function uses - * select() and returns an error if the file descriptor - * is \c FD_SETSIZE or greater. - * - * \param ctx Socket to check - * \param rw Bitflag composed of MBEDTLS_NET_POLL_READ and - * MBEDTLS_NET_POLL_WRITE specifying the events - * to wait for: - * - If MBEDTLS_NET_POLL_READ is set, the function - * will return as soon as the net context is available - * for reading. - * - If MBEDTLS_NET_POLL_WRITE is set, the function - * will return as soon as the net context is available - * for writing. - * \param timeout Maximal amount of time to wait before returning, - * in milliseconds. If \c timeout is zero, the - * function returns immediately. If \c timeout is - * -1u, the function blocks potentially indefinitely. - * - * \return Bitmask composed of MBEDTLS_NET_POLL_READ/WRITE - * on success or timeout, or a negative return code otherwise. - */ -int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout ); - -/** - * \brief Set the socket blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_block( mbedtls_net_context *ctx ); - -/** - * \brief Set the socket non-blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ); - -/** - * \brief Portable usleep helper - * - * \param usec Amount of microseconds to sleep - * - * \note Real amount of time slept will not be less than - * select()'s timeout granularity (typically, 10ms). - */ -void mbedtls_net_usleep( unsigned long usec ); - -/** - * \brief Read at most 'len' characters. If no error occurs, - * the actual amount read is returned. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * - * \return the number of bytes received, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_READ indicates read() would block. - */ -int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ); - -/** - * \brief Write at most 'len' characters. If no error occurs, - * the actual amount read is returned. - * - * \param ctx Socket - * \param buf The buffer to read from - * \param len The length of the buffer - * - * \return the number of bytes sent, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block. - */ -int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ); - -/** - * \brief Read at most 'len' characters, blocking for at most - * 'timeout' seconds. If no error occurs, the actual amount - * read is returned. - * - * \note The current implementation of this function uses - * select() and returns an error if the file descriptor - * is \c FD_SETSIZE or greater. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * \param timeout Maximum number of milliseconds to wait for data - * 0 means no timeout (wait forever) - * - * \return The number of bytes received if successful. - * MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out. - * MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. - * Another negative error code (MBEDTLS_ERR_NET_xxx) - * for other failures. - * - * \note This function will block (until data becomes available or - * timeout is reached) even if the socket is set to - * non-blocking. Handling timeouts with non-blocking reads - * requires a different strategy. - */ -int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, - uint32_t timeout ); - -/** - * \brief Gracefully shutdown the connection and free associated data - * - * \param ctx The context to free - */ -void mbedtls_net_free( mbedtls_net_context *ctx ); - -#ifdef __cplusplus -} -#endif - -#endif /* net_sockets.h */ diff --git a/mbedtls/nist_kw.c b/mbedtls/nist_kw.c deleted file mode 100644 index 3da3f89d9..000000000 --- a/mbedtls/nist_kw.c +++ /dev/null @@ -1,795 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes - * only - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * Definition of Key Wrapping: - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf - * RFC 3394 "Advanced Encryption Standard (AES) Key Wrap Algorithm" - * RFC 5649 "Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm" - * - * Note: RFC 3394 defines different methodology for intermediate operations for - * the wrapping and unwrapping operation than the definition in NIST SP 800-38F. - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_NIST_KW_C) - -#include "mbedtls/nist_kw.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#if !defined(MBEDTLS_NIST_KW_ALT) - -#define KW_SEMIBLOCK_LENGTH 8 -#define MIN_SEMIBLOCKS_COUNT 3 - -/* constant-time buffer comparison */ -static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n ) -{ - size_t i; - volatile const unsigned char *A = (volatile const unsigned char *) a; - volatile const unsigned char *B = (volatile const unsigned char *) b; - volatile unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - { - /* Read volatile data in order before computing diff. - * This avoids IAR compiler warning: - * 'the order of volatile accesses is undefined ..' */ - unsigned char x = A[i], y = B[i]; - diff |= x ^ y; - } - - return( diff ); -} - -/*! The 64-bit default integrity check value (ICV) for KW mode. */ -static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}; -/*! The 32-bit default integrity check value (ICV) for KWP mode. */ -static const unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6}; - -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -do { \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} while( 0 ) -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -do { \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} while( 0 ) -#endif - -/* - * Initialize context - */ -void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_nist_kw_context ) ); -} - -int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits, - const int is_wrap ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - cipher_info = mbedtls_cipher_info_from_values( cipher, - keybits, - MBEDTLS_MODE_ECB ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( cipher_info->block_size != 16 ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* - * SP 800-38F currently defines AES cipher as the only block cipher allowed: - * "For KW and KWP, the underlying block cipher shall be approved, and the - * block size shall be 128 bits. Currently, the AES block cipher, with key - * lengths of 128, 192, or 256 bits, is the only block cipher that fits - * this profile." - * Currently we don't support other 128 bit block ciphers for key wrapping, - * such as Camellia and Aria. - */ - if( cipher != MBEDTLS_CIPHER_ID_AES ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - mbedtls_cipher_free( &ctx->cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, - is_wrap ? MBEDTLS_ENCRYPT : - MBEDTLS_DECRYPT ) - ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Free context - */ -void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx ) -{ - mbedtls_cipher_free( &ctx->cipher_ctx ); - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_nist_kw_context ) ); -} - -/* - * Helper function for Xoring the uint64_t "t" with the encrypted A. - * Defined in NIST SP 800-38F section 6.1 - */ -static void calc_a_xor_t( unsigned char A[KW_SEMIBLOCK_LENGTH], uint64_t t ) -{ - size_t i = 0; - for( i = 0; i < sizeof( t ); i++ ) - { - A[i] ^= ( t >> ( ( sizeof( t ) - 1 - i ) * 8 ) ) & 0xff; - } -} - -/* - * KW-AE as defined in SP 800-38F section 6.2 - * KWP-AE as defined in SP 800-38F section 6.3 - */ -int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, - mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t *out_len, size_t out_size ) -{ - int ret = 0; - size_t semiblocks = 0; - size_t s; - size_t olen, padlen = 0; - uint64_t t = 0; - unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; - - *out_len = 0; - /* - * Generate the String to work on - */ - if( mode == MBEDTLS_KW_MODE_KW ) - { - if( out_size < in_len + KW_SEMIBLOCK_LENGTH ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - /* - * According to SP 800-38F Table 1, the plaintext length for KW - * must be between 2 to 2^54-1 semiblocks inclusive. - */ - if( in_len < 16 || -#if SIZE_MAX > 0x1FFFFFFFFFFFFF8 - in_len > 0x1FFFFFFFFFFFFF8 || -#endif - in_len % KW_SEMIBLOCK_LENGTH != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - memcpy( output, NIST_KW_ICV1, KW_SEMIBLOCK_LENGTH ); - memmove( output + KW_SEMIBLOCK_LENGTH, input, in_len ); - } - else - { - if( in_len % 8 != 0 ) - { - padlen = ( 8 - ( in_len % 8 ) ); - } - - if( out_size < in_len + KW_SEMIBLOCK_LENGTH + padlen ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - /* - * According to SP 800-38F Table 1, the plaintext length for KWP - * must be between 1 and 2^32-1 octets inclusive. - */ - if( in_len < 1 -#if SIZE_MAX > 0xFFFFFFFF - || in_len > 0xFFFFFFFF -#endif - ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 ); - PUT_UINT32_BE( ( in_len & 0xffffffff ), output, - KW_SEMIBLOCK_LENGTH / 2 ); - - memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len ); - memset( output + KW_SEMIBLOCK_LENGTH + in_len, 0, padlen ); - } - semiblocks = ( ( in_len + padlen ) / KW_SEMIBLOCK_LENGTH ) + 1; - - s = 6 * ( semiblocks - 1 ); - - if( mode == MBEDTLS_KW_MODE_KWP - && in_len <= KW_SEMIBLOCK_LENGTH ) - { - memcpy( inbuff, output, 16 ); - ret = mbedtls_cipher_update( &ctx->cipher_ctx, - inbuff, 16, output, &olen ); - if( ret != 0 ) - goto cleanup; - } - else - { - unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH; - unsigned char *A = output; - - /* - * Do the wrapping function W, as defined in RFC 3394 section 2.2.1 - */ - if( semiblocks < MIN_SEMIBLOCKS_COUNT ) - { - ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - goto cleanup; - } - - /* Calculate intermediate values */ - for( t = 1; t <= s; t++ ) - { - memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH ); - memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R2, KW_SEMIBLOCK_LENGTH ); - - ret = mbedtls_cipher_update( &ctx->cipher_ctx, - inbuff, 16, outbuff, &olen ); - if( ret != 0 ) - goto cleanup; - - memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); - calc_a_xor_t( A, t ); - - memcpy( R2, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); - R2 += KW_SEMIBLOCK_LENGTH; - if( R2 >= output + ( semiblocks * KW_SEMIBLOCK_LENGTH ) ) - R2 = output + KW_SEMIBLOCK_LENGTH; - } - } - - *out_len = semiblocks * KW_SEMIBLOCK_LENGTH; - -cleanup: - - if( ret != 0) - { - memset( output, 0, semiblocks * KW_SEMIBLOCK_LENGTH ); - } - mbedtls_platform_zeroize( inbuff, KW_SEMIBLOCK_LENGTH * 2 ); - mbedtls_platform_zeroize( outbuff, KW_SEMIBLOCK_LENGTH * 2 ); - - return( ret ); -} - -/* - * W-1 function as defined in RFC 3394 section 2.2.2 - * This function assumes the following: - * 1. Output buffer is at least of size ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH. - * 2. The input buffer is of size semiblocks * KW_SEMIBLOCK_LENGTH. - * 3. Minimal number of semiblocks is 3. - * 4. A is a buffer to hold the first semiblock of the input buffer. - */ -static int unwrap( mbedtls_nist_kw_context *ctx, - const unsigned char *input, size_t semiblocks, - unsigned char A[KW_SEMIBLOCK_LENGTH], - unsigned char *output, size_t* out_len ) -{ - int ret = 0; - const size_t s = 6 * ( semiblocks - 1 ); - size_t olen; - uint64_t t = 0; - unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char *R = NULL; - *out_len = 0; - - if( semiblocks < MIN_SEMIBLOCKS_COUNT ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - memcpy( A, input, KW_SEMIBLOCK_LENGTH ); - memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH ); - R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH; - - /* Calculate intermediate values */ - for( t = s; t >= 1; t-- ) - { - calc_a_xor_t( A, t ); - - memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH ); - memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R, KW_SEMIBLOCK_LENGTH ); - - ret = mbedtls_cipher_update( &ctx->cipher_ctx, - inbuff, 16, outbuff, &olen ); - if( ret != 0 ) - goto cleanup; - - memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); - - /* Set R as LSB64 of outbuff */ - memcpy( R, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); - - if( R == output ) - R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH; - else - R -= KW_SEMIBLOCK_LENGTH; - } - - *out_len = ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH; - -cleanup: - if( ret != 0) - memset( output, 0, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH ); - mbedtls_platform_zeroize( inbuff, sizeof( inbuff ) ); - mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) ); - - return( ret ); -} - -/* - * KW-AD as defined in SP 800-38F section 6.2 - * KWP-AD as defined in SP 800-38F section 6.3 - */ -int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, - mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t *out_len, size_t out_size ) -{ - int ret = 0; - size_t i, olen; - unsigned char A[KW_SEMIBLOCK_LENGTH]; - unsigned char diff, bad_padding = 0; - - *out_len = 0; - if( out_size < in_len - KW_SEMIBLOCK_LENGTH ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - if( mode == MBEDTLS_KW_MODE_KW ) - { - /* - * According to SP 800-38F Table 1, the ciphertext length for KW - * must be between 3 to 2^54 semiblocks inclusive. - */ - if( in_len < 24 || -#if SIZE_MAX > 0x200000000000000 - in_len > 0x200000000000000 || -#endif - in_len % KW_SEMIBLOCK_LENGTH != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH, - A, output, out_len ); - if( ret != 0 ) - goto cleanup; - - /* Check ICV in "constant-time" */ - diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH ); - - if( diff != 0 ) - { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - goto cleanup; - } - - } - else if( mode == MBEDTLS_KW_MODE_KWP ) - { - size_t padlen = 0; - uint32_t Plen; - /* - * According to SP 800-38F Table 1, the ciphertext length for KWP - * must be between 2 to 2^29 semiblocks inclusive. - */ - if( in_len < KW_SEMIBLOCK_LENGTH * 2 || -#if SIZE_MAX > 0x100000000 - in_len > 0x100000000 || -#endif - in_len % KW_SEMIBLOCK_LENGTH != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - if( in_len == KW_SEMIBLOCK_LENGTH * 2 ) - { - unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; - ret = mbedtls_cipher_update( &ctx->cipher_ctx, - input, 16, outbuff, &olen ); - if( ret != 0 ) - goto cleanup; - - memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); - memcpy( output, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); - mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) ); - *out_len = KW_SEMIBLOCK_LENGTH; - } - else - { - /* in_len >= KW_SEMIBLOCK_LENGTH * 3 */ - ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH, - A, output, out_len ); - if( ret != 0 ) - goto cleanup; - } - - /* Check ICV in "constant-time" */ - diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 ); - - if( diff != 0 ) - { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 ); - - /* - * Plen is the length of the plaintext, when the input is valid. - * If Plen is larger than the plaintext and padding, padlen will be - * larger than 8, because of the type wrap around. - */ - padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen; - if ( padlen > 7 ) - { - padlen &= 7; - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - /* Check padding in "constant-time" */ - for( diff = 0, i = 0; i < KW_SEMIBLOCK_LENGTH; i++ ) - { - if( i >= KW_SEMIBLOCK_LENGTH - padlen ) - diff |= output[*out_len - KW_SEMIBLOCK_LENGTH + i]; - else - bad_padding |= output[*out_len - KW_SEMIBLOCK_LENGTH + i]; - } - - if( diff != 0 ) - { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - if( ret != 0 ) - { - goto cleanup; - } - memset( output + Plen, 0, padlen ); - *out_len = Plen; - } - else - { - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto cleanup; - } - -cleanup: - if( ret != 0 ) - { - memset( output, 0, *out_len ); - *out_len = 0; - } - - mbedtls_platform_zeroize( &bad_padding, sizeof( bad_padding) ); - mbedtls_platform_zeroize( &diff, sizeof( diff ) ); - mbedtls_platform_zeroize( A, sizeof( A ) ); - - return( ret ); -} - -#endif /* !MBEDTLS_NIST_KW_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) - -#define KW_TESTS 3 - -/* - * Test vectors taken from NIST - * https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#KW - */ -static const unsigned int key_len[KW_TESTS] = { 16, 24, 32 }; - -static const unsigned char kw_key[KW_TESTS][32] = { - { 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2, - 0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 }, - { 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b, - 0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d, - 0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 }, - { 0x11, 0x2a, 0xd4, 0x1b, 0x48, 0x56, 0xc7, 0x25, - 0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33, - 0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d, - 0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 } -}; - -static const unsigned char kw_msg[KW_TESTS][40] = { - { 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea, - 0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f }, - { 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb, - 0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d, - 0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45, - 0xc0, 0x9d, 0x15, 0x8f, 0x51, 0xce, 0x62, 0x9d, - 0xe2, 0xaf, 0x26, 0xe3, 0x25, 0x0e, 0x6b, 0x4c }, - { 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7, - 0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8, - 0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 } -}; - -static const size_t kw_msg_len[KW_TESTS] = { 16, 40, 24 }; -static const size_t kw_out_len[KW_TESTS] = { 24, 48, 32 }; -static const unsigned char kw_res[KW_TESTS][48] = { - { 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d, - 0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3, - 0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb }, - { 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91, - 0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec, - 0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d, - 0x6c, 0x42, 0x6f, 0xc6, 0x97, 0x15, 0x63, 0xe8, - 0xa1, 0x4a, 0x55, 0x8e, 0x09, 0x64, 0x16, 0x19, - 0xbf, 0x03, 0xfc, 0xaf, 0x90, 0xb1, 0xfc, 0x2d }, - { 0xba, 0x8a, 0x25, 0x9a, 0x47, 0x1b, 0x78, 0x7d, - 0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87, - 0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9, - 0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 } -}; - -static const unsigned char kwp_key[KW_TESTS][32] = { - { 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a, - 0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 }, - { 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98, - 0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7, - 0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 }, - { 0x95, 0xda, 0x27, 0x00, 0xca, 0x6f, 0xd9, 0xa5, - 0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f, - 0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae, - 0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a } -}; - -static const unsigned char kwp_msg[KW_TESTS][31] = { - { 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8, - 0x96 }, - { 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb, - 0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19, - 0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66, - 0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f }, - { 0xd1 } -}; -static const size_t kwp_msg_len[KW_TESTS] = { 9, 31, 1 }; - -static const unsigned char kwp_res[KW_TESTS][48] = { - { 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e, - 0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7, - 0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 }, - { 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13, - 0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88, - 0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63, - 0x8b, 0xcc, 0x81, 0x66, 0x84, 0x68, 0x17, 0x90, - 0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 }, - { 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd, - 0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4 } -}; -static const size_t kwp_out_len[KW_TESTS] = { 24, 40, 16 }; - -int mbedtls_nist_kw_self_test( int verbose ) -{ - mbedtls_nist_kw_context ctx; - unsigned char out[48]; - size_t olen; - int i; - int ret = 0; - mbedtls_nist_kw_init( &ctx ); - - for( i = 0; i < KW_TESTS; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " KW-AES-%u ", (unsigned int) key_len[i] * 8 ); - - ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, - kw_key[i], key_len[i] * 8, 1 ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " KW: setup failed " ); - - goto end; - } - - ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KW, kw_msg[i], - kw_msg_len[i], out, &olen, sizeof( out ) ); - if( ret != 0 || kw_out_len[i] != olen || - memcmp( out, kw_res[i], kw_out_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed. "); - - ret = 1; - goto end; - } - - if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, - kw_key[i], key_len[i] * 8, 0 ) ) - != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " KW: setup failed "); - - goto end; - } - - ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KW, - out, olen, out, &olen, sizeof( out ) ); - - if( ret != 0 || olen != kw_msg_len[i] || - memcmp( out, kw_msg[i], kw_msg_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto end; - } - - if( verbose != 0 ) - mbedtls_printf( " passed\n" ); - } - - for( i = 0; i < KW_TESTS; i++ ) - { - olen = sizeof( out ); - if( verbose != 0 ) - mbedtls_printf( " KWP-AES-%u ", (unsigned int) key_len[i] * 8 ); - - ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i], - key_len[i] * 8, 1 ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " KWP: setup failed " ); - - goto end; - } - ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i], - kwp_msg_len[i], out, &olen, sizeof( out ) ); - - if( ret != 0 || kwp_out_len[i] != olen || - memcmp( out, kwp_res[i], kwp_out_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed. "); - - ret = 1; - goto end; - } - - if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, - kwp_key[i], key_len[i] * 8, 0 ) ) - != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " KWP: setup failed "); - - goto end; - } - - ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KWP, out, - olen, out, &olen, sizeof( out ) ); - - if( ret != 0 || olen != kwp_msg_len[i] || - memcmp( out, kwp_msg[i], kwp_msg_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed. "); - - ret = 1; - goto end; - } - - if( verbose != 0 ) - mbedtls_printf( " passed\n" ); - } -end: - mbedtls_nist_kw_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_NIST_KW_C */ diff --git a/mbedtls/nist_kw.h b/mbedtls/nist_kw.h deleted file mode 100644 index 413596494..000000000 --- a/mbedtls/nist_kw.h +++ /dev/null @@ -1,210 +0,0 @@ -#pragma GCC system_header -/** - * \file nist_kw.h - * - * \brief This file provides an API for key wrapping (KW) and key wrapping with - * padding (KWP) as defined in NIST SP 800-38F. - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf - * - * Key wrapping specifies a deterministic authenticated-encryption mode - * of operation, according to NIST SP 800-38F: Recommendation for - * Block Cipher Modes of Operation: Methods for Key Wrapping. Its - * purpose is to protect cryptographic keys. - * - * Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP. - * https://tools.ietf.org/html/rfc3394 - * https://tools.ietf.org/html/rfc5649 - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_NIST_KW_H -#define MBEDTLS_NIST_KW_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "cipher.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum -{ - MBEDTLS_KW_MODE_KW = 0, - MBEDTLS_KW_MODE_KWP = 1 -} mbedtls_nist_kw_mode_t; - -#if !defined(MBEDTLS_NIST_KW_ALT) -// Regular implementation -// - -/** - * \brief The key wrapping context-type definition. The key wrapping context is passed - * to the APIs called. - * - * \note The definition of this type may change in future library versions. - * Don't make any assumptions on this context! - */ -typedef struct { - mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ -} mbedtls_nist_kw_context; - -#else /* MBEDTLS_NIST_key wrapping_ALT */ -#include "nist_kw_alt.h" -#endif /* MBEDTLS_NIST_KW_ALT */ - -/** - * \brief This function initializes the specified key wrapping context - * to make references valid and prepare the context - * for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free(). - * - * \param ctx The key wrapping context to initialize. - * - */ -void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx ); - -/** - * \brief This function initializes the key wrapping context set in the - * \p ctx parameter and sets the encryption key. - * - * \param ctx The key wrapping context. - * \param cipher The 128-bit block cipher to use. Only AES is supported. - * \param key The Key Encryption Key (KEK). - * \param keybits The KEK size in bits. This must be acceptable by the cipher. - * \param is_wrap Specify whether the operation within the context is wrapping or unwrapping - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input. - * \return \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers - * which are not supported. - * \return cipher-specific error code on failure of the underlying cipher. - */ -int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits, - const int is_wrap ); - -/** - * \brief This function releases and clears the specified key wrapping context - * and underlying cipher sub-context. - * - * \param ctx The key wrapping context to clear. - */ -void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx ); - -/** - * \brief This function encrypts a buffer using key wrapping. - * - * \param ctx The key wrapping context to use for encryption. - * \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) - * \param input The buffer holding the input data. - * \param in_len The length of the input data in Bytes. - * The input uses units of 8 Bytes called semiblocks. - *
    • For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive.
    • - *
    • For KWP mode: any length between 1 and 2^32-1 inclusive.
    - * \param[out] output The buffer holding the output data. - *
    • For KW mode: Must be at least 8 bytes larger than \p in_len.
    • - *
    • For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of - * 8 bytes for KWP (15 bytes at most).
    - * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. - * \param[in] out_size The capacity of the output buffer. - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. - * \return cipher-specific error code on failure of the underlying cipher. - */ -int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t* out_len, size_t out_size ); - -/** - * \brief This function decrypts a buffer using key wrapping. - * - * \param ctx The key wrapping context to use for decryption. - * \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) - * \param input The buffer holding the input data. - * \param in_len The length of the input data in Bytes. - * The input uses units of 8 Bytes called semiblocks. - * The input must be a multiple of semiblocks. - *
    • For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive.
    • - *
    • For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.
    - * \param[out] output The buffer holding the output data. - * The output buffer's minimal length is 8 bytes shorter than \p in_len. - * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. - * For KWP mode, the length could be up to 15 bytes shorter than \p in_len, - * depending on how much padding was added to the data. - * \param[in] out_size The capacity of the output buffer. - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. - * \return \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext. - * \return cipher-specific error code on failure of the underlying cipher. - */ -int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t* out_len, size_t out_size); - - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/** - * \brief The key wrapping checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_nist_kw_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_NIST_KW_H */ diff --git a/mbedtls/oid.c b/mbedtls/oid.c deleted file mode 100644 index 860d5479c..000000000 --- a/mbedtls/oid.c +++ /dev/null @@ -1,796 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file oid.c - * - * \brief Object Identifier (OID) database - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_OID_C) - -#include "mbedtls/oid.h" -#include "mbedtls/rsa.h" - -#include -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#define mbedtls_snprintf snprintf -#endif - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) -#include "mbedtls/x509.h" -#endif - -/* - * Macro to automatically add the size of #define'd OIDs - */ -#define ADD_LEN(s) s, MBEDTLS_OID_SIZE(s) - -/* - * Macro to generate an internal function for oid_XXX_from_asn1() (used by - * the other functions) - */ -#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ - static const TYPE_T * oid_ ## NAME ## _from_asn1( \ - const mbedtls_asn1_buf *oid ) \ - { \ - const TYPE_T *p = (LIST); \ - const mbedtls_oid_descriptor_t *cur = \ - (const mbedtls_oid_descriptor_t *) p; \ - if( p == NULL || oid == NULL ) return( NULL ); \ - while( cur->asn1 != NULL ) { \ - if( cur->asn1_len == oid->len && \ - memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \ - return( p ); \ - } \ - p++; \ - cur = (const mbedtls_oid_descriptor_t *) p; \ - } \ - return( NULL ); \ - } - -/* - * Macro to generate a function for retrieving a single attribute from the - * descriptor of an mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ -int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ -{ \ - const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ - *ATTR1 = data->descriptor.ATTR1; \ - return( 0 ); \ -} - -/* - * Macro to generate a function for retrieving a single attribute from an - * mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ -int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ -{ \ - const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ - *ATTR1 = data->ATTR1; \ - return( 0 ); \ -} - -/* - * Macro to generate a function for retrieving two attributes from an - * mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \ - ATTR2_TYPE, ATTR2) \ -int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \ - ATTR2_TYPE * ATTR2 ) \ -{ \ - const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ - *(ATTR1) = data->ATTR1; \ - *(ATTR2) = data->ATTR2; \ - return( 0 ); \ -} - -/* - * Macro to generate a function for retrieving the OID based on a single - * attribute from a mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \ -int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ -{ \ - const TYPE_T *cur = (LIST); \ - while( cur->descriptor.asn1 != NULL ) { \ - if( cur->ATTR1 == (ATTR1) ) { \ - *oid = cur->descriptor.asn1; \ - *olen = cur->descriptor.asn1_len; \ - return( 0 ); \ - } \ - cur++; \ - } \ - return( MBEDTLS_ERR_OID_NOT_FOUND ); \ -} - -/* - * Macro to generate a function for retrieving the OID based on two - * attributes from a mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \ - ATTR2_TYPE, ATTR2) \ -int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ - size_t *olen ) \ -{ \ - const TYPE_T *cur = (LIST); \ - while( cur->descriptor.asn1 != NULL ) { \ - if( cur->ATTR1 == (ATTR1) && cur->ATTR2 == (ATTR2) ) { \ - *oid = cur->descriptor.asn1; \ - *olen = cur->descriptor.asn1_len; \ - return( 0 ); \ - } \ - cur++; \ - } \ - return( MBEDTLS_ERR_OID_NOT_FOUND ); \ -} - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) -/* - * For X520 attribute types - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - const char *short_name; -} oid_x520_attr_t; - -static const oid_x520_attr_t oid_x520_attr_type[] = -{ - { - { ADD_LEN( MBEDTLS_OID_AT_CN ), "id-at-commonName", "Common Name" }, - "CN", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_COUNTRY ), "id-at-countryName", "Country" }, - "C", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_LOCALITY ), "id-at-locality", "Locality" }, - "L", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_STATE ), "id-at-state", "State" }, - "ST", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" }, - "O", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" }, - "OU", - }, - { - { ADD_LEN( MBEDTLS_OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" }, - "emailAddress", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" }, - "serialNumber", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" }, - "postalAddress", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" }, - "postalCode", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_SUR_NAME ), "id-at-surName", "Surname" }, - "SN", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" }, - "GN", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_INITIALS ), "id-at-initials", "Initials" }, - "initials", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" }, - "generationQualifier", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_TITLE ), "id-at-title", "Title" }, - "title", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" }, - "dnQualifier", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" }, - "pseudonym", - }, - { - { ADD_LEN( MBEDTLS_OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" }, - "DC", - }, - { - { ADD_LEN( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER ), "id-at-uniqueIdentifier", "Unique Identifier" }, - "uniqueIdentifier", - }, - { - { NULL, 0, NULL, NULL }, - NULL, - } -}; - -FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type) -FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name) - -/* - * For X509 extensions - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - int ext_type; -} oid_x509_ext_t; - -static const oid_x509_ext_t oid_x509_ext[] = -{ - { - { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" }, - MBEDTLS_X509_EXT_BASIC_CONSTRAINTS, - }, - { - { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" }, - MBEDTLS_X509_EXT_KEY_USAGE, - }, - { - { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" }, - MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE, - }, - { - { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" }, - MBEDTLS_X509_EXT_SUBJECT_ALT_NAME, - }, - { - { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" }, - MBEDTLS_X509_EXT_NS_CERT_TYPE, - }, - { - { NULL, 0, NULL, NULL }, - 0, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext) -FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type) - -static const mbedtls_oid_descriptor_t oid_ext_key_usage[] = -{ - { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" }, - { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" }, - { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" }, - { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" }, - { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" }, - { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" }, - { NULL, 0, NULL, NULL }, -}; - -FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage) -FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description) -#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ - -#if defined(MBEDTLS_MD_C) -/* - * For SignatureAlgorithmIdentifier - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_alg; - mbedtls_pk_type_t pk_alg; -} oid_sig_alg_t; - -static const oid_sig_alg_t oid_sig_alg[] = -{ -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_MD2_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" }, - MBEDTLS_MD_MD2, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD2_C */ -#if defined(MBEDTLS_MD4_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" }, - MBEDTLS_MD_MD4, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD4_C */ -#if defined(MBEDTLS_MD5_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" }, - MBEDTLS_MD_MD5, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD5_C */ -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" }, - MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" }, - MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA, - }, - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, - MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" }, - MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA, - }, - { - { ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, - MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_SHA512_C */ -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" }, - MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECDSA_C) -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, - MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, - MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, - }, - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, - MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, - MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, - }, - { - { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, - MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_ECDSA_C */ -#if defined(MBEDTLS_RSA_C) - { - { ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, - MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS, - }, -#endif /* MBEDTLS_RSA_C */ - { - { NULL, 0, NULL, NULL }, - MBEDTLS_MD_NONE, MBEDTLS_PK_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg) -FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description) -FN_OID_GET_ATTR2(mbedtls_oid_get_sig_alg, oid_sig_alg_t, sig_alg, mbedtls_md_type_t, md_alg, mbedtls_pk_type_t, pk_alg) -FN_OID_GET_OID_BY_ATTR2(mbedtls_oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, mbedtls_pk_type_t, pk_alg, mbedtls_md_type_t, md_alg) -#endif /* MBEDTLS_MD_C */ - -/* - * For PublicKeyInfo (PKCS1, RFC 5480) - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_pk_type_t pk_alg; -} oid_pk_alg_t; - -static const oid_pk_alg_t oid_pk_alg[] = -{ - { - { ADD_LEN( MBEDTLS_OID_PKCS1_RSA ), "rsaEncryption", "RSA" }, - MBEDTLS_PK_RSA, - }, - { - { ADD_LEN( MBEDTLS_OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" }, - MBEDTLS_PK_ECKEY, - }, - { - { ADD_LEN( MBEDTLS_OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" }, - MBEDTLS_PK_ECKEY_DH, - }, - { - { NULL, 0, NULL, NULL }, - MBEDTLS_PK_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg) -FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg) - -#if defined(MBEDTLS_ECP_C) -/* - * For namedCurve (RFC 5480) - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_ecp_group_id grp_id; -} oid_ecp_grp_t; - -static const oid_ecp_grp_t oid_ecp_grp[] = -{ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" }, - MBEDTLS_ECP_DP_SECP192R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" }, - MBEDTLS_ECP_DP_SECP224R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" }, - MBEDTLS_ECP_DP_SECP256R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" }, - MBEDTLS_ECP_DP_SECP384R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, - MBEDTLS_ECP_DP_SECP521R1, - }, -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, - MBEDTLS_ECP_DP_SECP192K1, - }, -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, - MBEDTLS_ECP_DP_SECP224K1, - }, -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, - MBEDTLS_ECP_DP_SECP256K1, - }, -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, - MBEDTLS_ECP_DP_BP256R1, - }, -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" }, - MBEDTLS_ECP_DP_BP384R1, - }, -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - { - { ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" }, - MBEDTLS_ECP_DP_BP512R1, - }, -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - { - { NULL, 0, NULL, NULL }, - MBEDTLS_ECP_DP_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp) -FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id) -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_CIPHER_C) -/* - * For PKCS#5 PBES2 encryption algorithm - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_cipher_type_t cipher_alg; -} oid_cipher_alg_t; - -static const oid_cipher_alg_t oid_cipher_alg[] = -{ - { - { ADD_LEN( MBEDTLS_OID_DES_CBC ), "desCBC", "DES-CBC" }, - MBEDTLS_CIPHER_DES_CBC, - }, - { - { ADD_LEN( MBEDTLS_OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" }, - MBEDTLS_CIPHER_DES_EDE3_CBC, - }, - { - { NULL, 0, NULL, NULL }, - MBEDTLS_CIPHER_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg) -FN_OID_GET_ATTR1(mbedtls_oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, mbedtls_cipher_type_t, cipher_alg) -#endif /* MBEDTLS_CIPHER_C */ - -#if defined(MBEDTLS_MD_C) -/* - * For digestAlgorithm - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_alg; -} oid_md_alg_t; - -static const oid_md_alg_t oid_md_alg[] = -{ -#if defined(MBEDTLS_MD2_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, - MBEDTLS_MD_MD2, - }, -#endif /* MBEDTLS_MD2_C */ -#if defined(MBEDTLS_MD4_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, - MBEDTLS_MD_MD4, - }, -#endif /* MBEDTLS_MD4_C */ -#if defined(MBEDTLS_MD5_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, - MBEDTLS_MD_MD5, - }, -#endif /* MBEDTLS_MD5_C */ -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, - MBEDTLS_MD_SHA1, - }, -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, - MBEDTLS_MD_SHA224, - }, - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, - MBEDTLS_MD_SHA256, - }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, - MBEDTLS_MD_SHA384, - }, - { - { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, - MBEDTLS_MD_SHA512, - }, -#endif /* MBEDTLS_SHA512_C */ - { - { NULL, 0, NULL, NULL }, - MBEDTLS_MD_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg) -FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg) - -/* - * For HMAC digestAlgorithm - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_hmac; -} oid_md_hmac_t; - -static const oid_md_hmac_t oid_md_hmac[] = -{ -#if defined(MBEDTLS_SHA1_C) - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" }, - MBEDTLS_MD_SHA1, - }, -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" }, - MBEDTLS_MD_SHA224, - }, - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" }, - MBEDTLS_MD_SHA256, - }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" }, - MBEDTLS_MD_SHA384, - }, - { - { ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" }, - MBEDTLS_MD_SHA512, - }, -#endif /* MBEDTLS_SHA512_C */ - { - { NULL, 0, NULL, NULL }, - MBEDTLS_MD_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac) -FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac) -#endif /* MBEDTLS_MD_C */ - -#if defined(MBEDTLS_PKCS12_C) -/* - * For PKCS#12 PBEs - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_alg; - mbedtls_cipher_type_t cipher_alg; -} oid_pkcs12_pbe_alg_t; - -static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = -{ - { - { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" }, - MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE3_CBC, - }, - { - { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" }, - MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE_CBC, - }, - { - { NULL, 0, NULL, NULL }, - MBEDTLS_MD_NONE, MBEDTLS_CIPHER_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg) -FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, mbedtls_md_type_t, md_alg, mbedtls_cipher_type_t, cipher_alg) -#endif /* MBEDTLS_PKCS12_C */ - -#define OID_SAFE_SNPRINTF \ - do { \ - if( ret < 0 || (size_t) ret >= n ) \ - return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); \ - \ - n -= (size_t) ret; \ - p += (size_t) ret; \ - } while( 0 ) - -/* Return the x.y.z.... style numeric string for the given OID */ -int mbedtls_oid_get_numeric_string( char *buf, size_t size, - const mbedtls_asn1_buf *oid ) -{ - int ret; - size_t i, n; - unsigned int value; - char *p; - - p = buf; - n = size; - - /* First byte contains first two dots */ - if( oid->len > 0 ) - { - ret = mbedtls_snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 ); - OID_SAFE_SNPRINTF; - } - - value = 0; - for( i = 1; i < oid->len; i++ ) - { - /* Prevent overflow in value. */ - if( ( ( value << 7 ) >> 7 ) != value ) - return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); - - value <<= 7; - value += oid->p[i] & 0x7F; - - if( !( oid->p[i] & 0x80 ) ) - { - /* Last byte */ - ret = mbedtls_snprintf( p, n, ".%d", value ); - OID_SAFE_SNPRINTF; - value = 0; - } - } - - return( (int) ( size - n ) ); -} - -#endif /* MBEDTLS_OID_C */ diff --git a/mbedtls/oid.h b/mbedtls/oid.h deleted file mode 100644 index ef6ada41b..000000000 --- a/mbedtls/oid.h +++ /dev/null @@ -1,631 +0,0 @@ -#pragma GCC system_header -/** - * \file oid.h - * - * \brief Object Identifier (OID) database - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_OID_H -#define MBEDTLS_OID_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "asn1.h" -#include "pk.h" - -#include - -#if defined(MBEDTLS_CIPHER_C) -#include "cipher.h" -#endif - -#if defined(MBEDTLS_MD_C) -#include "md.h" -#endif - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) -#include "x509.h" -#endif - -#define MBEDTLS_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */ -#define MBEDTLS_ERR_OID_BUF_TOO_SMALL -0x000B /**< output buffer is too small */ - -/* - * Top level OID tuples - */ -#define MBEDTLS_OID_ISO_MEMBER_BODIES "\x2a" /* {iso(1) member-body(2)} */ -#define MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x2b" /* {iso(1) identified-organization(3)} */ -#define MBEDTLS_OID_ISO_CCITT_DS "\x55" /* {joint-iso-ccitt(2) ds(5)} */ -#define MBEDTLS_OID_ISO_ITU_COUNTRY "\x60" /* {joint-iso-itu-t(2) country(16)} */ - -/* - * ISO Member bodies OID parts - */ -#define MBEDTLS_OID_COUNTRY_US "\x86\x48" /* {us(840)} */ -#define MBEDTLS_OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */ -#define MBEDTLS_OID_RSA_COMPANY MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \ - MBEDTLS_OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */ -#define MBEDTLS_OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */ -#define MBEDTLS_OID_ANSI_X9_62 MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \ - MBEDTLS_OID_ORG_ANSI_X9_62 - -/* - * ISO Identified organization OID parts - */ -#define MBEDTLS_OID_ORG_DOD "\x06" /* {dod(6)} */ -#define MBEDTLS_OID_ORG_OIW "\x0e" -#define MBEDTLS_OID_OIW_SECSIG MBEDTLS_OID_ORG_OIW "\x03" -#define MBEDTLS_OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG "\x02" -#define MBEDTLS_OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_ALG "\x1a" -#define MBEDTLS_OID_ORG_CERTICOM "\x81\x04" /* certicom(132) */ -#define MBEDTLS_OID_CERTICOM MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_CERTICOM -#define MBEDTLS_OID_ORG_TELETRUST "\x24" /* teletrust(36) */ -#define MBEDTLS_OID_TELETRUST MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_TELETRUST - -/* - * ISO ITU OID parts - */ -#define MBEDTLS_OID_ORGANIZATION "\x01" /* {organization(1)} */ -#define MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ISO_ITU_COUNTRY MBEDTLS_OID_COUNTRY_US MBEDTLS_OID_ORGANIZATION /* {joint-iso-itu-t(2) country(16) us(840) organization(1)} */ - -#define MBEDTLS_OID_ORG_GOV "\x65" /* {gov(101)} */ -#define MBEDTLS_OID_GOV MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_GOV /* {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)} */ - -#define MBEDTLS_OID_ORG_NETSCAPE "\x86\xF8\x42" /* {netscape(113730)} */ -#define MBEDTLS_OID_NETSCAPE MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_NETSCAPE /* Netscape OID {joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730)} */ - -/* ISO arc for standard certificate and CRL extensions */ -#define MBEDTLS_OID_ID_CE MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */ - -#define MBEDTLS_OID_NIST_ALG MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */ - -/** - * Private Internet Extensions - * { iso(1) identified-organization(3) dod(6) internet(1) - * security(5) mechanisms(5) pkix(7) } - */ -#define MBEDTLS_OID_PKIX MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x05\x05\x07" - -/* - * Arc for standard naming attributes - */ -#define MBEDTLS_OID_AT MBEDTLS_OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */ -#define MBEDTLS_OID_AT_CN MBEDTLS_OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */ -#define MBEDTLS_OID_AT_SUR_NAME MBEDTLS_OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */ -#define MBEDTLS_OID_AT_SERIAL_NUMBER MBEDTLS_OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */ -#define MBEDTLS_OID_AT_COUNTRY MBEDTLS_OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */ -#define MBEDTLS_OID_AT_LOCALITY MBEDTLS_OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */ -#define MBEDTLS_OID_AT_STATE MBEDTLS_OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */ -#define MBEDTLS_OID_AT_ORGANIZATION MBEDTLS_OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */ -#define MBEDTLS_OID_AT_ORG_UNIT MBEDTLS_OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */ -#define MBEDTLS_OID_AT_TITLE MBEDTLS_OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */ -#define MBEDTLS_OID_AT_POSTAL_ADDRESS MBEDTLS_OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */ -#define MBEDTLS_OID_AT_POSTAL_CODE MBEDTLS_OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */ -#define MBEDTLS_OID_AT_GIVEN_NAME MBEDTLS_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */ -#define MBEDTLS_OID_AT_INITIALS MBEDTLS_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */ -#define MBEDTLS_OID_AT_GENERATION_QUALIFIER MBEDTLS_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */ -#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributType:= {id-at 45} */ -#define MBEDTLS_OID_AT_DN_QUALIFIER MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */ -#define MBEDTLS_OID_AT_PSEUDONYM MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */ - -#define MBEDTLS_OID_DOMAIN_COMPONENT "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */ - -/* - * OIDs for standard certificate extensions - */ -#define MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } */ -#define MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } */ -#define MBEDTLS_OID_KEY_USAGE MBEDTLS_OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } */ -#define MBEDTLS_OID_CERTIFICATE_POLICIES MBEDTLS_OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } */ -#define MBEDTLS_OID_POLICY_MAPPINGS MBEDTLS_OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } */ -#define MBEDTLS_OID_SUBJECT_ALT_NAME MBEDTLS_OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } */ -#define MBEDTLS_OID_ISSUER_ALT_NAME MBEDTLS_OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } */ -#define MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } */ -#define MBEDTLS_OID_BASIC_CONSTRAINTS MBEDTLS_OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } */ -#define MBEDTLS_OID_NAME_CONSTRAINTS MBEDTLS_OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } */ -#define MBEDTLS_OID_POLICY_CONSTRAINTS MBEDTLS_OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } */ -#define MBEDTLS_OID_EXTENDED_KEY_USAGE MBEDTLS_OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */ -#define MBEDTLS_OID_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } */ -#define MBEDTLS_OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */ -#define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */ - -/* - * Netscape certificate extensions - */ -#define MBEDTLS_OID_NS_CERT MBEDTLS_OID_NETSCAPE "\x01" -#define MBEDTLS_OID_NS_CERT_TYPE MBEDTLS_OID_NS_CERT "\x01" -#define MBEDTLS_OID_NS_BASE_URL MBEDTLS_OID_NS_CERT "\x02" -#define MBEDTLS_OID_NS_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x03" -#define MBEDTLS_OID_NS_CA_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x04" -#define MBEDTLS_OID_NS_RENEWAL_URL MBEDTLS_OID_NS_CERT "\x07" -#define MBEDTLS_OID_NS_CA_POLICY_URL MBEDTLS_OID_NS_CERT "\x08" -#define MBEDTLS_OID_NS_SSL_SERVER_NAME MBEDTLS_OID_NS_CERT "\x0C" -#define MBEDTLS_OID_NS_COMMENT MBEDTLS_OID_NS_CERT "\x0D" -#define MBEDTLS_OID_NS_DATA_TYPE MBEDTLS_OID_NETSCAPE "\x02" -#define MBEDTLS_OID_NS_CERT_SEQUENCE MBEDTLS_OID_NS_DATA_TYPE "\x05" - -/* - * OIDs for CRL extensions - */ -#define MBEDTLS_OID_PRIVATE_KEY_USAGE_PERIOD MBEDTLS_OID_ID_CE "\x10" -#define MBEDTLS_OID_CRL_NUMBER MBEDTLS_OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */ - -/* - * X.509 v3 Extended key usage OIDs - */ -#define MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE MBEDTLS_OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */ - -#define MBEDTLS_OID_KP MBEDTLS_OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */ -#define MBEDTLS_OID_SERVER_AUTH MBEDTLS_OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */ -#define MBEDTLS_OID_CLIENT_AUTH MBEDTLS_OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */ -#define MBEDTLS_OID_CODE_SIGNING MBEDTLS_OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */ -#define MBEDTLS_OID_EMAIL_PROTECTION MBEDTLS_OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */ -#define MBEDTLS_OID_TIME_STAMPING MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */ -#define MBEDTLS_OID_OCSP_SIGNING MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */ - -/* - * PKCS definition OIDs - */ - -#define MBEDTLS_OID_PKCS MBEDTLS_OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */ -#define MBEDTLS_OID_PKCS1 MBEDTLS_OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */ -#define MBEDTLS_OID_PKCS5 MBEDTLS_OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */ -#define MBEDTLS_OID_PKCS9 MBEDTLS_OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */ -#define MBEDTLS_OID_PKCS12 MBEDTLS_OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */ - -/* - * PKCS#1 OIDs - */ -#define MBEDTLS_OID_PKCS1_RSA MBEDTLS_OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */ -#define MBEDTLS_OID_PKCS1_MD2 MBEDTLS_OID_PKCS1 "\x02" /**< md2WithRSAEncryption ::= { pkcs-1 2 } */ -#define MBEDTLS_OID_PKCS1_MD4 MBEDTLS_OID_PKCS1 "\x03" /**< md4WithRSAEncryption ::= { pkcs-1 3 } */ -#define MBEDTLS_OID_PKCS1_MD5 MBEDTLS_OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */ -#define MBEDTLS_OID_PKCS1_SHA1 MBEDTLS_OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */ -#define MBEDTLS_OID_PKCS1_SHA224 MBEDTLS_OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */ -#define MBEDTLS_OID_PKCS1_SHA256 MBEDTLS_OID_PKCS1 "\x0b" /**< sha256WithRSAEncryption ::= { pkcs-1 11 } */ -#define MBEDTLS_OID_PKCS1_SHA384 MBEDTLS_OID_PKCS1 "\x0c" /**< sha384WithRSAEncryption ::= { pkcs-1 12 } */ -#define MBEDTLS_OID_PKCS1_SHA512 MBEDTLS_OID_PKCS1 "\x0d" /**< sha512WithRSAEncryption ::= { pkcs-1 13 } */ - -#define MBEDTLS_OID_RSA_SHA_OBS "\x2B\x0E\x03\x02\x1D" - -#define MBEDTLS_OID_PKCS9_EMAIL MBEDTLS_OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */ - -/* RFC 4055 */ -#define MBEDTLS_OID_RSASSA_PSS MBEDTLS_OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */ -#define MBEDTLS_OID_MGF1 MBEDTLS_OID_PKCS1 "\x08" /**< id-mgf1 ::= { pkcs-1 8 } */ - -/* - * Digest algorithms - */ -#define MBEDTLS_OID_DIGEST_ALG_MD2 MBEDTLS_OID_RSA_COMPANY "\x02\x02" /**< id-mbedtls_md2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } */ -#define MBEDTLS_OID_DIGEST_ALG_MD4 MBEDTLS_OID_RSA_COMPANY "\x02\x04" /**< id-mbedtls_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */ -#define MBEDTLS_OID_DIGEST_ALG_MD5 MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA1 MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */ - -#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */ - -#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */ - -#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */ - -#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */ - -#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */ - -#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */ - -#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */ - -/* - * Encryption algorithms - */ -#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */ -#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */ -#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */ - -/* - * Key Wrapping algorithms - */ -/* - * RFC 5649 - */ -#define MBEDTLS_OID_AES128_KW MBEDTLS_OID_AES "\x05" /** id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */ -#define MBEDTLS_OID_AES128_KWP MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */ -#define MBEDTLS_OID_AES192_KW MBEDTLS_OID_AES "\x19" /** id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */ -#define MBEDTLS_OID_AES192_KWP MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */ -#define MBEDTLS_OID_AES256_KW MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */ -#define MBEDTLS_OID_AES256_KWP MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */ -/* - * PKCS#5 OIDs - */ -#define MBEDTLS_OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */ -#define MBEDTLS_OID_PKCS5_PBES2 MBEDTLS_OID_PKCS5 "\x0d" /**< id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} */ -#define MBEDTLS_OID_PKCS5_PBMAC1 MBEDTLS_OID_PKCS5 "\x0e" /**< id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14} */ - -/* - * PKCS#5 PBES1 algorithms - */ -#define MBEDTLS_OID_PKCS5_PBE_MD2_DES_CBC MBEDTLS_OID_PKCS5 "\x01" /**< pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1} */ -#define MBEDTLS_OID_PKCS5_PBE_MD2_RC2_CBC MBEDTLS_OID_PKCS5 "\x04" /**< pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4} */ -#define MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC MBEDTLS_OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */ -#define MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC MBEDTLS_OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */ -#define MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */ -#define MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */ - -/* - * PKCS#8 OIDs - */ -#define MBEDTLS_OID_PKCS9_CSR_EXT_REQ MBEDTLS_OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */ - -/* - * PKCS#12 PBE OIDs - */ -#define MBEDTLS_OID_PKCS12_PBE MBEDTLS_OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */ - -#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128 MBEDTLS_OID_PKCS12_PBE "\x01" /**< pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1} */ -#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_40 MBEDTLS_OID_PKCS12_PBE "\x02" /**< pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 2} */ -#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */ -#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */ -#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */ -#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDTLS_OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */ - -/* - * EC key algorithms from RFC 5480 - */ - -/* id-ecPublicKey OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } */ -#define MBEDTLS_OID_EC_ALG_UNRESTRICTED MBEDTLS_OID_ANSI_X9_62 "\x02\01" - -/* id-ecDH OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) - * schemes(1) ecdh(12) } */ -#define MBEDTLS_OID_EC_ALG_ECDH MBEDTLS_OID_CERTICOM "\x01\x0c" - -/* - * ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2 - */ - -/* secp192r1 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 1 } */ -#define MBEDTLS_OID_EC_GRP_SECP192R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x01" - -/* secp224r1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 33 } */ -#define MBEDTLS_OID_EC_GRP_SECP224R1 MBEDTLS_OID_CERTICOM "\x00\x21" - -/* secp256r1 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 } */ -#define MBEDTLS_OID_EC_GRP_SECP256R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x07" - -/* secp384r1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 34 } */ -#define MBEDTLS_OID_EC_GRP_SECP384R1 MBEDTLS_OID_CERTICOM "\x00\x22" - -/* secp521r1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 35 } */ -#define MBEDTLS_OID_EC_GRP_SECP521R1 MBEDTLS_OID_CERTICOM "\x00\x23" - -/* secp192k1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 31 } */ -#define MBEDTLS_OID_EC_GRP_SECP192K1 MBEDTLS_OID_CERTICOM "\x00\x1f" - -/* secp224k1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 32 } */ -#define MBEDTLS_OID_EC_GRP_SECP224K1 MBEDTLS_OID_CERTICOM "\x00\x20" - -/* secp256k1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 10 } */ -#define MBEDTLS_OID_EC_GRP_SECP256K1 MBEDTLS_OID_CERTICOM "\x00\x0a" - -/* RFC 5639 4.1 - * ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1) - * identified-organization(3) teletrust(36) algorithm(3) signature- - * algorithm(3) ecSign(2) 8} - * ellipticCurve OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1} - * versionOne OBJECT IDENTIFIER ::= {ellipticCurve 1} */ -#define MBEDTLS_OID_EC_BRAINPOOL_V1 MBEDTLS_OID_TELETRUST "\x03\x03\x02\x08\x01\x01" - -/* brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} */ -#define MBEDTLS_OID_EC_GRP_BP256R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x07" - -/* brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} */ -#define MBEDTLS_OID_EC_GRP_BP384R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0B" - -/* brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} */ -#define MBEDTLS_OID_EC_GRP_BP512R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0D" - -/* - * SEC1 C.1 - * - * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } - * id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)} - */ -#define MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE MBEDTLS_OID_ANSI_X9_62 "\x01" -#define MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE "\x01" - -/* - * ECDSA signature identifiers, from RFC 5480 - */ -#define MBEDTLS_OID_ANSI_X9_62_SIG MBEDTLS_OID_ANSI_X9_62 "\x04" /* signatures(4) */ -#define MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 MBEDTLS_OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */ - -/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */ -#define MBEDTLS_OID_ECDSA_SHA1 MBEDTLS_OID_ANSI_X9_62_SIG "\x01" - -/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) - * ecdsa-with-SHA2(3) 1 } */ -#define MBEDTLS_OID_ECDSA_SHA224 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x01" - -/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) - * ecdsa-with-SHA2(3) 2 } */ -#define MBEDTLS_OID_ECDSA_SHA256 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x02" - -/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) - * ecdsa-with-SHA2(3) 3 } */ -#define MBEDTLS_OID_ECDSA_SHA384 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x03" - -/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) - * ecdsa-with-SHA2(3) 4 } */ -#define MBEDTLS_OID_ECDSA_SHA512 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x04" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Base OID descriptor structure - */ -typedef struct mbedtls_oid_descriptor_t -{ - const char *asn1; /*!< OID ASN.1 representation */ - size_t asn1_len; /*!< length of asn1 */ - const char *name; /*!< official name (e.g. from RFC) */ - const char *description; /*!< human friendly description */ -} mbedtls_oid_descriptor_t; - -/** - * \brief Translate an ASN.1 OID into its numeric representation - * (e.g. "\x2A\x86\x48\x86\xF7\x0D" into "1.2.840.113549") - * - * \param buf buffer to put representation in - * \param size size of the buffer - * \param oid OID to translate - * - * \return Length of the string written (excluding final NULL) or - * MBEDTLS_ERR_OID_BUF_TOO_SMALL in case of error - */ -int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_buf *oid ); - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) -/** - * \brief Translate an X.509 extension OID into local values - * - * \param oid OID to use - * \param ext_type place to store the extension type - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_x509_ext_type( const mbedtls_asn1_buf *oid, int *ext_type ); -#endif - -/** - * \brief Translate an X.509 attribute type OID into the short name - * (e.g. the OID for an X520 Common Name into "CN") - * - * \param oid OID to use - * \param short_name place to store the string pointer - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_attr_short_name( const mbedtls_asn1_buf *oid, const char **short_name ); - -/** - * \brief Translate PublicKeyAlgorithm OID into pk_type - * - * \param oid OID to use - * \param pk_alg place to store public key algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_pk_alg( const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_alg ); - -/** - * \brief Translate pk_type into PublicKeyAlgorithm OID - * - * \param pk_alg Public key type to look for - * \param oid place to store ASN.1 OID string pointer - * \param olen length of the OID - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_type_t pk_alg, - const char **oid, size_t *olen ); - -#if defined(MBEDTLS_ECP_C) -/** - * \brief Translate NamedCurve OID into an EC group identifier - * - * \param oid OID to use - * \param grp_id place to store group id - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id ); - -/** - * \brief Translate EC group identifier into NamedCurve OID - * - * \param grp_id EC group identifier - * \param oid place to store ASN.1 OID string pointer - * \param olen length of the OID - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_oid_by_ec_grp( mbedtls_ecp_group_id grp_id, - const char **oid, size_t *olen ); -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_MD_C) -/** - * \brief Translate SignatureAlgorithm OID into md_type and pk_type - * - * \param oid OID to use - * \param md_alg place to store message digest algorithm - * \param pk_alg place to store public key algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_sig_alg( const mbedtls_asn1_buf *oid, - mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg ); - -/** - * \brief Translate SignatureAlgorithm OID into description - * - * \param oid OID to use - * \param desc place to store string pointer - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_sig_alg_desc( const mbedtls_asn1_buf *oid, const char **desc ); - -/** - * \brief Translate md_type and pk_type into SignatureAlgorithm OID - * - * \param md_alg message digest algorithm - * \param pk_alg public key algorithm - * \param oid place to store ASN.1 OID string pointer - * \param olen length of the OID - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const char **oid, size_t *olen ); - -/** - * \brief Translate hash algorithm OID into md_type - * - * \param oid OID to use - * \param md_alg place to store message digest algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg ); - -/** - * \brief Translate hmac algorithm OID into md_type - * - * \param oid OID to use - * \param md_hmac place to store message hmac algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac ); -#endif /* MBEDTLS_MD_C */ - -/** - * \brief Translate Extended Key Usage OID into description - * - * \param oid OID to use - * \param desc place to store string pointer - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc ); - -/** - * \brief Translate md_type into hash algorithm OID - * - * \param md_alg message digest algorithm - * \param oid place to store ASN.1 OID string pointer - * \param olen length of the OID - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_oid_by_md( mbedtls_md_type_t md_alg, const char **oid, size_t *olen ); - -#if defined(MBEDTLS_CIPHER_C) -/** - * \brief Translate encryption algorithm OID into cipher_type - * - * \param oid OID to use - * \param cipher_alg place to store cipher algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_cipher_alg( const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg ); -#endif /* MBEDTLS_CIPHER_C */ - -#if defined(MBEDTLS_PKCS12_C) -/** - * \brief Translate PKCS#12 PBE algorithm OID into md_type and - * cipher_type - * - * \param oid OID to use - * \param md_alg place to store message digest algorithm - * \param cipher_alg place to store cipher algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_pkcs12_pbe_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg, - mbedtls_cipher_type_t *cipher_alg ); -#endif /* MBEDTLS_PKCS12_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* oid.h */ diff --git a/mbedtls/padlock.c b/mbedtls/padlock.c deleted file mode 100644 index 41a29f3c7..000000000 --- a/mbedtls/padlock.c +++ /dev/null @@ -1,208 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * VIA PadLock support functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * This implementation is based on the VIA PadLock Programming Guide: - * - * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ - * programming_guide.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PADLOCK_C) - -#include "mbedtls/padlock.h" - -#include - -#ifndef asm -#define asm __asm -#endif - -#if defined(MBEDTLS_HAVE_X86) - -/* - * PadLock detection routine - */ -int mbedtls_padlock_has_support( int feature ) -{ - static int flags = -1; - int ebx = 0, edx = 0; - - if( flags == -1 ) - { - asm( "movl %%ebx, %0 \n\t" - "movl $0xC0000000, %%eax \n\t" - "cpuid \n\t" - "cmpl $0xC0000001, %%eax \n\t" - "movl $0, %%edx \n\t" - "jb unsupported \n\t" - "movl $0xC0000001, %%eax \n\t" - "cpuid \n\t" - "unsupported: \n\t" - "movl %%edx, %1 \n\t" - "movl %2, %%ebx \n\t" - : "=m" (ebx), "=m" (edx) - : "m" (ebx) - : "eax", "ecx", "edx" ); - - flags = edx; - } - - return( flags & feature ); -} - -/* - * PadLock AES-ECB block en(de)cryption - */ -int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - int ebx = 0; - uint32_t *rk; - uint32_t *blk; - uint32_t *ctrl; - unsigned char buf[256]; - - rk = ctx->rk; - blk = MBEDTLS_PADLOCK_ALIGN16( buf ); - memcpy( blk, input, 16 ); - - ctrl = blk + 4; - *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); - - asm( "pushfl \n\t" - "popfl \n\t" - "movl %%ebx, %0 \n\t" - "movl $1, %%ecx \n\t" - "movl %2, %%edx \n\t" - "movl %3, %%ebx \n\t" - "movl %4, %%esi \n\t" - "movl %4, %%edi \n\t" - ".byte 0xf3,0x0f,0xa7,0xc8 \n\t" - "movl %1, %%ebx \n\t" - : "=m" (ebx) - : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) - : "memory", "ecx", "edx", "esi", "edi" ); - - memcpy( output, blk, 16 ); - - return( 0 ); -} - -/* - * PadLock AES-CBC buffer en(de)cryption - */ -int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int ebx = 0; - size_t count; - uint32_t *rk; - uint32_t *iw; - uint32_t *ctrl; - unsigned char buf[256]; - - if( ( (long) input & 15 ) != 0 || - ( (long) output & 15 ) != 0 ) - return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED ); - - rk = ctx->rk; - iw = MBEDTLS_PADLOCK_ALIGN16( buf ); - memcpy( iw, iv, 16 ); - - ctrl = iw + 4; - *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 ); - - count = ( length + 15 ) >> 4; - - asm( "pushfl \n\t" - "popfl \n\t" - "movl %%ebx, %0 \n\t" - "movl %2, %%ecx \n\t" - "movl %3, %%edx \n\t" - "movl %4, %%ebx \n\t" - "movl %5, %%esi \n\t" - "movl %6, %%edi \n\t" - "movl %7, %%eax \n\t" - ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" - "movl %1, %%ebx \n\t" - : "=m" (ebx) - : "m" (ebx), "m" (count), "m" (ctrl), - "m" (rk), "m" (input), "m" (output), "m" (iw) - : "memory", "eax", "ecx", "edx", "esi", "edi" ); - - memcpy( iv, iw, 16 ); - - return( 0 ); -} - -#endif /* MBEDTLS_HAVE_X86 */ - -#endif /* MBEDTLS_PADLOCK_C */ diff --git a/mbedtls/padlock.h b/mbedtls/padlock.h deleted file mode 100644 index 3ec9d4fa2..000000000 --- a/mbedtls/padlock.h +++ /dev/null @@ -1,152 +0,0 @@ -#pragma GCC system_header -/** - * \file padlock.h - * - * \brief VIA PadLock ACE for HW encryption/decryption supported by some - * processors - * - * \warning These functions are only for internal use by other library - * functions; you must not call them directly. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_PADLOCK_H -#define MBEDTLS_PADLOCK_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "aes.h" - -#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */ - -#if defined(__has_feature) -#if __has_feature(address_sanitizer) -#define MBEDTLS_HAVE_ASAN -#endif -#endif - -/* Some versions of ASan result in errors about not enough registers */ -#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) && \ - !defined(MBEDTLS_HAVE_ASAN) - -#ifndef MBEDTLS_HAVE_X86 -#define MBEDTLS_HAVE_X86 -#endif - -#include - -#define MBEDTLS_PADLOCK_RNG 0x000C -#define MBEDTLS_PADLOCK_ACE 0x00C0 -#define MBEDTLS_PADLOCK_PHE 0x0C00 -#define MBEDTLS_PADLOCK_PMM 0x3000 - -#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) (x) & ~15)) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Internal PadLock detection routine - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param feature The feature to detect - * - * \return non-zero if CPU has support for the feature, 0 otherwise - */ -int mbedtls_padlock_has_support( int feature ); - -/** - * \brief Internal PadLock AES-ECB block en(de)cryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param input 16-byte input block - * \param output 16-byte output block - * - * \return 0 if success, 1 if operation failed - */ -int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); - -/** - * \brief Internal PadLock AES-CBC buffer en(de)cryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if success, 1 if operation failed - */ -int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -#ifdef __cplusplus -} -#endif - -#endif /* HAVE_X86 */ - -#endif /* padlock.h */ diff --git a/mbedtls/pem.c b/mbedtls/pem.c deleted file mode 100644 index 571fc6093..000000000 --- a/mbedtls/pem.c +++ /dev/null @@ -1,532 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Privacy Enhanced Mail (PEM) decoding - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) - -#include "mbedtls/pem.h" -#include "mbedtls/base64.h" -#include "mbedtls/des.h" -#include "mbedtls/aes.h" -#include "mbedtls/md5.h" -#include "mbedtls/cipher.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) -void mbedtls_pem_init( mbedtls_pem_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_pem_context ) ); -} - -#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) -/* - * Read a 16-byte hex string and convert it to binary - */ -static int pem_get_iv( const unsigned char *s, unsigned char *iv, - size_t iv_len ) -{ - size_t i, j, k; - - memset( iv, 0, iv_len ); - - for( i = 0; i < iv_len * 2; i++, s++ ) - { - if( *s >= '0' && *s <= '9' ) j = *s - '0'; else - if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else - if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else - return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); - - k = ( ( i & 1 ) != 0 ) ? j : j << 4; - - iv[i >> 1] = (unsigned char)( iv[i >> 1] | k ); - } - - return( 0 ); -} - -static int pem_pbkdf1( unsigned char *key, size_t keylen, - unsigned char *iv, - const unsigned char *pwd, size_t pwdlen ) -{ - mbedtls_md5_context md5_ctx; - unsigned char md5sum[16]; - size_t use_len; - int ret; - - mbedtls_md5_init( &md5_ctx ); - - /* - * key[ 0..15] = MD5(pwd || IV) - */ - if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 ) - goto exit; - - if( keylen <= 16 ) - { - memcpy( key, md5sum, keylen ); - goto exit; - } - - memcpy( key, md5sum, 16 ); - - /* - * key[16..23] = MD5(key[ 0..15] || pwd || IV]) - */ - if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, md5sum, 16 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 ) - goto exit; - - use_len = 16; - if( keylen < 32 ) - use_len = keylen - 16; - - memcpy( key + 16, md5sum, use_len ); - -exit: - mbedtls_md5_free( &md5_ctx ); - mbedtls_platform_zeroize( md5sum, 16 ); - - return( ret ); -} - -#if defined(MBEDTLS_DES_C) -/* - * Decrypt with DES-CBC, using PBKDF1 for key derivation - */ -static int pem_des_decrypt( unsigned char des_iv[8], - unsigned char *buf, size_t buflen, - const unsigned char *pwd, size_t pwdlen ) -{ - mbedtls_des_context des_ctx; - unsigned char des_key[8]; - int ret; - - mbedtls_des_init( &des_ctx ); - - if( ( ret = pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_des_setkey_dec( &des_ctx, des_key ) ) != 0 ) - goto exit; - ret = mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen, - des_iv, buf, buf ); - -exit: - mbedtls_des_free( &des_ctx ); - mbedtls_platform_zeroize( des_key, 8 ); - - return( ret ); -} - -/* - * Decrypt with 3DES-CBC, using PBKDF1 for key derivation - */ -static int pem_des3_decrypt( unsigned char des3_iv[8], - unsigned char *buf, size_t buflen, - const unsigned char *pwd, size_t pwdlen ) -{ - mbedtls_des3_context des3_ctx; - unsigned char des3_key[24]; - int ret; - - mbedtls_des3_init( &des3_ctx ); - - if( ( ret = pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_des3_set3key_dec( &des3_ctx, des3_key ) ) != 0 ) - goto exit; - ret = mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen, - des3_iv, buf, buf ); - -exit: - mbedtls_des3_free( &des3_ctx ); - mbedtls_platform_zeroize( des3_key, 24 ); - - return( ret ); -} -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) -/* - * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation - */ -static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, - unsigned char *buf, size_t buflen, - const unsigned char *pwd, size_t pwdlen ) -{ - mbedtls_aes_context aes_ctx; - unsigned char aes_key[32]; - int ret; - - mbedtls_aes_init( &aes_ctx ); - - if( ( ret = pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ) ) != 0 ) - goto exit; - ret = mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen, - aes_iv, buf, buf ); - -exit: - mbedtls_aes_free( &aes_ctx ); - mbedtls_platform_zeroize( aes_key, keylen ); - - return( ret ); -} -#endif /* MBEDTLS_AES_C */ - -#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - -int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer, - const unsigned char *data, const unsigned char *pwd, - size_t pwdlen, size_t *use_len ) -{ - int ret, enc; - size_t len; - unsigned char *buf; - const unsigned char *s1, *s2, *end; -#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) - unsigned char pem_iv[16]; - mbedtls_cipher_type_t enc_alg = MBEDTLS_CIPHER_NONE; -#else - ((void) pwd); - ((void) pwdlen); -#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - - if( ctx == NULL ) - return( MBEDTLS_ERR_PEM_BAD_INPUT_DATA ); - - s1 = (unsigned char *) strstr( (const char *) data, header ); - - if( s1 == NULL ) - return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); - - s2 = (unsigned char *) strstr( (const char *) data, footer ); - - if( s2 == NULL || s2 <= s1 ) - return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); - - s1 += strlen( header ); - if( *s1 == ' ' ) s1++; - if( *s1 == '\r' ) s1++; - if( *s1 == '\n' ) s1++; - else return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); - - end = s2; - end += strlen( footer ); - if( *end == ' ' ) end++; - if( *end == '\r' ) end++; - if( *end == '\n' ) end++; - *use_len = end - data; - - enc = 0; - - if( s2 - s1 >= 22 && memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) - { -#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) - enc++; - - s1 += 22; - if( *s1 == '\r' ) s1++; - if( *s1 == '\n' ) s1++; - else return( MBEDTLS_ERR_PEM_INVALID_DATA ); - - -#if defined(MBEDTLS_DES_C) - if( s2 - s1 >= 23 && memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) - { - enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC; - - s1 += 23; - if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8 ) != 0 ) - return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); - - s1 += 16; - } - else if( s2 - s1 >= 18 && memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) - { - enc_alg = MBEDTLS_CIPHER_DES_CBC; - - s1 += 18; - if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8) != 0 ) - return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); - - s1 += 16; - } -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) - if( s2 - s1 >= 14 && memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) - { - if( s2 - s1 < 22 ) - return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); - else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) - enc_alg = MBEDTLS_CIPHER_AES_128_CBC; - else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) - enc_alg = MBEDTLS_CIPHER_AES_192_CBC; - else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 ) - enc_alg = MBEDTLS_CIPHER_AES_256_CBC; - else - return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); - - s1 += 22; - if( s2 - s1 < 32 || pem_get_iv( s1, pem_iv, 16 ) != 0 ) - return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); - - s1 += 32; - } -#endif /* MBEDTLS_AES_C */ - - if( enc_alg == MBEDTLS_CIPHER_NONE ) - return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); - - if( *s1 == '\r' ) s1++; - if( *s1 == '\n' ) s1++; - else return( MBEDTLS_ERR_PEM_INVALID_DATA ); -#else - return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - } - - if( s1 >= s2 ) - return( MBEDTLS_ERR_PEM_INVALID_DATA ); - - ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 ); - - if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER ) - return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); - - if( ( buf = mbedtls_calloc( 1, len ) ) == NULL ) - return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); - - if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 ) - { - mbedtls_platform_zeroize( buf, len ); - mbedtls_free( buf ); - return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); - } - - if( enc != 0 ) - { -#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) - if( pwd == NULL ) - { - mbedtls_platform_zeroize( buf, len ); - mbedtls_free( buf ); - return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ); - } - - ret = 0; - -#if defined(MBEDTLS_DES_C) - if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC ) - ret = pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen ); - else if( enc_alg == MBEDTLS_CIPHER_DES_CBC ) - ret = pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen ); -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) - if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC ) - ret = pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen ); - else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC ) - ret = pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen ); - else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC ) - ret = pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen ); -#endif /* MBEDTLS_AES_C */ - - if( ret != 0 ) - { - mbedtls_free( buf ); - return( ret ); - } - - /* - * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3 - * length bytes (allow 4 to be sure) in all known use cases. - * - * Use that as a heuristic to try to detect password mismatches. - */ - if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) - { - mbedtls_platform_zeroize( buf, len ); - mbedtls_free( buf ); - return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ); - } -#else - mbedtls_platform_zeroize( buf, len ); - mbedtls_free( buf ); - return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - } - - ctx->buf = buf; - ctx->buflen = len; - - return( 0 ); -} - -void mbedtls_pem_free( mbedtls_pem_context *ctx ) -{ - if ( ctx->buf != NULL ) - { - mbedtls_platform_zeroize( ctx->buf, ctx->buflen ); - mbedtls_free( ctx->buf ); - } - mbedtls_free( ctx->info ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) ); -} -#endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_PEM_WRITE_C) -int mbedtls_pem_write_buffer( const char *header, const char *footer, - const unsigned char *der_data, size_t der_len, - unsigned char *buf, size_t buf_len, size_t *olen ) -{ - int ret; - unsigned char *encode_buf = NULL, *c, *p = buf; - size_t len = 0, use_len, add_len = 0; - - mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len ); - add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1; - - if( use_len + add_len > buf_len ) - { - *olen = use_len + add_len; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - if( use_len != 0 && - ( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) ) - return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); - - if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data, - der_len ) ) != 0 ) - { - mbedtls_free( encode_buf ); - return( ret ); - } - - memcpy( p, header, strlen( header ) ); - p += strlen( header ); - c = encode_buf; - - while( use_len ) - { - len = ( use_len > 64 ) ? 64 : use_len; - memcpy( p, c, len ); - use_len -= len; - p += len; - c += len; - *p++ = '\n'; - } - - memcpy( p, footer, strlen( footer ) ); - p += strlen( footer ); - - *p++ = '\0'; - *olen = p - buf; - - /* Clean any remaining data previously written to the buffer */ - memset( buf + *olen, 0, buf_len - *olen ); - - mbedtls_free( encode_buf ); - return( 0 ); -} -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ - diff --git a/mbedtls/pem.h b/mbedtls/pem.h deleted file mode 100644 index 7e3c63dda..000000000 --- a/mbedtls/pem.h +++ /dev/null @@ -1,172 +0,0 @@ -#pragma GCC system_header -/** - * \file pem.h - * - * \brief Privacy Enhanced Mail (PEM) decoding - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_PEM_H -#define MBEDTLS_PEM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -/** - * \name PEM Error codes - * These error codes are returned in case of errors reading the - * PEM data. - * \{ - */ -#define MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT -0x1080 /**< No PEM header or footer found. */ -#define MBEDTLS_ERR_PEM_INVALID_DATA -0x1100 /**< PEM string is not as expected. */ -#define MBEDTLS_ERR_PEM_ALLOC_FAILED -0x1180 /**< Failed to allocate memory. */ -#define MBEDTLS_ERR_PEM_INVALID_ENC_IV -0x1200 /**< RSA IV is not in hex-format. */ -#define MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG -0x1280 /**< Unsupported key encryption algorithm. */ -#define MBEDTLS_ERR_PEM_PASSWORD_REQUIRED -0x1300 /**< Private key password can't be empty. */ -#define MBEDTLS_ERR_PEM_PASSWORD_MISMATCH -0x1380 /**< Given private key password does not allow for correct decryption. */ -#define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE -0x1400 /**< Unavailable feature, e.g. hashing/encryption combination. */ -#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA -0x1480 /**< Bad input parameters to function. */ -/* \} name */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) -/** - * \brief PEM context structure - */ -typedef struct mbedtls_pem_context -{ - unsigned char *buf; /*!< buffer for decoded data */ - size_t buflen; /*!< length of the buffer */ - unsigned char *info; /*!< buffer for extra header information */ -} -mbedtls_pem_context; - -/** - * \brief PEM context setup - * - * \param ctx context to be initialized - */ -void mbedtls_pem_init( mbedtls_pem_context *ctx ); - -/** - * \brief Read a buffer for PEM information and store the resulting - * data into the specified context buffers. - * - * \param ctx context to use - * \param header header string to seek and expect - * \param footer footer string to seek and expect - * \param data source data to look in (must be nul-terminated) - * \param pwd password for decryption (can be NULL) - * \param pwdlen length of password - * \param use_len destination for total length used (set after header is - * correctly read, so unless you get - * MBEDTLS_ERR_PEM_BAD_INPUT_DATA or - * MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is - * the length to skip) - * - * \note Attempts to check password correctness by verifying if - * the decrypted text starts with an ASN.1 sequence of - * appropriate length - * - * \return 0 on success, or a specific PEM error code - */ -int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer, - const unsigned char *data, - const unsigned char *pwd, - size_t pwdlen, size_t *use_len ); - -/** - * \brief PEM context memory freeing - * - * \param ctx context to be freed - */ -void mbedtls_pem_free( mbedtls_pem_context *ctx ); -#endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a buffer of PEM information from a DER encoded - * buffer. - * - * \param header The header string to write. - * \param footer The footer string to write. - * \param der_data The DER data to encode. - * \param der_len The length of the DER data \p der_data in Bytes. - * \param buf The buffer to write to. - * \param buf_len The length of the output buffer \p buf in Bytes. - * \param olen The address at which to store the total length written - * or required (if \p buf_len is not enough). - * - * \note You may pass \c NULL for \p buf and \c 0 for \p buf_len - * to request the length of the resulting PEM buffer in - * `*olen`. - * - * \note This function may be called with overlapping \p der_data - * and \p buf buffers. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL if \p buf isn't large - * enough to hold the PEM buffer. In this case, `*olen` holds - * the required minimum size of \p buf. - * \return Another PEM or BASE64 error code on other kinds of failure. - */ -int mbedtls_pem_write_buffer( const char *header, const char *footer, - const unsigned char *der_data, size_t der_len, - unsigned char *buf, size_t buf_len, size_t *olen ); -#endif /* MBEDTLS_PEM_WRITE_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* pem.h */ diff --git a/mbedtls/pk.c b/mbedtls/pk.c deleted file mode 100644 index 3b8ec32ad..000000000 --- a/mbedtls/pk.c +++ /dev/null @@ -1,587 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Public Key abstraction layer - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PK_C) -#include "mbedtls/pk.h" -#include "mbedtls/pk_internal.h" - -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif - -#include -#include - -/* Parameter validation macros based on platform_util.h */ -#define PK_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) -#define PK_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -/* - * Initialise a mbedtls_pk_context - */ -void mbedtls_pk_init( mbedtls_pk_context *ctx ) -{ - PK_VALIDATE( ctx != NULL ); - - ctx->pk_info = NULL; - ctx->pk_ctx = NULL; -} - -/* - * Free (the components of) a mbedtls_pk_context - */ -void mbedtls_pk_free( mbedtls_pk_context *ctx ) -{ - if( ctx == NULL ) - return; - - if ( ctx->pk_info != NULL ) - ctx->pk_info->ctx_free_func( ctx->pk_ctx ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) ); -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx ) -{ - PK_VALIDATE( ctx != NULL ); - ctx->pk_info = NULL; - ctx->rs_ctx = NULL; -} - -/* - * Free the components of a restart context - */ -void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx ) -{ - if( ctx == NULL || ctx->pk_info == NULL || - ctx->pk_info->rs_free_func == NULL ) - { - return; - } - - ctx->pk_info->rs_free_func( ctx->rs_ctx ); - - ctx->pk_info = NULL; - ctx->rs_ctx = NULL; -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* - * Get pk_info structure from type - */ -const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ) -{ - switch( pk_type ) { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_PK_RSA: - return( &mbedtls_rsa_info ); -#endif -#if defined(MBEDTLS_ECP_C) - case MBEDTLS_PK_ECKEY: - return( &mbedtls_eckey_info ); - case MBEDTLS_PK_ECKEY_DH: - return( &mbedtls_eckeydh_info ); -#endif -#if defined(MBEDTLS_ECDSA_C) - case MBEDTLS_PK_ECDSA: - return( &mbedtls_ecdsa_info ); -#endif - /* MBEDTLS_PK_RSA_ALT omitted on purpose */ - default: - return( NULL ); - } -} - -/* - * Initialise context - */ -int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ) -{ - PK_VALIDATE_RET( ctx != NULL ); - if( info == NULL || ctx->pk_info != NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - ctx->pk_info = info; - - return( 0 ); -} - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/* - * Initialize an RSA-alt context - */ -int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, - mbedtls_pk_rsa_alt_decrypt_func decrypt_func, - mbedtls_pk_rsa_alt_sign_func sign_func, - mbedtls_pk_rsa_alt_key_len_func key_len_func ) -{ - mbedtls_rsa_alt_context *rsa_alt; - const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; - - PK_VALIDATE_RET( ctx != NULL ); - if( ctx->pk_info != NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - ctx->pk_info = info; - - rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx; - - rsa_alt->key = key; - rsa_alt->decrypt_func = decrypt_func; - rsa_alt->sign_func = sign_func; - rsa_alt->key_len_func = key_len_func; - - return( 0 ); -} -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -/* - * Tell if a PK can do the operations of the given type - */ -int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ) -{ - /* A context with null pk_info is not set up yet and can't do anything. - * For backward compatibility, also accept NULL instead of a context - * pointer. */ - if( ctx == NULL || ctx->pk_info == NULL ) - return( 0 ); - - return( ctx->pk_info->can_do( type ) ); -} - -/* - * Helper for mbedtls_pk_sign and mbedtls_pk_verify - */ -static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len ) -{ - const mbedtls_md_info_t *md_info; - - if( *hash_len != 0 && md_alg == MBEDTLS_MD_NONE ) - return( 0 ); - - if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) - return( -1 ); - - if ( *hash_len != 0 && *hash_len < mbedtls_md_get_size( md_info ) ) - return ( -1 ); - - *hash_len = mbedtls_md_get_size( md_info ); - return( 0 ); -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Helper to set up a restart context if needed - */ -static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx, - const mbedtls_pk_info_t *info ) -{ - /* Don't do anything if already set up or invalid */ - if( ctx == NULL || ctx->pk_info != NULL ) - return( 0 ); - - /* Should never happen when we're called */ - if( info->rs_alloc_func == NULL || info->rs_free_func == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - ctx->pk_info = info; - - return( 0 ); -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* - * Verify a signature (restartable) - */ -int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - mbedtls_pk_restart_ctx *rs_ctx ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || - hash != NULL ); - PK_VALIDATE_RET( sig != NULL ); - - if( ctx->pk_info == NULL || - pk_hashlen_helper( md_alg, &hash_len ) != 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* optimization: use non-restartable version if restart disabled */ - if( rs_ctx != NULL && - mbedtls_ecp_restart_is_enabled() && - ctx->pk_info->verify_rs_func != NULL ) - { - int ret; - - if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 ) - return( ret ); - - ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx, - md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx ); - - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) - mbedtls_pk_restart_free( rs_ctx ); - - return( ret ); - } -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - (void) rs_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - if( ctx->pk_info->verify_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len, - sig, sig_len ) ); -} - -/* - * Verify a signature - */ -int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len, - sig, sig_len, NULL ) ); -} - -/* - * Verify a signature with options - */ -int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, - mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || - hash != NULL ); - PK_VALIDATE_RET( sig != NULL ); - - if( ctx->pk_info == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ! mbedtls_pk_can_do( ctx, type ) ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - if( type == MBEDTLS_PK_RSASSA_PSS ) - { -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) - int ret; - const mbedtls_pk_rsassa_pss_options *pss_opts; - -#if SIZE_MAX > UINT_MAX - if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - if( options == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; - - if( sig_len < mbedtls_pk_get_len( ctx ) ) - return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - - ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ), - NULL, NULL, MBEDTLS_RSA_PUBLIC, - md_alg, (unsigned int) hash_len, hash, - pss_opts->mgf1_hash_id, - pss_opts->expected_salt_len, - sig ); - if( ret != 0 ) - return( ret ); - - if( sig_len > mbedtls_pk_get_len( ctx ) ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( 0 ); -#else - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ - } - - /* General case: no options */ - if( options != NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) ); -} - -/* - * Make a signature (restartable) - */ -int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_pk_restart_ctx *rs_ctx ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || - hash != NULL ); - PK_VALIDATE_RET( sig != NULL ); - - if( ctx->pk_info == NULL || - pk_hashlen_helper( md_alg, &hash_len ) != 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* optimization: use non-restartable version if restart disabled */ - if( rs_ctx != NULL && - mbedtls_ecp_restart_is_enabled() && - ctx->pk_info->sign_rs_func != NULL ) - { - int ret; - - if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 ) - return( ret ); - - ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg, - hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx ); - - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) - mbedtls_pk_restart_free( rs_ctx ); - - return( ret ); - } -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - (void) rs_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - if( ctx->pk_info->sign_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len, - sig, sig_len, f_rng, p_rng ) ); -} - -/* - * Make a signature - */ -int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len, - sig, sig_len, f_rng, p_rng, NULL ) ); -} - -/* - * Decrypt message - */ -int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( input != NULL || ilen == 0 ); - PK_VALIDATE_RET( output != NULL || osize == 0 ); - PK_VALIDATE_RET( olen != NULL ); - - if( ctx->pk_info == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ctx->pk_info->decrypt_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen, - output, olen, osize, f_rng, p_rng ) ); -} - -/* - * Encrypt message - */ -int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( input != NULL || ilen == 0 ); - PK_VALIDATE_RET( output != NULL || osize == 0 ); - PK_VALIDATE_RET( olen != NULL ); - - if( ctx->pk_info == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ctx->pk_info->encrypt_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen, - output, olen, osize, f_rng, p_rng ) ); -} - -/* - * Check public-private key pair - */ -int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ) -{ - PK_VALIDATE_RET( pub != NULL ); - PK_VALIDATE_RET( prv != NULL ); - - if( pub->pk_info == NULL || - prv->pk_info == NULL || - prv->pk_info->check_pair_func == NULL ) - { - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - } - - if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT ) - { - if( pub->pk_info->type != MBEDTLS_PK_RSA ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - } - else - { - if( pub->pk_info != prv->pk_info ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - } - - return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) ); -} - -/* - * Get key size in bits - */ -size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) -{ - /* For backward compatibility, accept NULL or a context that - * isn't set up yet, and return a fake value that should be safe. */ - if( ctx == NULL || ctx->pk_info == NULL ) - return( 0 ); - - return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) ); -} - -/* - * Export debug information - */ -int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ) -{ - PK_VALIDATE_RET( ctx != NULL ); - if( ctx->pk_info == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - if( ctx->pk_info->debug_func == NULL ) - return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); - - ctx->pk_info->debug_func( ctx->pk_ctx, items ); - return( 0 ); -} - -/* - * Access the PK type name - */ -const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx ) -{ - if( ctx == NULL || ctx->pk_info == NULL ) - return( "invalid PK" ); - - return( ctx->pk_info->name ); -} - -/* - * Access the PK type - */ -mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ) -{ - if( ctx == NULL || ctx->pk_info == NULL ) - return( MBEDTLS_PK_NONE ); - - return( ctx->pk_info->type ); -} - -#endif /* MBEDTLS_PK_C */ diff --git a/mbedtls/pk.h b/mbedtls/pk.h deleted file mode 100644 index 3a458cf81..000000000 --- a/mbedtls/pk.h +++ /dev/null @@ -1,781 +0,0 @@ -#pragma GCC system_header -/** - * \file pk.h - * - * \brief Public Key abstraction layer - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_PK_H -#define MBEDTLS_PK_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "md.h" - -#if defined(MBEDTLS_RSA_C) -#include "rsa.h" -#endif - -#if defined(MBEDTLS_ECP_C) -#include "ecp.h" -#endif - -#if defined(MBEDTLS_ECDSA_C) -#include "ecdsa.h" -#endif - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#define MBEDTLS_ERR_PK_ALLOC_FAILED -0x3F80 /**< Memory allocation failed. */ -#define MBEDTLS_ERR_PK_TYPE_MISMATCH -0x3F00 /**< Type mismatch, eg attempt to encrypt with an ECDSA key */ -#define MBEDTLS_ERR_PK_BAD_INPUT_DATA -0x3E80 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_PK_FILE_IO_ERROR -0x3E00 /**< Read/write of file failed. */ -#define MBEDTLS_ERR_PK_KEY_INVALID_VERSION -0x3D80 /**< Unsupported key version */ -#define MBEDTLS_ERR_PK_KEY_INVALID_FORMAT -0x3D00 /**< Invalid key tag or value. */ -#define MBEDTLS_ERR_PK_UNKNOWN_PK_ALG -0x3C80 /**< Key algorithm is unsupported (only RSA and EC are supported). */ -#define MBEDTLS_ERR_PK_PASSWORD_REQUIRED -0x3C00 /**< Private key password can't be empty. */ -#define MBEDTLS_ERR_PK_PASSWORD_MISMATCH -0x3B80 /**< Given private key password does not allow for correct decryption. */ -#define MBEDTLS_ERR_PK_INVALID_PUBKEY -0x3B00 /**< The pubkey tag or value is invalid (only RSA and EC are supported). */ -#define MBEDTLS_ERR_PK_INVALID_ALG -0x3A80 /**< The algorithm tag or value is invalid. */ -#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */ -#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */ -#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The buffer contains a valid signature followed by more data. */ - -/* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED -0x3880 /**< PK hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Public key types - */ -typedef enum { - MBEDTLS_PK_NONE=0, - MBEDTLS_PK_RSA, - MBEDTLS_PK_ECKEY, - MBEDTLS_PK_ECKEY_DH, - MBEDTLS_PK_ECDSA, - MBEDTLS_PK_RSA_ALT, - MBEDTLS_PK_RSASSA_PSS, -} mbedtls_pk_type_t; - -/** - * \brief Options for RSASSA-PSS signature verification. - * See \c mbedtls_rsa_rsassa_pss_verify_ext() - */ -typedef struct mbedtls_pk_rsassa_pss_options -{ - mbedtls_md_type_t mgf1_hash_id; - int expected_salt_len; - -} mbedtls_pk_rsassa_pss_options; - -/** - * \brief Types for interfacing with the debug module - */ -typedef enum -{ - MBEDTLS_PK_DEBUG_NONE = 0, - MBEDTLS_PK_DEBUG_MPI, - MBEDTLS_PK_DEBUG_ECP, -} mbedtls_pk_debug_type; - -/** - * \brief Item to send to the debug module - */ -typedef struct mbedtls_pk_debug_item -{ - mbedtls_pk_debug_type type; - const char *name; - void *value; -} mbedtls_pk_debug_item; - -/** Maximum number of item send for debugging, plus 1 */ -#define MBEDTLS_PK_DEBUG_MAX_ITEMS 3 - -/** - * \brief Public key information and operations - */ -typedef struct mbedtls_pk_info_t mbedtls_pk_info_t; - -/** - * \brief Public key container - */ -typedef struct mbedtls_pk_context -{ - const mbedtls_pk_info_t * pk_info; /**< Public key information */ - void * pk_ctx; /**< Underlying public key context */ -} mbedtls_pk_context; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Context for resuming operations - */ -typedef struct -{ - const mbedtls_pk_info_t * pk_info; /**< Public key information */ - void * rs_ctx; /**< Underlying restart context */ -} mbedtls_pk_restart_ctx; -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_pk_restart_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_RSA_C) -/** - * Quick access to an RSA context inside a PK context. - * - * \warning You must make sure the PK context actually holds an RSA context - * before using this function! - */ -static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk ) -{ - return( (mbedtls_rsa_context *) (pk).pk_ctx ); -} -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/** - * Quick access to an EC context inside a PK context. - * - * \warning You must make sure the PK context actually holds an EC context - * before using this function! - */ -static inline mbedtls_ecp_keypair *mbedtls_pk_ec( const mbedtls_pk_context pk ) -{ - return( (mbedtls_ecp_keypair *) (pk).pk_ctx ); -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/** - * \brief Types for RSA-alt abstraction - */ -typedef int (*mbedtls_pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen, - const unsigned char *input, unsigned char *output, - size_t output_max_len ); -typedef int (*mbedtls_pk_rsa_alt_sign_func)( void *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, - const unsigned char *hash, unsigned char *sig ); -typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx ); -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -/** - * \brief Return information associated with the given PK type - * - * \param pk_type PK type to search for. - * - * \return The PK info associated with the type or NULL if not found. - */ -const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ); - -/** - * \brief Initialize a #mbedtls_pk_context (as NONE). - * - * \param ctx The context to initialize. - * This must not be \c NULL. - */ -void mbedtls_pk_init( mbedtls_pk_context *ctx ); - -/** - * \brief Free the components of a #mbedtls_pk_context. - * - * \param ctx The context to clear. It must have been initialized. - * If this is \c NULL, this function does nothing. - */ -void mbedtls_pk_free( mbedtls_pk_context *ctx ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context - * - * \param ctx The context to initialize. - * This must not be \c NULL. - */ -void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx ); - -/** - * \brief Free the components of a restart context - * - * \param ctx The context to clear. It must have been initialized. - * If this is \c NULL, this function does nothing. - */ -void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx ); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief Initialize a PK context with the information given - * and allocates the type-specific PK subcontext. - * - * \param ctx Context to initialize. It must not have been set - * up yet (type #MBEDTLS_PK_NONE). - * \param info Information to use - * - * \return 0 on success, - * MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input, - * MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure. - * - * \note For contexts holding an RSA-alt key, use - * \c mbedtls_pk_setup_rsa_alt() instead. - */ -int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ); - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/** - * \brief Initialize an RSA-alt context - * - * \param ctx Context to initialize. It must not have been set - * up yet (type #MBEDTLS_PK_NONE). - * \param key RSA key pointer - * \param decrypt_func Decryption function - * \param sign_func Signing function - * \param key_len_func Function returning key length in bytes - * - * \return 0 on success, or MBEDTLS_ERR_PK_BAD_INPUT_DATA if the - * context wasn't already initialized as RSA_ALT. - * - * \note This function replaces \c mbedtls_pk_setup() for RSA-alt. - */ -int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, - mbedtls_pk_rsa_alt_decrypt_func decrypt_func, - mbedtls_pk_rsa_alt_sign_func sign_func, - mbedtls_pk_rsa_alt_key_len_func key_len_func ); -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -/** - * \brief Get the size in bits of the underlying key - * - * \param ctx The context to query. It must have been initialized. - * - * \return Key size in bits, or 0 on error - */ -size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ); - -/** - * \brief Get the length in bytes of the underlying key - * - * \param ctx The context to query. It must have been initialized. - * - * \return Key length in bytes, or 0 on error - */ -static inline size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx ) -{ - return( ( mbedtls_pk_get_bitlen( ctx ) + 7 ) / 8 ); -} - -/** - * \brief Tell if a context can do the operation given by type - * - * \param ctx The context to query. It must have been initialized. - * \param type The desired type. - * - * \return 1 if the context can do operations on the given type. - * \return 0 if the context cannot do the operations on the given - * type. This is always the case for a context that has - * been initialized but not set up, or that has been - * cleared with mbedtls_pk_free(). - */ -int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ); - -/** - * \brief Verify signature (including padding if relevant). - * - * \param ctx The PK context to use. It must have been set up. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length or 0 (see notes) - * \param sig Signature to verify - * \param sig_len Signature length - * - * \return 0 on success (signature is valid), - * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid - * signature in sig but its length is less than \p siglen, - * or a specific error code. - * - * \note For RSA keys, the default padding type is PKCS#1 v1.5. - * Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... ) - * to verify RSASSA_PSS signatures. - * - * \note If hash_len is 0, then the length associated with md_alg - * is used instead, or an error returned if it is invalid. - * - * \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0 - */ -int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ); - -/** - * \brief Restartable version of \c mbedtls_pk_verify() - * - * \note Performs the same job as \c mbedtls_pk_verify(), but can - * return early and restart according to the limit set with - * \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC - * operations. For RSA, same as \c mbedtls_pk_verify(). - * - * \param ctx The PK context to use. It must have been set up. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length or 0 (see notes) - * \param sig Signature to verify - * \param sig_len Signature length - * \param rs_ctx Restart context (NULL to disable restart) - * - * \return See \c mbedtls_pk_verify(), or - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - mbedtls_pk_restart_ctx *rs_ctx ); - -/** - * \brief Verify signature, with options. - * (Includes verification of the padding depending on type.) - * - * \param type Signature type (inc. possible padding type) to verify - * \param options Pointer to type-specific options, or NULL - * \param ctx The PK context to use. It must have been set up. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length or 0 (see notes) - * \param sig Signature to verify - * \param sig_len Signature length - * - * \return 0 on success (signature is valid), - * #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be - * used for this type of signatures, - * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid - * signature in sig but its length is less than \p siglen, - * or a specific error code. - * - * \note If hash_len is 0, then the length associated with md_alg - * is used instead, or an error returned if it is invalid. - * - * \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0 - * - * \note If type is MBEDTLS_PK_RSASSA_PSS, then options must point - * to a mbedtls_pk_rsassa_pss_options structure, - * otherwise it must be NULL. - */ -int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, - mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ); - -/** - * \brief Make signature, including padding if relevant. - * - * \param ctx The PK context to use. It must have been set up - * with a private key. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length or 0 (see notes) - * \param sig Place to write the signature - * \param sig_len Number of bytes written - * \param f_rng RNG function - * \param p_rng RNG parameter - * - * \return 0 on success, or a specific error code. - * - * \note For RSA keys, the default padding type is PKCS#1 v1.5. - * There is no interface in the PK module to make RSASSA-PSS - * signatures yet. - * - * \note If hash_len is 0, then the length associated with md_alg - * is used instead, or an error returned if it is invalid. - * - * \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. - * For ECDSA, md_alg may never be MBEDTLS_MD_NONE. - * - * \note In order to ensure enough space for the signature, the - * \p sig buffer size must be of at least - * `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes. - */ -int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - -/** - * \brief Restartable version of \c mbedtls_pk_sign() - * - * \note Performs the same job as \c mbedtls_pk_sign(), but can - * return early and restart according to the limit set with - * \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC - * operations. For RSA, same as \c mbedtls_pk_sign(). - * - * \note In order to ensure enough space for the signature, the - * \p sig buffer size must be of at least - * `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes. - * - * \param ctx The PK context to use. It must have been set up - * with a private key. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length or 0 (see notes) - * \param sig Place to write the signature - * \param sig_len Number of bytes written - * \param f_rng RNG function - * \param p_rng RNG parameter - * \param rs_ctx Restart context (NULL to disable restart) - * - * \return See \c mbedtls_pk_sign(), or - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_pk_restart_ctx *rs_ctx ); - -/** - * \brief Decrypt message (including padding if relevant). - * - * \param ctx The PK context to use. It must have been set up - * with a private key. - * \param input Input to decrypt - * \param ilen Input size - * \param output Decrypted output - * \param olen Decrypted message length - * \param osize Size of the output buffer - * \param f_rng RNG function - * \param p_rng RNG parameter - * - * \note For RSA keys, the default padding type is PKCS#1 v1.5. - * - * \return 0 on success, or a specific error code. - */ -int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - -/** - * \brief Encrypt message (including padding if relevant). - * - * \param ctx The PK context to use. It must have been set up. - * \param input Message to encrypt - * \param ilen Message size - * \param output Encrypted output - * \param olen Encrypted output length - * \param osize Size of the output buffer - * \param f_rng RNG function - * \param p_rng RNG parameter - * - * \note For RSA keys, the default padding type is PKCS#1 v1.5. - * - * \return 0 on success, or a specific error code. - */ -int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - -/** - * \brief Check if a public-private pair of keys matches. - * - * \param pub Context holding a public key. - * \param prv Context holding a private (and public) key. - * - * \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA - */ -int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ); - -/** - * \brief Export debug information - * - * \param ctx The PK context to use. It must have been initialized. - * \param items Place to write debug items - * - * \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA - */ -int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ); - -/** - * \brief Access the type name - * - * \param ctx The PK context to use. It must have been initialized. - * - * \return Type name on success, or "invalid PK" - */ -const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx ); - -/** - * \brief Get the key type - * - * \param ctx The PK context to use. It must have been initialized. - * - * \return Type on success. - * \return #MBEDTLS_PK_NONE for a context that has not been set up. - */ -mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ); - -#if defined(MBEDTLS_PK_PARSE_C) -/** \ingroup pk_module */ -/** - * \brief Parse a private key in PEM or DER format - * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param key Input buffer to parse. - * The buffer must contain the input exactly, with no - * extra trailing material. For PEM, the buffer must - * contain a null-terminated string. - * \param keylen Size of \b key in bytes. - * For PEM data, this includes the terminating null byte, - * so \p keylen must be equal to `strlen(key) + 1`. - * \param pwd Optional password for decryption. - * Pass \c NULL if expecting a non-encrypted key. - * Pass a string of \p pwdlen bytes if expecting an encrypted - * key; a non-encrypted key will also be accepted. - * The empty password is not supported. - * \param pwdlen Size of the password in bytes. - * Ignored if \p pwd is \c NULL. - * - * \note On entry, ctx must be empty, either freshly initialised - * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a - * specific key type, check the result with mbedtls_pk_can_do(). - * - * \note The key is also checked for correctness. - * - * \return 0 if successful, or a specific PK or PEM error code - */ -int mbedtls_pk_parse_key( mbedtls_pk_context *ctx, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ); - -/** \ingroup pk_module */ -/** - * \brief Parse a public key in PEM or DER format - * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param key Input buffer to parse. - * The buffer must contain the input exactly, with no - * extra trailing material. For PEM, the buffer must - * contain a null-terminated string. - * \param keylen Size of \b key in bytes. - * For PEM data, this includes the terminating null byte, - * so \p keylen must be equal to `strlen(key) + 1`. - * - * \note On entry, ctx must be empty, either freshly initialised - * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a - * specific key type, check the result with mbedtls_pk_can_do(). - * - * \note The key is also checked for correctness. - * - * \return 0 if successful, or a specific PK or PEM error code - */ -int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, - const unsigned char *key, size_t keylen ); - -#if defined(MBEDTLS_FS_IO) -/** \ingroup pk_module */ -/** - * \brief Load and parse a private key - * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param path filename to read the private key from - * \param password Optional password to decrypt the file. - * Pass \c NULL if expecting a non-encrypted key. - * Pass a null-terminated string if expecting an encrypted - * key; a non-encrypted key will also be accepted. - * The empty password is not supported. - * - * \note On entry, ctx must be empty, either freshly initialised - * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a - * specific key type, check the result with mbedtls_pk_can_do(). - * - * \note The key is also checked for correctness. - * - * \return 0 if successful, or a specific PK or PEM error code - */ -int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, - const char *path, const char *password ); - -/** \ingroup pk_module */ -/** - * \brief Load and parse a public key - * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param path filename to read the public key from - * - * \note On entry, ctx must be empty, either freshly initialised - * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If - * you need a specific key type, check the result with - * mbedtls_pk_can_do(). - * - * \note The key is also checked for correctness. - * - * \return 0 if successful, or a specific PK or PEM error code - */ -int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ); -#endif /* MBEDTLS_FS_IO */ -#endif /* MBEDTLS_PK_PARSE_C */ - -#if defined(MBEDTLS_PK_WRITE_C) -/** - * \brief Write a private key to a PKCS#1 or SEC1 DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx PK context which must contain a valid private key. - * \param buf buffer to write to - * \param size size of the buffer - * - * \return length of data written if successful, or a specific - * error code - */ -int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); - -/** - * \brief Write a public key to a SubjectPublicKeyInfo DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx PK context which must contain a valid public or private key. - * \param buf buffer to write to - * \param size size of the buffer - * - * \return length of data written if successful, or a specific - * error code - */ -int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a public key to a PEM string - * - * \param ctx PK context which must contain a valid public or private key. - * \param buf Buffer to write to. The output includes a - * terminating null byte. - * \param size Size of the buffer in bytes. - * - * \return 0 if successful, or a specific error code - */ -int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); - -/** - * \brief Write a private key to a PKCS#1 or SEC1 PEM string - * - * \param ctx PK context which must contain a valid private key. - * \param buf Buffer to write to. The output includes a - * terminating null byte. - * \param size Size of the buffer in bytes. - * - * \return 0 if successful, or a specific error code - */ -int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_PK_WRITE_C */ - -/* - * WARNING: Low-level functions. You probably do not want to use these unless - * you are certain you do ;) - */ - -#if defined(MBEDTLS_PK_PARSE_C) -/** - * \brief Parse a SubjectPublicKeyInfo DER structure - * - * \param p the position in the ASN.1 data - * \param end end of the buffer - * \param pk The PK context to fill. It must have been initialized - * but not set up. - * - * \return 0 if successful, or a specific PK error code - */ -int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, - mbedtls_pk_context *pk ); -#endif /* MBEDTLS_PK_PARSE_C */ - -#if defined(MBEDTLS_PK_WRITE_C) -/** - * \brief Write a subjectPublicKey to ASN.1 data - * Note: function works backwards in data buffer - * - * \param p reference to current position pointer - * \param start start of the buffer (for bounds-checking) - * \param key PK context which must contain a valid public or private key. - * - * \return the length written or a negative error code - */ -int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, - const mbedtls_pk_context *key ); -#endif /* MBEDTLS_PK_WRITE_C */ - -/* - * Internal module functions. You probably do not want to use these unless you - * know you do. - */ -#if defined(MBEDTLS_FS_IO) -int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_PK_H */ diff --git a/mbedtls/pk_internal.h b/mbedtls/pk_internal.h deleted file mode 100644 index 09fe60c27..000000000 --- a/mbedtls/pk_internal.h +++ /dev/null @@ -1,164 +0,0 @@ -#pragma GCC system_header -/** - * \file pk_internal.h - * - * \brief Public Key abstraction layer: wrapper functions - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_PK_WRAP_H -#define MBEDTLS_PK_WRAP_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "pk.h" - -struct mbedtls_pk_info_t -{ - /** Public key type */ - mbedtls_pk_type_t type; - - /** Type name */ - const char *name; - - /** Get key size in bits */ - size_t (*get_bitlen)( const void * ); - - /** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */ - int (*can_do)( mbedtls_pk_type_t type ); - - /** Verify signature */ - int (*verify_func)( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ); - - /** Make signature */ - int (*sign_func)( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /** Verify signature (restartable) */ - int (*verify_rs_func)( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ); - - /** Make signature (restartable) */ - int (*sign_rs_func)( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, void *rs_ctx ); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - /** Decrypt message */ - int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - - /** Encrypt message */ - int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - - /** Check public-private key pair */ - int (*check_pair_func)( const void *pub, const void *prv ); - - /** Allocate a new context */ - void * (*ctx_alloc_func)( void ); - - /** Free the given context */ - void (*ctx_free_func)( void *ctx ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /** Allocate the restart context */ - void * (*rs_alloc_func)( void ); - - /** Free the restart context */ - void (*rs_free_func)( void *rs_ctx ); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - /** Interface with the debug module */ - void (*debug_func)( const void *ctx, mbedtls_pk_debug_item *items ); - -}; -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/* Container for RSA-alt */ -typedef struct -{ - void *key; - mbedtls_pk_rsa_alt_decrypt_func decrypt_func; - mbedtls_pk_rsa_alt_sign_func sign_func; - mbedtls_pk_rsa_alt_key_len_func key_len_func; -} mbedtls_rsa_alt_context; -#endif - -#if defined(MBEDTLS_RSA_C) -extern const mbedtls_pk_info_t mbedtls_rsa_info; -#endif - -#if defined(MBEDTLS_ECP_C) -extern const mbedtls_pk_info_t mbedtls_eckey_info; -extern const mbedtls_pk_info_t mbedtls_eckeydh_info; -#endif - -#if defined(MBEDTLS_ECDSA_C) -extern const mbedtls_pk_info_t mbedtls_ecdsa_info; -#endif - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -extern const mbedtls_pk_info_t mbedtls_rsa_alt_info; -#endif - -#endif /* MBEDTLS_PK_WRAP_H */ diff --git a/mbedtls/pk_wrap.c b/mbedtls/pk_wrap.c deleted file mode 100644 index 97cbd71da..000000000 --- a/mbedtls/pk_wrap.c +++ /dev/null @@ -1,757 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Public Key abstraction layer: wrapper functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PK_C) -#include "mbedtls/pk_internal.h" - -/* Even if RSA not activated, for the sake of RSA-alt */ -#include "mbedtls/rsa.h" - -#include - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -#include "mbedtls/platform_util.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include -#include - -#if defined(MBEDTLS_RSA_C) -static int rsa_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_RSA || - type == MBEDTLS_PK_RSASSA_PSS ); -} - -static size_t rsa_get_bitlen( const void *ctx ) -{ - const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx; - return( 8 * mbedtls_rsa_get_len( rsa ) ); -} - -static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - size_t rsa_len = mbedtls_rsa_get_len( rsa ); - -#if SIZE_MAX > UINT_MAX - if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - if( sig_len < rsa_len ) - return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - - if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL, - MBEDTLS_RSA_PUBLIC, md_alg, - (unsigned int) hash_len, hash, sig ) ) != 0 ) - return( ret ); - - /* The buffer contains a valid signature followed by extra data. - * We have a special error code for that so that so that callers can - * use mbedtls_pk_verify() to check "Does the buffer start with a - * valid signature?" and not just "Does the buffer contain a valid - * signature?". */ - if( sig_len > rsa_len ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( 0 ); -} - -static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - -#if SIZE_MAX > UINT_MAX - if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - *sig_len = mbedtls_rsa_get_len( rsa ); - - return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, - md_alg, (unsigned int) hash_len, hash, sig ) ); -} - -static int rsa_decrypt_wrap( void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - - if( ilen != mbedtls_rsa_get_len( rsa ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng, - MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); -} - -static int rsa_encrypt_wrap( void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; - *olen = mbedtls_rsa_get_len( rsa ); - - if( *olen > osize ) - return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); - - return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC, - ilen, input, output ) ); -} - -static int rsa_check_pair_wrap( const void *pub, const void *prv ) -{ - return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, - (const mbedtls_rsa_context *) prv ) ); -} - -static void *rsa_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); - - if( ctx != NULL ) - mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); - - return( ctx ); -} - -static void rsa_free_wrap( void *ctx ) -{ - mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); - mbedtls_free( ctx ); -} - -static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) -{ - items->type = MBEDTLS_PK_DEBUG_MPI; - items->name = "rsa.N"; - items->value = &( ((mbedtls_rsa_context *) ctx)->N ); - - items++; - - items->type = MBEDTLS_PK_DEBUG_MPI; - items->name = "rsa.E"; - items->value = &( ((mbedtls_rsa_context *) ctx)->E ); -} - -const mbedtls_pk_info_t mbedtls_rsa_info = { - MBEDTLS_PK_RSA, - "RSA", - rsa_get_bitlen, - rsa_can_do, - rsa_verify_wrap, - rsa_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - rsa_decrypt_wrap, - rsa_encrypt_wrap, - rsa_check_pair_wrap, - rsa_alloc_wrap, - rsa_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - rsa_debug, -}; -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/* - * Generic EC key - */ -static int eckey_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECKEY_DH || - type == MBEDTLS_PK_ECDSA ); -} - -static size_t eckey_get_bitlen( const void *ctx ) -{ - return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); -} - -#if defined(MBEDTLS_ECDSA_C) -/* Forward declarations */ -static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ); - -static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); - -static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - mbedtls_ecdsa_context ecdsa; - - mbedtls_ecdsa_init( &ecdsa ); - - if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) - ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); - - mbedtls_ecdsa_free( &ecdsa ); - - return( ret ); -} - -static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret; - mbedtls_ecdsa_context ecdsa; - - mbedtls_ecdsa_init( &ecdsa ); - - if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) - ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, - f_rng, p_rng ); - - mbedtls_ecdsa_free( &ecdsa ); - - return( ret ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* Forward declarations */ -static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ); - -static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx ); - -/* - * Restart context for ECDSA operations with ECKEY context - * - * We need to store an actual ECDSA context, as we need to pass the same to - * the underlying ecdsa function, so we can't create it on the fly every time. - */ -typedef struct -{ - mbedtls_ecdsa_restart_ctx ecdsa_rs; - mbedtls_ecdsa_context ecdsa_ctx; -} eckey_restart_ctx; - -static void *eckey_rs_alloc( void ) -{ - eckey_restart_ctx *rs_ctx; - - void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) ); - - if( ctx != NULL ) - { - rs_ctx = ctx; - mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs ); - mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx ); - } - - return( ctx ); -} - -static void eckey_rs_free( void *ctx ) -{ - eckey_restart_ctx *rs_ctx; - - if( ctx == NULL) - return; - - rs_ctx = ctx; - mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs ); - mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx ); - - mbedtls_free( ctx ); -} - -static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ) -{ - int ret; - eckey_restart_ctx *rs = rs_ctx; - - /* Should never happen */ - if( rs == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - /* set up our own sub-context if needed (that is, on first run) */ - if( rs->ecdsa_ctx.grp.pbits == 0 ) - MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); - - MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx, - md_alg, hash, hash_len, - sig, sig_len, &rs->ecdsa_rs ) ); - -cleanup: - return( ret ); -} - -static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx ) -{ - int ret; - eckey_restart_ctx *rs = rs_ctx; - - /* Should never happen */ - if( rs == NULL ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - - /* set up our own sub-context if needed (that is, on first run) */ - if( rs->ecdsa_ctx.grp.pbits == 0 ) - MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); - - MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg, - hash, hash_len, sig, sig_len, - f_rng, p_rng, &rs->ecdsa_rs ) ); - -cleanup: - return( ret ); -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_ECDSA_C */ - -static int eckey_check_pair( const void *pub, const void *prv ) -{ - return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, - (const mbedtls_ecp_keypair *) prv ) ); -} - -static void *eckey_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); - - if( ctx != NULL ) - mbedtls_ecp_keypair_init( ctx ); - - return( ctx ); -} - -static void eckey_free_wrap( void *ctx ) -{ - mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); - mbedtls_free( ctx ); -} - -static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) -{ - items->type = MBEDTLS_PK_DEBUG_ECP; - items->name = "eckey.Q"; - items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); -} - -const mbedtls_pk_info_t mbedtls_eckey_info = { - MBEDTLS_PK_ECKEY, - "EC", - eckey_get_bitlen, - eckey_can_do, -#if defined(MBEDTLS_ECDSA_C) - eckey_verify_wrap, - eckey_sign_wrap, -#if defined(MBEDTLS_ECP_RESTARTABLE) - eckey_verify_rs_wrap, - eckey_sign_rs_wrap, -#endif -#else /* MBEDTLS_ECDSA_C */ - NULL, - NULL, -#endif /* MBEDTLS_ECDSA_C */ - NULL, - NULL, - eckey_check_pair, - eckey_alloc_wrap, - eckey_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - eckey_rs_alloc, - eckey_rs_free, -#endif - eckey_debug, -}; - -/* - * EC key restricted to ECDH - */ -static int eckeydh_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECKEY_DH ); -} - -const mbedtls_pk_info_t mbedtls_eckeydh_info = { - MBEDTLS_PK_ECKEY_DH, - "EC_DH", - eckey_get_bitlen, /* Same underlying key structure */ - eckeydh_can_do, - NULL, - NULL, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - NULL, - NULL, - eckey_check_pair, - eckey_alloc_wrap, /* Same underlying key structure */ - eckey_free_wrap, /* Same underlying key structure */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - eckey_debug, /* Same underlying key structure */ -}; -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_ECDSA_C) -static int ecdsa_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_ECDSA ); -} - -static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len ) -{ - int ret; - ((void) md_alg); - - ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, - hash, hash_len, sig, sig_len ); - - if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( ret ); -} - -static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, - md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx ) -{ - int ret; - ((void) md_alg); - - ret = mbedtls_ecdsa_read_signature_restartable( - (mbedtls_ecdsa_context *) ctx, - hash, hash_len, sig, sig_len, - (mbedtls_ecdsa_restart_ctx *) rs_ctx ); - - if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) - return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); - - return( ret ); -} - -static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx ) -{ - return( mbedtls_ecdsa_write_signature_restartable( - (mbedtls_ecdsa_context *) ctx, - md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng, - (mbedtls_ecdsa_restart_ctx *) rs_ctx ) ); - -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -static void *ecdsa_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); - - if( ctx != NULL ) - mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); - - return( ctx ); -} - -static void ecdsa_free_wrap( void *ctx ) -{ - mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); - mbedtls_free( ctx ); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -static void *ecdsa_rs_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) ); - - if( ctx != NULL ) - mbedtls_ecdsa_restart_init( ctx ); - - return( ctx ); -} - -static void ecdsa_rs_free( void *ctx ) -{ - mbedtls_ecdsa_restart_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -const mbedtls_pk_info_t mbedtls_ecdsa_info = { - MBEDTLS_PK_ECDSA, - "ECDSA", - eckey_get_bitlen, /* Compatible key structures */ - ecdsa_can_do, - ecdsa_verify_wrap, - ecdsa_sign_wrap, -#if defined(MBEDTLS_ECP_RESTARTABLE) - ecdsa_verify_rs_wrap, - ecdsa_sign_rs_wrap, -#endif - NULL, - NULL, - eckey_check_pair, /* Compatible key structures */ - ecdsa_alloc_wrap, - ecdsa_free_wrap, -#if defined(MBEDTLS_ECP_RESTARTABLE) - ecdsa_rs_alloc, - ecdsa_rs_free, -#endif - eckey_debug, /* Compatible key structures */ -}; -#endif /* MBEDTLS_ECDSA_C */ - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/* - * Support for alternative RSA-private implementations - */ - -static int rsa_alt_can_do( mbedtls_pk_type_t type ) -{ - return( type == MBEDTLS_PK_RSA ); -} - -static size_t rsa_alt_get_bitlen( const void *ctx ) -{ - const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; - - return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); -} - -static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; - -#if SIZE_MAX > UINT_MAX - if( UINT_MAX < hash_len ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); -#endif /* SIZE_MAX > UINT_MAX */ - - *sig_len = rsa_alt->key_len_func( rsa_alt->key ); - - return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, - md_alg, (unsigned int) hash_len, hash, sig ) ); -} - -static int rsa_alt_decrypt_wrap( void *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; - - ((void) f_rng); - ((void) p_rng); - - if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - return( rsa_alt->decrypt_func( rsa_alt->key, - MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); -} - -#if defined(MBEDTLS_RSA_C) -static int rsa_alt_check_pair( const void *pub, const void *prv ) -{ - unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; - unsigned char hash[32]; - size_t sig_len = 0; - int ret; - - if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - - memset( hash, 0x2a, sizeof( hash ) ); - - if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, - hash, sizeof( hash ), - sig, &sig_len, NULL, NULL ) ) != 0 ) - { - return( ret ); - } - - if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, - hash, sizeof( hash ), sig, sig_len ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - return( 0 ); -} -#endif /* MBEDTLS_RSA_C */ - -static void *rsa_alt_alloc_wrap( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); - - if( ctx != NULL ) - memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); - - return( ctx ); -} - -static void rsa_alt_free_wrap( void *ctx ) -{ - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); - mbedtls_free( ctx ); -} - -const mbedtls_pk_info_t mbedtls_rsa_alt_info = { - MBEDTLS_PK_RSA_ALT, - "RSA-alt", - rsa_alt_get_bitlen, - rsa_alt_can_do, - NULL, - rsa_alt_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - rsa_alt_decrypt_wrap, - NULL, -#if defined(MBEDTLS_RSA_C) - rsa_alt_check_pair, -#else - NULL, -#endif - rsa_alt_alloc_wrap, - rsa_alt_free_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - NULL, - NULL, -#endif - NULL, -}; - -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -#endif /* MBEDTLS_PK_C */ diff --git a/mbedtls/pkcs11.c b/mbedtls/pkcs11.c deleted file mode 100644 index 89434ed25..000000000 --- a/mbedtls/pkcs11.c +++ /dev/null @@ -1,278 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file pkcs11.c - * - * \brief Wrapper for PKCS#11 library libpkcs11-helper - * - * \author Adriaan de Jong - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#include "mbedtls/pkcs11.h" - -#if defined(MBEDTLS_PKCS11_C) - -#include "mbedtls/md.h" -#include "mbedtls/oid.h" -#include "mbedtls/x509_crt.h" - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include - -void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) ); -} - -int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) -{ - int ret = 1; - unsigned char *cert_blob = NULL; - size_t cert_blob_size = 0; - - if( cert == NULL ) - { - ret = 2; - goto cleanup; - } - - if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, - &cert_blob_size ) != CKR_OK ) - { - ret = 3; - goto cleanup; - } - - cert_blob = mbedtls_calloc( 1, cert_blob_size ); - if( NULL == cert_blob ) - { - ret = 4; - goto cleanup; - } - - if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, - &cert_blob_size ) != CKR_OK ) - { - ret = 5; - goto cleanup; - } - - if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) ) - { - ret = 6; - goto cleanup; - } - - ret = 0; - -cleanup: - if( NULL != cert_blob ) - mbedtls_free( cert_blob ); - - return( ret ); -} - - -int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key, - pkcs11h_certificate_t pkcs11_cert ) -{ - int ret = 1; - mbedtls_x509_crt cert; - - mbedtls_x509_crt_init( &cert ); - - if( priv_key == NULL ) - goto cleanup; - - if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) ) - goto cleanup; - - priv_key->len = mbedtls_pk_get_len( &cert.pk ); - priv_key->pkcs11h_cert = pkcs11_cert; - - ret = 0; - -cleanup: - mbedtls_x509_crt_free( &cert ); - - return( ret ); -} - -void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key ) -{ - if( NULL != priv_key ) - pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert ); -} - -int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ) -{ - size_t input_len, output_len; - - if( NULL == ctx ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( MBEDTLS_RSA_PRIVATE != mode ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - output_len = input_len = ctx->len; - - if( input_len < 16 || input_len > output_max_len ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* Determine size of output buffer */ - if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, - input_len, NULL, &output_len ) != CKR_OK ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - if( output_len > output_max_len ) - return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); - - if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, - input_len, output, &output_len ) != CKR_OK ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - *olen = output_len; - return( 0 ); -} - -int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ) -{ - size_t sig_len = 0, asn_len = 0, oid_size = 0; - unsigned char *p = sig; - const char *oid; - - if( NULL == ctx ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( MBEDTLS_RSA_PRIVATE != mode ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( md_alg != MBEDTLS_MD_NONE ) - { - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hashlen = mbedtls_md_get_size( md_info ); - asn_len = 10 + oid_size; - } - - sig_len = ctx->len; - if( hashlen > sig_len || asn_len > sig_len || - hashlen + asn_len > sig_len ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - if( md_alg != MBEDTLS_MD_NONE ) - { - /* - * DigestInfo ::= SEQUENCE { - * digestAlgorithm DigestAlgorithmIdentifier, - * digest Digest } - * - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * - * Digest ::= OCTET STRING - */ - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char) ( 0x04 + oid_size ); - *p++ = MBEDTLS_ASN1_OID; - *p++ = oid_size & 0xFF; - memcpy( p, oid, oid_size ); - p += oid_size; - *p++ = MBEDTLS_ASN1_NULL; - *p++ = 0x00; - *p++ = MBEDTLS_ASN1_OCTET_STRING; - *p++ = hashlen; - } - - memcpy( p, hash, hashlen ); - - if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig, - asn_len + hashlen, sig, &sig_len ) != CKR_OK ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - return( 0 ); -} - -#endif /* defined(MBEDTLS_PKCS11_C) */ diff --git a/mbedtls/pkcs11.h b/mbedtls/pkcs11.h deleted file mode 100644 index d00102e5e..000000000 --- a/mbedtls/pkcs11.h +++ /dev/null @@ -1,201 +0,0 @@ -#pragma GCC system_header -/** - * \file pkcs11.h - * - * \brief Wrapper for PKCS#11 library libpkcs11-helper - * - * \author Adriaan de Jong - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_PKCS11_H -#define MBEDTLS_PKCS11_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PKCS11_C) - -#include "x509_crt.h" - -#include - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Context for PKCS #11 private keys. - */ -typedef struct mbedtls_pkcs11_context -{ - pkcs11h_certificate_t pkcs11h_cert; - int len; -} mbedtls_pkcs11_context; - -/** - * Initialize a mbedtls_pkcs11_context. - * (Just making memory references valid.) - */ -void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ); - -/** - * Fill in a mbed TLS certificate, based on the given PKCS11 helper certificate. - * - * \param cert X.509 certificate to fill - * \param pkcs11h_cert PKCS #11 helper certificate - * - * \return 0 on success. - */ -int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11h_cert ); - -/** - * Set up a mbedtls_pkcs11_context storing the given certificate. Note that the - * mbedtls_pkcs11_context will take over control of the certificate, freeing it when - * done. - * - * \param priv_key Private key structure to fill. - * \param pkcs11_cert PKCS #11 helper certificate - * - * \return 0 on success - */ -int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key, - pkcs11h_certificate_t pkcs11_cert ); - -/** - * Free the contents of the given private key context. Note that the structure - * itself is not freed. - * - * \param priv_key Private key structure to cleanup - */ -void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key ); - -/** - * \brief Do an RSA private key decrypt, then remove the message - * padding - * - * \param ctx PKCS #11 context - * \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature - * \param input buffer holding the encrypted data - * \param output buffer that will hold the plaintext - * \param olen will contain the plaintext length - * \param output_max_len maximum length of the output buffer - * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code - * - * \note The output buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise - * an error is thrown. - */ -int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ); - -/** - * \brief Do a private RSA to sign a message digest - * - * \param ctx PKCS #11 context - * \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature - * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) - * \param hashlen message digest length (for MBEDTLS_MD_NONE only) - * \param hash buffer holding the message digest - * \param sig buffer that will hold the ciphertext - * - * \return 0 if the signing operation was successful, - * or an MBEDTLS_ERR_RSA_XXX error code - * - * \note The "sig" buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). - */ -int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ); - -/** - * SSL/TLS wrappers for PKCS#11 functions - */ -static inline int mbedtls_ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen, - const unsigned char *input, unsigned char *output, - size_t output_max_len ) -{ - return mbedtls_pkcs11_decrypt( (mbedtls_pkcs11_context *) ctx, mode, olen, input, output, - output_max_len ); -} - -static inline int mbedtls_ssl_pkcs11_sign( void *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, - const unsigned char *hash, unsigned char *sig ) -{ - ((void) f_rng); - ((void) p_rng); - return mbedtls_pkcs11_sign( (mbedtls_pkcs11_context *) ctx, mode, md_alg, - hashlen, hash, sig ); -} - -static inline size_t mbedtls_ssl_pkcs11_key_len( void *ctx ) -{ - return ( (mbedtls_pkcs11_context *) ctx )->len; -} - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_PKCS11_C */ - -#endif /* MBEDTLS_PKCS11_H */ diff --git a/mbedtls/pkcs12.c b/mbedtls/pkcs12.c deleted file mode 100644 index a85f9be98..000000000 --- a/mbedtls/pkcs12.c +++ /dev/null @@ -1,403 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * PKCS#12 Personal Information Exchange Syntax - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 - * - * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf - * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PKCS12_C) - -#include "mbedtls/pkcs12.h" -#include "mbedtls/asn1.h" -#include "mbedtls/cipher.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_ARC4_C) -#include "mbedtls/arc4.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) - -static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, - mbedtls_asn1_buf *salt, int *iterations ) -{ - int ret; - unsigned char **p = ¶ms->p; - const unsigned char *end = params->p + params->len; - - /* - * pkcs-12PbeParams ::= SEQUENCE { - * salt OCTET STRING, - * iterations INTEGER - * } - * - */ - if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); - - salt->p = *p; - *p += salt->len; - - if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 ) - return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); - - if( *p != end ) - return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -#define PKCS12_MAX_PWDLEN 128 - -static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - unsigned char *key, size_t keylen, - unsigned char *iv, size_t ivlen ) -{ - int ret, iterations = 0; - mbedtls_asn1_buf salt; - size_t i; - unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; - - if( pwdlen > PKCS12_MAX_PWDLEN ) - return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); - - memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); - memset( &unipwd, 0, sizeof(unipwd) ); - - if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, - &iterations ) ) != 0 ) - return( ret ); - - for( i = 0; i < pwdlen; i++ ) - unipwd[i * 2 + 1] = pwd[i]; - - if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, - salt.p, salt.len, md_type, - MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 ) - { - return( ret ); - } - - if( iv == NULL || ivlen == 0 ) - return( 0 ); - - if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, - salt.p, salt.len, md_type, - MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 ) - { - return( ret ); - } - return( 0 ); -} - -#undef PKCS12_MAX_PWDLEN - -int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t len, - unsigned char *output ) -{ -#if !defined(MBEDTLS_ARC4_C) - ((void) pbe_params); - ((void) mode); - ((void) pwd); - ((void) pwdlen); - ((void) data); - ((void) len); - ((void) output); - return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); -#else - int ret; - unsigned char key[16]; - mbedtls_arc4_context ctx; - ((void) mode); - - mbedtls_arc4_init( &ctx ); - - if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1, - pwd, pwdlen, - key, 16, NULL, 0 ) ) != 0 ) - { - return( ret ); - } - - mbedtls_arc4_setup( &ctx, key, 16 ); - if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_platform_zeroize( key, sizeof( key ) ); - mbedtls_arc4_free( &ctx ); - - return( ret ); -#endif /* MBEDTLS_ARC4_C */ -} - -int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, - mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t len, - unsigned char *output ) -{ - int ret, keylen = 0; - unsigned char key[32]; - unsigned char iv[16]; - const mbedtls_cipher_info_t *cipher_info; - mbedtls_cipher_context_t cipher_ctx; - size_t olen = 0; - - cipher_info = mbedtls_cipher_info_from_type( cipher_type ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); - - keylen = cipher_info->key_bitlen / 8; - - if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, - key, keylen, - iv, cipher_info->iv_size ) ) != 0 ) - { - return( ret ); - } - - mbedtls_cipher_init( &cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len, - output, &olen ) ) != 0 ) - { - goto exit; - } - - if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) - ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; - -exit: - mbedtls_platform_zeroize( key, sizeof( key ) ); - mbedtls_platform_zeroize( iv, sizeof( iv ) ); - mbedtls_cipher_free( &cipher_ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_ASN1_PARSE_C */ - -static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, - const unsigned char *filler, size_t fill_len ) -{ - unsigned char *p = data; - size_t use_len; - - while( data_len > 0 ) - { - use_len = ( data_len > fill_len ) ? fill_len : data_len; - memcpy( p, filler, use_len ); - p += use_len; - data_len -= use_len; - } -} - -int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *salt, size_t saltlen, - mbedtls_md_type_t md_type, int id, int iterations ) -{ - int ret; - unsigned int j; - - unsigned char diversifier[128]; - unsigned char salt_block[128], pwd_block[128], hash_block[128]; - unsigned char hash_output[MBEDTLS_MD_MAX_SIZE]; - unsigned char *p; - unsigned char c; - - size_t hlen, use_len, v, i; - - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - - // This version only allows max of 64 bytes of password or salt - if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) - return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); - - md_info = mbedtls_md_info_from_type( md_type ); - if( md_info == NULL ) - return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); - - mbedtls_md_init( &md_ctx ); - - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - return( ret ); - hlen = mbedtls_md_get_size( md_info ); - - if( hlen <= 32 ) - v = 64; - else - v = 128; - - memset( diversifier, (unsigned char) id, v ); - - pkcs12_fill_buffer( salt_block, v, salt, saltlen ); - pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); - - p = data; - while( datalen > 0 ) - { - // Calculate hash( diversifier || salt_block || pwd_block ) - if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 ) - goto exit; - - // Perform remaining ( iterations - 1 ) recursive hash calculations - for( i = 1; i < (size_t) iterations; i++ ) - { - if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 ) - goto exit; - } - - use_len = ( datalen > hlen ) ? hlen : datalen; - memcpy( p, hash_output, use_len ); - datalen -= use_len; - p += use_len; - - if( datalen == 0 ) - break; - - // Concatenating copies of hash_output into hash_block (B) - pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); - - // B += 1 - for( i = v; i > 0; i-- ) - if( ++hash_block[i - 1] != 0 ) - break; - - // salt_block += B - c = 0; - for( i = v; i > 0; i-- ) - { - j = salt_block[i - 1] + hash_block[i - 1] + c; - c = (unsigned char) (j >> 8); - salt_block[i - 1] = j & 0xFF; - } - - // pwd_block += B - c = 0; - for( i = v; i > 0; i-- ) - { - j = pwd_block[i - 1] + hash_block[i - 1] + c; - c = (unsigned char) (j >> 8); - pwd_block[i - 1] = j & 0xFF; - } - } - - ret = 0; - -exit: - mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) ); - mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) ); - mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) ); - mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) ); - - mbedtls_md_free( &md_ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_PKCS12_C */ diff --git a/mbedtls/pkcs12.h b/mbedtls/pkcs12.h deleted file mode 100644 index fba5c9023..000000000 --- a/mbedtls/pkcs12.h +++ /dev/null @@ -1,156 +0,0 @@ -#pragma GCC system_header -/** - * \file pkcs12.h - * - * \brief PKCS#12 Personal Information Exchange Syntax - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_PKCS12_H -#define MBEDTLS_PKCS12_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "md.h" -#include "cipher.h" -#include "asn1.h" - -#include - -#define MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA -0x1F80 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE -0x1F00 /**< Feature not available, e.g. unsupported encryption scheme. */ -#define MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT -0x1E80 /**< PBE ASN.1 data not as expected. */ -#define MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH -0x1E00 /**< Given private key password does not allow for correct decryption. */ - -#define MBEDTLS_PKCS12_DERIVE_KEY 1 /**< encryption/decryption key */ -#define MBEDTLS_PKCS12_DERIVE_IV 2 /**< initialization vector */ -#define MBEDTLS_PKCS12_DERIVE_MAC_KEY 3 /**< integrity / MAC key */ - -#define MBEDTLS_PKCS12_PBE_DECRYPT 0 -#define MBEDTLS_PKCS12_PBE_ENCRYPT 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) - -/** - * \brief PKCS12 Password Based function (encryption / decryption) - * for pbeWithSHAAnd128BitRC4 - * - * \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure - * \param mode either MBEDTLS_PKCS12_PBE_ENCRYPT or MBEDTLS_PKCS12_PBE_DECRYPT - * \param pwd the password used (may be NULL if no password is used) - * \param pwdlen length of the password (may be 0) - * \param input the input data - * \param len data length - * \param output the output buffer - * - * \return 0 if successful, or a MBEDTLS_ERR_XXX code - */ -int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *input, size_t len, - unsigned char *output ); - -/** - * \brief PKCS12 Password Based function (encryption / decryption) - * for cipher-based and mbedtls_md-based PBE's - * - * \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure - * \param mode either MBEDTLS_PKCS12_PBE_ENCRYPT or MBEDTLS_PKCS12_PBE_DECRYPT - * \param cipher_type the cipher used - * \param md_type the mbedtls_md used - * \param pwd the password used (may be NULL if no password is used) - * \param pwdlen length of the password (may be 0) - * \param input the input data - * \param len data length - * \param output the output buffer - * - * \return 0 if successful, or a MBEDTLS_ERR_XXX code - */ -int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, - mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *input, size_t len, - unsigned char *output ); - -#endif /* MBEDTLS_ASN1_PARSE_C */ - -/** - * \brief The PKCS#12 derivation function uses a password and a salt - * to produce pseudo-random bits for a particular "purpose". - * - * Depending on the given id, this function can produce an - * encryption/decryption key, an nitialization vector or an - * integrity key. - * - * \param data buffer to store the derived data in - * \param datalen length to fill - * \param pwd password to use (may be NULL if no password is used) - * \param pwdlen length of the password (may be 0) - * \param salt salt buffer to use - * \param saltlen length of the salt - * \param mbedtls_md mbedtls_md type to use during the derivation - * \param id id that describes the purpose (can be MBEDTLS_PKCS12_DERIVE_KEY, - * MBEDTLS_PKCS12_DERIVE_IV or MBEDTLS_PKCS12_DERIVE_MAC_KEY) - * \param iterations number of iterations - * - * \return 0 if successful, or a MD, BIGNUM type error. - */ -int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *salt, size_t saltlen, - mbedtls_md_type_t mbedtls_md, int id, int iterations ); - -#ifdef __cplusplus -} -#endif - -#endif /* pkcs12.h */ diff --git a/mbedtls/pkcs5.c b/mbedtls/pkcs5.c deleted file mode 100644 index 00d8e9f17..000000000 --- a/mbedtls/pkcs5.c +++ /dev/null @@ -1,454 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file pkcs5.c - * - * \brief PKCS#5 functions - * - * \author Mathias Olsson - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * PKCS#5 includes PBKDF2 and more - * - * http://tools.ietf.org/html/rfc2898 (Specification) - * http://tools.ietf.org/html/rfc6070 (Test vectors) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PKCS5_C) - -#include "mbedtls/pkcs5.h" - -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" -#include "mbedtls/cipher.h" -#include "mbedtls/oid.h" -#endif /* MBEDTLS_ASN1_PARSE_C */ - -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) -static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params, - mbedtls_asn1_buf *salt, int *iterations, - int *keylen, mbedtls_md_type_t *md_type ) -{ - int ret; - mbedtls_asn1_buf prf_alg_oid; - unsigned char *p = params->p; - const unsigned char *end = params->p + params->len; - - if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - /* - * PBKDF2-params ::= SEQUENCE { - * salt OCTET STRING, - * iterationCount INTEGER, - * keyLength INTEGER OPTIONAL - * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1 - * } - * - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - - salt->p = p; - p += salt->len; - - if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - - if( p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 ) - { - if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - } - - if( p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - - if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - if( p != end ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t datalen, - unsigned char *output ) -{ - int ret, iterations = 0, keylen = 0; - unsigned char *p, *end; - mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params; - mbedtls_asn1_buf salt; - mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; - unsigned char key[32], iv[32]; - size_t olen = 0; - const mbedtls_md_info_t *md_info; - const mbedtls_cipher_info_t *cipher_info; - mbedtls_md_context_t md_ctx; - mbedtls_cipher_type_t cipher_alg; - mbedtls_cipher_context_t cipher_ctx; - - p = pbe_params->p; - end = p + pbe_params->len; - - /* - * PBES2-params ::= SEQUENCE { - * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, - * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} - * } - */ - if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 ) - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - - // Only PBKDF2 supported at the moment - // - if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params, - &salt, &iterations, &keylen, - &md_type ) ) != 0 ) - { - return( ret ); - } - - md_info = mbedtls_md_info_from_type( md_type ); - if( md_info == NULL ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid, - &enc_scheme_params ) ) != 0 ) - { - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - } - - if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - cipher_info = mbedtls_cipher_info_from_type( cipher_alg ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - - /* - * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored - * since it is optional and we don't know if it was set or not - */ - keylen = cipher_info->key_bitlen / 8; - - if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING || - enc_scheme_params.len != cipher_info->iv_size ) - { - return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT ); - } - - mbedtls_md_init( &md_ctx ); - mbedtls_cipher_init( &cipher_ctx ); - - memcpy( iv, enc_scheme_params.p, enc_scheme_params.len ); - - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len, - iterations, keylen, key ) ) != 0 ) - { - goto exit; - } - - if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len, - data, datalen, output, &olen ) ) != 0 ) - ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH; - -exit: - mbedtls_md_free( &md_ctx ); - mbedtls_cipher_free( &cipher_ctx ); - - return( ret ); -} -#endif /* MBEDTLS_ASN1_PARSE_C */ - -int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password, - size_t plen, const unsigned char *salt, size_t slen, - unsigned int iteration_count, - uint32_t key_length, unsigned char *output ) -{ - int ret = 0, j; - unsigned int i; - unsigned char md1[MBEDTLS_MD_MAX_SIZE]; - unsigned char work[MBEDTLS_MD_MAX_SIZE]; - unsigned char md_size = mbedtls_md_get_size( ctx->md_info ); - size_t use_len; - unsigned char *out_p = output; - unsigned char counter[4]; - - memset( counter, 0, 4 ); - counter[3] = 1; - -#if UINT_MAX > 0xFFFFFFFF - if( iteration_count > 0xFFFFFFFF ) - return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA ); -#endif - - while( key_length ) - { - // U1 ends up in work - // - if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) - goto cleanup; - - if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 ) - goto cleanup; - - if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 ) - goto cleanup; - - if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 ) - goto cleanup; - - memcpy( md1, work, md_size ); - - for( i = 1; i < iteration_count; i++ ) - { - // U2 ends up in md1 - // - if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) - goto cleanup; - - if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 ) - goto cleanup; - - if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 ) - goto cleanup; - - // U1 xor U2 - // - for( j = 0; j < md_size; j++ ) - work[j] ^= md1[j]; - } - - use_len = ( key_length < md_size ) ? key_length : md_size; - memcpy( out_p, work, use_len ); - - key_length -= (uint32_t) use_len; - out_p += use_len; - - for( i = 4; i > 0; i-- ) - if( ++counter[i - 1] != 0 ) - break; - } - -cleanup: - /* Zeroise buffers to clear sensitive data from memory. */ - mbedtls_platform_zeroize( work, MBEDTLS_MD_MAX_SIZE ); - mbedtls_platform_zeroize( md1, MBEDTLS_MD_MAX_SIZE ); - - return( ret ); -} - -#if defined(MBEDTLS_SELF_TEST) - -#if !defined(MBEDTLS_SHA1_C) -int mbedtls_pkcs5_self_test( int verbose ) -{ - if( verbose != 0 ) - mbedtls_printf( " PBKDF2 (SHA1): skipped\n\n" ); - - return( 0 ); -} -#else - -#define MAX_TESTS 6 - -static const size_t plen[MAX_TESTS] = - { 8, 8, 8, 24, 9 }; - -static const unsigned char password[MAX_TESTS][32] = -{ - "password", - "password", - "password", - "passwordPASSWORDpassword", - "pass\0word", -}; - -static const size_t slen[MAX_TESTS] = - { 4, 4, 4, 36, 5 }; - -static const unsigned char salt[MAX_TESTS][40] = -{ - "salt", - "salt", - "salt", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", - "sa\0lt", -}; - -static const uint32_t it_cnt[MAX_TESTS] = - { 1, 2, 4096, 4096, 4096 }; - -static const uint32_t key_len[MAX_TESTS] = - { 20, 20, 20, 25, 16 }; - -static const unsigned char result_key[MAX_TESTS][32] = -{ - { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, - 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, - 0x2f, 0xe0, 0x37, 0xa6 }, - { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, - 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, - 0xd8, 0xde, 0x89, 0x57 }, - { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, - 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, - 0x65, 0xa4, 0x29, 0xc1 }, - { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, - 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, - 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, - 0x38 }, - { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, - 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 }, -}; - -int mbedtls_pkcs5_self_test( int verbose ) -{ - mbedtls_md_context_t sha1_ctx; - const mbedtls_md_info_t *info_sha1; - int ret, i; - unsigned char key[64]; - - mbedtls_md_init( &sha1_ctx ); - - info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); - if( info_sha1 == NULL ) - { - ret = 1; - goto exit; - } - - if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 ) - { - ret = 1; - goto exit; - } - - for( i = 0; i < MAX_TESTS; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i ); - - ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i], - slen[i], it_cnt[i], key_len[i], key ); - if( ret != 0 || - memcmp( result_key[i], key, key_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -exit: - mbedtls_md_free( &sha1_ctx ); - - return( ret ); -} -#endif /* MBEDTLS_SHA1_C */ - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_PKCS5_C */ diff --git a/mbedtls/pkcs5.h b/mbedtls/pkcs5.h deleted file mode 100644 index e0929b4aa..000000000 --- a/mbedtls/pkcs5.h +++ /dev/null @@ -1,135 +0,0 @@ -#pragma GCC system_header -/** - * \file pkcs5.h - * - * \brief PKCS#5 functions - * - * \author Mathias Olsson - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_PKCS5_H -#define MBEDTLS_PKCS5_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "asn1.h" -#include "md.h" - -#include -#include - -#define MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA -0x2f80 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_PKCS5_INVALID_FORMAT -0x2f00 /**< Unexpected ASN.1 data. */ -#define MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE -0x2e80 /**< Requested encryption or digest alg not available. */ -#define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH -0x2e00 /**< Given private key password does not allow for correct decryption. */ - -#define MBEDTLS_PKCS5_DECRYPT 0 -#define MBEDTLS_PKCS5_ENCRYPT 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) - -/** - * \brief PKCS#5 PBES2 function - * - * \param pbe_params the ASN.1 algorithm parameters - * \param mode either MBEDTLS_PKCS5_DECRYPT or MBEDTLS_PKCS5_ENCRYPT - * \param pwd password to use when generating key - * \param pwdlen length of password - * \param data data to process - * \param datalen length of data - * \param output output buffer - * - * \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails. - */ -int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t datalen, - unsigned char *output ); - -#endif /* MBEDTLS_ASN1_PARSE_C */ - -/** - * \brief PKCS#5 PBKDF2 using HMAC - * - * \param ctx Generic HMAC context - * \param password Password to use when generating key - * \param plen Length of password - * \param salt Salt to use when generating key - * \param slen Length of salt - * \param iteration_count Iteration count - * \param key_length Length of generated key in bytes - * \param output Generated key. Must be at least as big as key_length - * - * \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails. - */ -int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password, - size_t plen, const unsigned char *salt, size_t slen, - unsigned int iteration_count, - uint32_t key_length, unsigned char *output ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_pkcs5_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* pkcs5.h */ diff --git a/mbedtls/pkparse.c b/mbedtls/pkparse.c deleted file mode 100644 index cb93676d0..000000000 --- a/mbedtls/pkparse.c +++ /dev/null @@ -1,1576 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Public Key layer for parsing key files and structures - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PK_PARSE_C) - -#include "mbedtls/pk.h" -#include "mbedtls/asn1.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif -#if defined(MBEDTLS_PKCS5_C) -#include "mbedtls/pkcs5.h" -#endif -#if defined(MBEDTLS_PKCS12_C) -#include "mbedtls/pkcs12.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -/* Parameter validation macros based on platform_util.h */ -#define PK_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) -#define PK_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_FS_IO) -/* - * Load all data from a file into a given buffer. - * - * The file is expected to contain either PEM or DER encoded data. - * A terminating null byte is always appended. It is included in the announced - * length only if the data looks like it is PEM encoded. - */ -int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ) -{ - FILE *f; - long size; - - PK_VALIDATE_RET( path != NULL ); - PK_VALIDATE_RET( buf != NULL ); - PK_VALIDATE_RET( n != NULL ); - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); - - fseek( f, 0, SEEK_END ); - if( ( size = ftell( f ) ) == -1 ) - { - fclose( f ); - return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); - } - fseek( f, 0, SEEK_SET ); - - *n = (size_t) size; - - if( *n + 1 == 0 || - ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) - { - fclose( f ); - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - } - - if( fread( *buf, 1, *n, f ) != *n ) - { - fclose( f ); - - mbedtls_platform_zeroize( *buf, *n ); - mbedtls_free( *buf ); - - return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); - } - - fclose( f ); - - (*buf)[*n] = '\0'; - - if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) - ++*n; - - return( 0 ); -} - -/* - * Load and parse a private key - */ -int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, - const char *path, const char *pwd ) -{ - int ret; - size_t n; - unsigned char *buf; - - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( path != NULL ); - - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - if( pwd == NULL ) - ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 ); - else - ret = mbedtls_pk_parse_key( ctx, buf, n, - (const unsigned char *) pwd, strlen( pwd ) ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} - -/* - * Load and parse a public key - */ -int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ) -{ - int ret; - size_t n; - unsigned char *buf; - - PK_VALIDATE_RET( ctx != NULL ); - PK_VALIDATE_RET( path != NULL ); - - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - ret = mbedtls_pk_parse_public_key( ctx, buf, n ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_ECP_C) -/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf - * - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } - * -- implicitCurve NULL - * } - */ -static int pk_get_ecparams( unsigned char **p, const unsigned char *end, - mbedtls_asn1_buf *params ) -{ - int ret; - - if ( end - *p < 1 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - /* Tag may be either OID or SEQUENCE */ - params->tag = **p; - if( params->tag != MBEDTLS_ASN1_OID -#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) - && params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) -#endif - ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } - - if( ( ret = mbedtls_asn1_get_tag( p, end, ¶ms->len, params->tag ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - params->p = *p; - *p += params->len; - - if( *p != end ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) -/* - * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. - * WARNING: the resulting group should only be used with - * pk_group_id_from_specified(), since its base point may not be set correctly - * if it was encoded compressed. - * - * SpecifiedECDomain ::= SEQUENCE { - * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), - * fieldID FieldID {{FieldTypes}}, - * curve Curve, - * base ECPoint, - * order INTEGER, - * cofactor INTEGER OPTIONAL, - * hash HashAlgorithm OPTIONAL, - * ... - * } - * - * We only support prime-field as field type, and ignore hash and cofactor. - */ -static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) -{ - int ret; - unsigned char *p = params->p; - const unsigned char * const end = params->p + params->len; - const unsigned char *end_field, *end_curve; - size_t len; - int ver; - - /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ - if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( ver < 1 || ver > 3 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - - /* - * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field - * fieldType FIELD-ID.&id({IOSet}), - * parameters FIELD-ID.&Type({IOSet}{@fieldType}) - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - end_field = p + len; - - /* - * FIELD-ID ::= TYPE-IDENTIFIER - * FieldTypes FIELD-ID ::= { - * { Prime-p IDENTIFIED BY prime-field } | - * { Characteristic-two IDENTIFIED BY characteristic-two-field } - * } - * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 ) - return( ret ); - - if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) || - memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) - { - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - } - - p += len; - - /* Prime-p ::= INTEGER -- Field of size p. */ - if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - grp->pbits = mbedtls_mpi_bitlen( &grp->P ); - - if( p != end_field ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* - * Curve ::= SEQUENCE { - * a FieldElement, - * b FieldElement, - * seed BIT STRING OPTIONAL - * -- Shall be present if used in SpecifiedECDomain - * -- with version equal to ecdpVer2 or ecdpVer3 - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - end_curve = p + len; - - /* - * FieldElement ::= OCTET STRING - * containing an integer in the case of a prime field - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || - ( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - p += len; - - if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || - ( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - p += len; - - /* Ignore seed BIT STRING OPTIONAL */ - if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 ) - p += len; - - if( p != end_curve ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* - * ECPoint ::= OCTET STRING - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G, - ( const unsigned char *) p, len ) ) != 0 ) - { - /* - * If we can't read the point because it's compressed, cheat by - * reading only the X coordinate and the parity bit of Y. - */ - if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE || - ( p[0] != 0x02 && p[0] != 0x03 ) || - len != mbedtls_mpi_size( &grp->P ) + 1 || - mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 || - mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 || - mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - } - } - - p += len; - - /* - * order INTEGER - */ - if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - grp->nbits = mbedtls_mpi_bitlen( &grp->N ); - - /* - * Allow optional elements by purposefully not enforcing p == end here. - */ - - return( 0 ); -} - -/* - * Find the group id associated with an (almost filled) group as generated by - * pk_group_from_specified(), or return an error if unknown. - */ -static int pk_group_id_from_group( const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id ) -{ - int ret = 0; - mbedtls_ecp_group ref; - const mbedtls_ecp_group_id *id; - - mbedtls_ecp_group_init( &ref ); - - for( id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++ ) - { - /* Load the group associated to that id */ - mbedtls_ecp_group_free( &ref ); - MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref, *id ) ); - - /* Compare to the group we were given, starting with easy tests */ - if( grp->pbits == ref.pbits && grp->nbits == ref.nbits && - mbedtls_mpi_cmp_mpi( &grp->P, &ref.P ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->A, &ref.A ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->B, &ref.B ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->N, &ref.N ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 && - mbedtls_mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 && - /* For Y we may only know the parity bit, so compare only that */ - mbedtls_mpi_get_bit( &grp->G.Y, 0 ) == mbedtls_mpi_get_bit( &ref.G.Y, 0 ) ) - { - break; - } - - } - -cleanup: - mbedtls_ecp_group_free( &ref ); - - *grp_id = *id; - - if( ret == 0 && *id == MBEDTLS_ECP_DP_NONE ) - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - - return( ret ); -} - -/* - * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID - */ -static int pk_group_id_from_specified( const mbedtls_asn1_buf *params, - mbedtls_ecp_group_id *grp_id ) -{ - int ret; - mbedtls_ecp_group grp; - - mbedtls_ecp_group_init( &grp ); - - if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 ) - goto cleanup; - - ret = pk_group_id_from_group( &grp, grp_id ); - -cleanup: - mbedtls_ecp_group_free( &grp ); - - return( ret ); -} -#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ - -/* - * Use EC parameters to initialise an EC group - * - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } - * -- implicitCurve NULL - */ -static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) -{ - int ret; - mbedtls_ecp_group_id grp_id; - - if( params->tag == MBEDTLS_ASN1_OID ) - { - if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 ) - return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); - } - else - { -#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) - if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 ) - return( ret ); -#else - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); -#endif - } - - /* - * grp may already be initilialized; if so, make sure IDs match - */ - if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - - if( ( ret = mbedtls_ecp_group_load( grp, grp_id ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * EC public key is an EC point - * - * The caller is responsible for clearing the structure upon failure if - * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE - * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state. - */ -static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end, - mbedtls_ecp_keypair *key ) -{ - int ret; - - if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q, - (const unsigned char *) *p, end - *p ) ) == 0 ) - { - ret = mbedtls_ecp_check_pubkey( &key->grp, &key->Q ); - } - - /* - * We know mbedtls_ecp_point_read_binary consumed all bytes or failed - */ - *p = (unsigned char *) end; - - return( ret ); -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_RSA_C) -/* - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ -static int pk_get_rsapubkey( unsigned char **p, - const unsigned char *end, - mbedtls_rsa_context *rsa ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* Import N */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); - - if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0, - NULL, 0, NULL, 0 ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); - - *p += len; - - /* Import E */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); - - if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, - NULL, 0, *p, len ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); - - *p += len; - - if( mbedtls_rsa_complete( rsa ) != 0 || - mbedtls_rsa_check_pubkey( rsa ) != 0 ) - { - return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); - } - - if( *p != end ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} -#endif /* MBEDTLS_RSA_C */ - -/* Get a PK algorithm identifier - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - */ -static int pk_get_pk_alg( unsigned char **p, - const unsigned char *end, - mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params ) -{ - int ret; - mbedtls_asn1_buf alg_oid; - - memset( params, 0, sizeof(mbedtls_asn1_buf) ); - - if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_ALG + ret ); - - if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - /* - * No parameters with RSA (only for EC) - */ - if( *pk_alg == MBEDTLS_PK_RSA && - ( ( params->tag != MBEDTLS_ASN1_NULL && params->tag != 0 ) || - params->len != 0 ) ) - { - return( MBEDTLS_ERR_PK_INVALID_ALG ); - } - - return( 0 ); -} - -/* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - */ -int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, - mbedtls_pk_context *pk ) -{ - int ret; - size_t len; - mbedtls_asn1_buf alg_params; - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - const mbedtls_pk_info_t *pk_info; - - PK_VALIDATE_RET( p != NULL ); - PK_VALIDATE_RET( *p != NULL ); - PK_VALIDATE_RET( end != NULL ); - PK_VALIDATE_RET( pk != NULL ); - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = *p + len; - - if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_RSA_C) - if( pk_alg == MBEDTLS_PK_RSA ) - { - ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) ); - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_C) - if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY ) - { - ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp ); - if( ret == 0 ) - ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) ); - } else -#endif /* MBEDTLS_ECP_C */ - ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; - - if( ret == 0 && *p != end ) - ret = MBEDTLS_ERR_PK_INVALID_PUBKEY + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - - if( ret != 0 ) - mbedtls_pk_free( pk ); - - return( ret ); -} - -#if defined(MBEDTLS_RSA_C) -/* - * Wrapper around mbedtls_asn1_get_mpi() that rejects zero. - * - * The value zero is: - * - never a valid value for an RSA parameter - * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete(). - * - * Since values can't be omitted in PKCS#1, passing a zero value to - * rsa_complete() would be incorrect, so reject zero values early. - */ -static int asn1_get_nonzero_mpi( unsigned char **p, - const unsigned char *end, - mbedtls_mpi *X ) -{ - int ret; - - ret = mbedtls_asn1_get_mpi( p, end, X ); - if( ret != 0 ) - return( ret ); - - if( mbedtls_mpi_cmp_int( X, 0 ) == 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - - return( 0 ); -} - -/* - * Parse a PKCS#1 encoded private RSA key - */ -static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, - const unsigned char *key, - size_t keylen ) -{ - int ret, version; - size_t len; - unsigned char *p, *end; - - mbedtls_mpi T; - mbedtls_mpi_init( &T ); - - p = (unsigned char *) key; - end = p + keylen; - - /* - * This function parses the RSAPrivateKey (PKCS#1) - * - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * otherPrimeInfos OtherPrimeInfos OPTIONAL - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - if( version != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); - } - - /* Import N */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, &T, NULL, NULL, - NULL, NULL ) ) != 0 ) - goto cleanup; - - /* Import E */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL, - NULL, &T ) ) != 0 ) - goto cleanup; - - /* Import D */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL, - &T, NULL ) ) != 0 ) - goto cleanup; - - /* Import P */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, NULL, &T, NULL, - NULL, NULL ) ) != 0 ) - goto cleanup; - - /* Import Q */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_rsa_import( rsa, NULL, NULL, &T, - NULL, NULL ) ) != 0 ) - goto cleanup; - -#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT) - /* - * The RSA CRT parameters DP, DQ and QP are nominally redundant, in - * that they can be easily recomputed from D, P and Q. However by - * parsing them from the PKCS1 structure it is possible to avoid - * recalculating them which both reduces the overhead of loading - * RSA private keys into memory and also avoids side channels which - * can arise when computing those values, since all of D, P, and Q - * are secret. See https://eprint.iacr.org/2020/055 for a - * description of one such attack. - */ - - /* Import DP */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_mpi_copy( &rsa->DP, &T ) ) != 0 ) - goto cleanup; - - /* Import DQ */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_mpi_copy( &rsa->DQ, &T ) ) != 0 ) - goto cleanup; - - /* Import QP */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = mbedtls_mpi_copy( &rsa->QP, &T ) ) != 0 ) - goto cleanup; - -#else - /* Verify existance of the CRT params */ - if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || - ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ) - goto cleanup; -#endif - - /* rsa_complete() doesn't complete anything with the default - * implementation but is still called: - * - for the benefit of alternative implementation that may want to - * pre-compute stuff beyond what's provided (eg Montgomery factors) - * - as is also sanity-checks the key - * - * Furthermore, we also check the public part for consistency with - * mbedtls_pk_parse_pubkey(), as it includes size minima for example. - */ - if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 || - ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 ) - { - goto cleanup; - } - - if( p != end ) - { - ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ; - } - -cleanup: - - mbedtls_mpi_free( &T ); - - if( ret != 0 ) - { - /* Wrap error code if it's coming from a lower level */ - if( ( ret & 0xff80 ) == 0 ) - ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret; - else - ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - - mbedtls_rsa_free( rsa ); - } - - return( ret ); -} -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/* - * Parse a SEC1 encoded private EC key - */ -static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck, - const unsigned char *key, - size_t keylen ) -{ - int ret; - int version, pubkey_done; - size_t len; - mbedtls_asn1_buf params; - unsigned char *p = (unsigned char *) key; - unsigned char *end = p + keylen; - unsigned char *end2; - - /* - * RFC 5915, or SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( version != 1 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 ) - { - mbedtls_ecp_keypair_free( eck ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - p += len; - - pubkey_done = 0; - if( p != end ) - { - /* - * Is 'parameters' present? - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) - { - if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || - ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) - { - mbedtls_ecp_keypair_free( eck ); - return( ret ); - } - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - mbedtls_ecp_keypair_free( eck ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - } - - if( p != end ) - { - /* - * Is 'publickey' present? If not, or if we can't read it (eg because it - * is compressed), create it from the private key. - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) - { - end2 = p + len; - - if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( p + len != end2 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 ) - pubkey_done = 1; - else - { - /* - * The only acceptable failure mode of pk_get_ecpubkey() above - * is if the point format is not recognized. - */ - if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - } - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - mbedtls_ecp_keypair_free( eck ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - } - - if( ! pubkey_done && - ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G, - NULL, NULL ) ) != 0 ) - { - mbedtls_ecp_keypair_free( eck ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) - { - mbedtls_ecp_keypair_free( eck ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_ECP_C */ - -/* - * Parse an unencrypted PKCS#8 encoded private key - * - * Notes: - * - * - This function does not own the key buffer. It is the - * responsibility of the caller to take care of zeroizing - * and freeing it after use. - * - * - The function is responsible for freeing the provided - * PK context on failure. - * - */ -static int pk_parse_key_pkcs8_unencrypted_der( - mbedtls_pk_context *pk, - const unsigned char* key, - size_t keylen ) -{ - int ret, version; - size_t len; - mbedtls_asn1_buf params; - unsigned char *p = (unsigned char *) key; - unsigned char *end = p + keylen; - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - const mbedtls_pk_info_t *pk_info; - - /* - * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208) - * - * PrivateKeyInfo ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] IMPLICIT Attributes OPTIONAL } - * - * Version ::= INTEGER - * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier - * PrivateKey ::= OCTET STRING - * - * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey - */ - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( version != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret ); - - if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, ¶ms ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( len < 1 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_RSA_C) - if( pk_alg == MBEDTLS_PK_RSA ) - { - if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 ) - { - mbedtls_pk_free( pk ); - return( ret ); - } - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_C) - if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH ) - { - if( ( ret = pk_use_ecparams( ¶ms, &mbedtls_pk_ec( *pk )->grp ) ) != 0 || - ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len ) ) != 0 ) - { - mbedtls_pk_free( pk ); - return( ret ); - } - } else -#endif /* MBEDTLS_ECP_C */ - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - return( 0 ); -} - -/* - * Parse an encrypted PKCS#8 encoded private key - * - * To save space, the decryption happens in-place on the given key buffer. - * Also, while this function may modify the keybuffer, it doesn't own it, - * and instead it is the responsibility of the caller to zeroize and properly - * free it after use. - * - */ -#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) -static int pk_parse_key_pkcs8_encrypted_der( - mbedtls_pk_context *pk, - unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) -{ - int ret, decrypted = 0; - size_t len; - unsigned char *buf; - unsigned char *p, *end; - mbedtls_asn1_buf pbe_alg_oid, pbe_params; -#if defined(MBEDTLS_PKCS12_C) - mbedtls_cipher_type_t cipher_alg; - mbedtls_md_type_t md_alg; -#endif - - p = key; - end = p + keylen; - - if( pwdlen == 0 ) - return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); - - /* - * This function parses the EncryptedPrivateKeyInfo object (PKCS#8) - * - * EncryptedPrivateKeyInfo ::= SEQUENCE { - * encryptionAlgorithm EncryptionAlgorithmIdentifier, - * encryptedData EncryptedData - * } - * - * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - * - * EncryptedData ::= OCTET STRING - * - * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo - * - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - - buf = p; - - /* - * Decrypt EncryptedData with appropriate PBE - */ -#if defined(MBEDTLS_PKCS12_C) - if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 ) - { - if( ( ret = mbedtls_pkcs12_pbe( &pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT, - cipher_alg, md_alg, - pwd, pwdlen, p, len, buf ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - - return( ret ); - } - - decrypted = 1; - } - else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 ) - { - if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params, - MBEDTLS_PKCS12_PBE_DECRYPT, - pwd, pwdlen, - p, len, buf ) ) != 0 ) - { - return( ret ); - } - - // Best guess for password mismatch when using RC4. If first tag is - // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE - // - if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - - decrypted = 1; - } - else -#endif /* MBEDTLS_PKCS12_C */ -#if defined(MBEDTLS_PKCS5_C) - if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid ) == 0 ) - { - if( ( ret = mbedtls_pkcs5_pbes2( &pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen, - p, len, buf ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - - return( ret ); - } - - decrypted = 1; - } - else -#endif /* MBEDTLS_PKCS5_C */ - { - ((void) pwd); - } - - if( decrypted == 0 ) - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) ); -} -#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ - -/* - * Parse a private key - */ -int mbedtls_pk_parse_key( mbedtls_pk_context *pk, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) -{ - int ret; - const mbedtls_pk_info_t *pk_info; -#if defined(MBEDTLS_PEM_PARSE_C) - size_t len; - mbedtls_pem_context pem; -#endif - - PK_VALIDATE_RET( pk != NULL ); - if( keylen == 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - PK_VALIDATE_RET( key != NULL ); - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init( &pem ); - -#if defined(MBEDTLS_RSA_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN RSA PRIVATE KEY-----", - "-----END RSA PRIVATE KEY-----", - key, pwd, pwdlen, &len ); - - if( ret == 0 ) - { - pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ); - if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || - ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), - pem.buf, pem.buflen ) ) != 0 ) - { - mbedtls_pk_free( pk ); - } - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) - return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN EC PRIVATE KEY-----", - "-----END EC PRIVATE KEY-----", - key, pwd, pwdlen, &len ); - if( ret == 0 ) - { - pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); - - if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || - ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), - pem.buf, pem.buflen ) ) != 0 ) - { - mbedtls_pk_free( pk ); - } - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) - return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); - else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) - return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); -#endif /* MBEDTLS_ECP_C */ - - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN PRIVATE KEY-----", - "-----END PRIVATE KEY-----", - key, NULL, 0, &len ); - if( ret == 0 ) - { - if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, - pem.buf, pem.buflen ) ) != 0 ) - { - mbedtls_pk_free( pk ); - } - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); - -#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN ENCRYPTED PRIVATE KEY-----", - "-----END ENCRYPTED PRIVATE KEY-----", - key, NULL, 0, &len ); - if( ret == 0 ) - { - if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, - pem.buf, pem.buflen, - pwd, pwdlen ) ) != 0 ) - { - mbedtls_pk_free( pk ); - } - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); -#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ -#else - ((void) pwd); - ((void) pwdlen); -#endif /* MBEDTLS_PEM_PARSE_C */ - - /* - * At this point we only know it's not a PEM formatted key. Could be any - * of the known DER encoded private key formats - * - * We try the different DER format parsers to see if one passes without - * error - */ -#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) - { - unsigned char *key_copy; - - if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL ) - return( MBEDTLS_ERR_PK_ALLOC_FAILED ); - - memcpy( key_copy, key, keylen ); - - ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen, - pwd, pwdlen ); - - mbedtls_platform_zeroize( key_copy, keylen ); - mbedtls_free( key_copy ); - } - - if( ret == 0 ) - return( 0 ); - - mbedtls_pk_free( pk ); - mbedtls_pk_init( pk ); - - if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH ) - { - return( ret ); - } -#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ - - if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 ) - return( 0 ); - - mbedtls_pk_free( pk ); - mbedtls_pk_init( pk ); - -#if defined(MBEDTLS_RSA_C) - - pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ); - if( mbedtls_pk_setup( pk, pk_info ) == 0 && - pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) == 0 ) - { - return( 0 ); - } - - mbedtls_pk_free( pk ); - mbedtls_pk_init( pk ); -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) - pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); - if( mbedtls_pk_setup( pk, pk_info ) == 0 && - pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), - key, keylen ) == 0 ) - { - return( 0 ); - } - mbedtls_pk_free( pk ); -#endif /* MBEDTLS_ECP_C */ - - /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't, - * it is ok to leave the PK context initialized but not - * freed: It is the caller's responsibility to call pk_init() - * before calling this function, and to call pk_free() - * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C - * isn't, this leads to mbedtls_pk_free() being called - * twice, once here and once by the caller, but this is - * also ok and in line with the mbedtls_pk_free() calls - * on failed PEM parsing attempts. */ - - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); -} - -/* - * Parse a public key - */ -int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, - const unsigned char *key, size_t keylen ) -{ - int ret; - unsigned char *p; -#if defined(MBEDTLS_RSA_C) - const mbedtls_pk_info_t *pk_info; -#endif -#if defined(MBEDTLS_PEM_PARSE_C) - size_t len; - mbedtls_pem_context pem; -#endif - - PK_VALIDATE_RET( ctx != NULL ); - if( keylen == 0 ) - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); - PK_VALIDATE_RET( key != NULL || keylen == 0 ); - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init( &pem ); -#if defined(MBEDTLS_RSA_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN RSA PUBLIC KEY-----", - "-----END RSA PUBLIC KEY-----", - key, NULL, 0, &len ); - - if( ret == 0 ) - { - p = pem.buf; - if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) - return( ret ); - - if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 ) - mbedtls_pk_free( ctx ); - - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - mbedtls_pem_free( &pem ); - return( ret ); - } -#endif /* MBEDTLS_RSA_C */ - - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( key[keylen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN PUBLIC KEY-----", - "-----END PUBLIC KEY-----", - key, NULL, 0, &len ); - - if( ret == 0 ) - { - /* - * Was PEM encoded - */ - p = pem.buf; - - ret = mbedtls_pk_parse_subpubkey( &p, p + pem.buflen, ctx ); - mbedtls_pem_free( &pem ); - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - mbedtls_pem_free( &pem ); - return( ret ); - } - mbedtls_pem_free( &pem ); -#endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_RSA_C) - if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) - return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); - - if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) - return( ret ); - - p = (unsigned char *)key; - ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) ); - if( ret == 0 ) - { - return( ret ); - } - mbedtls_pk_free( ctx ); - if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) - { - return( ret ); - } -#endif /* MBEDTLS_RSA_C */ - p = (unsigned char *) key; - - ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_PK_PARSE_C */ diff --git a/mbedtls/pkwrite.c b/mbedtls/pkwrite.c deleted file mode 100644 index 0398c6c1d..000000000 --- a/mbedtls/pkwrite.c +++ /dev/null @@ -1,604 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Public Key layer for writing key files and structures - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PK_WRITE_C) - -#include "mbedtls/pk.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/bignum.h" -#include "mbedtls/ecp.h" -#include "mbedtls/platform_util.h" -#endif -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -/* Parameter validation macros based on platform_util.h */ -#define PK_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) -#define PK_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_RSA_C) -/* - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ -static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, - mbedtls_rsa_context *rsa ) -{ - int ret; - size_t len = 0; - mbedtls_mpi T; - - mbedtls_mpi_init( &T ); - - /* Export E */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export N */ - if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) - goto end_of_export; - len += ret; - -end_of_export: - - mbedtls_mpi_free( &T ); - if( ret < 0 ) - return( ret ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return( (int) len ); -} -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/* - * EC public key is an EC point - */ -static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec ) -{ - int ret; - size_t len = 0; - unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; - - if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q, - MBEDTLS_ECP_PF_UNCOMPRESSED, - &len, buf, sizeof( buf ) ) ) != 0 ) - { - return( ret ); - } - - if( *p < start || (size_t)( *p - start ) < len ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *p -= len; - memcpy( *p, buf, len ); - - return( (int) len ); -} - -/* - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * } - */ -static int pk_write_ec_param( unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec ) -{ - int ret; - size_t len = 0; - const char *oid; - size_t oid_len; - - if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 ) - return( ret ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); - - return( (int) len ); -} - -/* - * privateKey OCTET STRING -- always of length ceil(log2(n)/8) - */ -static int pk_write_ec_private( unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec ) -{ - int ret; - size_t byte_length = ( ec->grp.pbits + 7 ) / 8; - unsigned char tmp[MBEDTLS_ECP_MAX_BYTES]; - - ret = mbedtls_mpi_write_binary( &ec->d, tmp, byte_length ); - if( ret != 0 ) - goto exit; - ret = mbedtls_asn1_write_octet_string( p, start, tmp, byte_length ); - -exit: - mbedtls_platform_zeroize( tmp, byte_length ); - return( ret ); -} -#endif /* MBEDTLS_ECP_C */ - -int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, - const mbedtls_pk_context *key ) -{ - int ret; - size_t len = 0; - - PK_VALIDATE_RET( p != NULL ); - PK_VALIDATE_RET( *p != NULL ); - PK_VALIDATE_RET( start != NULL ); - PK_VALIDATE_RET( key != NULL ); - -#if defined(MBEDTLS_RSA_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) - MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) ); - else -#endif -#if defined(MBEDTLS_ECP_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) - MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) ); - else -#endif - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - return( (int) len ); -} - -int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) -{ - int ret; - unsigned char *c; - size_t len = 0, par_len = 0, oid_len; - const char *oid; - - PK_VALIDATE_RET( key != NULL ); - if( size == 0 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - PK_VALIDATE_RET( buf != NULL ); - - c = buf + size; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); - - if( c - buf < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - /* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - */ - *--c = 0; - len += 1; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); - - if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ), - &oid, &oid_len ) ) != 0 ) - { - return( ret ); - } - -#if defined(MBEDTLS_ECP_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) - { - MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) ); - } -#endif - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len, - par_len ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return( (int) len ); -} - -int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) -{ - int ret; - unsigned char *c; - size_t len = 0; - - PK_VALIDATE_RET( key != NULL ); - if( size == 0 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - PK_VALIDATE_RET( buf != NULL ); - - c = buf + size; - -#if defined(MBEDTLS_RSA_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) - { - mbedtls_mpi T; /* Temporary holding the exported parameters */ - mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); - - /* - * Export the parameters one after another to avoid simultaneous copies. - */ - - mbedtls_mpi_init( &T ); - - /* Export QP */ - if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export DQ */ - if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export DP */ - if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export Q */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, - &T, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export P */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T, - NULL, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export D */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, - NULL, &T, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export E */ - if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, - NULL, NULL, &T ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - /* Export N */ - if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, - NULL, NULL, NULL ) ) != 0 || - ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) - goto end_of_export; - len += ret; - - end_of_export: - - mbedtls_mpi_free( &T ); - if( ret < 0 ) - return( ret ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, - buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - } - else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) - { - mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key ); - size_t pub_len = 0, par_len = 0; - - /* - * RFC 5915, or SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ - - /* publicKey */ - MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); - - if( c - buf < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - *--c = 0; - pub_len += 1; - - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); - - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ); - len += pub_len; - - /* parameters */ - MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); - - MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) ); - MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); - len += par_len; - - /* privateKey */ - MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_private( &c, buf, ec ) ); - - /* version */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - } - else -#endif /* MBEDTLS_ECP_C */ - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - return( (int) len ); -} - -#if defined(MBEDTLS_PEM_WRITE_C) - -#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" -#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" - -#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" -#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" -#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" -#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" - -/* - * Max sizes of key per types. Shown as tag + len (+ content). - */ - -#if defined(MBEDTLS_RSA_C) -/* - * RSA public keys: - * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 - * algorithm AlgorithmIdentifier, 1 + 1 (sequence) - * + 1 + 1 + 9 (rsa oid) - * + 1 + 1 (params null) - * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) - * RSAPublicKey ::= SEQUENCE { 1 + 3 - * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 - * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 - * } - */ -#define RSA_PUB_DER_MAX_BYTES ( 38 + 2 * MBEDTLS_MPI_MAX_SIZE ) - -/* - * RSA private keys: - * RSAPrivateKey ::= SEQUENCE { 1 + 3 - * version Version, 1 + 1 + 1 - * modulus INTEGER, 1 + 3 + MPI_MAX + 1 - * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1 - * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1 - * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported) - * } - */ -#define MPI_MAX_SIZE_2 ( MBEDTLS_MPI_MAX_SIZE / 2 + \ - MBEDTLS_MPI_MAX_SIZE % 2 ) -#define RSA_PRV_DER_MAX_BYTES ( 47 + 3 * MBEDTLS_MPI_MAX_SIZE \ - + 5 * MPI_MAX_SIZE_2 ) - -#else /* MBEDTLS_RSA_C */ - -#define RSA_PUB_DER_MAX_BYTES 0 -#define RSA_PRV_DER_MAX_BYTES 0 - -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/* - * EC public keys: - * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2 - * algorithm AlgorithmIdentifier, 1 + 1 (sequence) - * + 1 + 1 + 7 (ec oid) - * + 1 + 1 + 9 (namedCurve oid) - * subjectPublicKey BIT STRING 1 + 2 + 1 [1] - * + 1 (point format) [1] - * + 2 * ECP_MAX (coords) [1] - * } - */ -#define ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) - -/* - * EC private keys: - * ECPrivateKey ::= SEQUENCE { 1 + 2 - * version INTEGER , 1 + 1 + 1 - * privateKey OCTET STRING, 1 + 1 + ECP_MAX - * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9) - * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above - * } - */ -#define ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) - -#else /* MBEDTLS_ECP_C */ - -#define ECP_PUB_DER_MAX_BYTES 0 -#define ECP_PRV_DER_MAX_BYTES 0 - -#endif /* MBEDTLS_ECP_C */ - -#define PUB_DER_MAX_BYTES ( RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ - RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES ) -#define PRV_DER_MAX_BYTES ( RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \ - RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES ) - -int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) -{ - int ret; - unsigned char output_buf[PUB_DER_MAX_BYTES]; - size_t olen = 0; - - PK_VALIDATE_RET( key != NULL ); - PK_VALIDATE_RET( buf != NULL || size == 0 ); - - if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf, - sizeof(output_buf) ) ) < 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, - output_buf + sizeof(output_buf) - ret, - ret, buf, size, &olen ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) -{ - int ret; - unsigned char output_buf[PRV_DER_MAX_BYTES]; - const char *begin, *end; - size_t olen = 0; - - PK_VALIDATE_RET( key != NULL ); - PK_VALIDATE_RET( buf != NULL || size == 0 ); - - if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) - return( ret ); - -#if defined(MBEDTLS_RSA_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) - { - begin = PEM_BEGIN_PRIVATE_KEY_RSA; - end = PEM_END_PRIVATE_KEY_RSA; - } - else -#endif -#if defined(MBEDTLS_ECP_C) - if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) - { - begin = PEM_BEGIN_PRIVATE_KEY_EC; - end = PEM_END_PRIVATE_KEY_EC; - } - else -#endif - return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); - - if( ( ret = mbedtls_pem_write_buffer( begin, end, - output_buf + sizeof(output_buf) - ret, - ret, buf, size, &olen ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_PEM_WRITE_C */ - -#endif /* MBEDTLS_PK_WRITE_C */ diff --git a/mbedtls/platform.c b/mbedtls/platform.c deleted file mode 100644 index 5eb57c7a8..000000000 --- a/mbedtls/platform.c +++ /dev/null @@ -1,386 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Platform abstraction layer - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PLATFORM_C) - -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" - -/* The compile time configuration of memory allocation via the macros - * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime - * configuration via mbedtls_platform_set_calloc_free(). So, omit everything - * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */ -#if defined(MBEDTLS_PLATFORM_MEMORY) && \ - !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \ - defined(MBEDTLS_PLATFORM_FREE_MACRO) ) - -#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -static void *platform_calloc_uninit( size_t n, size_t size ) -{ - ((void) n); - ((void) size); - return( NULL ); -} - -#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit -#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ - -#if !defined(MBEDTLS_PLATFORM_STD_FREE) -static void platform_free_uninit( void *ptr ) -{ - ((void) ptr); -} - -#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit -#endif /* !MBEDTLS_PLATFORM_STD_FREE */ - -static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; -static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE; - -void * mbedtls_calloc( size_t nmemb, size_t size ) -{ - return (*mbedtls_calloc_func)( nmemb, size ); -} - -void mbedtls_free( void * ptr ) -{ - (*mbedtls_free_func)( ptr ); -} - -int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), - void (*free_func)( void * ) ) -{ - mbedtls_calloc_func = calloc_func; - mbedtls_free_func = free_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_MEMORY && - !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && - defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */ - -#if defined(_WIN32) -#include -int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) -{ - int ret; - va_list argp; - - /* Avoid calling the invalid parameter handler by checking ourselves */ - if( s == NULL || n == 0 || fmt == NULL ) - return( -1 ); - - va_start( argp, fmt ); -#if defined(_TRUNCATE) && !defined(__MINGW32__) - ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp ); -#else - ret = _vsnprintf( s, n, fmt, argp ); - if( ret < 0 || (size_t) ret == n ) - { - s[n-1] = '\0'; - ret = -1; - } -#endif - va_end( argp ); - - return( ret ); -} -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_snprintf_uninit( char * s, size_t n, - const char * format, ... ) -{ - ((void) s); - ((void) n); - ((void) format); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ - -int (*mbedtls_snprintf)( char * s, size_t n, - const char * format, - ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF; - -int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, - const char * format, - ... ) ) -{ - mbedtls_snprintf = snprintf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_printf_uninit( const char *format, ... ) -{ - ((void) format); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ - -int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF; - -int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ) -{ - mbedtls_printf = printf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) -{ - ((void) stream); - ((void) format); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ - -int (*mbedtls_fprintf)( FILE *, const char *, ... ) = - MBEDTLS_PLATFORM_STD_FPRINTF; - -int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) -{ - mbedtls_fprintf = fprintf_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_EXIT) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static void platform_exit_uninit( int status ) -{ - ((void) status); -} - -#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit -#endif /* !MBEDTLS_PLATFORM_STD_EXIT */ - -void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT; - -int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) -{ - mbedtls_exit = exit_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ - -#if defined(MBEDTLS_HAVE_TIME) - -#if defined(MBEDTLS_PLATFORM_TIME_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_TIME) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer ) -{ - ((void) timer); - return( 0 ); -} - -#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit -#endif /* !MBEDTLS_PLATFORM_STD_TIME */ - -mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME; - -int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) ) -{ - mbedtls_time = time_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ - -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) -/* Default implementations for the platform independent seed functions use - * standard libc file functions to read from and write to a pre-defined filename - */ -int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) -{ - FILE *file; - size_t n; - - if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) - return( -1 ); - - if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) - { - fclose( file ); - mbedtls_platform_zeroize( buf, buf_len ); - return( -1 ); - } - - fclose( file ); - return( (int)n ); -} - -int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) -{ - FILE *file; - size_t n; - - if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL ) - return -1; - - if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len ) - { - fclose( file ); - return -1; - } - - fclose( file ); - return( (int)n ); -} -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len ) -{ - ((void) buf); - ((void) buf_len); - return( -1 ); -} - -#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit -#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ - -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len ) -{ - ((void) buf); - ((void) buf_len); - return( -1 ); -} - -#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit -#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ - -int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) = - MBEDTLS_PLATFORM_STD_NV_SEED_READ; -int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) = - MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; - -int mbedtls_platform_set_nv_seed( - int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), - int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) ) -{ - mbedtls_nv_seed_read = nv_seed_read_func; - mbedtls_nv_seed_write = nv_seed_write_func; - return( 0 ); -} -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) -/* - * Placeholder platform setup that does nothing by default - */ -int mbedtls_platform_setup( mbedtls_platform_context *ctx ) -{ - (void)ctx; - - return( 0 ); -} - -/* - * Placeholder platform teardown that does nothing by default - */ -void mbedtls_platform_teardown( mbedtls_platform_context *ctx ) -{ - (void)ctx; -} -#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ - -#endif /* MBEDTLS_PLATFORM_C */ diff --git a/mbedtls/platform.h b/mbedtls/platform.h deleted file mode 100644 index 3dd1007c9..000000000 --- a/mbedtls/platform.h +++ /dev/null @@ -1,393 +0,0 @@ -#pragma GCC system_header -/** - * \file platform.h - * - * \brief This file contains the definitions and functions of the - * Mbed TLS platform abstraction layer. - * - * The platform abstraction layer removes the need for the library - * to directly link to standard C library functions or operating - * system services, making the library easier to port and embed. - * Application developers and users of the library can provide their own - * implementations of these functions, or implementations specific to - * their platform, which can be statically linked to the library or - * dynamically configured at runtime. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_PLATFORM_H -#define MBEDTLS_PLATFORM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "platform_time.h" -#endif - -#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */ -#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) -#include -#include -#include -#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) -#if defined(_WIN32) -#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */ -#else -#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */ -#endif -#endif -#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) -#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) -#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FREE) -#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT) -#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_TIME) -#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) -#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) -#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */ -#endif -#if defined(MBEDTLS_FS_IO) -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) -#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read -#endif -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) -#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write -#endif -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) -#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" -#endif -#endif /* MBEDTLS_FS_IO */ -#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ -#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) -#include MBEDTLS_PLATFORM_STD_MEM_HDR -#endif -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ - - -/* \} name SECTION: Module settings */ - -/* - * The function pointers for calloc and free. - */ -#if defined(MBEDTLS_PLATFORM_MEMORY) -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ - defined(MBEDTLS_PLATFORM_CALLOC_MACRO) -#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO -#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO -#else -/* For size_t */ -#include -extern void *mbedtls_calloc( size_t n, size_t size ); -extern void mbedtls_free( void *ptr ); - -/** - * \brief This function dynamically sets the memory-management - * functions used by the library, during runtime. - * - * \param calloc_func The \c calloc function implementation. - * \param free_func The \c free function implementation. - * - * \return \c 0. - */ -int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), - void (*free_func)( void * ) ); -#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ -#else /* !MBEDTLS_PLATFORM_MEMORY */ -#define mbedtls_free free -#define mbedtls_calloc calloc -#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ - -/* - * The function pointers for fprintf - */ -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -/* We need FILE * */ -#include -extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... ); - -/** - * \brief This function dynamically configures the fprintf - * function that is called when the - * mbedtls_fprintf() function is invoked by the library. - * - * \param fprintf_func The \c fprintf function implementation. - * - * \return \c 0. - */ -int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, - ... ) ); -#else -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) -#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO -#else -#define mbedtls_fprintf fprintf -#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ - -/* - * The function pointers for printf - */ -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) -extern int (*mbedtls_printf)( const char *format, ... ); - -/** - * \brief This function dynamically configures the snprintf - * function that is called when the mbedtls_snprintf() - * function is invoked by the library. - * - * \param printf_func The \c printf function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); -#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) -#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO -#else -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ - -/* - * The function pointers for snprintf - * - * The snprintf implementation should conform to C99: - * - it *must* always correctly zero-terminate the buffer - * (except when n == 0, then it must leave the buffer untouched) - * - however it is acceptable to return -1 instead of the required length when - * the destination buffer is too short. - */ -#if defined(_WIN32) -/* For Windows (inc. MSYS2), we provide our own fixed implementation */ -int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); - -/** - * \brief This function allows configuring a custom - * \c snprintf function pointer. - * - * \param snprintf_func The \c snprintf function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, - const char * format, ... ) ); -#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) -#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO -#else -#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF -#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ - -/* - * The function pointers for exit - */ -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) -extern void (*mbedtls_exit)( int status ); - -/** - * \brief This function dynamically configures the exit - * function that is called when the mbedtls_exit() - * function is invoked by the library. - * - * \param exit_func The \c exit function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); -#else -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) -#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO -#else -#define mbedtls_exit exit -#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ - -/* - * The default exit values - */ -#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) -#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS -#else -#define MBEDTLS_EXIT_SUCCESS 0 -#endif -#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) -#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE -#else -#define MBEDTLS_EXIT_FAILURE 1 -#endif - -/* - * The function pointers for reading from and writing a seed file to - * Non-Volatile storage (NV) in a platform-independent way - * - * Only enabled when the NV seed entropy source is enabled - */ -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) -/* Internal standard platform definitions */ -int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ); -int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ); -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ); -extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ); - -/** - * \brief This function allows configuring custom seed file writing and - * reading functions. - * - * \param nv_seed_read_func The seed reading function implementation. - * \param nv_seed_write_func The seed writing function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_nv_seed( - int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), - int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) - ); -#else -#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ - defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) -#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO -#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO -#else -#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read -#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write -#endif -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) - -/** - * \brief The platform context structure. - * - * \note This structure may be used to assist platform-specific - * setup or teardown operations. - */ -typedef struct mbedtls_platform_context -{ - char dummy; /**< A placeholder member, as empty structs are not portable. */ -} -mbedtls_platform_context; - -#else -#include "platform_alt.h" -#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ - -/** - * \brief This function performs any platform-specific initialization - * operations. - * - * \note This function should be called before any other library functions. - * - * Its implementation is platform-specific, and unless - * platform-specific code is provided, it does nothing. - * - * \note The usage and necessity of this function is dependent on the platform. - * - * \param ctx The platform context. - * - * \return \c 0 on success. - */ -int mbedtls_platform_setup( mbedtls_platform_context *ctx ); -/** - * \brief This function performs any platform teardown operations. - * - * \note This function should be called after every other Mbed TLS module - * has been correctly freed using the appropriate free function. - * - * Its implementation is platform-specific, and unless - * platform-specific code is provided, it does nothing. - * - * \note The usage and necessity of this function is dependent on the platform. - * - * \param ctx The platform context. - * - */ -void mbedtls_platform_teardown( mbedtls_platform_context *ctx ); - -#ifdef __cplusplus -} -#endif - -#endif /* platform.h */ diff --git a/mbedtls/platform_time.h b/mbedtls/platform_time.h deleted file mode 100644 index 173d8ebc2..000000000 --- a/mbedtls/platform_time.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma GCC system_header -/** - * \file platform_time.h - * - * \brief mbed TLS Platform time abstraction - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_PLATFORM_TIME_H -#define MBEDTLS_PLATFORM_TIME_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -/* - * The time_t datatype - */ -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) -typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; -#else -/* For time_t */ -#include -typedef time_t mbedtls_time_t; -#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ - -/* - * The function pointers for time - */ -#if defined(MBEDTLS_PLATFORM_TIME_ALT) -extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); - -/** - * \brief Set your own time function pointer - * - * \param time_func the time function implementation - * - * \return 0 - */ -int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); -#else -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) -#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO -#else -#define mbedtls_time time -#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ - -#ifdef __cplusplus -} -#endif - -#endif /* platform_time.h */ diff --git a/mbedtls/platform_util.c b/mbedtls/platform_util.c deleted file mode 100644 index 2d04b2696..000000000 --- a/mbedtls/platform_util.c +++ /dev/null @@ -1,177 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Common and shared functions used by multiple modules in the Mbed TLS - * library. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * Ensure gmtime_r is available even with -std=c99; must be defined before - * config.h, which pulls in glibc's features.h. Harmless on other platforms. - */ -#if !defined(_POSIX_C_SOURCE) -#define _POSIX_C_SOURCE 200112L -#endif - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "mbedtls/platform_util.h" -#include "mbedtls/platform.h" -#include "mbedtls/threading.h" - -#include -#include - -#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT) -/* - * This implementation should never be optimized out by the compiler - * - * This implementation for mbedtls_platform_zeroize() was inspired from Colin - * Percival's blog article at: - * - * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html - * - * It uses a volatile function pointer to the standard memset(). Because the - * pointer is volatile the compiler expects it to change at - * any time and will not optimize out the call that could potentially perform - * other operations on the input buffer instead of just setting it to 0. - * Nevertheless, as pointed out by davidtgoldblatt on Hacker News - * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for - * details), optimizations of the following form are still possible: - * - * if( memset_func != memset ) - * memset_func( buf, 0, len ); - * - * Note that it is extremely difficult to guarantee that - * mbedtls_platform_zeroize() will not be optimized out by aggressive compilers - * in a portable way. For this reason, Mbed TLS also provides the configuration - * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure - * mbedtls_platform_zeroize() to use a suitable implementation for their - * platform and needs. - */ -static void * (* const volatile memset_func)( void *, int, size_t ) = memset; - -void mbedtls_platform_zeroize( void *buf, size_t len ) -{ - MBEDTLS_INTERNAL_VALIDATE( len == 0 || buf != NULL ); - - if( len > 0 ) - memset_func( buf, 0, len ); -} -#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -#include -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__))) -#include -#endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__)) */ - -#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) -/* - * This is a convenience shorthand macro to avoid checking the long - * preprocessor conditions above. Ideally, we could expose this macro in - * platform_util.h and simply use it in platform_util.c, threading.c and - * threading.h. However, this macro is not part of the Mbed TLS public API, so - * we keep it private by only defining it in this file - */ -#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) -#define PLATFORM_UTIL_USE_GMTIME -#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ - -#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */ - -struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, - struct tm *tm_buf ) -{ -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL ); -#elif !defined(PLATFORM_UTIL_USE_GMTIME) - return( gmtime_r( tt, tm_buf ) ); -#else - struct tm *lt; - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) - return( NULL ); -#endif /* MBEDTLS_THREADING_C */ - - lt = gmtime( tt ); - - if( lt != NULL ) - { - memcpy( tm_buf, lt, sizeof( struct tm ) ); - } - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) - return( NULL ); -#endif /* MBEDTLS_THREADING_C */ - - return( ( lt == NULL ) ? NULL : tm_buf ); -#endif /* _WIN32 && !EFIX64 && !EFI32 */ -} -#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */ diff --git a/mbedtls/platform_util.h b/mbedtls/platform_util.h deleted file mode 100644 index 84cc01d95..000000000 --- a/mbedtls/platform_util.h +++ /dev/null @@ -1,222 +0,0 @@ -#pragma GCC system_header -/** - * \file platform_util.h - * - * \brief Common and shared functions used by multiple modules in the Mbed TLS - * library. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_PLATFORM_UTIL_H -#define MBEDTLS_PLATFORM_UTIL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#if defined(MBEDTLS_HAVE_TIME_DATE) -#include "platform_time.h" -#include -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_CHECK_PARAMS) - -#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) -/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert - * (which is what our config.h suggests). */ -#include -#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ - -#if defined(MBEDTLS_PARAM_FAILED) -/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h. - * - * This flag can be used to check whether it is safe to assume that - * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed(). - */ -#define MBEDTLS_PARAM_FAILED_ALT - -#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT) -#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) -#define MBEDTLS_PARAM_FAILED_ALT - -#else /* MBEDTLS_PARAM_FAILED */ -#define MBEDTLS_PARAM_FAILED( cond ) \ - mbedtls_param_failed( #cond, __FILE__, __LINE__ ) - -/** - * \brief User supplied callback function for parameter validation failure. - * See #MBEDTLS_CHECK_PARAMS for context. - * - * This function will be called unless an alternative treatement - * is defined through the #MBEDTLS_PARAM_FAILED macro. - * - * This function can return, and the operation will be aborted, or - * alternatively, through use of setjmp()/longjmp() can resume - * execution in the application code. - * - * \param failure_condition The assertion that didn't hold. - * \param file The file where the assertion failed. - * \param line The line in the file where the assertion failed. - */ -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ); -#endif /* MBEDTLS_PARAM_FAILED */ - -/* Internal macro meant to be called only from within the library. */ -#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \ - do { \ - if( !(cond) ) \ - { \ - MBEDTLS_PARAM_FAILED( cond ); \ - return( ret ); \ - } \ - } while( 0 ) - -/* Internal macro meant to be called only from within the library. */ -#define MBEDTLS_INTERNAL_VALIDATE( cond ) \ - do { \ - if( !(cond) ) \ - { \ - MBEDTLS_PARAM_FAILED( cond ); \ - return; \ - } \ - } while( 0 ) - -#else /* MBEDTLS_CHECK_PARAMS */ - -/* Internal macros meant to be called only from within the library. */ -#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 ) -#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 ) - -#endif /* MBEDTLS_CHECK_PARAMS */ - -/* Internal helper macros for deprecating API constants. */ -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here - * to avoid conflict with other headers which define and use - * it, too. We might want to move all these definitions here at - * some point for uniformity. */ -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t; -#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \ - ( (mbedtls_deprecated_string_constant_t) ( VAL ) ) -MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t; -#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \ - ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) ) -#undef MBEDTLS_DEPRECATED -#else /* MBEDTLS_DEPRECATED_WARNING */ -#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL -#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Securely zeroize a buffer - * - * The function is meant to wipe the data contained in a buffer so - * that it can no longer be recovered even if the program memory - * is later compromised. Call this function on sensitive data - * stored on the stack before returning from a function, and on - * sensitive data stored on the heap before freeing the heap - * object. - * - * It is extremely difficult to guarantee that calls to - * mbedtls_platform_zeroize() are not removed by aggressive - * compiler optimizations in a portable way. For this reason, Mbed - * TLS provides the configuration option - * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure - * mbedtls_platform_zeroize() to use a suitable implementation for - * their platform and needs - * - * \param buf Buffer to be zeroized - * \param len Length of the buffer in bytes - * - */ -void mbedtls_platform_zeroize( void *buf, size_t len ); - -#if defined(MBEDTLS_HAVE_TIME_DATE) -/** - * \brief Platform-specific implementation of gmtime_r() - * - * The function is a thread-safe abstraction that behaves - * similarly to the gmtime_r() function from Unix/POSIX. - * - * Mbed TLS will try to identify the underlying platform and - * make use of an appropriate underlying implementation (e.g. - * gmtime_r() for POSIX and gmtime_s() for Windows). If this is - * not possible, then gmtime() will be used. In this case, calls - * from the library to gmtime() will be guarded by the mutex - * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is - * enabled. It is recommended that calls from outside the library - * are also guarded by this mutex. - * - * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will - * unconditionally use the alternative implementation for - * mbedtls_platform_gmtime_r() supplied by the user at compile time. - * - * \param tt Pointer to an object containing time (in seconds) since the - * epoch to be converted - * \param tm_buf Pointer to an object where the results will be stored - * - * \return Pointer to an object of type struct tm on success, otherwise - * NULL - */ -struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, - struct tm *tm_buf ); -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_PLATFORM_UTIL_H */ diff --git a/mbedtls/poly1305.c b/mbedtls/poly1305.c deleted file mode 100644 index 36931317a..000000000 --- a/mbedtls/poly1305.c +++ /dev/null @@ -1,597 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file poly1305.c - * - * \brief Poly1305 authentication algorithm. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_POLY1305_C) - -#include "mbedtls/poly1305.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_POLY1305_ALT) - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* Parameter validation macros */ -#define POLY1305_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ) -#define POLY1305_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#define POLY1305_BLOCK_SIZE_BYTES ( 16U ) - -#define BYTES_TO_U32_LE( data, offset ) \ - ( (uint32_t) (data)[offset] \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \ - | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \ - ) - -/* - * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier. - * However we provided an alternative for platforms without such a multiplier. - */ -#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION) -static uint64_t mul64( uint32_t a, uint32_t b ) -{ - /* a = al + 2**16 ah, b = bl + 2**16 bh */ - const uint16_t al = (uint16_t) a; - const uint16_t bl = (uint16_t) b; - const uint16_t ah = a >> 16; - const uint16_t bh = b >> 16; - - /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */ - const uint32_t lo = (uint32_t) al * bl; - const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh; - const uint32_t hi = (uint32_t) ah * bh; - - return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) ); -} -#else -static inline uint64_t mul64( uint32_t a, uint32_t b ) -{ - return( (uint64_t) a * b ); -} -#endif - - -/** - * \brief Process blocks with Poly1305. - * - * \param ctx The Poly1305 context. - * \param nblocks Number of blocks to process. Note that this - * function only processes full blocks. - * \param input Buffer containing the input block(s). - * \param needs_padding Set to 0 if the padding bit has already been - * applied to the input data before calling this - * function. Otherwise, set this parameter to 1. - */ -static void poly1305_process( mbedtls_poly1305_context *ctx, - size_t nblocks, - const unsigned char *input, - uint32_t needs_padding ) -{ - uint64_t d0, d1, d2, d3; - uint32_t acc0, acc1, acc2, acc3, acc4; - uint32_t r0, r1, r2, r3; - uint32_t rs1, rs2, rs3; - size_t offset = 0U; - size_t i; - - r0 = ctx->r[0]; - r1 = ctx->r[1]; - r2 = ctx->r[2]; - r3 = ctx->r[3]; - - rs1 = r1 + ( r1 >> 2U ); - rs2 = r2 + ( r2 >> 2U ); - rs3 = r3 + ( r3 >> 2U ); - - acc0 = ctx->acc[0]; - acc1 = ctx->acc[1]; - acc2 = ctx->acc[2]; - acc3 = ctx->acc[3]; - acc4 = ctx->acc[4]; - - /* Process full blocks */ - for( i = 0U; i < nblocks; i++ ) - { - /* The input block is treated as a 128-bit little-endian integer */ - d0 = BYTES_TO_U32_LE( input, offset + 0 ); - d1 = BYTES_TO_U32_LE( input, offset + 4 ); - d2 = BYTES_TO_U32_LE( input, offset + 8 ); - d3 = BYTES_TO_U32_LE( input, offset + 12 ); - - /* Compute: acc += (padded) block as a 130-bit integer */ - d0 += (uint64_t) acc0; - d1 += (uint64_t) acc1 + ( d0 >> 32U ); - d2 += (uint64_t) acc2 + ( d1 >> 32U ); - d3 += (uint64_t) acc3 + ( d2 >> 32U ); - acc0 = (uint32_t) d0; - acc1 = (uint32_t) d1; - acc2 = (uint32_t) d2; - acc3 = (uint32_t) d3; - acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding; - - /* Compute: acc *= r */ - d0 = mul64( acc0, r0 ) + - mul64( acc1, rs3 ) + - mul64( acc2, rs2 ) + - mul64( acc3, rs1 ); - d1 = mul64( acc0, r1 ) + - mul64( acc1, r0 ) + - mul64( acc2, rs3 ) + - mul64( acc3, rs2 ) + - mul64( acc4, rs1 ); - d2 = mul64( acc0, r2 ) + - mul64( acc1, r1 ) + - mul64( acc2, r0 ) + - mul64( acc3, rs3 ) + - mul64( acc4, rs2 ); - d3 = mul64( acc0, r3 ) + - mul64( acc1, r2 ) + - mul64( acc2, r1 ) + - mul64( acc3, r0 ) + - mul64( acc4, rs3 ); - acc4 *= r0; - - /* Compute: acc %= (2^130 - 5) (partial remainder) */ - d1 += ( d0 >> 32 ); - d2 += ( d1 >> 32 ); - d3 += ( d2 >> 32 ); - acc0 = (uint32_t) d0; - acc1 = (uint32_t) d1; - acc2 = (uint32_t) d2; - acc3 = (uint32_t) d3; - acc4 = (uint32_t) ( d3 >> 32 ) + acc4; - - d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU ); - acc4 &= 3U; - acc0 = (uint32_t) d0; - d0 = (uint64_t) acc1 + ( d0 >> 32U ); - acc1 = (uint32_t) d0; - d0 = (uint64_t) acc2 + ( d0 >> 32U ); - acc2 = (uint32_t) d0; - d0 = (uint64_t) acc3 + ( d0 >> 32U ); - acc3 = (uint32_t) d0; - d0 = (uint64_t) acc4 + ( d0 >> 32U ); - acc4 = (uint32_t) d0; - - offset += POLY1305_BLOCK_SIZE_BYTES; - } - - ctx->acc[0] = acc0; - ctx->acc[1] = acc1; - ctx->acc[2] = acc2; - ctx->acc[3] = acc3; - ctx->acc[4] = acc4; -} - -/** - * \brief Compute the Poly1305 MAC - * - * \param ctx The Poly1305 context. - * \param mac The buffer to where the MAC is written. Must be - * big enough to contain the 16-byte MAC. - */ -static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx, - unsigned char mac[16] ) -{ - uint64_t d; - uint32_t g0, g1, g2, g3, g4; - uint32_t acc0, acc1, acc2, acc3, acc4; - uint32_t mask; - uint32_t mask_inv; - - acc0 = ctx->acc[0]; - acc1 = ctx->acc[1]; - acc2 = ctx->acc[2]; - acc3 = ctx->acc[3]; - acc4 = ctx->acc[4]; - - /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5. - * We do this by calculating acc - (2^130 - 5), then checking if - * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5) - */ - - /* Calculate acc + -(2^130 - 5) */ - d = ( (uint64_t) acc0 + 5U ); - g0 = (uint32_t) d; - d = ( (uint64_t) acc1 + ( d >> 32 ) ); - g1 = (uint32_t) d; - d = ( (uint64_t) acc2 + ( d >> 32 ) ); - g2 = (uint32_t) d; - d = ( (uint64_t) acc3 + ( d >> 32 ) ); - g3 = (uint32_t) d; - g4 = acc4 + (uint32_t) ( d >> 32U ); - - /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */ - mask = (uint32_t) 0U - ( g4 >> 2U ); - mask_inv = ~mask; - - /* If 131st bit is set then acc=g, otherwise, acc is unmodified */ - acc0 = ( acc0 & mask_inv ) | ( g0 & mask ); - acc1 = ( acc1 & mask_inv ) | ( g1 & mask ); - acc2 = ( acc2 & mask_inv ) | ( g2 & mask ); - acc3 = ( acc3 & mask_inv ) | ( g3 & mask ); - - /* Add 's' */ - d = (uint64_t) acc0 + ctx->s[0]; - acc0 = (uint32_t) d; - d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U ); - acc1 = (uint32_t) d; - d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U ); - acc2 = (uint32_t) d; - acc3 += ctx->s[3] + (uint32_t) ( d >> 32U ); - - /* Compute MAC (128 least significant bits of the accumulator) */ - mac[ 0] = (unsigned char)( acc0 ); - mac[ 1] = (unsigned char)( acc0 >> 8 ); - mac[ 2] = (unsigned char)( acc0 >> 16 ); - mac[ 3] = (unsigned char)( acc0 >> 24 ); - mac[ 4] = (unsigned char)( acc1 ); - mac[ 5] = (unsigned char)( acc1 >> 8 ); - mac[ 6] = (unsigned char)( acc1 >> 16 ); - mac[ 7] = (unsigned char)( acc1 >> 24 ); - mac[ 8] = (unsigned char)( acc2 ); - mac[ 9] = (unsigned char)( acc2 >> 8 ); - mac[10] = (unsigned char)( acc2 >> 16 ); - mac[11] = (unsigned char)( acc2 >> 24 ); - mac[12] = (unsigned char)( acc3 ); - mac[13] = (unsigned char)( acc3 >> 8 ); - mac[14] = (unsigned char)( acc3 >> 16 ); - mac[15] = (unsigned char)( acc3 >> 24 ); -} - -void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ) -{ - POLY1305_VALIDATE( ctx != NULL ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); -} - -void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); -} - -int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, - const unsigned char key[32] ) -{ - POLY1305_VALIDATE_RET( ctx != NULL ); - POLY1305_VALIDATE_RET( key != NULL ); - - /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */ - ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU; - ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU; - ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU; - ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU; - - ctx->s[0] = BYTES_TO_U32_LE( key, 16 ); - ctx->s[1] = BYTES_TO_U32_LE( key, 20 ); - ctx->s[2] = BYTES_TO_U32_LE( key, 24 ); - ctx->s[3] = BYTES_TO_U32_LE( key, 28 ); - - /* Initial accumulator state */ - ctx->acc[0] = 0U; - ctx->acc[1] = 0U; - ctx->acc[2] = 0U; - ctx->acc[3] = 0U; - ctx->acc[4] = 0U; - - /* Queue initially empty */ - mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) ); - ctx->queue_len = 0U; - - return( 0 ); -} - -int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - size_t offset = 0U; - size_t remaining = ilen; - size_t queue_free_len; - size_t nblocks; - POLY1305_VALIDATE_RET( ctx != NULL ); - POLY1305_VALIDATE_RET( ilen == 0 || input != NULL ); - - if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) ) - { - queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); - - if( ilen < queue_free_len ) - { - /* Not enough data to complete the block. - * Store this data with the other leftovers. - */ - memcpy( &ctx->queue[ctx->queue_len], - input, - ilen ); - - ctx->queue_len += ilen; - - remaining = 0U; - } - else - { - /* Enough data to produce a complete block */ - memcpy( &ctx->queue[ctx->queue_len], - input, - queue_free_len ); - - ctx->queue_len = 0U; - - poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */ - - offset += queue_free_len; - remaining -= queue_free_len; - } - } - - if( remaining >= POLY1305_BLOCK_SIZE_BYTES ) - { - nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES; - - poly1305_process( ctx, nblocks, &input[offset], 1U ); - - offset += nblocks * POLY1305_BLOCK_SIZE_BYTES; - remaining %= POLY1305_BLOCK_SIZE_BYTES; - } - - if( remaining > 0U ) - { - /* Store partial block */ - ctx->queue_len = remaining; - memcpy( ctx->queue, &input[offset], remaining ); - } - - return( 0 ); -} - -int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, - unsigned char mac[16] ) -{ - POLY1305_VALIDATE_RET( ctx != NULL ); - POLY1305_VALIDATE_RET( mac != NULL ); - - /* Process any leftover data */ - if( ctx->queue_len > 0U ) - { - /* Add padding bit */ - ctx->queue[ctx->queue_len] = 1U; - ctx->queue_len++; - - /* Pad with zeroes */ - memset( &ctx->queue[ctx->queue_len], - 0, - POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); - - poly1305_process( ctx, 1U, /* Process 1 block */ - ctx->queue, 0U ); /* Already padded above */ - } - - poly1305_compute_mac( ctx, mac ); - - return( 0 ); -} - -int mbedtls_poly1305_mac( const unsigned char key[32], - const unsigned char *input, - size_t ilen, - unsigned char mac[16] ) -{ - mbedtls_poly1305_context ctx; - int ret; - POLY1305_VALIDATE_RET( key != NULL ); - POLY1305_VALIDATE_RET( mac != NULL ); - POLY1305_VALIDATE_RET( ilen == 0 || input != NULL ); - - mbedtls_poly1305_init( &ctx ); - - ret = mbedtls_poly1305_starts( &ctx, key ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_poly1305_update( &ctx, input, ilen ); - if( ret != 0 ) - goto cleanup; - - ret = mbedtls_poly1305_finish( &ctx, mac ); - -cleanup: - mbedtls_poly1305_free( &ctx ); - return( ret ); -} - -#endif /* MBEDTLS_POLY1305_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_keys[2][32] = -{ - { - 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, - 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8, - 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd, - 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b - }, - { - 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, - 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0, - 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09, - 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0 - } -}; - -static const unsigned char test_data[2][127] = -{ - { - 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f, - 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65, - 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f, - 0x75, 0x70 - }, - { - 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72, - 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f, - 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20, - 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20, - 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, - 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c, - 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77, - 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65, - 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20, - 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75, - 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e - } -}; - -static const size_t test_data_len[2] = -{ - 34U, - 127U -}; - -static const unsigned char test_mac[2][16] = -{ - { - 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, - 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9 - }, - { - 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61, - 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62 - } -}; - -#define ASSERT( cond, args ) \ - do \ - { \ - if( ! ( cond ) ) \ - { \ - if( verbose != 0 ) \ - mbedtls_printf args; \ - \ - return( -1 ); \ - } \ - } \ - while( 0 ) - -int mbedtls_poly1305_self_test( int verbose ) -{ - unsigned char mac[16]; - unsigned i; - int ret; - - for( i = 0U; i < 2U; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " Poly1305 test %u ", i ); - - ret = mbedtls_poly1305_mac( test_keys[i], - test_data[i], - test_data_len[i], - mac ); - ASSERT( 0 == ret, ( "error code: %i\n", ret ) ); - - ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) ); - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_POLY1305_C */ diff --git a/mbedtls/poly1305.h b/mbedtls/poly1305.h deleted file mode 100644 index 7a31e09f2..000000000 --- a/mbedtls/poly1305.h +++ /dev/null @@ -1,219 +0,0 @@ -#pragma GCC system_header -/** - * \file poly1305.h - * - * \brief This file contains Poly1305 definitions and functions. - * - * Poly1305 is a one-time message authenticator that can be used to - * authenticate messages. Poly1305-AES was created by Daniel - * Bernstein https://cr.yp.to/mac/poly1305-20050329.pdf The generic - * Poly1305 algorithm (not tied to AES) was also standardized in RFC - * 7539. - * - * \author Daniel King - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#ifndef MBEDTLS_POLY1305_H -#define MBEDTLS_POLY1305_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0057 /**< Invalid input parameter(s). */ - -/* MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE is deprecated and should not be - * used. */ -#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE -0x0059 /**< Feature not available. For example, s part of the API is not implemented. */ - -/* MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED is deprecated and should not be used. - */ -#define MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED -0x005B /**< Poly1305 hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_POLY1305_ALT) - -typedef struct mbedtls_poly1305_context -{ - uint32_t r[4]; /** The value for 'r' (low 128 bits of the key). */ - uint32_t s[4]; /** The value for 's' (high 128 bits of the key). */ - uint32_t acc[5]; /** The accumulator number. */ - uint8_t queue[16]; /** The current partial block of data. */ - size_t queue_len; /** The number of bytes stored in 'queue'. */ -} -mbedtls_poly1305_context; - -#else /* MBEDTLS_POLY1305_ALT */ -#include "poly1305_alt.h" -#endif /* MBEDTLS_POLY1305_ALT */ - -/** - * \brief This function initializes the specified Poly1305 context. - * - * It must be the first API called before using - * the context. - * - * It is usually followed by a call to - * \c mbedtls_poly1305_starts(), then one or more calls to - * \c mbedtls_poly1305_update(), then one call to - * \c mbedtls_poly1305_finish(), then finally - * \c mbedtls_poly1305_free(). - * - * \param ctx The Poly1305 context to initialize. This must - * not be \c NULL. - */ -void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ); - -/** - * \brief This function releases and clears the specified - * Poly1305 context. - * - * \param ctx The Poly1305 context to clear. This may be \c NULL, in which - * case this function is a no-op. If it is not \c NULL, it must - * point to an initialized Poly1305 context. - */ -void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ); - -/** - * \brief This function sets the one-time authentication key. - * - * \warning The key must be unique and unpredictable for each - * invocation of Poly1305. - * - * \param ctx The Poly1305 context to which the key should be bound. - * This must be initialized. - * \param key The buffer containing the \c 32 Byte (\c 256 Bit) key. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, - const unsigned char key[32] ); - -/** - * \brief This functions feeds an input buffer into an ongoing - * Poly1305 computation. - * - * It is called between \c mbedtls_cipher_poly1305_starts() and - * \c mbedtls_cipher_poly1305_finish(). - * It can be called repeatedly to process a stream of data. - * - * \param ctx The Poly1305 context to use for the Poly1305 operation. - * This must be initialized and bound to a key. - * \param ilen The length of the input data in Bytes. - * Any value is accepted. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `ilen == 0`. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief This function generates the Poly1305 Message - * Authentication Code (MAC). - * - * \param ctx The Poly1305 context to use for the Poly1305 operation. - * This must be initialized and bound to a key. - * \param mac The buffer to where the MAC is written. This must - * be a writable buffer of length \c 16 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, - unsigned char mac[16] ); - -/** - * \brief This function calculates the Poly1305 MAC of the input - * buffer with the provided key. - * - * \warning The key must be unique and unpredictable for each - * invocation of Poly1305. - * - * \param key The buffer containing the \c 32 Byte (\c 256 Bit) key. - * \param ilen The length of the input data in Bytes. - * Any value is accepted. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `ilen == 0`. - * \param mac The buffer to where the MAC is written. This must be - * a writable buffer of length \c 16 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_mac( const unsigned char key[32], - const unsigned char *input, - size_t ilen, - unsigned char mac[16] ); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The Poly1305 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_poly1305_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_POLY1305_H */ diff --git a/mbedtls/ripemd160.c b/mbedtls/ripemd160.c deleted file mode 100644 index 74fc8323a..000000000 --- a/mbedtls/ripemd160.c +++ /dev/null @@ -1,602 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * RIPE MD-160 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * The RIPEMD-160 algorithm was designed by RIPE in 1996 - * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html - * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_RIPEMD160_C) - -#include "mbedtls/ripemd160.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_RIPEMD160_ALT) - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) ); -} - -void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) ); -} - -void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst, - const mbedtls_ripemd160_context *src ) -{ - *dst = *src; -} - -/* - * RIPEMD-160 context setup - */ -int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx ) -{ - mbedtls_ripemd160_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) -/* - * Process one block - */ -int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, - const unsigned char data[64] ) -{ - struct - { - uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; - } local; - - GET_UINT32_LE( local.X[ 0], data, 0 ); - GET_UINT32_LE( local.X[ 1], data, 4 ); - GET_UINT32_LE( local.X[ 2], data, 8 ); - GET_UINT32_LE( local.X[ 3], data, 12 ); - GET_UINT32_LE( local.X[ 4], data, 16 ); - GET_UINT32_LE( local.X[ 5], data, 20 ); - GET_UINT32_LE( local.X[ 6], data, 24 ); - GET_UINT32_LE( local.X[ 7], data, 28 ); - GET_UINT32_LE( local.X[ 8], data, 32 ); - GET_UINT32_LE( local.X[ 9], data, 36 ); - GET_UINT32_LE( local.X[10], data, 40 ); - GET_UINT32_LE( local.X[11], data, 44 ); - GET_UINT32_LE( local.X[12], data, 48 ); - GET_UINT32_LE( local.X[13], data, 52 ); - GET_UINT32_LE( local.X[14], data, 56 ); - GET_UINT32_LE( local.X[15], data, 60 ); - - local.A = local.Ap = ctx->state[0]; - local.B = local.Bp = ctx->state[1]; - local.C = local.Cp = ctx->state[2]; - local.D = local.Dp = ctx->state[3]; - local.E = local.Ep = ctx->state[4]; - -#define F1( x, y, z ) ( (x) ^ (y) ^ (z) ) -#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) -#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) ) -#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) ) -#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) ) - -#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) ) - -#define P( a, b, c, d, e, r, s, f, k ) \ - do \ - { \ - (a) += f( (b), (c), (d) ) + local.X[r] + (k); \ - (a) = S( (a), (s) ) + (e); \ - (c) = S( (c), 10 ); \ - } while( 0 ) - -#define P2( a, b, c, d, e, r, s, rp, sp ) \ - do \ - { \ - P( (a), (b), (c), (d), (e), (r), (s), F, K ); \ - P( a ## p, b ## p, c ## p, d ## p, e ## p, \ - (rp), (sp), Fp, Kp ); \ - } while( 0 ) - -#define F F1 -#define K 0x00000000 -#define Fp F5 -#define Kp 0x50A28BE6 - P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 ); - P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 ); - P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 ); - P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 ); - P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 ); - P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 ); - P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 ); - P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 ); - P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 ); - P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 ); - P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 ); - P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 ); - P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 ); - P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 ); - P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 ); - P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F2 -#define K 0x5A827999 -#define Fp F4 -#define Kp 0x5C4DD124 - P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 ); - P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 ); - P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 ); - P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 ); - P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 ); - P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 ); - P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 ); - P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 ); - P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 ); - P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 ); - P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 ); - P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 ); - P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 ); - P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 ); - P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 ); - P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F3 -#define K 0x6ED9EBA1 -#define Fp F3 -#define Kp 0x6D703EF3 - P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 ); - P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 ); - P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 ); - P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 ); - P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 ); - P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 ); - P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 ); - P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 ); - P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 ); - P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 ); - P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 ); - P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 ); - P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 ); - P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 ); - P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 ); - P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F4 -#define K 0x8F1BBCDC -#define Fp F2 -#define Kp 0x7A6D76E9 - P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 ); - P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 ); - P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 ); - P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 ); - P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 ); - P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 ); - P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 ); - P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 ); - P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 ); - P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 ); - P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 ); - P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 ); - P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 ); - P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 ); - P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 ); - P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F5 -#define K 0xA953FD4E -#define Fp F1 -#define Kp 0x00000000 - P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 ); - P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 ); - P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 ); - P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 ); - P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 ); - P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 ); - P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 ); - P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 ); - P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 ); - P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 ); - P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 ); - P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 ); - P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 ); - P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 ); - P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 ); - P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 ); -#undef F -#undef K -#undef Fp -#undef Kp - - local.C = ctx->state[1] + local.C + local.Dp; - ctx->state[1] = ctx->state[2] + local.D + local.Ep; - ctx->state[2] = ctx->state[3] + local.E + local.Ap; - ctx->state[3] = ctx->state[4] + local.A + local.Bp; - ctx->state[4] = ctx->state[0] + local.B + local.Cp; - ctx->state[0] = local.C; - - /* Zeroise variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize( &local, sizeof( local ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_ripemd160_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ - -/* - * RIPEMD-160 process buffer - */ -int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - - if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), input, ilen ); - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_ripemd160_update_ret( ctx, input, ilen ); -} -#endif - -static const unsigned char ripemd160_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * RIPEMD-160 final digest - */ -int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx, - unsigned char output[20] ) -{ - int ret; - uint32_t last, padn; - uint32_t high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_LE( low, msglen, 0 ); - PUT_UINT32_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 ); - if( ret != 0 ) - return( ret ); - - PUT_UINT32_LE( ctx->state[0], output, 0 ); - PUT_UINT32_LE( ctx->state[1], output, 4 ); - PUT_UINT32_LE( ctx->state[2], output, 8 ); - PUT_UINT32_LE( ctx->state[3], output, 12 ); - PUT_UINT32_LE( ctx->state[4], output, 16 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, - unsigned char output[20] ) -{ - mbedtls_ripemd160_finish_ret( ctx, output ); -} -#endif - -#endif /* ! MBEDTLS_RIPEMD160_ALT */ - -/* - * output = RIPEMD-160( input buffer ) - */ -int mbedtls_ripemd160_ret( const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - int ret; - mbedtls_ripemd160_context ctx; - - mbedtls_ripemd160_init( &ctx ); - - if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_ripemd160_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ripemd160( const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - mbedtls_ripemd160_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * Test vectors from the RIPEMD-160 paper and - * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC - */ -#define TESTS 8 -static const unsigned char ripemd160_test_str[TESTS][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }, -}; - -static const size_t ripemd160_test_strlen[TESTS] = -{ - 0, 1, 3, 14, 26, 56, 62, 80 -}; - -static const unsigned char ripemd160_test_md[TESTS][20] = -{ - { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, - 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, - { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, - 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, - { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, - 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, - { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, - 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, - { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, - 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, - { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, - 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, - { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, - 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, - { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, - 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, -}; - -/* - * Checkup routine - */ -int mbedtls_ripemd160_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char output[20]; - - memset( output, 0, sizeof output ); - - for( i = 0; i < TESTS; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 ); - - ret = mbedtls_ripemd160_ret( ripemd160_test_str[i], - ripemd160_test_strlen[i], output ); - if( ret != 0 ) - goto fail; - - if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_RIPEMD160_C */ diff --git a/mbedtls/ripemd160.h b/mbedtls/ripemd160.h deleted file mode 100644 index 201ac441f..000000000 --- a/mbedtls/ripemd160.h +++ /dev/null @@ -1,263 +0,0 @@ -#pragma GCC system_header -/** - * \file ripemd160.h - * - * \brief RIPE MD-160 message digest - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_RIPEMD160_H -#define MBEDTLS_RIPEMD160_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -/* MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED is deprecated and should not be used. - */ -#define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED -0x0031 /**< RIPEMD160 hardware accelerator failed */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_RIPEMD160_ALT) -// Regular implementation -// - -/** - * \brief RIPEMD-160 context structure - */ -typedef struct mbedtls_ripemd160_context -{ - uint32_t total[2]; /*!< number of bytes processed */ - uint32_t state[5]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -mbedtls_ripemd160_context; - -#else /* MBEDTLS_RIPEMD160_ALT */ -#include "ripemd160.h" -#endif /* MBEDTLS_RIPEMD160_ALT */ - -/** - * \brief Initialize RIPEMD-160 context - * - * \param ctx RIPEMD-160 context to be initialized - */ -void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ); - -/** - * \brief Clear RIPEMD-160 context - * - * \param ctx RIPEMD-160 context to be cleared - */ -void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ); - -/** - * \brief Clone (the state of) an RIPEMD-160 context - * - * \param dst The destination context - * \param src The context to be cloned - */ -void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst, - const mbedtls_ripemd160_context *src ); - -/** - * \brief RIPEMD-160 context setup - * - * \param ctx context to be initialized - * - * \return 0 if successful - */ -int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx ); - -/** - * \brief RIPEMD-160 process buffer - * - * \param ctx RIPEMD-160 context - * \param input buffer holding the data - * \param ilen length of the input data - * - * \return 0 if successful - */ -int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief RIPEMD-160 final digest - * - * \param ctx RIPEMD-160 context - * \param output RIPEMD-160 checksum result - * - * \return 0 if successful - */ -int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx, - unsigned char output[20] ); - -/** - * \brief RIPEMD-160 process data block (internal use only) - * - * \param ctx RIPEMD-160 context - * \param data buffer holding one block of data - * - * \return 0 if successful - */ -int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, - const unsigned char data[64] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief RIPEMD-160 context setup - * - * \disabled_deprecated Superseded by mbedtls_ripemd160_starts_ret() in 2.7.0 - * - * \param ctx context to be initialized - */ -MBEDTLS_DEPRECATED void mbedtls_ripemd160_starts( - mbedtls_ripemd160_context *ctx ); - -/** - * \brief RIPEMD-160 process buffer - * - * \disabled_deprecated Superseded by mbedtls_ripemd160_update_ret() in 2.7.0 - * - * \param ctx RIPEMD-160 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -MBEDTLS_DEPRECATED void mbedtls_ripemd160_update( - mbedtls_ripemd160_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief RIPEMD-160 final digest - * - * \disabled_deprecated Superseded by mbedtls_ripemd160_finish_ret() in 2.7.0 - * - * \param ctx RIPEMD-160 context - * \param output RIPEMD-160 checksum result - */ -MBEDTLS_DEPRECATED void mbedtls_ripemd160_finish( - mbedtls_ripemd160_context *ctx, - unsigned char output[20] ); - -/** - * \brief RIPEMD-160 process data block (internal use only) - * - * \disabled_deprecated Superseded by mbedtls_internal_ripemd160_process() in 2.7.0 - * - * \param ctx RIPEMD-160 context - * \param data buffer holding one block of data - */ -MBEDTLS_DEPRECATED void mbedtls_ripemd160_process( - mbedtls_ripemd160_context *ctx, - const unsigned char data[64] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Output = RIPEMD-160( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output RIPEMD-160 checksum result - * - * \return 0 if successful - */ -int mbedtls_ripemd160_ret( const unsigned char *input, - size_t ilen, - unsigned char output[20] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief Output = RIPEMD-160( input buffer ) - * - * \disabled_deprecated Superseded by mbedtls_ripemd160_ret() in 2.7.0 - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output RIPEMD-160 checksum result - */ -MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input, - size_t ilen, - unsigned char output[20] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_ripemd160_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_ripemd160.h */ diff --git a/mbedtls/rsa.c b/mbedtls/rsa.c deleted file mode 100644 index e73bec859..000000000 --- a/mbedtls/rsa.c +++ /dev/null @@ -1,2804 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * The RSA public-key cryptosystem - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * The following sources were referenced in the design of this implementation - * of the RSA algorithm: - * - * [1] A method for obtaining digital signatures and public-key cryptosystems - * R Rivest, A Shamir, and L Adleman - * http://people.csail.mit.edu/rivest/pubs.html#RSA78 - * - * [2] Handbook of Applied Cryptography - 1997, Chapter 8 - * Menezes, van Oorschot and Vanstone - * - * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks - * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and - * Stefan Mangard - * https://arxiv.org/abs/1702.08719v2 - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_RSA_C) - -#include "mbedtls/rsa.h" -#include "mbedtls/rsa_internal.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PKCS1_V21) -#include "mbedtls/md.h" -#endif - -#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__) -#include -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if !defined(MBEDTLS_RSA_ALT) - -/* Parameter validation macros */ -#define RSA_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA ) -#define RSA_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if defined(MBEDTLS_PKCS1_V15) -/* constant-time buffer comparison */ -static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n ) -{ - size_t i; - const unsigned char *A = (const unsigned char *) a; - const unsigned char *B = (const unsigned char *) b; - unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - diff |= A[i] ^ B[i]; - - return( diff ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -int mbedtls_rsa_import( mbedtls_rsa_context *ctx, - const mbedtls_mpi *N, - const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *E ) -{ - int ret; - RSA_VALIDATE_RET( ctx != NULL ); - - if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) || - ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) || - ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) || - ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) || - ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } - - if( N != NULL ) - ctx->len = mbedtls_mpi_size( &ctx->N ); - - return( 0 ); -} - -int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, - unsigned char const *N, size_t N_len, - unsigned char const *P, size_t P_len, - unsigned char const *Q, size_t Q_len, - unsigned char const *D, size_t D_len, - unsigned char const *E, size_t E_len ) -{ - int ret = 0; - RSA_VALIDATE_RET( ctx != NULL ); - - if( N != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) ); - ctx->len = mbedtls_mpi_size( &ctx->N ); - } - - if( P != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) ); - - if( Q != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) ); - - if( D != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) ); - - if( E != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) ); - -cleanup: - - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - - return( 0 ); -} - -/* - * Checks whether the context fields are set in such a way - * that the RSA primitives will be able to execute without error. - * It does *not* make guarantees for consistency of the parameters. - */ -static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv, - int blinding_needed ) -{ -#if !defined(MBEDTLS_RSA_NO_CRT) - /* blinding_needed is only used for NO_CRT to decide whether - * P,Q need to be present or not. */ - ((void) blinding_needed); -#endif - - if( ctx->len != mbedtls_mpi_size( &ctx->N ) || - ctx->len > MBEDTLS_MPI_MAX_SIZE ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - /* - * 1. Modular exponentiation needs positive, odd moduli. - */ - - /* Modular exponentiation wrt. N is always used for - * RSA public key operations. */ - if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 || - mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* Modular exponentiation for P and Q is only - * used for private key operations and if CRT - * is used. */ - if( is_priv && - ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 || - mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 || - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 || - mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } -#endif /* !MBEDTLS_RSA_NO_CRT */ - - /* - * 2. Exponents must be positive - */ - - /* Always need E for public key operations */ - if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_RSA_NO_CRT) - /* For private key operations, use D or DP & DQ - * as (unblinded) exponents. */ - if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); -#else - if( is_priv && - ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 || - mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Blinding shouldn't make exponents negative either, - * so check that P, Q >= 1 if that hasn't yet been - * done as part of 1. */ -#if defined(MBEDTLS_RSA_NO_CRT) - if( is_priv && blinding_needed && - ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 || - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } -#endif - - /* It wouldn't lead to an error if it wasn't satisfied, - * but check for QP >= 1 nonetheless. */ -#if !defined(MBEDTLS_RSA_NO_CRT) - if( is_priv && - mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } -#endif - - return( 0 ); -} - -int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) -{ - int ret = 0; - int have_N, have_P, have_Q, have_D, have_E; -#if !defined(MBEDTLS_RSA_NO_CRT) - int have_DP, have_DQ, have_QP; -#endif - int n_missing, pq_missing, d_missing, is_pub, is_priv; - - RSA_VALIDATE_RET( ctx != NULL ); - - have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 ); - have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 ); - have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 ); - have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 ); - have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 ); - have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 ); - have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 ); -#endif - - /* - * Check whether provided parameters are enough - * to deduce all others. The following incomplete - * parameter sets for private keys are supported: - * - * (1) P, Q missing. - * (2) D and potentially N missing. - * - */ - - n_missing = have_P && have_Q && have_D && have_E; - pq_missing = have_N && !have_P && !have_Q && have_D && have_E; - d_missing = have_P && have_Q && !have_D && have_E; - is_pub = have_N && !have_P && !have_Q && !have_D && have_E; - - /* These three alternatives are mutually exclusive */ - is_priv = n_missing || pq_missing || d_missing; - - if( !is_priv && !is_pub ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * Step 1: Deduce N if P, Q are provided. - */ - - if( !have_N && have_P && have_Q ) - { - if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, - &ctx->Q ) ) != 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } - - ctx->len = mbedtls_mpi_size( &ctx->N ); - } - - /* - * Step 2: Deduce and verify all remaining core parameters. - */ - - if( pq_missing ) - { - ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D, - &ctx->P, &ctx->Q ); - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - - } - else if( d_missing ) - { - if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P, - &ctx->Q, - &ctx->E, - &ctx->D ) ) != 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } - } - - /* - * Step 3: Deduce all additional parameters specific - * to our current RSA implementation. - */ - -#if !defined(MBEDTLS_RSA_NO_CRT) - if( is_priv && ! ( have_DP && have_DQ && have_QP ) ) - { - ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, - &ctx->DP, &ctx->DQ, &ctx->QP ); - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* - * Step 3: Basic sanity checks - */ - - return( rsa_check_context( ctx, is_priv, 1 ) ); -} - -int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, - unsigned char *N, size_t N_len, - unsigned char *P, size_t P_len, - unsigned char *Q, size_t Q_len, - unsigned char *D, size_t D_len, - unsigned char *E, size_t E_len ) -{ - int ret = 0; - int is_priv; - RSA_VALIDATE_RET( ctx != NULL ); - - /* Check if key is private or public */ - is_priv = - mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; - - if( !is_priv ) - { - /* If we're trying to export private parameters for a public key, - * something must be wrong. */ - if( P != NULL || Q != NULL || D != NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - } - - if( N != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) ); - - if( P != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) ); - - if( Q != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) ); - - if( D != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) ); - - if( E != NULL ) - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) ); - -cleanup: - - return( ret ); -} - -int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, - mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, - mbedtls_mpi *D, mbedtls_mpi *E ) -{ - int ret; - int is_priv; - RSA_VALIDATE_RET( ctx != NULL ); - - /* Check if key is private or public */ - is_priv = - mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; - - if( !is_priv ) - { - /* If we're trying to export private parameters for a public key, - * something must be wrong. */ - if( P != NULL || Q != NULL || D != NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - } - - /* Export all requested core parameters. */ - - if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) || - ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) || - ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) || - ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) || - ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Export CRT parameters - * This must also be implemented if CRT is not used, for being able to - * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt - * can be used in this case. - */ -int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, - mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ) -{ - int ret; - int is_priv; - RSA_VALIDATE_RET( ctx != NULL ); - - /* Check if key is private or public */ - is_priv = - mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && - mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; - - if( !is_priv ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* Export all requested blinding parameters. */ - if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) || - ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) || - ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } -#else - if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, - DP, DQ, QP ) ) != 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); - } -#endif - - return( 0 ); -} - -/* - * Initialize an RSA context - */ -void mbedtls_rsa_init( mbedtls_rsa_context *ctx, - int padding, - int hash_id ) -{ - RSA_VALIDATE( ctx != NULL ); - RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 || - padding == MBEDTLS_RSA_PKCS_V21 ); - - memset( ctx, 0, sizeof( mbedtls_rsa_context ) ); - - mbedtls_rsa_set_padding( ctx, padding, hash_id ); - -#if defined(MBEDTLS_THREADING_C) - /* Set ctx->ver to nonzero to indicate that the mutex has been - * initialized and will need to be freed. */ - ctx->ver = 1; - mbedtls_mutex_init( &ctx->mutex ); -#endif -} - -/* - * Set padding for an existing RSA context - */ -void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, - int hash_id ) -{ - RSA_VALIDATE( ctx != NULL ); - RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 || - padding == MBEDTLS_RSA_PKCS_V21 ); - - ctx->padding = padding; - ctx->hash_id = hash_id; -} - -/* - * Get length in bytes of RSA modulus - */ - -size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ) -{ - return( ctx->len ); -} - - -#if defined(MBEDTLS_GENPRIME) - -/* - * Generate an RSA keypair - * - * This generation method follows the RSA key pair generation procedure of - * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072. - */ -int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - unsigned int nbits, int exponent ) -{ - int ret; - mbedtls_mpi H, G, L; - int prime_quality = 0; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( f_rng != NULL ); - - /* - * If the modulus is 1024 bit long or shorter, then the security strength of - * the RSA algorithm is less than or equal to 80 bits and therefore an error - * rate of 2^-80 is sufficient. - */ - if( nbits > 1024 ) - prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR; - - mbedtls_mpi_init( &H ); - mbedtls_mpi_init( &G ); - mbedtls_mpi_init( &L ); - - if( nbits < 128 || exponent < 3 || nbits % 2 != 0 ) - { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - /* - * find primes P and Q with Q < P so that: - * 1. |P-Q| > 2^( nbits / 2 - 100 ) - * 2. GCD( E, (P-1)*(Q-1) ) == 1 - * 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 ) - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) ); - - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, - prime_quality, f_rng, p_rng ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, - prime_quality, f_rng, p_rng ) ); - - /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) ); - if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) ) - continue; - - /* not required by any standards, but some users rely on the fact that P > Q */ - if( H.s < 0 ) - mbedtls_mpi_swap( &ctx->P, &ctx->Q ); - - /* Temporarily replace P,Q by P-1, Q-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) ); - - /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); - if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) - continue; - - /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) ); - - if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a)) - continue; - - break; - } - while( 1 ); - - /* Restore P,Q */ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); - - ctx->len = mbedtls_mpi_size( &ctx->N ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* - * DP = D mod (P - 1) - * DQ = D mod (Q - 1) - * QP = Q^-1 mod P - */ - MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, - &ctx->DP, &ctx->DQ, &ctx->QP ) ); -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Double-check */ - MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) ); - -cleanup: - - mbedtls_mpi_free( &H ); - mbedtls_mpi_free( &G ); - mbedtls_mpi_free( &L ); - - if( ret != 0 ) - { - mbedtls_rsa_free( ctx ); - if( ( -ret & ~0x7f ) == 0 ) - ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret; - return( ret ); - } - - return( 0 ); -} - -#endif /* MBEDTLS_GENPRIME */ - -/* - * Check a public RSA key - */ -int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - - if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 ) - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - - if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 || - mbedtls_mpi_bitlen( &ctx->E ) < 2 || - mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - return( 0 ); -} - -/* - * Check for the consistency of all fields in an RSA private key context - */ -int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - - if( mbedtls_rsa_check_pubkey( ctx ) != 0 || - rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q, - &ctx->D, &ctx->E, NULL, NULL ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - -#if !defined(MBEDTLS_RSA_NO_CRT) - else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D, - &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } -#endif - - return( 0 ); -} - -/* - * Check if contexts holding a public and private key match - */ -int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, - const mbedtls_rsa_context *prv ) -{ - RSA_VALIDATE_RET( pub != NULL ); - RSA_VALIDATE_RET( prv != NULL ); - - if( mbedtls_rsa_check_pubkey( pub ) != 0 || - mbedtls_rsa_check_privkey( prv ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 || - mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 ) - { - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - } - - return( 0 ); -} - -/* - * Do an RSA public key operation - */ -int mbedtls_rsa_public( mbedtls_rsa_context *ctx, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - size_t olen; - mbedtls_mpi T; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( output != NULL ); - - if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - mbedtls_mpi_init( &T ); - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); - - if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) - { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - - olen = ctx->len; - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - mbedtls_mpi_free( &T ); - - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret ); - - return( 0 ); -} - -/* - * Generate or update blinding values, see section 10 of: - * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, - * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer - * Berlin Heidelberg, 1996. p. 104-113. - */ -static int rsa_prepare_blinding( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) -{ - int ret, count = 0; - mbedtls_mpi R; - - mbedtls_mpi_init( &R ); - - if( ctx->Vf.p != NULL ) - { - /* We already have blinding values, just update them by squaring */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) ); - - goto cleanup; - } - - /* Unblinding value: Vf = random number, invertible mod N */ - do { - if( count++ > 10 ) - { - ret = MBEDTLS_ERR_RSA_RNG_FAILED; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); - - /* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */ - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, ctx->len - 1, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vf, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); - - /* At this point, Vi is invertible mod N if and only if both Vf and R - * are invertible mod N. If one of them isn't, we don't need to know - * which one, we just loop and choose new values for both of them. - * (Each iteration succeeds with overwhelming probability.) */ - ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N ); - if( ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - - } while( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - - /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); - - /* Blinding value: Vi = Vf^(-e) mod N - * (Vi already contains Vf^-1 at this point) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); - - -cleanup: - mbedtls_mpi_free( &R ); - - return( ret ); -} - -/* - * Exponent blinding supposed to prevent side-channel attacks using multiple - * traces of measurements to recover the RSA key. The more collisions are there, - * the more bits of the key can be recovered. See [3]. - * - * Collecting n collisions with m bit long blinding value requires 2^(m-m/n) - * observations on avarage. - * - * For example with 28 byte blinding to achieve 2 collisions the adversary has - * to make 2^112 observations on avarage. - * - * (With the currently (as of 2017 April) known best algorithms breaking 2048 - * bit RSA requires approximately as much time as trying out 2^112 random keys. - * Thus in this sense with 28 byte blinding the security is not reduced by - * side-channel attacks like the one in [3]) - * - * This countermeasure does not help if the key recovery is possible with a - * single trace. - */ -#define RSA_EXPONENT_BLINDING 28 - -/* - * Do an RSA private key operation - */ -int mbedtls_rsa_private( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - const unsigned char *input, - unsigned char *output ) -{ - int ret; - size_t olen; - - /* Temporary holding the result */ - mbedtls_mpi T; - - /* Temporaries holding P-1, Q-1 and the - * exponent blinding factor, respectively. */ - mbedtls_mpi P1, Q1, R; - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* Temporaries holding the results mod p resp. mod q. */ - mbedtls_mpi TP, TQ; - - /* Temporaries holding the blinded exponents for - * the mod p resp. mod q computation (if used). */ - mbedtls_mpi DP_blind, DQ_blind; - - /* Pointers to actual exponents to be used - either the unblinded - * or the blinded ones, depending on the presence of a PRNG. */ - mbedtls_mpi *DP = &ctx->DP; - mbedtls_mpi *DQ = &ctx->DQ; -#else - /* Temporary holding the blinded exponent (if used). */ - mbedtls_mpi D_blind; - - /* Pointer to actual exponent to be used - either the unblinded - * or the blinded one, depending on the presence of a PRNG. */ - mbedtls_mpi *D = &ctx->D; -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Temporaries holding the initial input and the double - * checked result; should be the same in the end. */ - mbedtls_mpi I, C; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( output != NULL ); - - if( rsa_check_context( ctx, 1 /* private key checks */, - f_rng != NULL /* blinding y/n */ ) != 0 ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - /* MPI Initialization */ - mbedtls_mpi_init( &T ); - - mbedtls_mpi_init( &P1 ); - mbedtls_mpi_init( &Q1 ); - mbedtls_mpi_init( &R ); - - if( f_rng != NULL ) - { -#if defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_init( &D_blind ); -#else - mbedtls_mpi_init( &DP_blind ); - mbedtls_mpi_init( &DQ_blind ); -#endif - } - -#if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ ); -#endif - - mbedtls_mpi_init( &I ); - mbedtls_mpi_init( &C ); - - /* End of MPI initialization */ - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); - if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) - { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) ); - - if( f_rng != NULL ) - { - /* - * Blinding - * T = T * Vi mod N - */ - MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); - - /* - * Exponent blinding - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); - -#if defined(MBEDTLS_RSA_NO_CRT) - /* - * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, - f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) ); - - D = &D_blind; -#else - /* - * DP_blind = ( P - 1 ) * R + DP - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, - f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind, - &ctx->DP ) ); - - DP = &DP_blind; - - /* - * DQ_blind = ( Q - 1 ) * R + DQ - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, - f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind, - &ctx->DQ ) ); - - DQ = &DQ_blind; -#endif /* MBEDTLS_RSA_NO_CRT */ - } - -#if defined(MBEDTLS_RSA_NO_CRT) - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) ); -#else - /* - * Faster decryption using the CRT - * - * TP = input ^ dP mod P - * TQ = input ^ dQ mod Q - */ - - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) ); - - /* - * T = (TP - TQ) * (Q^-1 mod P) mod P - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) ); - - /* - * T = TQ + T * Q - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) ); -#endif /* MBEDTLS_RSA_NO_CRT */ - - if( f_rng != NULL ) - { - /* - * Unblind - * T = T * Vf mod N - */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); - } - - /* Verify the result to prevent glitching attacks. */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E, - &ctx->N, &ctx->RN ) ); - if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; - goto cleanup; - } - - olen = ctx->len; - MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - mbedtls_mpi_free( &P1 ); - mbedtls_mpi_free( &Q1 ); - mbedtls_mpi_free( &R ); - - if( f_rng != NULL ) - { -#if defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free( &D_blind ); -#else - mbedtls_mpi_free( &DP_blind ); - mbedtls_mpi_free( &DQ_blind ); -#endif - } - - mbedtls_mpi_free( &T ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ ); -#endif - - mbedtls_mpi_free( &C ); - mbedtls_mpi_free( &I ); - - if( ret != 0 && ret >= -0x007f ) - return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret ); - - return( ret ); -} - -#if defined(MBEDTLS_PKCS1_V21) -/** - * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer. - * - * \param dst buffer to mask - * \param dlen length of destination buffer - * \param src source of the mask generation - * \param slen length of the source buffer - * \param md_ctx message digest context to use - */ -static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, - size_t slen, mbedtls_md_context_t *md_ctx ) -{ - unsigned char mask[MBEDTLS_MD_MAX_SIZE]; - unsigned char counter[4]; - unsigned char *p; - unsigned int hlen; - size_t i, use_len; - int ret = 0; - - memset( mask, 0, MBEDTLS_MD_MAX_SIZE ); - memset( counter, 0, 4 ); - - hlen = mbedtls_md_get_size( md_ctx->md_info ); - - /* Generate and apply dbMask */ - p = dst; - - while( dlen > 0 ) - { - use_len = hlen; - if( dlen < hlen ) - use_len = dlen; - - if( ( ret = mbedtls_md_starts( md_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( md_ctx, src, slen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( md_ctx, counter, 4 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_finish( md_ctx, mask ) ) != 0 ) - goto exit; - - for( i = 0; i < use_len; ++i ) - *p++ ^= mask[i]; - - counter[3]++; - - dlen -= use_len; - } - -exit: - mbedtls_platform_zeroize( mask, sizeof( mask ) ); - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function - */ -int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - const unsigned char *label, size_t label_len, - size_t ilen, - const unsigned char *input, - unsigned char *output ) -{ - size_t olen; - int ret; - unsigned char *p = output; - unsigned int hlen; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( label_len == 0 || label != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( f_rng == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - olen = ctx->len; - hlen = mbedtls_md_get_size( md_info ); - - /* first comparison checks for overflow */ - if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - memset( output, 0, olen ); - - *p++ = 0; - - /* Generate a random octet string seed */ - if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 ) - return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); - - p += hlen; - - /* Construct DB */ - if( ( ret = mbedtls_md( md_info, label, label_len, p ) ) != 0 ) - return( ret ); - p += hlen; - p += olen - 2 * hlen - 2 - ilen; - *p++ = 1; - memcpy( p, input, ilen ); - - mbedtls_md_init( &md_ctx ); - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - goto exit; - - /* maskedDB: Apply dbMask to DB */ - if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen, - &md_ctx ) ) != 0 ) - goto exit; - - /* maskedSeed: Apply seedMask to seed */ - if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, - &md_ctx ) ) != 0 ) - goto exit; - -exit: - mbedtls_md_free( &md_ctx ); - - if( ret != 0 ) - return( ret ); - - return( ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, output, output ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) ); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function - */ -int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t ilen, - const unsigned char *input, - unsigned char *output ) -{ - size_t nb_pad, olen; - int ret; - unsigned char *p = output; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - olen = ctx->len; - - /* first comparison checks for overflow */ - if( ilen + 11 < ilen || olen < ilen + 11 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - nb_pad = olen - 3 - ilen; - - *p++ = 0; - if( mode == MBEDTLS_RSA_PUBLIC ) - { - if( f_rng == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - *p++ = MBEDTLS_RSA_CRYPT; - - while( nb_pad-- > 0 ) - { - int rng_dl = 100; - - do { - ret = f_rng( p_rng, p, 1 ); - } while( *p == 0 && --rng_dl && ret == 0 ); - - /* Check if RNG failed to generate data */ - if( rng_dl == 0 || ret != 0 ) - return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); - - p++; - } - } - else - { - *p++ = MBEDTLS_RSA_SIGN; - - while( nb_pad-- > 0 ) - *p++ = 0xFF; - } - - *p++ = 0; - memcpy( p, input, ilen ); - - return( ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, output, output ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Add the message padding, then do an RSA operation - */ -int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t ilen, - const unsigned char *input, - unsigned char *output ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - - switch( ctx->padding ) - { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen, - input, output ); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0, - ilen, input, output ); -#endif - - default: - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - } -} - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function - */ -int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - const unsigned char *label, size_t label_len, - size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ) -{ - int ret; - size_t ilen, i, pad_len; - unsigned char *p, bad, pad_done; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - unsigned char lhash[MBEDTLS_MD_MAX_SIZE]; - unsigned int hlen; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); - RSA_VALIDATE_RET( label_len == 0 || label != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( olen != NULL ); - - /* - * Parameters sanity checks - */ - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - ilen = ctx->len; - - if( ilen < 16 || ilen > sizeof( buf ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hlen = mbedtls_md_get_size( md_info ); - - // checking for integer underflow - if( 2 * hlen + 2 > ilen ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * RSA operation - */ - ret = ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, input, buf ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); - - if( ret != 0 ) - goto cleanup; - - /* - * Unmask data and generate lHash - */ - mbedtls_md_init( &md_ctx ); - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - { - mbedtls_md_free( &md_ctx ); - goto cleanup; - } - - /* seed: Apply seedMask to maskedSeed */ - if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, - &md_ctx ) ) != 0 || - /* DB: Apply dbMask to maskedDB */ - ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, - &md_ctx ) ) != 0 ) - { - mbedtls_md_free( &md_ctx ); - goto cleanup; - } - - mbedtls_md_free( &md_ctx ); - - /* Generate lHash */ - if( ( ret = mbedtls_md( md_info, label, label_len, lhash ) ) != 0 ) - goto cleanup; - - /* - * Check contents, in "constant-time" - */ - p = buf; - bad = 0; - - bad |= *p++; /* First byte must be 0 */ - - p += hlen; /* Skip seed */ - - /* Check lHash */ - for( i = 0; i < hlen; i++ ) - bad |= lhash[i] ^ *p++; - - /* Get zero-padding len, but always read till end of buffer - * (minus one, for the 01 byte) */ - pad_len = 0; - pad_done = 0; - for( i = 0; i < ilen - 2 * hlen - 2; i++ ) - { - pad_done |= p[i]; - pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1; - } - - p += pad_len; - bad |= *p++ ^ 0x01; - - /* - * The only information "leaked" is whether the padding was correct or not - * (eg, no data is copied if it was not correct). This meets the - * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between - * the different error conditions. - */ - if( bad != 0 ) - { - ret = MBEDTLS_ERR_RSA_INVALID_PADDING; - goto cleanup; - } - - if( ilen - ( p - buf ) > output_max_len ) - { - ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; - goto cleanup; - } - - *olen = ilen - (p - buf); - memcpy( output, p, *olen ); - ret = 0; - -cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - mbedtls_platform_zeroize( lhash, sizeof( lhash ) ); - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches. - * - * \param value The value to analyze. - * \return Zero if \p value is zero, otherwise all-bits-one. - */ -static unsigned all_or_nothing_int( unsigned value ) -{ - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) ); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif -} - -/** Check whether a size is out of bounds, without branches. - * - * This is equivalent to `size > max`, but is likely to be compiled to - * to code using bitwise operation rather than a branch. - * - * \param size Size to check. - * \param max Maximum desired value for \p size. - * \return \c 0 if `size <= max`. - * \return \c 1 if `size > max`. - */ -static unsigned size_greater_than( size_t size, size_t max ) -{ - /* Return the sign bit (1 for negative) of (max - size). */ - return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) ); -} - -/** Choose between two integer values, without branches. - * - * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled - * to code using bitwise operation rather than a branch. - * - * \param cond Condition to test. - * \param if1 Value to use if \p cond is nonzero. - * \param if0 Value to use if \p cond is zero. - * \return \c if1 if \p cond is nonzero, otherwise \c if0. - */ -static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 ) -{ - unsigned mask = all_or_nothing_int( cond ); - return( ( mask & if1 ) | (~mask & if0 ) ); -} - -/** Shift some data towards the left inside a buffer without leaking - * the length of the data through side channels. - * - * `mem_move_to_left(start, total, offset)` is functionally equivalent to - * ``` - * memmove(start, start + offset, total - offset); - * memset(start + offset, 0, total - offset); - * ``` - * but it strives to use a memory access pattern (and thus total timing) - * that does not depend on \p offset. This timing independence comes at - * the expense of performance. - * - * \param start Pointer to the start of the buffer. - * \param total Total size of the buffer. - * \param offset Offset from which to copy \p total - \p offset bytes. - */ -static void mem_move_to_left( void *start, - size_t total, - size_t offset ) -{ - volatile unsigned char *buf = start; - size_t i, n; - if( total == 0 ) - return; - for( i = 0; i < total; i++ ) - { - unsigned no_op = size_greater_than( total - offset, i ); - /* The first `total - offset` passes are a no-op. The last - * `offset` passes shift the data one byte to the left and - * zero out the last byte. */ - for( n = 0; n < total - 1; n++ ) - { - unsigned char current = buf[n]; - unsigned char next = buf[n+1]; - buf[n] = if_int( no_op, current, next ); - } - buf[total-1] = if_int( no_op, buf[total-1], 0 ); - } -} - -/* - * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function - */ -int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ) -{ - int ret; - size_t ilen, i, plaintext_max_size; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - /* The following variables take sensitive values: their value must - * not leak into the observable behavior of the function other than - * the designated outputs (output, olen, return value). Otherwise - * this would open the execution of the function to - * side-channel-based variants of the Bleichenbacher padding oracle - * attack. Potential side channels include overall timing, memory - * access patterns (especially visible to an adversary who has access - * to a shared memory cache), and branches (especially visible to - * an adversary who has access to a shared code cache or to a shared - * branch predictor). */ - size_t pad_count = 0; - unsigned bad = 0; - unsigned char pad_done = 0; - size_t plaintext_size = 0; - unsigned output_too_large; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( olen != NULL ); - - ilen = ctx->len; - plaintext_max_size = ( output_max_len > ilen - 11 ? - ilen - 11 : - output_max_len ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( ilen < 16 || ilen > sizeof( buf ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - ret = ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, input, buf ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); - - if( ret != 0 ) - goto cleanup; - - /* Check and get padding length in constant time and constant - * memory trace. The first byte must be 0. */ - bad |= buf[0]; - - if( mode == MBEDTLS_RSA_PRIVATE ) - { - /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00 - * where PS must be at least 8 nonzero bytes. */ - bad |= buf[1] ^ MBEDTLS_RSA_CRYPT; - - /* Read the whole buffer. Set pad_done to nonzero if we find - * the 0x00 byte and remember the padding length in pad_count. */ - for( i = 2; i < ilen; i++ ) - { - pad_done |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1; - pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1; - } - } - else - { - /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00 - * where PS must be at least 8 bytes with the value 0xFF. */ - bad |= buf[1] ^ MBEDTLS_RSA_SIGN; - - /* Read the whole buffer. Set pad_done to nonzero if we find - * the 0x00 byte and remember the padding length in pad_count. - * If there's a non-0xff byte in the padding, the padding is bad. */ - for( i = 2; i < ilen; i++ ) - { - pad_done |= if_int( buf[i], 0, 1 ); - pad_count += if_int( pad_done, 0, 1 ); - bad |= if_int( pad_done, 0, buf[i] ^ 0xFF ); - } - } - - /* If pad_done is still zero, there's no data, only unfinished padding. */ - bad |= if_int( pad_done, 0, 1 ); - - /* There must be at least 8 bytes of padding. */ - bad |= size_greater_than( 8, pad_count ); - - /* If the padding is valid, set plaintext_size to the number of - * remaining bytes after stripping the padding. If the padding - * is invalid, avoid leaking this fact through the size of the - * output: use the maximum message size that fits in the output - * buffer. Do it without branches to avoid leaking the padding - * validity through timing. RSA keys are small enough that all the - * size_t values involved fit in unsigned int. */ - plaintext_size = if_int( bad, - (unsigned) plaintext_max_size, - (unsigned) ( ilen - pad_count - 3 ) ); - - /* Set output_too_large to 0 if the plaintext fits in the output - * buffer and to 1 otherwise. */ - output_too_large = size_greater_than( plaintext_size, - plaintext_max_size ); - - /* Set ret without branches to avoid timing attacks. Return: - * - INVALID_PADDING if the padding is bad (bad != 0). - * - OUTPUT_TOO_LARGE if the padding is good but the decrypted - * plaintext does not fit in the output buffer. - * - 0 if the padding is correct. */ - ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING, - if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE, - 0 ) ); - - /* If the padding is bad or the plaintext is too large, zero the - * data that we're about to copy to the output buffer. - * We need to copy the same amount of data - * from the same buffer whether the padding is good or not to - * avoid leaking the padding validity through overall timing or - * through memory or cache access patterns. */ - bad = all_or_nothing_int( bad | output_too_large ); - for( i = 11; i < ilen; i++ ) - buf[i] &= ~bad; - - /* If the plaintext is too large, truncate it to the buffer size. - * Copy anyway to avoid revealing the length through timing, because - * revealing the length is as bad as revealing the padding validity - * for a Bleichenbacher attack. */ - plaintext_size = if_int( output_too_large, - (unsigned) plaintext_max_size, - (unsigned) plaintext_size ); - - /* Move the plaintext to the leftmost position where it can start in - * the working buffer, i.e. make it start plaintext_max_size from - * the end of the buffer. Do this with a memory access trace that - * does not depend on the plaintext size. After this move, the - * starting location of the plaintext is no longer sensitive - * information. */ - mem_move_to_left( buf + ilen - plaintext_max_size, - plaintext_max_size, - plaintext_max_size - plaintext_size ); - - /* Finally copy the decrypted plaintext plus trailing zeros - * into the output buffer. */ - memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size ); - - /* Report the amount of data we copied to the output buffer. In case - * of errors (bad padding or output too large), the value of *olen - * when this function returns is not specified. Making it equivalent - * to the good case limits the risks of leaking the padding validity. */ - *olen = plaintext_size; - -cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Do an RSA operation, then remove the message padding - */ -int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len) -{ - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); - RSA_VALIDATE_RET( input != NULL ); - RSA_VALIDATE_RET( olen != NULL ); - - switch( ctx->padding ) - { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen, - input, output, output_max_len ); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0, - olen, input, output, - output_max_len ); -#endif - - default: - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - } -} - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function - */ -int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ) -{ - size_t olen; - unsigned char *p = sig; - unsigned char salt[MBEDTLS_MD_MAX_SIZE]; - size_t slen, min_slen, hlen, offset = 0; - int ret; - size_t msb; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - RSA_VALIDATE_RET( sig != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( f_rng == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - olen = ctx->len; - - if( md_alg != MBEDTLS_MD_NONE ) - { - /* Gather length of hash to sign */ - md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hashlen = mbedtls_md_get_size( md_info ); - } - - md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hlen = mbedtls_md_get_size( md_info ); - - /* Calculate the largest possible salt length. Normally this is the hash - * length, which is the maximum length the salt can have. If there is not - * enough room, use the maximum salt length that fits. The constraint is - * that the hash length plus the salt length plus 2 bytes must be at most - * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017 - * (PKCS#1 v2.2) §9.1.1 step 3. */ - min_slen = hlen - 2; - if( olen < hlen + min_slen + 2 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - else if( olen >= hlen + hlen + 2 ) - slen = hlen; - else - slen = olen - hlen - 2; - - memset( sig, 0, olen ); - - /* Generate salt of length slen */ - if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) - return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); - - /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ - msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; - p += olen - hlen - slen - 2; - *p++ = 0x01; - memcpy( p, salt, slen ); - p += slen; - - mbedtls_md_init( &md_ctx ); - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - goto exit; - - /* Generate H = Hash( M' ) */ - if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( &md_ctx, p, 8 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md_finish( &md_ctx, p ) ) != 0 ) - goto exit; - - /* Compensate for boundary condition when applying mask */ - if( msb % 8 == 0 ) - offset = 1; - - /* maskedDB: Apply dbMask to DB */ - if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, - &md_ctx ) ) != 0 ) - goto exit; - - msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; - sig[0] &= 0xFF >> ( olen * 8 - msb ); - - p += hlen; - *p++ = 0xBC; - - mbedtls_platform_zeroize( salt, sizeof( salt ) ); - -exit: - mbedtls_md_free( &md_ctx ); - - if( ret != 0 ) - return( ret ); - - return( ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, sig, sig ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) ); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function - */ - -/* Construct a PKCS v1.5 encoding of a hashed message - * - * This is used both for signature generation and verification. - * - * Parameters: - * - md_alg: Identifies the hash algorithm used to generate the given hash; - * MBEDTLS_MD_NONE if raw data is signed. - * - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE. - * - hash: Buffer containing the hashed message or the raw data. - * - dst_len: Length of the encoded message. - * - dst: Buffer to hold the encoded message. - * - * Assumptions: - * - hash has size hashlen if md_alg == MBEDTLS_MD_NONE. - * - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE. - * - dst points to a buffer of size at least dst_len. - * - */ -static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - size_t dst_len, - unsigned char *dst ) -{ - size_t oid_size = 0; - size_t nb_pad = dst_len; - unsigned char *p = dst; - const char *oid = NULL; - - /* Are we signing hashed or raw data? */ - if( md_alg != MBEDTLS_MD_NONE ) - { - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hashlen = mbedtls_md_get_size( md_info ); - - /* Double-check that 8 + hashlen + oid_size can be used as a - * 1-byte ASN.1 length encoding and that there's no overflow. */ - if( 8 + hashlen + oid_size >= 0x80 || - 10 + hashlen < hashlen || - 10 + hashlen + oid_size < 10 + hashlen ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * Static bounds check: - * - Need 10 bytes for five tag-length pairs. - * (Insist on 1-byte length encodings to protect against variants of - * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification) - * - Need hashlen bytes for hash - * - Need oid_size bytes for hash alg OID. - */ - if( nb_pad < 10 + hashlen + oid_size ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - nb_pad -= 10 + hashlen + oid_size; - } - else - { - if( nb_pad < hashlen ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - nb_pad -= hashlen; - } - - /* Need space for signature header and padding delimiter (3 bytes), - * and 8 bytes for the minimal padding */ - if( nb_pad < 3 + 8 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - nb_pad -= 3; - - /* Now nb_pad is the amount of memory to be filled - * with padding, and at least 8 bytes long. */ - - /* Write signature header and padding */ - *p++ = 0; - *p++ = MBEDTLS_RSA_SIGN; - memset( p, 0xFF, nb_pad ); - p += nb_pad; - *p++ = 0; - - /* Are we signing raw data? */ - if( md_alg == MBEDTLS_MD_NONE ) - { - memcpy( p, hash, hashlen ); - return( 0 ); - } - - /* Signing hashed data, add corresponding ASN.1 structure - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm DigestAlgorithmIdentifier, - * digest Digest } - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * Digest ::= OCTET STRING - * - * Schematic: - * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ] - * TAG-NULL + LEN [ NULL ] ] - * TAG-OCTET + LEN [ HASH ] ] - */ - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char)( 0x08 + oid_size + hashlen ); - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char)( 0x04 + oid_size ); - *p++ = MBEDTLS_ASN1_OID; - *p++ = (unsigned char) oid_size; - memcpy( p, oid, oid_size ); - p += oid_size; - *p++ = MBEDTLS_ASN1_NULL; - *p++ = 0x00; - *p++ = MBEDTLS_ASN1_OCTET_STRING; - *p++ = (unsigned char) hashlen; - memcpy( p, hash, hashlen ); - p += hashlen; - - /* Just a sanity-check, should be automatic - * after the initial bounds check. */ - if( p != dst + dst_len ) - { - mbedtls_platform_zeroize( dst, dst_len ); - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - return( 0 ); -} - -/* - * Do an RSA operation to sign the message digest - */ -int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ) -{ - int ret; - unsigned char *sig_try = NULL, *verif = NULL; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - RSA_VALIDATE_RET( sig != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * Prepare PKCS1-v1.5 encoding (padding and hash identifier) - */ - - if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, - ctx->len, sig ) ) != 0 ) - return( ret ); - - /* - * Call respective RSA primitive - */ - - if( mode == MBEDTLS_RSA_PUBLIC ) - { - /* Skip verification on a public key operation */ - return( mbedtls_rsa_public( ctx, sig, sig ) ); - } - - /* Private key operation - * - * In order to prevent Lenstra's attack, make the signature in a - * temporary buffer and check it before returning it. - */ - - sig_try = mbedtls_calloc( 1, ctx->len ); - if( sig_try == NULL ) - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - - verif = mbedtls_calloc( 1, ctx->len ); - if( verif == NULL ) - { - mbedtls_free( sig_try ); - return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); - } - - MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) ); - - if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED; - goto cleanup; - } - - memcpy( sig, sig_try, ctx->len ); - -cleanup: - mbedtls_free( sig_try ); - mbedtls_free( verif ); - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Do an RSA operation to sign the message digest - */ -int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - RSA_VALIDATE_RET( sig != NULL ); - - switch( ctx->padding ) - { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg, - hashlen, hash, sig ); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg, - hashlen, hash, sig ); -#endif - - default: - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - } -} - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function - */ -int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - mbedtls_md_type_t mgf1_hash_id, - int expected_salt_len, - const unsigned char *sig ) -{ - int ret; - size_t siglen; - unsigned char *p; - unsigned char *hash_start; - unsigned char result[MBEDTLS_MD_MAX_SIZE]; - unsigned char zeros[8]; - unsigned int hlen; - size_t observed_salt_len, msb; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - siglen = ctx->len; - - if( siglen < 16 || siglen > sizeof( buf ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - ret = ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, sig, buf ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf ); - - if( ret != 0 ) - return( ret ); - - p = buf; - - if( buf[siglen - 1] != 0xBC ) - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - - if( md_alg != MBEDTLS_MD_NONE ) - { - /* Gather length of hash to sign */ - md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hashlen = mbedtls_md_get_size( md_info ); - } - - md_info = mbedtls_md_info_from_type( mgf1_hash_id ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hlen = mbedtls_md_get_size( md_info ); - - memset( zeros, 0, 8 ); - - /* - * Note: EMSA-PSS verification is over the length of N - 1 bits - */ - msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; - - if( buf[0] >> ( 8 - siglen * 8 + msb ) ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* Compensate for boundary condition when applying mask */ - if( msb % 8 == 0 ) - { - p++; - siglen -= 1; - } - - if( siglen < hlen + 2 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - hash_start = p + siglen - hlen - 1; - - mbedtls_md_init( &md_ctx ); - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) - goto exit; - - ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx ); - if( ret != 0 ) - goto exit; - - buf[0] &= 0xFF >> ( siglen * 8 - msb ); - - while( p < hash_start - 1 && *p == 0 ) - p++; - - if( *p++ != 0x01 ) - { - ret = MBEDTLS_ERR_RSA_INVALID_PADDING; - goto exit; - } - - observed_salt_len = hash_start - p; - - if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY && - observed_salt_len != (size_t) expected_salt_len ) - { - ret = MBEDTLS_ERR_RSA_INVALID_PADDING; - goto exit; - } - - /* - * Generate H = Hash( M' ) - */ - ret = mbedtls_md_starts( &md_ctx ); - if ( ret != 0 ) - goto exit; - ret = mbedtls_md_update( &md_ctx, zeros, 8 ); - if ( ret != 0 ) - goto exit; - ret = mbedtls_md_update( &md_ctx, hash, hashlen ); - if ( ret != 0 ) - goto exit; - ret = mbedtls_md_update( &md_ctx, p, observed_salt_len ); - if ( ret != 0 ) - goto exit; - ret = mbedtls_md_finish( &md_ctx, result ); - if ( ret != 0 ) - goto exit; - - if( memcmp( hash_start, result, hlen ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; - goto exit; - } - -exit: - mbedtls_md_free( &md_ctx ); - - return( ret ); -} - -/* - * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function - */ -int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ) -{ - mbedtls_md_type_t mgf1_hash_id; - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE ) - ? (mbedtls_md_type_t) ctx->hash_id - : md_alg; - - return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode, - md_alg, hashlen, hash, - mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY, - sig ) ); - -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function - */ -int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ) -{ - int ret = 0; - size_t sig_len; - unsigned char *encoded = NULL, *encoded_expected = NULL; - - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - sig_len = ctx->len; - - if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* - * Prepare expected PKCS1 v1.5 encoding of hash. - */ - - if( ( encoded = mbedtls_calloc( 1, sig_len ) ) == NULL || - ( encoded_expected = mbedtls_calloc( 1, sig_len ) ) == NULL ) - { - ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; - goto cleanup; - } - - if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len, - encoded_expected ) ) != 0 ) - goto cleanup; - - /* - * Apply RSA primitive to get what should be PKCS1 encoded hash. - */ - - ret = ( mode == MBEDTLS_RSA_PUBLIC ) - ? mbedtls_rsa_public( ctx, sig, encoded ) - : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, encoded ); - if( ret != 0 ) - goto cleanup; - - /* - * Compare - */ - - if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected, - sig_len ) ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; - goto cleanup; - } - -cleanup: - - if( encoded != NULL ) - { - mbedtls_platform_zeroize( encoded, sig_len ); - mbedtls_free( encoded ); - } - - if( encoded_expected != NULL ) - { - mbedtls_platform_zeroize( encoded_expected, sig_len ); - mbedtls_free( encoded_expected ); - } - - return( ret ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Do an RSA operation and check the message digest - */ -int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ) -{ - RSA_VALIDATE_RET( ctx != NULL ); - RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || - mode == MBEDTLS_RSA_PUBLIC ); - RSA_VALIDATE_RET( sig != NULL ); - RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && - hashlen == 0 ) || - hash != NULL ); - - switch( ctx->padding ) - { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg, - hashlen, hash, sig ); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg, - hashlen, hash, sig ); -#endif - - default: - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); - } -} - -/* - * Copy the components of an RSA key - */ -int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ) -{ - int ret; - RSA_VALIDATE_RET( dst != NULL ); - RSA_VALIDATE_RET( src != NULL ); - - dst->len = src->len; - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) ); -#endif - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) ); - - dst->padding = src->padding; - dst->hash_id = src->hash_id; - -cleanup: - if( ret != 0 ) - mbedtls_rsa_free( dst ); - - return( ret ); -} - -/* - * Free the components of an RSA key - */ -void mbedtls_rsa_free( mbedtls_rsa_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_mpi_free( &ctx->Vi ); - mbedtls_mpi_free( &ctx->Vf ); - mbedtls_mpi_free( &ctx->RN ); - mbedtls_mpi_free( &ctx->D ); - mbedtls_mpi_free( &ctx->Q ); - mbedtls_mpi_free( &ctx->P ); - mbedtls_mpi_free( &ctx->E ); - mbedtls_mpi_free( &ctx->N ); - -#if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free( &ctx->RQ ); - mbedtls_mpi_free( &ctx->RP ); - mbedtls_mpi_free( &ctx->QP ); - mbedtls_mpi_free( &ctx->DQ ); - mbedtls_mpi_free( &ctx->DP ); -#endif /* MBEDTLS_RSA_NO_CRT */ - -#if defined(MBEDTLS_THREADING_C) - /* Free the mutex, but only if it hasn't been freed already. */ - if( ctx->ver != 0 ) - { - mbedtls_mutex_free( &ctx->mutex ); - ctx->ver = 0; - } -#endif -} - -#endif /* !MBEDTLS_RSA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -#include "mbedtls/sha1.h" - -/* - * Example RSA-1024 keypair, for test purposes - */ -#define KEY_LEN 128 - -#define RSA_N "9292758453063D803DD603D5E777D788" \ - "8ED1D5BF35786190FA2F23EBC0848AEA" \ - "DDA92CA6C3D80B32C4D109BE0F36D6AE" \ - "7130B9CED7ACDF54CFC7555AC14EEBAB" \ - "93A89813FBF3C4F8066D2D800F7C38A8" \ - "1AE31942917403FF4946B0A83D3D3E05" \ - "EE57C6F5F5606FB5D4BC6CD34EE0801A" \ - "5E94BB77B07507233A0BC7BAC8F90F79" - -#define RSA_E "10001" - -#define RSA_D "24BF6185468786FDD303083D25E64EFC" \ - "66CA472BC44D253102F8B4A9D3BFA750" \ - "91386C0077937FE33FA3252D28855837" \ - "AE1B484A8A9A45F7EE8C0C634F99E8CD" \ - "DF79C5CE07EE72C7F123142198164234" \ - "CABB724CF78B8173B9F880FC86322407" \ - "AF1FEDFDDE2BEB674CA15F3E81A1521E" \ - "071513A1E85B5DFA031F21ECAE91A34D" - -#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \ - "2C01CAD19EA484A87EA4377637E75500" \ - "FCB2005C5C7DD6EC4AC023CDA285D796" \ - "C3D9E75E1EFC42488BB4F1D13AC30A57" - -#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \ - "E211C2B9E5DB1ED0BF61D0D9899620F4" \ - "910E4168387E3C30AA1E00C339A79508" \ - "8452DD96A9A5EA5D9DCA68DA636032AF" - -#define PT_LEN 24 -#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ - "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" - -#if defined(MBEDTLS_PKCS1_V15) -static int myrand( void *rng_state, unsigned char *output, size_t len ) -{ -#if !defined(__OpenBSD__) && !defined(__NetBSD__) - size_t i; - - if( rng_state != NULL ) - rng_state = NULL; - - for( i = 0; i < len; ++i ) - output[i] = rand(); -#else - if( rng_state != NULL ) - rng_state = NULL; - - arc4random_buf( output, len ); -#endif /* !OpenBSD && !NetBSD */ - - return( 0 ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Checkup routine - */ -int mbedtls_rsa_self_test( int verbose ) -{ - int ret = 0; -#if defined(MBEDTLS_PKCS1_V15) - size_t len; - mbedtls_rsa_context rsa; - unsigned char rsa_plaintext[PT_LEN]; - unsigned char rsa_decrypted[PT_LEN]; - unsigned char rsa_ciphertext[KEY_LEN]; -#if defined(MBEDTLS_SHA1_C) - unsigned char sha1sum[20]; -#endif - - mbedtls_mpi K; - - mbedtls_mpi_init( &K ); - mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) ); - MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) ); - - MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) ); - - if( verbose != 0 ) - mbedtls_printf( " RSA key validation: " ); - - if( mbedtls_rsa_check_pubkey( &rsa ) != 0 || - mbedtls_rsa_check_privkey( &rsa ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n PKCS#1 encryption : " ); - - memcpy( rsa_plaintext, RSA_PT, PT_LEN ); - - if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC, - PT_LEN, rsa_plaintext, - rsa_ciphertext ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n PKCS#1 decryption : " ); - - if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, - &len, rsa_ciphertext, rsa_decrypted, - sizeof(rsa_decrypted) ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -#if defined(MBEDTLS_SHA1_C) - if( verbose != 0 ) - mbedtls_printf( " PKCS#1 data sign : " ); - - if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL, - MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0, - sha1sum, rsa_ciphertext ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n PKCS#1 sig. verify: " ); - - if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, - MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0, - sha1sum, rsa_ciphertext ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); -#endif /* MBEDTLS_SHA1_C */ - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -cleanup: - mbedtls_mpi_free( &K ); - mbedtls_rsa_free( &rsa ); -#else /* MBEDTLS_PKCS1_V15 */ - ((void) verbose); -#endif /* MBEDTLS_PKCS1_V15 */ - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_RSA_C */ diff --git a/mbedtls/rsa.h b/mbedtls/rsa.h deleted file mode 100644 index 9416758d0..000000000 --- a/mbedtls/rsa.h +++ /dev/null @@ -1,1304 +0,0 @@ -#pragma GCC system_header -/** - * \file rsa.h - * - * \brief This file provides an API for the RSA public-key cryptosystem. - * - * The RSA public-key cryptosystem is defined in Public-Key - * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption - * and Public-Key Cryptography Standards (PKCS) #1 v2.1: - * RSA Cryptography Specifications. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_RSA_H -#define MBEDTLS_RSA_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "bignum.h" -#include "md.h" - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -/* - * RSA Error codes - */ -#define MBEDTLS_ERR_RSA_BAD_INPUT_DATA -0x4080 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_RSA_INVALID_PADDING -0x4100 /**< Input data contains invalid padding and is rejected. */ -#define MBEDTLS_ERR_RSA_KEY_GEN_FAILED -0x4180 /**< Something failed during generation of a key. */ -#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED -0x4200 /**< Key failed to pass the validity check of the library. */ -#define MBEDTLS_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */ -#define MBEDTLS_ERR_RSA_PRIVATE_FAILED -0x4300 /**< The private key operation failed. */ -#define MBEDTLS_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */ -#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */ -#define MBEDTLS_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */ - -/* MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION is deprecated and should not be used. - */ -#define MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION -0x4500 /**< The implementation does not offer the requested operation, for example, because of security violations or lack of functionality. */ - -/* MBEDTLS_ERR_RSA_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_RSA_HW_ACCEL_FAILED -0x4580 /**< RSA hardware accelerator failed. */ - -/* - * RSA constants - */ -#define MBEDTLS_RSA_PUBLIC 0 /**< Request private key operation. */ -#define MBEDTLS_RSA_PRIVATE 1 /**< Request public key operation. */ - -#define MBEDTLS_RSA_PKCS_V15 0 /**< Use PKCS#1 v1.5 encoding. */ -#define MBEDTLS_RSA_PKCS_V21 1 /**< Use PKCS#1 v2.1 encoding. */ - -#define MBEDTLS_RSA_SIGN 1 /**< Identifier for RSA signature operations. */ -#define MBEDTLS_RSA_CRYPT 2 /**< Identifier for RSA encryption and decryption operations. */ - -#define MBEDTLS_RSA_SALT_LEN_ANY -1 - -/* - * The above constants may be used even if the RSA module is compile out, - * eg for alternative (PKCS#11) RSA implemenations in the PK layers. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_RSA_ALT) -// Regular implementation -// - -/** - * \brief The RSA context structure. - * - * \note Direct manipulation of the members of this structure - * is deprecated. All manipulation should instead be done through - * the public interface functions. - */ -typedef struct mbedtls_rsa_context -{ - int ver; /*!< Reserved for internal purposes. - * Do not set this field in application - * code. Its meaning might change without - * notice. */ - size_t len; /*!< The size of \p N in Bytes. */ - - mbedtls_mpi N; /*!< The public modulus. */ - mbedtls_mpi E; /*!< The public exponent. */ - - mbedtls_mpi D; /*!< The private exponent. */ - mbedtls_mpi P; /*!< The first prime factor. */ - mbedtls_mpi Q; /*!< The second prime factor. */ - - mbedtls_mpi DP; /*!< D % (P - 1). */ - mbedtls_mpi DQ; /*!< D % (Q - 1). */ - mbedtls_mpi QP; /*!< 1 / (Q % P). */ - - mbedtls_mpi RN; /*!< cached R^2 mod N. */ - - mbedtls_mpi RP; /*!< cached R^2 mod P. */ - mbedtls_mpi RQ; /*!< cached R^2 mod Q. */ - - mbedtls_mpi Vi; /*!< The cached blinding value. */ - mbedtls_mpi Vf; /*!< The cached un-blinding value. */ - - int padding; /*!< Selects padding mode: - #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and - #MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */ - int hash_id; /*!< Hash identifier of mbedtls_md_type_t type, - as specified in md.h for use in the MGF - mask generating function used in the - EME-OAEP and EMSA-PSS encodings. */ -#if defined(MBEDTLS_THREADING_C) - /* Invariant: the mutex is initialized iff ver != 0. */ - mbedtls_threading_mutex_t mutex; /*!< Thread-safety mutex. */ -#endif -} -mbedtls_rsa_context; - -#else /* MBEDTLS_RSA_ALT */ -#include "rsa_alt.h" -#endif /* MBEDTLS_RSA_ALT */ - -/** - * \brief This function initializes an RSA context. - * - * \note Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP - * encryption scheme and the RSASSA-PSS signature scheme. - * - * \note The \p hash_id parameter is ignored when using - * #MBEDTLS_RSA_PKCS_V15 padding. - * - * \note The choice of padding mode is strictly enforced for private key - * operations, since there might be security concerns in - * mixing padding modes. For public key operations it is - * a default value, which can be overridden by calling specific - * \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions. - * - * \note The hash selected in \p hash_id is always used for OEAP - * encryption. For PSS signatures, it is always used for - * making signatures, but can be overridden for verifying them. - * If set to #MBEDTLS_MD_NONE, it is always overridden. - * - * \param ctx The RSA context to initialize. This must not be \c NULL. - * \param padding The padding mode to use. This must be either - * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. - * \param hash_id The hash identifier of ::mbedtls_md_type_t type, if - * \p padding is #MBEDTLS_RSA_PKCS_V21. It is unused - * otherwise. - */ -void mbedtls_rsa_init( mbedtls_rsa_context *ctx, - int padding, - int hash_id ); - -/** - * \brief This function imports a set of core parameters into an - * RSA context. - * - * \note This function can be called multiple times for successive - * imports, if the parameters are not simultaneously present. - * - * Any sequence of calls to this function should be followed - * by a call to mbedtls_rsa_complete(), which checks and - * completes the provided information to a ready-for-use - * public or private RSA key. - * - * \note See mbedtls_rsa_complete() for more information on which - * parameters are necessary to set up a private or public - * RSA key. - * - * \note The imported parameters are copied and need not be preserved - * for the lifetime of the RSA context being set up. - * - * \param ctx The initialized RSA context to store the parameters in. - * \param N The RSA modulus. This may be \c NULL. - * \param P The first prime factor of \p N. This may be \c NULL. - * \param Q The second prime factor of \p N. This may be \c NULL. - * \param D The private exponent. This may be \c NULL. - * \param E The public exponent. This may be \c NULL. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_rsa_import( mbedtls_rsa_context *ctx, - const mbedtls_mpi *N, - const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *E ); - -/** - * \brief This function imports core RSA parameters, in raw big-endian - * binary format, into an RSA context. - * - * \note This function can be called multiple times for successive - * imports, if the parameters are not simultaneously present. - * - * Any sequence of calls to this function should be followed - * by a call to mbedtls_rsa_complete(), which checks and - * completes the provided information to a ready-for-use - * public or private RSA key. - * - * \note See mbedtls_rsa_complete() for more information on which - * parameters are necessary to set up a private or public - * RSA key. - * - * \note The imported parameters are copied and need not be preserved - * for the lifetime of the RSA context being set up. - * - * \param ctx The initialized RSA context to store the parameters in. - * \param N The RSA modulus. This may be \c NULL. - * \param N_len The Byte length of \p N; it is ignored if \p N == NULL. - * \param P The first prime factor of \p N. This may be \c NULL. - * \param P_len The Byte length of \p P; it ns ignored if \p P == NULL. - * \param Q The second prime factor of \p N. This may be \c NULL. - * \param Q_len The Byte length of \p Q; it is ignored if \p Q == NULL. - * \param D The private exponent. This may be \c NULL. - * \param D_len The Byte length of \p D; it is ignored if \p D == NULL. - * \param E The public exponent. This may be \c NULL. - * \param E_len The Byte length of \p E; it is ignored if \p E == NULL. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, - unsigned char const *N, size_t N_len, - unsigned char const *P, size_t P_len, - unsigned char const *Q, size_t Q_len, - unsigned char const *D, size_t D_len, - unsigned char const *E, size_t E_len ); - -/** - * \brief This function completes an RSA context from - * a set of imported core parameters. - * - * To setup an RSA public key, precisely \p N and \p E - * must have been imported. - * - * To setup an RSA private key, sufficient information must - * be present for the other parameters to be derivable. - * - * The default implementation supports the following: - *
    • Derive \p P, \p Q from \p N, \p D, \p E.
    • - *
    • Derive \p N, \p D from \p P, \p Q, \p E.
    - * Alternative implementations need not support these. - * - * If this function runs successfully, it guarantees that - * the RSA context can be used for RSA operations without - * the risk of failure or crash. - * - * \warning This function need not perform consistency checks - * for the imported parameters. In particular, parameters that - * are not needed by the implementation might be silently - * discarded and left unchecked. To check the consistency - * of the key material, see mbedtls_rsa_check_privkey(). - * - * \param ctx The initialized RSA context holding imported parameters. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations - * failed. - * - */ -int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ); - -/** - * \brief This function exports the core parameters of an RSA key. - * - * If this function runs successfully, the non-NULL buffers - * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully - * written, with additional unused space filled leading by - * zero Bytes. - * - * Possible reasons for returning - * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
      - *
    • An alternative RSA implementation is in use, which - * stores the key externally, and either cannot or should - * not export it into RAM.
    • - *
    • A SW or HW implementation might not support a certain - * deduction. For example, \p P, \p Q from \p N, \p D, - * and \p E if the former are not part of the - * implementation.
    - * - * If the function fails due to an unsupported operation, - * the RSA context stays intact and remains usable. - * - * \param ctx The initialized RSA context. - * \param N The MPI to hold the RSA modulus. - * This may be \c NULL if this field need not be exported. - * \param P The MPI to hold the first prime factor of \p N. - * This may be \c NULL if this field need not be exported. - * \param Q The MPI to hold the second prime factor of \p N. - * This may be \c NULL if this field need not be exported. - * \param D The MPI to hold the private exponent. - * This may be \c NULL if this field need not be exported. - * \param E The MPI to hold the public exponent. - * This may be \c NULL if this field need not be exported. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the - * requested parameters cannot be done due to missing - * functionality or because of security policies. - * \return A non-zero return code on any other failure. - * - */ -int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, - mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, - mbedtls_mpi *D, mbedtls_mpi *E ); - -/** - * \brief This function exports core parameters of an RSA key - * in raw big-endian binary format. - * - * If this function runs successfully, the non-NULL buffers - * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully - * written, with additional unused space filled leading by - * zero Bytes. - * - * Possible reasons for returning - * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
      - *
    • An alternative RSA implementation is in use, which - * stores the key externally, and either cannot or should - * not export it into RAM.
    • - *
    • A SW or HW implementation might not support a certain - * deduction. For example, \p P, \p Q from \p N, \p D, - * and \p E if the former are not part of the - * implementation.
    - * If the function fails due to an unsupported operation, - * the RSA context stays intact and remains usable. - * - * \note The length parameters are ignored if the corresponding - * buffer pointers are NULL. - * - * \param ctx The initialized RSA context. - * \param N The Byte array to store the RSA modulus, - * or \c NULL if this field need not be exported. - * \param N_len The size of the buffer for the modulus. - * \param P The Byte array to hold the first prime factor of \p N, - * or \c NULL if this field need not be exported. - * \param P_len The size of the buffer for the first prime factor. - * \param Q The Byte array to hold the second prime factor of \p N, - * or \c NULL if this field need not be exported. - * \param Q_len The size of the buffer for the second prime factor. - * \param D The Byte array to hold the private exponent, - * or \c NULL if this field need not be exported. - * \param D_len The size of the buffer for the private exponent. - * \param E The Byte array to hold the public exponent, - * or \c NULL if this field need not be exported. - * \param E_len The size of the buffer for the public exponent. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the - * requested parameters cannot be done due to missing - * functionality or because of security policies. - * \return A non-zero return code on any other failure. - */ -int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, - unsigned char *N, size_t N_len, - unsigned char *P, size_t P_len, - unsigned char *Q, size_t Q_len, - unsigned char *D, size_t D_len, - unsigned char *E, size_t E_len ); - -/** - * \brief This function exports CRT parameters of a private RSA key. - * - * \note Alternative RSA implementations not using CRT-parameters - * internally can implement this function based on - * mbedtls_rsa_deduce_opt(). - * - * \param ctx The initialized RSA context. - * \param DP The MPI to hold \c D modulo `P-1`, - * or \c NULL if it need not be exported. - * \param DQ The MPI to hold \c D modulo `Q-1`, - * or \c NULL if it need not be exported. - * \param QP The MPI to hold modular inverse of \c Q modulo \c P, - * or \c NULL if it need not be exported. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - * - */ -int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, - mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ); - -/** - * \brief This function sets padding for an already initialized RSA - * context. See mbedtls_rsa_init() for details. - * - * \param ctx The initialized RSA context to be configured. - * \param padding The padding mode to use. This must be either - * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. - * \param hash_id The #MBEDTLS_RSA_PKCS_V21 hash identifier. - */ -void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, - int hash_id ); - -/** - * \brief This function retrieves the length of RSA modulus in Bytes. - * - * \param ctx The initialized RSA context. - * - * \return The length of the RSA modulus in Bytes. - * - */ -size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ); - -/** - * \brief This function generates an RSA keypair. - * - * \note mbedtls_rsa_init() must be called before this function, - * to set up the RSA context. - * - * \param ctx The initialized RSA context used to hold the key. - * \param f_rng The RNG function to be used for key generation. - * This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't need a context. - * \param nbits The size of the public key in bits. - * \param exponent The public exponent to use. For example, \c 65537. - * This must be odd and greater than \c 1. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - unsigned int nbits, int exponent ); - -/** - * \brief This function checks if a context contains at least an RSA - * public key. - * - * If the function runs successfully, it is guaranteed that - * enough information is present to perform an RSA public key - * operation using mbedtls_rsa_public(). - * - * \param ctx The initialized RSA context to check. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - * - */ -int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ); - -/** - * \brief This function checks if a context contains an RSA private key - * and perform basic consistency checks. - * - * \note The consistency checks performed by this function not only - * ensure that mbedtls_rsa_private() can be called successfully - * on the given context, but that the various parameters are - * mutually consistent with high probability, in the sense that - * mbedtls_rsa_public() and mbedtls_rsa_private() are inverses. - * - * \warning This function should catch accidental misconfigurations - * like swapping of parameters, but it cannot establish full - * trust in neither the quality nor the consistency of the key - * material that was used to setup the given RSA context: - *
    • Consistency: Imported parameters that are irrelevant - * for the implementation might be silently dropped. If dropped, - * the current function does not have access to them, - * and therefore cannot check them. See mbedtls_rsa_complete(). - * If you want to check the consistency of the entire - * content of an PKCS1-encoded RSA private key, for example, you - * should use mbedtls_rsa_validate_params() before setting - * up the RSA context. - * Additionally, if the implementation performs empirical checks, - * these checks substantiate but do not guarantee consistency.
    • - *
    • Quality: This function is not expected to perform - * extended quality assessments like checking that the prime - * factors are safe. Additionally, it is the responsibility of the - * user to ensure the trustworthiness of the source of his RSA - * parameters, which goes beyond what is effectively checkable - * by the library.
    - * - * \param ctx The initialized RSA context to check. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ); - -/** - * \brief This function checks a public-private RSA key pair. - * - * It checks each of the contexts, and makes sure they match. - * - * \param pub The initialized RSA context holding the public key. - * \param prv The initialized RSA context holding the private key. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, - const mbedtls_rsa_context *prv ); - -/** - * \brief This function performs an RSA public key operation. - * - * \param ctx The initialized RSA context to use. - * \param input The input buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \note This function does not handle message padding. - * - * \note Make sure to set \p input[0] = 0 or ensure that - * input is smaller than \p N. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_public( mbedtls_rsa_context *ctx, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function performs an RSA private key operation. - * - * \note Blinding is used if and only if a PRNG is provided. - * - * \note If blinding is used, both the base of exponentation - * and the exponent are blinded, providing protection - * against some side-channel attacks. - * - * \warning It is deprecated and a security risk to not provide - * a PRNG here and thereby prevent the use of blinding. - * Future versions of the library may enforce the presence - * of a PRNG. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function, used for blinding. It is discouraged - * and deprecated to pass \c NULL here, in which case - * blinding will be omitted. - * \param p_rng The RNG context to pass to \p f_rng. This may be \c NULL - * if \p f_rng is \c NULL or if \p f_rng doesn't need a context. - * \param input The input buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - * - */ -int mbedtls_rsa_private( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function adds the message padding, then performs an RSA - * operation. - * - * It is the generic wrapper for performing a PKCS#1 encryption - * operation using the \p mode from the context. - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PUBLIC. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG to use. It is mandatory for PKCS#1 v2.1 padding - * encoding, and for PKCS#1 v1.5 padding encoding when used - * with \p mode set to #MBEDTLS_RSA_PUBLIC. For PKCS#1 v1.5 - * padding encoding and \p mode set to #MBEDTLS_RSA_PRIVATE, - * it is used for blinding and should be provided in this - * case; see mbedtls_rsa_private() for more. - * \param p_rng The RNG context to be passed to \p f_rng. May be - * \c NULL if \p f_rng is \c NULL or if \p f_rng doesn't - * need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param ilen The length of the plaintext in Bytes. - * \param input The input data to encrypt. This must be a readable - * buffer of size \p ilen Bytes. This must not be \c NULL. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t ilen, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function performs a PKCS#1 v1.5 encryption operation - * (RSAES-PKCS1-v1_5-ENCRYPT). - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PUBLIC. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function to use. It is needed for padding generation - * if \p mode is #MBEDTLS_RSA_PUBLIC. If \p mode is - * #MBEDTLS_RSA_PRIVATE (discouraged), it is used for - * blinding and should be provided; see mbedtls_rsa_private(). - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng is \c NULL or if \p f_rng - * doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param ilen The length of the plaintext in Bytes. - * \param input The input data to encrypt. This must be a readable - * buffer of size \p ilen Bytes. This must not be \c NULL. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t ilen, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function performs a PKCS#1 v2.1 OAEP encryption - * operation (RSAES-OAEP-ENCRYPT). - * - * \note The output buffer must be as large as the size - * of ctx->N. For example, 128 Bytes if RSA-1024 is used. - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PUBLIC. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initnialized RSA context to use. - * \param f_rng The RNG function to use. This is needed for padding - * generation and must be provided. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param label The buffer holding the custom label to use. - * This must be a readable buffer of length \p label_len - * Bytes. It may be \c NULL if \p label_len is \c 0. - * \param label_len The length of the label in Bytes. - * \param ilen The length of the plaintext buffer \p input in Bytes. - * \param input The input data to encrypt. This must be a readable - * buffer of size \p ilen Bytes. This must not be \c NULL. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - const unsigned char *label, size_t label_len, - size_t ilen, - const unsigned char *input, - unsigned char *output ); - -/** - * \brief This function performs an RSA operation, then removes the - * message padding. - * - * It is the generic wrapper for performing a PKCS#1 decryption - * operation using the \p mode from the context. - * - * \note The output buffer length \c output_max_len should be - * as large as the size \p ctx->len of \p ctx->N (for example, - * 128 Bytes if RSA-1024 is used) to be able to hold an - * arbitrary decrypted message. If it is not large enough to - * hold the decryption of the particular ciphertext provided, - * the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PRIVATE. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. If \p mode is - * #MBEDTLS_RSA_PUBLIC, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param olen The address at which to store the length of - * the plaintext. This must not be \c NULL. - * \param input The ciphertext buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The buffer used to hold the plaintext. This must - * be a writable buffer of length \p output_max_len Bytes. - * \param output_max_len The length in Bytes of the output buffer \p output. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ); - -/** - * \brief This function performs a PKCS#1 v1.5 decryption - * operation (RSAES-PKCS1-v1_5-DECRYPT). - * - * \note The output buffer length \c output_max_len should be - * as large as the size \p ctx->len of \p ctx->N, for example, - * 128 Bytes if RSA-1024 is used, to be able to hold an - * arbitrary decrypted message. If it is not large enough to - * hold the decryption of the particular ciphertext provided, - * the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PRIVATE. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. If \p mode is - * #MBEDTLS_RSA_PUBLIC, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param olen The address at which to store the length of - * the plaintext. This must not be \c NULL. - * \param input The ciphertext buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The buffer used to hold the plaintext. This must - * be a writable buffer of length \p output_max_len Bytes. - * \param output_max_len The length in Bytes of the output buffer \p output. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - * - */ -int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ); - -/** - * \brief This function performs a PKCS#1 v2.1 OAEP decryption - * operation (RSAES-OAEP-DECRYPT). - * - * \note The output buffer length \c output_max_len should be - * as large as the size \p ctx->len of \p ctx->N, for - * example, 128 Bytes if RSA-1024 is used, to be able to - * hold an arbitrary decrypted message. If it is not - * large enough to hold the decryption of the particular - * ciphertext provided, the function returns - * #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PRIVATE. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. If \p mode is - * #MBEDTLS_RSA_PUBLIC, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param label The buffer holding the custom label to use. - * This must be a readable buffer of length \p label_len - * Bytes. It may be \c NULL if \p label_len is \c 0. - * \param label_len The length of the label in Bytes. - * \param olen The address at which to store the length of - * the plaintext. This must not be \c NULL. - * \param input The ciphertext buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The buffer used to hold the plaintext. This must - * be a writable buffer of length \p output_max_len Bytes. - * \param output_max_len The length in Bytes of the output buffer \p output. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - const unsigned char *label, size_t label_len, - size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ); - -/** - * \brief This function performs a private RSA operation to sign - * a message digest using PKCS#1. - * - * It is the generic wrapper for performing a PKCS#1 - * signature using the \p mode from the context. - * - * \note The \p sig buffer must be as large as the size - * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. - * - * \note For PKCS#1 v2.1 encoding, see comments on - * mbedtls_rsa_rsassa_pss_sign() for details on - * \p md_alg and \p hash_id. - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PRIVATE. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function to use. If the padding mode is PKCS#1 v2.1, - * this must be provided. If the padding mode is PKCS#1 v1.5 and - * \p mode is #MBEDTLS_RSA_PRIVATE, it is used for blinding - * and should be provided; see mbedtls_rsa_private() for more - * more. It is ignored otherwise. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng is \c NULL or doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. - * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ); - -/** - * \brief This function performs a PKCS#1 v1.5 signature - * operation (RSASSA-PKCS1-v1_5-SIGN). - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PRIVATE. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. If \p mode is - * #MBEDTLS_RSA_PUBLIC, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng is \c NULL or doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. - * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ); - -/** - * \brief This function performs a PKCS#1 v2.1 PSS signature - * operation (RSASSA-PSS-SIGN). - * - * \note The \p hash_id in the RSA context is the one used for the - * encoding. \p md_alg in the function call is the type of hash - * that is encoded. According to RFC-3447: Public-Key - * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography - * Specifications it is advised to keep both hashes the - * same. - * - * \note This function always uses the maximum possible salt size, - * up to the length of the payload hash. This choice of salt - * size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 - * v2.2) §9.1.1 step 3. Furthermore this function enforces a - * minimum salt size which is the hash size minus 2 bytes. If - * this minimum size is too large given the key size (the salt - * size, plus the hash size, plus 2 bytes must be no more than - * the key size in bytes), this function returns - * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PRIVATE. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PUBLIC and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. It must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context argument. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. - * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ); - -/** - * \brief This function performs a public RSA operation and checks - * the message digest. - * - * This is the generic wrapper for performing a PKCS#1 - * verification using the mode from the context. - * - * \note For PKCS#1 v2.1 encoding, see comments on - * mbedtls_rsa_rsassa_pss_verify() about \p md_alg and - * \p hash_id. - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * set to #MBEDTLS_RSA_PUBLIC. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA public key context to use. - * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. Otherwise, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * This is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ); - -/** - * \brief This function performs a PKCS#1 v1.5 verification - * operation (RSASSA-PKCS1-v1_5-VERIFY). - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * set to #MBEDTLS_RSA_PUBLIC. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA public key context to use. - * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. Otherwise, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * This is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ); - -/** - * \brief This function performs a PKCS#1 v2.1 PSS verification - * operation (RSASSA-PSS-VERIFY). - * - * The hash function for the MGF mask generating function - * is that specified in the RSA context. - * - * \note The \p hash_id in the RSA context is the one used for the - * verification. \p md_alg in the function call is the type of - * hash that is verified. According to RFC-3447: Public-Key - * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography - * Specifications it is advised to keep both hashes the - * same. If \p hash_id in the RSA context is unset, - * the \p md_alg from the function call is used. - * - * \disabled_deprecated It is deprecated and discouraged to call this function - * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library - * are likely to remove the \p mode argument and have it - * implicitly set to #MBEDTLS_RSA_PUBLIC. - * - * \note Alternative implementations of RSA need not support - * mode being set to #MBEDTLS_RSA_PRIVATE and might instead - * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. - * - * \param ctx The initialized RSA public key context to use. - * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. Otherwise, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * This is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig ); - -/** - * \brief This function performs a PKCS#1 v2.1 PSS verification - * operation (RSASSA-PSS-VERIFY). - * - * The hash function for the MGF mask generating function - * is that specified in \p mgf1_hash_id. - * - * \note The \p sig buffer must be as large as the size - * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. - * - * \note The \p hash_id in the RSA context is ignored. - * - * \param ctx The initialized RSA public key context to use. - * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, - * this is used for blinding and should be provided; see - * mbedtls_rsa_private() for more. Otherwise, it is ignored. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a context. - * \param mode The mode of operation. This must be either - * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest. - * This is only used if \p md_alg is #MBEDTLS_MD_NONE. - * \param hash The buffer holding the message digest or raw data. - * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable - * buffer of length \p hashlen Bytes. If \p md_alg is not - * #MBEDTLS_MD_NONE, it must be a readable buffer of length - * the size of the hash corresponding to \p md_alg. - * \param mgf1_hash_id The message digest used for mask generation. - * \param expected_salt_len The length of the salt used in padding. Use - * #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - mbedtls_md_type_t mgf1_hash_id, - int expected_salt_len, - const unsigned char *sig ); - -/** - * \brief This function copies the components of an RSA context. - * - * \param dst The destination context. This must be initialized. - * \param src The source context. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure. - */ -int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ); - -/** - * \brief This function frees the components of an RSA key. - * - * \param ctx The RSA context to free. May be \c NULL, in which case - * this function is a no-op. If it is not \c NULL, it must - * point to an initialized RSA context. - */ -void mbedtls_rsa_free( mbedtls_rsa_context *ctx ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The RSA checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_rsa_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* rsa.h */ diff --git a/mbedtls/rsa_internal.c b/mbedtls/rsa_internal.c deleted file mode 100644 index a0f8854b3..000000000 --- a/mbedtls/rsa_internal.c +++ /dev/null @@ -1,530 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Helper functions for the RSA module - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - * - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_RSA_C) - -#include "mbedtls/rsa.h" -#include "mbedtls/bignum.h" -#include "mbedtls/rsa_internal.h" - -/* - * Compute RSA prime factors from public and private exponents - * - * Summary of algorithm: - * Setting F := lcm(P-1,Q-1), the idea is as follows: - * - * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2) - * is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the - * square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four - * possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1) - * or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime - * factors of N. - * - * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same - * construction still applies since (-)^K is the identity on the set of - * roots of 1 in Z/NZ. - * - * The public and private key primitives (-)^E and (-)^D are mutually inverse - * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e. - * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L. - * Splitting L = 2^t * K with K odd, we have - * - * DE - 1 = FL = (F/2) * (2^(t+1)) * K, - * - * so (F / 2) * K is among the numbers - * - * (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord - * - * where ord is the order of 2 in (DE - 1). - * We can therefore iterate through these numbers apply the construction - * of (a) and (b) above to attempt to factor N. - * - */ -int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, - mbedtls_mpi const *E, mbedtls_mpi const *D, - mbedtls_mpi *P, mbedtls_mpi *Q ) -{ - int ret = 0; - - uint16_t attempt; /* Number of current attempt */ - uint16_t iter; /* Number of squares computed in the current attempt */ - - uint16_t order; /* Order of 2 in DE - 1 */ - - mbedtls_mpi T; /* Holds largest odd divisor of DE - 1 */ - mbedtls_mpi K; /* Temporary holding the current candidate */ - - const unsigned char primes[] = { 2, - 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, - 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, - 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251 - }; - - const size_t num_primes = sizeof( primes ) / sizeof( *primes ); - - if( P == NULL || Q == NULL || P->p != NULL || Q->p != NULL ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || - mbedtls_mpi_cmp_int( D, 1 ) <= 0 || - mbedtls_mpi_cmp_mpi( D, N ) >= 0 || - mbedtls_mpi_cmp_int( E, 1 ) <= 0 || - mbedtls_mpi_cmp_mpi( E, N ) >= 0 ) - { - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - } - - /* - * Initializations and temporary changes - */ - - mbedtls_mpi_init( &K ); - mbedtls_mpi_init( &T ); - - /* T := DE - 1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, D, E ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &T, &T, 1 ) ); - - if( ( order = (uint16_t) mbedtls_mpi_lsb( &T ) ) == 0 ) - { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - - /* After this operation, T holds the largest odd divisor of DE - 1. */ - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &T, order ) ); - - /* - * Actual work - */ - - /* Skip trying 2 if N == 1 mod 8 */ - attempt = 0; - if( N->p[0] % 8 == 1 ) - attempt = 1; - - for( ; attempt < num_primes; ++attempt ) - { - mbedtls_mpi_lset( &K, primes[attempt] ); - - /* Check if gcd(K,N) = 1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) ); - if( mbedtls_mpi_cmp_int( P, 1 ) != 0 ) - continue; - - /* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ... - * and check whether they have nontrivial GCD with N. */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &K, &K, &T, N, - Q /* temporarily use Q for storing Montgomery - * multiplication helper values */ ) ); - - for( iter = 1; iter <= order; ++iter ) - { - /* If we reach 1 prematurely, there's no point - * in continuing to square K */ - if( mbedtls_mpi_cmp_int( &K, 1 ) == 0 ) - break; - - MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) ); - - if( mbedtls_mpi_cmp_int( P, 1 ) == 1 && - mbedtls_mpi_cmp_mpi( P, N ) == -1 ) - { - /* - * Have found a nontrivial divisor P of N. - * Set Q := N / P. - */ - - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( Q, NULL, N, P ) ); - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &K ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, N ) ); - } - - /* - * If we get here, then either we prematurely aborted the loop because - * we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must - * be 1 if D,E,N were consistent. - * Check if that's the case and abort if not, to avoid very long, - * yet eventually failing, computations if N,D,E were not sane. - */ - if( mbedtls_mpi_cmp_int( &K, 1 ) != 0 ) - { - break; - } - } - - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - -cleanup: - - mbedtls_mpi_free( &K ); - mbedtls_mpi_free( &T ); - return( ret ); -} - -/* - * Given P, Q and the public exponent E, deduce D. - * This is essentially a modular inversion. - */ -int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P, - mbedtls_mpi const *Q, - mbedtls_mpi const *E, - mbedtls_mpi *D ) -{ - int ret = 0; - mbedtls_mpi K, L; - - if( D == NULL || mbedtls_mpi_cmp_int( D, 0 ) != 0 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - - if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 || - mbedtls_mpi_cmp_int( Q, 1 ) <= 0 || - mbedtls_mpi_cmp_int( E, 0 ) == 0 ) - { - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - } - - mbedtls_mpi_init( &K ); - mbedtls_mpi_init( &L ); - - /* Temporarily put K := P-1 and L := Q-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) ); - - /* Temporarily put D := gcd(P-1, Q-1) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( D, &K, &L ) ); - - /* K := LCM(P-1, Q-1) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &L ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &K, NULL, &K, D ) ); - - /* Compute modular inverse of E in LCM(P-1, Q-1) */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( D, E, &K ) ); - -cleanup: - - mbedtls_mpi_free( &K ); - mbedtls_mpi_free( &L ); - - return( ret ); -} - -/* - * Check that RSA CRT parameters are in accordance with core parameters. - */ -int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *DP, - const mbedtls_mpi *DQ, const mbedtls_mpi *QP ) -{ - int ret = 0; - - mbedtls_mpi K, L; - mbedtls_mpi_init( &K ); - mbedtls_mpi_init( &L ); - - /* Check that DP - D == 0 mod P - 1 */ - if( DP != NULL ) - { - if( P == NULL ) - { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DP, D ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) ); - - if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* Check that DQ - D == 0 mod Q - 1 */ - if( DQ != NULL ) - { - if( Q == NULL ) - { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DQ, D ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) ); - - if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* Check that QP * Q - 1 == 0 mod P */ - if( QP != NULL ) - { - if( P == NULL || Q == NULL ) - { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, QP, Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, P ) ); - if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - -cleanup: - - /* Wrap MPI error codes by RSA check failure error code */ - if( ret != 0 && - ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED && - ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA ) - { - ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - mbedtls_mpi_free( &K ); - mbedtls_mpi_free( &L ); - - return( ret ); -} - -/* - * Check that core RSA parameters are sane. - */ -int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P, - const mbedtls_mpi *Q, const mbedtls_mpi *D, - const mbedtls_mpi *E, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret = 0; - mbedtls_mpi K, L; - - mbedtls_mpi_init( &K ); - mbedtls_mpi_init( &L ); - - /* - * Step 1: If PRNG provided, check that P and Q are prime - */ - -#if defined(MBEDTLS_GENPRIME) - /* - * When generating keys, the strongest security we support aims for an error - * rate of at most 2^-100 and we are aiming for the same certainty here as - * well. - */ - if( f_rng != NULL && P != NULL && - ( ret = mbedtls_mpi_is_prime_ext( P, 50, f_rng, p_rng ) ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - - if( f_rng != NULL && Q != NULL && - ( ret = mbedtls_mpi_is_prime_ext( Q, 50, f_rng, p_rng ) ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } -#else - ((void) f_rng); - ((void) p_rng); -#endif /* MBEDTLS_GENPRIME */ - - /* - * Step 2: Check that 1 < N = P * Q - */ - - if( P != NULL && Q != NULL && N != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) ); - if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 || - mbedtls_mpi_cmp_mpi( &K, N ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* - * Step 3: Check and 1 < D, E < N if present. - */ - - if( N != NULL && D != NULL && E != NULL ) - { - if ( mbedtls_mpi_cmp_int( D, 1 ) <= 0 || - mbedtls_mpi_cmp_int( E, 1 ) <= 0 || - mbedtls_mpi_cmp_mpi( D, N ) >= 0 || - mbedtls_mpi_cmp_mpi( E, N ) >= 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* - * Step 4: Check that D, E are inverse modulo P-1 and Q-1 - */ - - if( P != NULL && Q != NULL && D != NULL && E != NULL ) - { - if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 || - mbedtls_mpi_cmp_int( Q, 1 ) <= 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - - /* Compute DE-1 mod P-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) ); - if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - - /* Compute DE-1 mod Q-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) ); - if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) - { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - -cleanup: - - mbedtls_mpi_free( &K ); - mbedtls_mpi_free( &L ); - - /* Wrap MPI error codes by RSA check failure error code */ - if( ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ) - { - ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - return( ret ); -} - -int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, mbedtls_mpi *DP, - mbedtls_mpi *DQ, mbedtls_mpi *QP ) -{ - int ret = 0; - mbedtls_mpi K; - mbedtls_mpi_init( &K ); - - /* DP = D mod P-1 */ - if( DP != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DP, D, &K ) ); - } - - /* DQ = D mod Q-1 */ - if( DQ != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DQ, D, &K ) ); - } - - /* QP = Q^{-1} mod P */ - if( QP != NULL ) - { - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( QP, Q, P ) ); - } - -cleanup: - mbedtls_mpi_free( &K ); - - return( ret ); -} - -#endif /* MBEDTLS_RSA_C */ diff --git a/mbedtls/rsa_internal.h b/mbedtls/rsa_internal.h deleted file mode 100644 index 9bc55a2aa..000000000 --- a/mbedtls/rsa_internal.h +++ /dev/null @@ -1,252 +0,0 @@ -#pragma GCC system_header -/** - * \file rsa_internal.h - * - * \brief Context-independent RSA helper functions - * - * This module declares some RSA-related helper functions useful when - * implementing the RSA interface. These functions are provided in a separate - * compilation unit in order to make it easy for designers of alternative RSA - * implementations to use them in their own code, as it is conceived that the - * functionality they provide will be necessary for most complete - * implementations. - * - * End-users of Mbed TLS who are not providing their own alternative RSA - * implementations should not use these functions directly, and should instead - * use only the functions declared in rsa.h. - * - * The interface provided by this module will be maintained through LTS (Long - * Term Support) branches of Mbed TLS, but may otherwise be subject to change, - * and must be considered an internal interface of the library. - * - * There are two classes of helper functions: - * - * (1) Parameter-generating helpers. These are: - * - mbedtls_rsa_deduce_primes - * - mbedtls_rsa_deduce_private_exponent - * - mbedtls_rsa_deduce_crt - * Each of these functions takes a set of core RSA parameters and - * generates some other, or CRT related parameters. - * - * (2) Parameter-checking helpers. These are: - * - mbedtls_rsa_validate_params - * - mbedtls_rsa_validate_crt - * They take a set of core or CRT related RSA parameters and check their - * validity. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - * - */ - -#ifndef MBEDTLS_RSA_INTERNAL_H -#define MBEDTLS_RSA_INTERNAL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "bignum.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * \brief Compute RSA prime moduli P, Q from public modulus N=PQ - * and a pair of private and public key. - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param N RSA modulus N = PQ, with P, Q to be found - * \param E RSA public exponent - * \param D RSA private exponent - * \param P Pointer to MPI holding first prime factor of N on success - * \param Q Pointer to MPI holding second prime factor of N on success - * - * \return - * - 0 if successful. In this case, P and Q constitute a - * factorization of N. - * - A non-zero error code otherwise. - * - * \note It is neither checked that P, Q are prime nor that - * D, E are modular inverses wrt. P-1 and Q-1. For that, - * use the helper function \c mbedtls_rsa_validate_params. - * - */ -int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, mbedtls_mpi const *E, - mbedtls_mpi const *D, - mbedtls_mpi *P, mbedtls_mpi *Q ); - -/** - * \brief Compute RSA private exponent from - * prime moduli and public key. - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param P First prime factor of RSA modulus - * \param Q Second prime factor of RSA modulus - * \param E RSA public exponent - * \param D Pointer to MPI holding the private exponent on success. - * - * \return - * - 0 if successful. In this case, D is set to a simultaneous - * modular inverse of E modulo both P-1 and Q-1. - * - A non-zero error code otherwise. - * - * \note This function does not check whether P and Q are primes. - * - */ -int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P, - mbedtls_mpi const *Q, - mbedtls_mpi const *E, - mbedtls_mpi *D ); - - -/** - * \brief Generate RSA-CRT parameters - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param P First prime factor of N - * \param Q Second prime factor of N - * \param D RSA private exponent - * \param DP Output variable for D modulo P-1 - * \param DQ Output variable for D modulo Q-1 - * \param QP Output variable for the modular inverse of Q modulo P. - * - * \return 0 on success, non-zero error code otherwise. - * - * \note This function does not check whether P, Q are - * prime and whether D is a valid private exponent. - * - */ -int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, mbedtls_mpi *DP, - mbedtls_mpi *DQ, mbedtls_mpi *QP ); - - -/** - * \brief Check validity of core RSA parameters - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param N RSA modulus N = PQ - * \param P First prime factor of N - * \param Q Second prime factor of N - * \param D RSA private exponent - * \param E RSA public exponent - * \param f_rng PRNG to be used for primality check, or NULL - * \param p_rng PRNG context for f_rng, or NULL - * - * \return - * - 0 if the following conditions are satisfied - * if all relevant parameters are provided: - * - P prime if f_rng != NULL (%) - * - Q prime if f_rng != NULL (%) - * - 1 < N = P * Q - * - 1 < D, E < N - * - D and E are modular inverses modulo P-1 and Q-1 - * (%) This is only done if MBEDTLS_GENPRIME is defined. - * - A non-zero error code otherwise. - * - * \note The function can be used with a restricted set of arguments - * to perform specific checks only. E.g., calling it with - * (-,P,-,-,-) and a PRNG amounts to a primality check for P. - */ -int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P, - const mbedtls_mpi *Q, const mbedtls_mpi *D, - const mbedtls_mpi *E, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief Check validity of RSA CRT parameters - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param P First prime factor of RSA modulus - * \param Q Second prime factor of RSA modulus - * \param D RSA private exponent - * \param DP MPI to check for D modulo P-1 - * \param DQ MPI to check for D modulo P-1 - * \param QP MPI to check for the modular inverse of Q modulo P. - * - * \return - * - 0 if the following conditions are satisfied: - * - D = DP mod P-1 if P, D, DP != NULL - * - Q = DQ mod P-1 if P, D, DQ != NULL - * - QP = Q^-1 mod P if P, Q, QP != NULL - * - \c MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if check failed, - * potentially including \c MBEDTLS_ERR_MPI_XXX if some - * MPI calculations failed. - * - \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA if insufficient - * data was provided to check DP, DQ or QP. - * - * \note The function can be used with a restricted set of arguments - * to perform specific checks only. E.g., calling it with the - * parameters (P, -, D, DP, -, -) will check DP = D mod P-1. - */ -int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *DP, - const mbedtls_mpi *DQ, const mbedtls_mpi *QP ); - -#ifdef __cplusplus -} -#endif - -#endif /* rsa_internal.h */ diff --git a/mbedtls/sha1.c b/mbedtls/sha1.c deleted file mode 100644 index b08284050..000000000 --- a/mbedtls/sha1.c +++ /dev/null @@ -1,619 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SHA1_C) - -#include "mbedtls/sha1.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#define SHA1_VALIDATE_RET(cond) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA ) - -#define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if !defined(MBEDTLS_SHA1_ALT) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) -{ - SHA1_VALIDATE( ctx != NULL ); - - memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); -} - -void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); -} - -void mbedtls_sha1_clone( mbedtls_sha1_context *dst, - const mbedtls_sha1_context *src ) -{ - SHA1_VALIDATE( dst != NULL ); - SHA1_VALIDATE( src != NULL ); - - *dst = *src; -} - -/* - * SHA-1 context setup - */ -int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ) -{ - SHA1_VALIDATE_RET( ctx != NULL ); - - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) -{ - mbedtls_sha1_starts_ret( ctx ); -} -#endif - -#if !defined(MBEDTLS_SHA1_PROCESS_ALT) -int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, - const unsigned char data[64] ) -{ - struct - { - uint32_t temp, W[16], A, B, C, D, E; - } local; - - SHA1_VALIDATE_RET( ctx != NULL ); - SHA1_VALIDATE_RET( (const unsigned char *)data != NULL ); - - GET_UINT32_BE( local.W[ 0], data, 0 ); - GET_UINT32_BE( local.W[ 1], data, 4 ); - GET_UINT32_BE( local.W[ 2], data, 8 ); - GET_UINT32_BE( local.W[ 3], data, 12 ); - GET_UINT32_BE( local.W[ 4], data, 16 ); - GET_UINT32_BE( local.W[ 5], data, 20 ); - GET_UINT32_BE( local.W[ 6], data, 24 ); - GET_UINT32_BE( local.W[ 7], data, 28 ); - GET_UINT32_BE( local.W[ 8], data, 32 ); - GET_UINT32_BE( local.W[ 9], data, 36 ); - GET_UINT32_BE( local.W[10], data, 40 ); - GET_UINT32_BE( local.W[11], data, 44 ); - GET_UINT32_BE( local.W[12], data, 48 ); - GET_UINT32_BE( local.W[13], data, 52 ); - GET_UINT32_BE( local.W[14], data, 56 ); - GET_UINT32_BE( local.W[15], data, 60 ); - -#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) - -#define R(t) \ - ( \ - local.temp = local.W[( (t) - 3 ) & 0x0F] ^ \ - local.W[( (t) - 8 ) & 0x0F] ^ \ - local.W[( (t) - 14 ) & 0x0F] ^ \ - local.W[ (t) & 0x0F], \ - ( local.W[(t) & 0x0F] = S(local.temp,1) ) \ - ) - -#define P(a,b,c,d,e,x) \ - do \ - { \ - (e) += S((a),5) + F((b),(c),(d)) + K + (x); \ - (b) = S((b),30); \ - } while( 0 ) - - local.A = ctx->state[0]; - local.B = ctx->state[1]; - local.C = ctx->state[2]; - local.D = ctx->state[3]; - local.E = ctx->state[4]; - -#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) -#define K 0x5A827999 - - P( local.A, local.B, local.C, local.D, local.E, local.W[0] ); - P( local.E, local.A, local.B, local.C, local.D, local.W[1] ); - P( local.D, local.E, local.A, local.B, local.C, local.W[2] ); - P( local.C, local.D, local.E, local.A, local.B, local.W[3] ); - P( local.B, local.C, local.D, local.E, local.A, local.W[4] ); - P( local.A, local.B, local.C, local.D, local.E, local.W[5] ); - P( local.E, local.A, local.B, local.C, local.D, local.W[6] ); - P( local.D, local.E, local.A, local.B, local.C, local.W[7] ); - P( local.C, local.D, local.E, local.A, local.B, local.W[8] ); - P( local.B, local.C, local.D, local.E, local.A, local.W[9] ); - P( local.A, local.B, local.C, local.D, local.E, local.W[10] ); - P( local.E, local.A, local.B, local.C, local.D, local.W[11] ); - P( local.D, local.E, local.A, local.B, local.C, local.W[12] ); - P( local.C, local.D, local.E, local.A, local.B, local.W[13] ); - P( local.B, local.C, local.D, local.E, local.A, local.W[14] ); - P( local.A, local.B, local.C, local.D, local.E, local.W[15] ); - P( local.E, local.A, local.B, local.C, local.D, R(16) ); - P( local.D, local.E, local.A, local.B, local.C, R(17) ); - P( local.C, local.D, local.E, local.A, local.B, R(18) ); - P( local.B, local.C, local.D, local.E, local.A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) ((x) ^ (y) ^ (z)) -#define K 0x6ED9EBA1 - - P( local.A, local.B, local.C, local.D, local.E, R(20) ); - P( local.E, local.A, local.B, local.C, local.D, R(21) ); - P( local.D, local.E, local.A, local.B, local.C, R(22) ); - P( local.C, local.D, local.E, local.A, local.B, R(23) ); - P( local.B, local.C, local.D, local.E, local.A, R(24) ); - P( local.A, local.B, local.C, local.D, local.E, R(25) ); - P( local.E, local.A, local.B, local.C, local.D, R(26) ); - P( local.D, local.E, local.A, local.B, local.C, R(27) ); - P( local.C, local.D, local.E, local.A, local.B, R(28) ); - P( local.B, local.C, local.D, local.E, local.A, R(29) ); - P( local.A, local.B, local.C, local.D, local.E, R(30) ); - P( local.E, local.A, local.B, local.C, local.D, R(31) ); - P( local.D, local.E, local.A, local.B, local.C, R(32) ); - P( local.C, local.D, local.E, local.A, local.B, R(33) ); - P( local.B, local.C, local.D, local.E, local.A, R(34) ); - P( local.A, local.B, local.C, local.D, local.E, R(35) ); - P( local.E, local.A, local.B, local.C, local.D, R(36) ); - P( local.D, local.E, local.A, local.B, local.C, R(37) ); - P( local.C, local.D, local.E, local.A, local.B, R(38) ); - P( local.B, local.C, local.D, local.E, local.A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define K 0x8F1BBCDC - - P( local.A, local.B, local.C, local.D, local.E, R(40) ); - P( local.E, local.A, local.B, local.C, local.D, R(41) ); - P( local.D, local.E, local.A, local.B, local.C, R(42) ); - P( local.C, local.D, local.E, local.A, local.B, R(43) ); - P( local.B, local.C, local.D, local.E, local.A, R(44) ); - P( local.A, local.B, local.C, local.D, local.E, R(45) ); - P( local.E, local.A, local.B, local.C, local.D, R(46) ); - P( local.D, local.E, local.A, local.B, local.C, R(47) ); - P( local.C, local.D, local.E, local.A, local.B, R(48) ); - P( local.B, local.C, local.D, local.E, local.A, R(49) ); - P( local.A, local.B, local.C, local.D, local.E, R(50) ); - P( local.E, local.A, local.B, local.C, local.D, R(51) ); - P( local.D, local.E, local.A, local.B, local.C, R(52) ); - P( local.C, local.D, local.E, local.A, local.B, R(53) ); - P( local.B, local.C, local.D, local.E, local.A, R(54) ); - P( local.A, local.B, local.C, local.D, local.E, R(55) ); - P( local.E, local.A, local.B, local.C, local.D, R(56) ); - P( local.D, local.E, local.A, local.B, local.C, R(57) ); - P( local.C, local.D, local.E, local.A, local.B, R(58) ); - P( local.B, local.C, local.D, local.E, local.A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) ((x) ^ (y) ^ (z)) -#define K 0xCA62C1D6 - - P( local.A, local.B, local.C, local.D, local.E, R(60) ); - P( local.E, local.A, local.B, local.C, local.D, R(61) ); - P( local.D, local.E, local.A, local.B, local.C, R(62) ); - P( local.C, local.D, local.E, local.A, local.B, R(63) ); - P( local.B, local.C, local.D, local.E, local.A, R(64) ); - P( local.A, local.B, local.C, local.D, local.E, R(65) ); - P( local.E, local.A, local.B, local.C, local.D, R(66) ); - P( local.D, local.E, local.A, local.B, local.C, R(67) ); - P( local.C, local.D, local.E, local.A, local.B, R(68) ); - P( local.B, local.C, local.D, local.E, local.A, R(69) ); - P( local.A, local.B, local.C, local.D, local.E, R(70) ); - P( local.E, local.A, local.B, local.C, local.D, R(71) ); - P( local.D, local.E, local.A, local.B, local.C, R(72) ); - P( local.C, local.D, local.E, local.A, local.B, R(73) ); - P( local.B, local.C, local.D, local.E, local.A, R(74) ); - P( local.A, local.B, local.C, local.D, local.E, R(75) ); - P( local.E, local.A, local.B, local.C, local.D, R(76) ); - P( local.D, local.E, local.A, local.B, local.C, R(77) ); - P( local.C, local.D, local.E, local.A, local.B, R(78) ); - P( local.B, local.C, local.D, local.E, local.A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += local.A; - ctx->state[1] += local.B; - ctx->state[2] += local.C; - ctx->state[3] += local.D; - ctx->state[4] += local.E; - - /* Zeroise buffers and variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize( &local, sizeof( local ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1_process( mbedtls_sha1_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_sha1_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_SHA1_PROCESS_ALT */ - -/* - * SHA-1 process buffer - */ -int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - SHA1_VALIDATE_RET( ctx != NULL ); - SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - - if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - memcpy( (void *) (ctx->buffer + left), input, ilen ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1_update( mbedtls_sha1_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_sha1_update_ret( ctx, input, ilen ); -} -#endif - -/* - * SHA-1 final digest - */ -int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, - unsigned char output[20] ) -{ - int ret; - uint32_t used; - uint32_t high, low; - - SHA1_VALIDATE_RET( ctx != NULL ); - SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); - - /* - * Add padding: 0x80 then 0x00 until 8 bytes remain for the length - */ - used = ctx->total[0] & 0x3F; - - ctx->buffer[used++] = 0x80; - - if( used <= 56 ) - { - /* Enough room for padding + length in current block */ - memset( ctx->buffer + used, 0, 56 - used ); - } - else - { - /* We'll need an extra block */ - memset( ctx->buffer + used, 0, 64 - used ); - - if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - memset( ctx->buffer, 0, 56 ); - } - - /* - * Add message length - */ - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_BE( high, ctx->buffer, 56 ); - PUT_UINT32_BE( low, ctx->buffer, 60 ); - - if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - /* - * Output final state - */ - PUT_UINT32_BE( ctx->state[0], output, 0 ); - PUT_UINT32_BE( ctx->state[1], output, 4 ); - PUT_UINT32_BE( ctx->state[2], output, 8 ); - PUT_UINT32_BE( ctx->state[3], output, 12 ); - PUT_UINT32_BE( ctx->state[4], output, 16 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, - unsigned char output[20] ) -{ - mbedtls_sha1_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_SHA1_ALT */ - -/* - * output = SHA-1( input buffer ) - */ -int mbedtls_sha1_ret( const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - int ret; - mbedtls_sha1_context ctx; - - SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); - SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); - - mbedtls_sha1_init( &ctx ); - - if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_sha1_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1( const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - mbedtls_sha1_ret( input, ilen, output ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * FIPS-180-1 test vectors - */ -static const unsigned char sha1_test_buf[3][57] = -{ - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const size_t sha1_test_buflen[3] = -{ - 3, 56, 1000 -}; - -static const unsigned char sha1_test_sum[3][20] = -{ - { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, - 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, - 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, - { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, - 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } -}; - -/* - * Checkup routine - */ -int mbedtls_sha1_self_test( int verbose ) -{ - int i, j, buflen, ret = 0; - unsigned char buf[1024]; - unsigned char sha1sum[20]; - mbedtls_sha1_context ctx; - - mbedtls_sha1_init( &ctx ); - - /* - * SHA-1 - */ - for( i = 0; i < 3; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " SHA-1 test #%d: ", i + 1 ); - - if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) - goto fail; - - if( i == 2 ) - { - memset( buf, 'a', buflen = 1000 ); - - for( j = 0; j < 1000; j++ ) - { - ret = mbedtls_sha1_update_ret( &ctx, buf, buflen ); - if( ret != 0 ) - goto fail; - } - } - else - { - ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i], - sha1_test_buflen[i] ); - if( ret != 0 ) - goto fail; - } - - if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 ) - goto fail; - - if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - goto exit; - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - -exit: - mbedtls_sha1_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA1_C */ diff --git a/mbedtls/sha1.h b/mbedtls/sha1.h deleted file mode 100644 index a90905fd2..000000000 --- a/mbedtls/sha1.h +++ /dev/null @@ -1,378 +0,0 @@ -#pragma GCC system_header -/** - * \file sha1.h - * - * \brief This file contains SHA-1 definitions and functions. - * - * The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in - * FIPS 180-4: Secure Hash Standard (SHS). - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. We recommend considering stronger message - * digests instead. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_SHA1_H -#define MBEDTLS_SHA1_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -/* MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED -0x0035 /**< SHA-1 hardware accelerator failed */ -#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA -0x0073 /**< SHA-1 input data was malformed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_SHA1_ALT) -// Regular implementation -// - -/** - * \brief The SHA-1 context structure. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -typedef struct mbedtls_sha1_context -{ - uint32_t total[2]; /*!< The number of Bytes processed. */ - uint32_t state[5]; /*!< The intermediate digest state. */ - unsigned char buffer[64]; /*!< The data block being processed. */ -} -mbedtls_sha1_context; - -#else /* MBEDTLS_SHA1_ALT */ -#include "sha1_alt.h" -#endif /* MBEDTLS_SHA1_ALT */ - -/** - * \brief This function initializes a SHA-1 context. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to initialize. - * This must not be \c NULL. - * - */ -void mbedtls_sha1_init( mbedtls_sha1_context *ctx ); - -/** - * \brief This function clears a SHA-1 context. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to clear. This may be \c NULL, - * in which case this function does nothing. If it is - * not \c NULL, it must point to an initialized - * SHA-1 context. - * - */ -void mbedtls_sha1_free( mbedtls_sha1_context *ctx ); - -/** - * \brief This function clones the state of a SHA-1 context. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param dst The SHA-1 context to clone to. This must be initialized. - * \param src The SHA-1 context to clone from. This must be initialized. - * - */ -void mbedtls_sha1_clone( mbedtls_sha1_context *dst, - const mbedtls_sha1_context *src ); - -/** - * \brief This function starts a SHA-1 checksum calculation. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to initialize. This must be initialized. - * - * \return \c 0 on success. - * \return A negative error code on failure. - * - */ -int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ); - -/** - * \brief This function feeds an input buffer into an ongoing SHA-1 - * checksum calculation. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief This function finishes the SHA-1 operation, and writes - * the result to the output buffer. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to use. This must be initialized and - * have a hash operation started. - * \param output The SHA-1 checksum result. This must be a writable - * buffer of length \c 20 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, - unsigned char output[20] ); - -/** - * \brief SHA-1 process data block (internal use only). - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to use. This must be initialized. - * \param data The data block being processed. This must be a - * readable buffer of length \c 64 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - * - */ -int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, - const unsigned char data[64] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function starts a SHA-1 checksum calculation. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \disabled_deprecated Superseded by mbedtls_sha1_starts_ret() in 2.7.0. - * - * \param ctx The SHA-1 context to initialize. This must be initialized. - * - */ -MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ); - -/** - * \brief This function feeds an input buffer into an ongoing SHA-1 - * checksum calculation. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \disabled_deprecated Superseded by mbedtls_sha1_update_ret() in 2.7.0. - * - * \param ctx The SHA-1 context. This must be initialized and - * have a hash operation started. - * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * - */ -MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief This function finishes the SHA-1 operation, and writes - * the result to the output buffer. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \disabled_deprecated Superseded by mbedtls_sha1_finish_ret() in 2.7.0. - * - * \param ctx The SHA-1 context. This must be initialized and - * have a hash operation started. - * \param output The SHA-1 checksum result. - * This must be a writable buffer of length \c 20 Bytes. - */ -MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, - unsigned char output[20] ); - -/** - * \brief SHA-1 process data block (internal use only). - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \disabled_deprecated Superseded by mbedtls_internal_sha1_process() in 2.7.0. - * - * \param ctx The SHA-1 context. This must be initialized. - * \param data The data block being processed. - * This must be a readable buffer of length \c 64 bytes. - * - */ -MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx, - const unsigned char data[64] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief This function calculates the SHA-1 checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-1 result is calculated as - * output = SHA-1(input buffer). - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * \param output The SHA-1 checksum result. - * This must be a writable buffer of length \c 20 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - * - */ -int mbedtls_sha1_ret( const unsigned char *input, - size_t ilen, - unsigned char output[20] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function calculates the SHA-1 checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-1 result is calculated as - * output = SHA-1(input buffer). - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \disabled_deprecated Superseded by mbedtls_sha1_ret() in 2.7.0 - * - * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * \param output The SHA-1 checksum result. This must be a writable - * buffer of size \c 20 Bytes. - * - */ -MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input, - size_t ilen, - unsigned char output[20] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The SHA-1 checkup routine. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \return \c 0 on success. - * \return \c 1 on failure. - * - */ -int mbedtls_sha1_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_sha1.h */ diff --git a/mbedtls/sha256.c b/mbedtls/sha256.c deleted file mode 100644 index c95a92c20..000000000 --- a/mbedtls/sha256.c +++ /dev/null @@ -1,651 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * FIPS-180-2 compliant SHA-256 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The SHA-256 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SHA256_C) - -#include "mbedtls/sha256.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#define SHA256_VALIDATE_RET(cond) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA ) -#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if !defined(MBEDTLS_SHA256_ALT) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -do { \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} while( 0 ) -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -do { \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} while( 0 ) -#endif - -void mbedtls_sha256_init( mbedtls_sha256_context *ctx ) -{ - SHA256_VALIDATE( ctx != NULL ); - - memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); -} - -void mbedtls_sha256_free( mbedtls_sha256_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); -} - -void mbedtls_sha256_clone( mbedtls_sha256_context *dst, - const mbedtls_sha256_context *src ) -{ - SHA256_VALIDATE( dst != NULL ); - SHA256_VALIDATE( src != NULL ); - - *dst = *src; -} - -/* - * SHA-256 context setup - */ -int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ) -{ - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 ); - - ctx->total[0] = 0; - ctx->total[1] = 0; - - if( is224 == 0 ) - { - /* SHA-256 */ - ctx->state[0] = 0x6A09E667; - ctx->state[1] = 0xBB67AE85; - ctx->state[2] = 0x3C6EF372; - ctx->state[3] = 0xA54FF53A; - ctx->state[4] = 0x510E527F; - ctx->state[5] = 0x9B05688C; - ctx->state[6] = 0x1F83D9AB; - ctx->state[7] = 0x5BE0CD19; - } - else - { - /* SHA-224 */ - ctx->state[0] = 0xC1059ED8; - ctx->state[1] = 0x367CD507; - ctx->state[2] = 0x3070DD17; - ctx->state[3] = 0xF70E5939; - ctx->state[4] = 0xFFC00B31; - ctx->state[5] = 0x68581511; - ctx->state[6] = 0x64F98FA7; - ctx->state[7] = 0xBEFA4FA4; - } - - ctx->is224 = is224; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, - int is224 ) -{ - mbedtls_sha256_starts_ret( ctx, is224 ); -} -#endif - -#if !defined(MBEDTLS_SHA256_PROCESS_ALT) -static const uint32_t K[] = -{ - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, -}; - -#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n)) -#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n)))) - -#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) -#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) - -#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) -#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) - -#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) - -#define R(t) \ - ( \ - local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \ - S0(local.W[(t) - 15]) + local.W[(t) - 16] \ - ) - -#define P(a,b,c,d,e,f,g,h,x,K) \ - do \ - { \ - local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ - local.temp2 = S2(a) + F0((a),(b),(c)); \ - (d) += local.temp1; (h) = local.temp1 + local.temp2; \ - } while( 0 ) - -int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, - const unsigned char data[64] ) -{ - struct - { - uint32_t temp1, temp2, W[64]; - uint32_t A[8]; - } local; - - unsigned int i; - - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( (const unsigned char *)data != NULL ); - - for( i = 0; i < 8; i++ ) - local.A[i] = ctx->state[i]; - -#if defined(MBEDTLS_SHA256_SMALLER) - for( i = 0; i < 64; i++ ) - { - if( i < 16 ) - GET_UINT32_BE( local.W[i], data, 4 * i ); - else - R( i ); - - P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], - local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); - - local.temp1 = local.A[7]; local.A[7] = local.A[6]; - local.A[6] = local.A[5]; local.A[5] = local.A[4]; - local.A[4] = local.A[3]; local.A[3] = local.A[2]; - local.A[2] = local.A[1]; local.A[1] = local.A[0]; - local.A[0] = local.temp1; - } -#else /* MBEDTLS_SHA256_SMALLER */ - for( i = 0; i < 16; i++ ) - GET_UINT32_BE( local.W[i], data, 4 * i ); - - for( i = 0; i < 16; i += 8 ) - { - P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], - local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] ); - P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], - local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] ); - P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], - local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] ); - P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], - local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] ); - P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], - local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] ); - P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], - local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] ); - P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], - local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] ); - P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], - local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7] ); - } - - for( i = 16; i < 64; i += 8 ) - { - P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], - local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] ); - P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], - local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] ); - P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], - local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] ); - P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], - local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] ); - P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], - local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] ); - P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], - local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] ); - P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], - local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] ); - P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], - local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] ); - } -#endif /* MBEDTLS_SHA256_SMALLER */ - - for( i = 0; i < 8; i++ ) - ctx->state[i] += local.A[i]; - - /* Zeroise buffers and variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize( &local, sizeof( local ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256_process( mbedtls_sha256_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_sha256_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_SHA256_PROCESS_ALT */ - -/* - * SHA-256 process buffer - */ -int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - uint32_t left; - - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); - - if( ilen == 0 ) - return( 0 ); - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - - if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - memcpy( (void *) (ctx->buffer + left), input, ilen ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256_update( mbedtls_sha256_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_sha256_update_ret( ctx, input, ilen ); -} -#endif - -/* - * SHA-256 final digest - */ -int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, - unsigned char output[32] ) -{ - int ret; - uint32_t used; - uint32_t high, low; - - SHA256_VALIDATE_RET( ctx != NULL ); - SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); - - /* - * Add padding: 0x80 then 0x00 until 8 bytes remain for the length - */ - used = ctx->total[0] & 0x3F; - - ctx->buffer[used++] = 0x80; - - if( used <= 56 ) - { - /* Enough room for padding + length in current block */ - memset( ctx->buffer + used, 0, 56 - used ); - } - else - { - /* We'll need an extra block */ - memset( ctx->buffer + used, 0, 64 - used ); - - if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - memset( ctx->buffer, 0, 56 ); - } - - /* - * Add message length - */ - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_BE( high, ctx->buffer, 56 ); - PUT_UINT32_BE( low, ctx->buffer, 60 ); - - if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - /* - * Output final state - */ - PUT_UINT32_BE( ctx->state[0], output, 0 ); - PUT_UINT32_BE( ctx->state[1], output, 4 ); - PUT_UINT32_BE( ctx->state[2], output, 8 ); - PUT_UINT32_BE( ctx->state[3], output, 12 ); - PUT_UINT32_BE( ctx->state[4], output, 16 ); - PUT_UINT32_BE( ctx->state[5], output, 20 ); - PUT_UINT32_BE( ctx->state[6], output, 24 ); - - if( ctx->is224 == 0 ) - PUT_UINT32_BE( ctx->state[7], output, 28 ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, - unsigned char output[32] ) -{ - mbedtls_sha256_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_SHA256_ALT */ - -/* - * output = SHA-256( input buffer ) - */ -int mbedtls_sha256_ret( const unsigned char *input, - size_t ilen, - unsigned char output[32], - int is224 ) -{ - int ret; - mbedtls_sha256_context ctx; - - SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 ); - SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); - SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); - - mbedtls_sha256_init( &ctx ); - - if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_sha256_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha256( const unsigned char *input, - size_t ilen, - unsigned char output[32], - int is224 ) -{ - mbedtls_sha256_ret( input, ilen, output, is224 ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) -/* - * FIPS-180-2 test vectors - */ -static const unsigned char sha256_test_buf[3][57] = -{ - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const size_t sha256_test_buflen[3] = -{ - 3, 56, 1000 -}; - -static const unsigned char sha256_test_sum[6][32] = -{ - /* - * SHA-224 test vectors - */ - { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, - 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, - 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, - 0xE3, 0x6C, 0x9D, 0xA7 }, - { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, - 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, - 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, - 0x52, 0x52, 0x25, 0x25 }, - { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, - 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, - 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, - 0x4E, 0xE7, 0xAD, 0x67 }, - - /* - * SHA-256 test vectors - */ - { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, - 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, - 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, - 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, - { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, - 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, - 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, - 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, - { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, - 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, - 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, - 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } -}; - -/* - * Checkup routine - */ -int mbedtls_sha256_self_test( int verbose ) -{ - int i, j, k, buflen, ret = 0; - unsigned char *buf; - unsigned char sha256sum[32]; - mbedtls_sha256_context ctx; - - buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); - if( NULL == buf ) - { - if( verbose != 0 ) - mbedtls_printf( "Buffer allocation failed\n" ); - - return( 1 ); - } - - mbedtls_sha256_init( &ctx ); - - for( i = 0; i < 6; i++ ) - { - j = i % 3; - k = i < 3; - - if( verbose != 0 ) - mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); - - if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 ) - goto fail; - - if( j == 2 ) - { - memset( buf, 'a', buflen = 1000 ); - - for( j = 0; j < 1000; j++ ) - { - ret = mbedtls_sha256_update_ret( &ctx, buf, buflen ); - if( ret != 0 ) - goto fail; - } - - } - else - { - ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j], - sha256_test_buflen[j] ); - if( ret != 0 ) - goto fail; - } - - if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 ) - goto fail; - - - if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - goto exit; - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - -exit: - mbedtls_sha256_free( &ctx ); - mbedtls_free( buf ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA256_C */ diff --git a/mbedtls/sha256.h b/mbedtls/sha256.h deleted file mode 100644 index afc6dbfce..000000000 --- a/mbedtls/sha256.h +++ /dev/null @@ -1,323 +0,0 @@ -#pragma GCC system_header -/** - * \file sha256.h - * - * \brief This file contains SHA-224 and SHA-256 definitions and functions. - * - * The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic - * hash functions are defined in FIPS 180-4: Secure Hash Standard (SHS). - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_SHA256_H -#define MBEDTLS_SHA256_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -/* MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED -0x0037 /**< SHA-256 hardware accelerator failed */ -#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA -0x0074 /**< SHA-256 input data was malformed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_SHA256_ALT) -// Regular implementation -// - -/** - * \brief The SHA-256 context structure. - * - * The structure is used both for SHA-256 and for SHA-224 - * checksum calculations. The choice between these two is - * made in the call to mbedtls_sha256_starts_ret(). - */ -typedef struct mbedtls_sha256_context -{ - uint32_t total[2]; /*!< The number of Bytes processed. */ - uint32_t state[8]; /*!< The intermediate digest state. */ - unsigned char buffer[64]; /*!< The data block being processed. */ - int is224; /*!< Determines which function to use: - 0: Use SHA-256, or 1: Use SHA-224. */ -} -mbedtls_sha256_context; - -#else /* MBEDTLS_SHA256_ALT */ -#include "sha256_alt.h" -#endif /* MBEDTLS_SHA256_ALT */ - -/** - * \brief This function initializes a SHA-256 context. - * - * \param ctx The SHA-256 context to initialize. This must not be \c NULL. - */ -void mbedtls_sha256_init( mbedtls_sha256_context *ctx ); - -/** - * \brief This function clears a SHA-256 context. - * - * \param ctx The SHA-256 context to clear. This may be \c NULL, in which - * case this function returns immediately. If it is not \c NULL, - * it must point to an initialized SHA-256 context. - */ -void mbedtls_sha256_free( mbedtls_sha256_context *ctx ); - -/** - * \brief This function clones the state of a SHA-256 context. - * - * \param dst The destination context. This must be initialized. - * \param src The context to clone. This must be initialized. - */ -void mbedtls_sha256_clone( mbedtls_sha256_context *dst, - const mbedtls_sha256_context *src ); - -/** - * \brief This function starts a SHA-224 or SHA-256 checksum - * calculation. - * - * \param ctx The context to use. This must be initialized. - * \param is224 This determines which function to use. This must be - * either \c 0 for SHA-256, or \c 1 for SHA-224. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ); - -/** - * \brief This function feeds an input buffer into an ongoing - * SHA-256 checksum calculation. - * - * \param ctx The SHA-256 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief This function finishes the SHA-256 operation, and writes - * the result to the output buffer. - * - * \param ctx The SHA-256 context. This must be initialized - * and have a hash operation started. - * \param output The SHA-224 or SHA-256 checksum result. - * This must be a writable buffer of length \c 32 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, - unsigned char output[32] ); - -/** - * \brief This function processes a single data block within - * the ongoing SHA-256 computation. This function is for - * internal use only. - * - * \param ctx The SHA-256 context. This must be initialized. - * \param data The buffer holding one block of data. This must - * be a readable buffer of length \c 64 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, - const unsigned char data[64] ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function starts a SHA-224 or SHA-256 checksum - * calculation. - * - * \disabled_deprecated Superseded by mbedtls_sha256_starts_ret() in 2.7.0. - * - * \param ctx The context to use. This must be initialized. - * \param is224 Determines which function to use. This must be - * either \c 0 for SHA-256, or \c 1 for SHA-224. - */ -MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, - int is224 ); - -/** - * \brief This function feeds an input buffer into an ongoing - * SHA-256 checksum calculation. - * - * \disabled_deprecated Superseded by mbedtls_sha256_update_ret() in 2.7.0. - * - * \param ctx The SHA-256 context to use. This must be - * initialized and have a hash operation started. - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - */ -MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief This function finishes the SHA-256 operation, and writes - * the result to the output buffer. - * - * \disabled_deprecated Superseded by mbedtls_sha256_finish_ret() in 2.7.0. - * - * \param ctx The SHA-256 context. This must be initialized and - * have a hash operation started. - * \param output The SHA-224 or SHA-256 checksum result. This must be - * a writable buffer of length \c 32 Bytes. - */ -MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, - unsigned char output[32] ); - -/** - * \brief This function processes a single data block within - * the ongoing SHA-256 computation. This function is for - * internal use only. - * - * \disabled_deprecated Superseded by mbedtls_internal_sha256_process() in 2.7.0. - * - * \param ctx The SHA-256 context. This must be initialized. - * \param data The buffer holding one block of data. This must be - * a readable buffer of size \c 64 Bytes. - */ -MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx, - const unsigned char data[64] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief This function calculates the SHA-224 or SHA-256 - * checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-256 result is calculated as - * output = SHA-256(input buffer). - * - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-224 or SHA-256 checksum result. This must - * be a writable buffer of length \c 32 Bytes. - * \param is224 Determines which function to use. This must be - * either \c 0 for SHA-256, or \c 1 for SHA-224. - */ -int mbedtls_sha256_ret( const unsigned char *input, - size_t ilen, - unsigned char output[32], - int is224 ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif - -/** - * \brief This function calculates the SHA-224 or SHA-256 checksum - * of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-256 result is calculated as - * output = SHA-256(input buffer). - * - * \disabled_deprecated Superseded by mbedtls_sha256_ret() in 2.7.0. - * - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-224 or SHA-256 checksum result. This must be - * a writable buffer of length \c 32 Bytes. - * \param is224 Determines which function to use. This must be either - * \c 0 for SHA-256, or \c 1 for SHA-224. - */ -MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input, - size_t ilen, - unsigned char output[32], - int is224 ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The SHA-224 and SHA-256 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_sha256_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_sha256.h */ diff --git a/mbedtls/sha512.c b/mbedtls/sha512.c deleted file mode 100644 index c278c288e..000000000 --- a/mbedtls/sha512.c +++ /dev/null @@ -1,687 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * FIPS-180-2 compliant SHA-384/512 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The SHA-512 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SHA512_C) - -#include "mbedtls/sha512.h" -#include "mbedtls/platform_util.h" - -#if defined(_MSC_VER) || defined(__WATCOMC__) - #define UL64(x) x##ui64 -#else - #define UL64(x) x##ULL -#endif - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_printf printf -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#define SHA512_VALIDATE_RET(cond) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA ) -#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) - -#if !defined(MBEDTLS_SHA512_ALT) - -/* - * 64-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT64_BE -#define GET_UINT64_BE(n,b,i) \ -{ \ - (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ - | ( (uint64_t) (b)[(i) + 1] << 48 ) \ - | ( (uint64_t) (b)[(i) + 2] << 40 ) \ - | ( (uint64_t) (b)[(i) + 3] << 32 ) \ - | ( (uint64_t) (b)[(i) + 4] << 24 ) \ - | ( (uint64_t) (b)[(i) + 5] << 16 ) \ - | ( (uint64_t) (b)[(i) + 6] << 8 ) \ - | ( (uint64_t) (b)[(i) + 7] ); \ -} -#endif /* GET_UINT64_BE */ - -#ifndef PUT_UINT64_BE -#define PUT_UINT64_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \ - (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 7] = (unsigned char) ( (n) ); \ -} -#endif /* PUT_UINT64_BE */ - -void mbedtls_sha512_init( mbedtls_sha512_context *ctx ) -{ - SHA512_VALIDATE( ctx != NULL ); - - memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); -} - -void mbedtls_sha512_free( mbedtls_sha512_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); -} - -void mbedtls_sha512_clone( mbedtls_sha512_context *dst, - const mbedtls_sha512_context *src ) -{ - SHA512_VALIDATE( dst != NULL ); - SHA512_VALIDATE( src != NULL ); - - *dst = *src; -} - -/* - * SHA-512 context setup - */ -int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ) -{ - SHA512_VALIDATE_RET( ctx != NULL ); - SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 ); - - ctx->total[0] = 0; - ctx->total[1] = 0; - - if( is384 == 0 ) - { - /* SHA-512 */ - ctx->state[0] = UL64(0x6A09E667F3BCC908); - ctx->state[1] = UL64(0xBB67AE8584CAA73B); - ctx->state[2] = UL64(0x3C6EF372FE94F82B); - ctx->state[3] = UL64(0xA54FF53A5F1D36F1); - ctx->state[4] = UL64(0x510E527FADE682D1); - ctx->state[5] = UL64(0x9B05688C2B3E6C1F); - ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); - ctx->state[7] = UL64(0x5BE0CD19137E2179); - } - else - { - /* SHA-384 */ - ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); - ctx->state[1] = UL64(0x629A292A367CD507); - ctx->state[2] = UL64(0x9159015A3070DD17); - ctx->state[3] = UL64(0x152FECD8F70E5939); - ctx->state[4] = UL64(0x67332667FFC00B31); - ctx->state[5] = UL64(0x8EB44A8768581511); - ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); - ctx->state[7] = UL64(0x47B5481DBEFA4FA4); - } - - ctx->is384 = is384; - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, - int is384 ) -{ - mbedtls_sha512_starts_ret( ctx, is384 ); -} -#endif - -#if !defined(MBEDTLS_SHA512_PROCESS_ALT) - -/* - * Round constants - */ -static const uint64_t K[80] = -{ - UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), - UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), - UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), - UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), - UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), - UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), - UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), - UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), - UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), - UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), - UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), - UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), - UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), - UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), - UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), - UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), - UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), - UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), - UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), - UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), - UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), - UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), - UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), - UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), - UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), - UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), - UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), - UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), - UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), - UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), - UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), - UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), - UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), - UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), - UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), - UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), - UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), - UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), - UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), - UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) -}; - -int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, - const unsigned char data[128] ) -{ - int i; - struct - { - uint64_t temp1, temp2, W[80]; - uint64_t A, B, C, D, E, F, G, H; - } local; - - SHA512_VALIDATE_RET( ctx != NULL ); - SHA512_VALIDATE_RET( (const unsigned char *)data != NULL ); - -#define SHR(x,n) ((x) >> (n)) -#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n)))) - -#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) -#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) - -#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) -#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) - -#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) - -#define P(a,b,c,d,e,f,g,h,x,K) \ - do \ - { \ - local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ - local.temp2 = S2(a) + F0((a),(b),(c)); \ - (d) += local.temp1; (h) = local.temp1 + local.temp2; \ - } while( 0 ) - - for( i = 0; i < 16; i++ ) - { - GET_UINT64_BE( local.W[i], data, i << 3 ); - } - - for( ; i < 80; i++ ) - { - local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] + - S0(local.W[i - 15]) + local.W[i - 16]; - } - - local.A = ctx->state[0]; - local.B = ctx->state[1]; - local.C = ctx->state[2]; - local.D = ctx->state[3]; - local.E = ctx->state[4]; - local.F = ctx->state[5]; - local.G = ctx->state[6]; - local.H = ctx->state[7]; - i = 0; - - do - { - P( local.A, local.B, local.C, local.D, local.E, - local.F, local.G, local.H, local.W[i], K[i] ); i++; - P( local.H, local.A, local.B, local.C, local.D, - local.E, local.F, local.G, local.W[i], K[i] ); i++; - P( local.G, local.H, local.A, local.B, local.C, - local.D, local.E, local.F, local.W[i], K[i] ); i++; - P( local.F, local.G, local.H, local.A, local.B, - local.C, local.D, local.E, local.W[i], K[i] ); i++; - P( local.E, local.F, local.G, local.H, local.A, - local.B, local.C, local.D, local.W[i], K[i] ); i++; - P( local.D, local.E, local.F, local.G, local.H, - local.A, local.B, local.C, local.W[i], K[i] ); i++; - P( local.C, local.D, local.E, local.F, local.G, - local.H, local.A, local.B, local.W[i], K[i] ); i++; - P( local.B, local.C, local.D, local.E, local.F, - local.G, local.H, local.A, local.W[i], K[i] ); i++; - } - while( i < 80 ); - - ctx->state[0] += local.A; - ctx->state[1] += local.B; - ctx->state[2] += local.C; - ctx->state[3] += local.D; - ctx->state[4] += local.E; - ctx->state[5] += local.F; - ctx->state[6] += local.G; - ctx->state[7] += local.H; - - /* Zeroise buffers and variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize( &local, sizeof( local ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512_process( mbedtls_sha512_context *ctx, - const unsigned char data[128] ) -{ - mbedtls_internal_sha512_process( ctx, data ); -} -#endif -#endif /* !MBEDTLS_SHA512_PROCESS_ALT */ - -/* - * SHA-512 process buffer - */ -int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - int ret; - size_t fill; - unsigned int left; - - SHA512_VALIDATE_RET( ctx != NULL ); - SHA512_VALIDATE_RET( ilen == 0 || input != NULL ); - - if( ilen == 0 ) - return( 0 ); - - left = (unsigned int) (ctx->total[0] & 0x7F); - fill = 128 - left; - - ctx->total[0] += (uint64_t) ilen; - - if( ctx->total[0] < (uint64_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - - if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 128 ) - { - if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) - return( ret ); - - input += 128; - ilen -= 128; - } - - if( ilen > 0 ) - memcpy( (void *) (ctx->buffer + left), input, ilen ); - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512_update( mbedtls_sha512_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_sha512_update_ret( ctx, input, ilen ); -} -#endif - -/* - * SHA-512 final digest - */ -int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, - unsigned char output[64] ) -{ - int ret; - unsigned used; - uint64_t high, low; - - SHA512_VALIDATE_RET( ctx != NULL ); - SHA512_VALIDATE_RET( (unsigned char *)output != NULL ); - - /* - * Add padding: 0x80 then 0x00 until 16 bytes remain for the length - */ - used = ctx->total[0] & 0x7F; - - ctx->buffer[used++] = 0x80; - - if( used <= 112 ) - { - /* Enough room for padding + length in current block */ - memset( ctx->buffer + used, 0, 112 - used ); - } - else - { - /* We'll need an extra block */ - memset( ctx->buffer + used, 0, 128 - used ); - - if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - memset( ctx->buffer, 0, 112 ); - } - - /* - * Add message length - */ - high = ( ctx->total[0] >> 61 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT64_BE( high, ctx->buffer, 112 ); - PUT_UINT64_BE( low, ctx->buffer, 120 ); - - if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) - return( ret ); - - /* - * Output final state - */ - PUT_UINT64_BE( ctx->state[0], output, 0 ); - PUT_UINT64_BE( ctx->state[1], output, 8 ); - PUT_UINT64_BE( ctx->state[2], output, 16 ); - PUT_UINT64_BE( ctx->state[3], output, 24 ); - PUT_UINT64_BE( ctx->state[4], output, 32 ); - PUT_UINT64_BE( ctx->state[5], output, 40 ); - - if( ctx->is384 == 0 ) - { - PUT_UINT64_BE( ctx->state[6], output, 48 ); - PUT_UINT64_BE( ctx->state[7], output, 56 ); - } - - return( 0 ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, - unsigned char output[64] ) -{ - mbedtls_sha512_finish_ret( ctx, output ); -} -#endif - -#endif /* !MBEDTLS_SHA512_ALT */ - -/* - * output = SHA-512( input buffer ) - */ -int mbedtls_sha512_ret( const unsigned char *input, - size_t ilen, - unsigned char output[64], - int is384 ) -{ - int ret; - mbedtls_sha512_context ctx; - - SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 ); - SHA512_VALIDATE_RET( ilen == 0 || input != NULL ); - SHA512_VALIDATE_RET( (unsigned char *)output != NULL ); - - mbedtls_sha512_init( &ctx ); - - if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 ) - goto exit; - -exit: - mbedtls_sha512_free( &ctx ); - - return( ret ); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha512( const unsigned char *input, - size_t ilen, - unsigned char output[64], - int is384 ) -{ - mbedtls_sha512_ret( input, ilen, output, is384 ); -} -#endif - -#if defined(MBEDTLS_SELF_TEST) - -/* - * FIPS-180-2 test vectors - */ -static const unsigned char sha512_test_buf[3][113] = -{ - { "abc" }, - { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, - { "" } -}; - -static const size_t sha512_test_buflen[3] = -{ - 3, 112, 1000 -}; - -static const unsigned char sha512_test_sum[6][64] = -{ - /* - * SHA-384 test vectors - */ - { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, - 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, - 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, - 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, - 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, - 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, - { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, - 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, - 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, - 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, - 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, - 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, - { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, - 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, - 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, - 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, - 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, - 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }, - - /* - * SHA-512 test vectors - */ - { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, - 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, - 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, - 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, - 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, - 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, - 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, - 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, - { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, - 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, - 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, - 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, - 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, - 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, - 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, - 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, - { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, - 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, - 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, - 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, - 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, - 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, - 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, - 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } -}; - -/* - * Checkup routine - */ -int mbedtls_sha512_self_test( int verbose ) -{ - int i, j, k, buflen, ret = 0; - unsigned char *buf; - unsigned char sha512sum[64]; - mbedtls_sha512_context ctx; - - buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); - if( NULL == buf ) - { - if( verbose != 0 ) - mbedtls_printf( "Buffer allocation failed\n" ); - - return( 1 ); - } - - mbedtls_sha512_init( &ctx ); - - for( i = 0; i < 6; i++ ) - { - j = i % 3; - k = i < 3; - - if( verbose != 0 ) - mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); - - if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 ) - goto fail; - - if( j == 2 ) - { - memset( buf, 'a', buflen = 1000 ); - - for( j = 0; j < 1000; j++ ) - { - ret = mbedtls_sha512_update_ret( &ctx, buf, buflen ); - if( ret != 0 ) - goto fail; - } - } - else - { - ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j], - sha512_test_buflen[j] ); - if( ret != 0 ) - goto fail; - } - - if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 ) - goto fail; - - if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) - { - ret = 1; - goto fail; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - goto exit; - -fail: - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - -exit: - mbedtls_sha512_free( &ctx ); - mbedtls_free( buf ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA512_C */ diff --git a/mbedtls/sha512.h b/mbedtls/sha512.h deleted file mode 100644 index 56cc7725d..000000000 --- a/mbedtls/sha512.h +++ /dev/null @@ -1,326 +0,0 @@ -#pragma GCC system_header -/** - * \file sha512.h - * \brief This file contains SHA-384 and SHA-512 definitions and functions. - * - * The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic - * hash functions are defined in FIPS 180-4: Secure Hash Standard (SHS). - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_SHA512_H -#define MBEDTLS_SHA512_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -/* MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED -0x0039 /**< SHA-512 hardware accelerator failed */ -#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA -0x0075 /**< SHA-512 input data was malformed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_SHA512_ALT) -// Regular implementation -// - -/** - * \brief The SHA-512 context structure. - * - * The structure is used both for SHA-384 and for SHA-512 - * checksum calculations. The choice between these two is - * made in the call to mbedtls_sha512_starts_ret(). - */ -typedef struct mbedtls_sha512_context -{ - uint64_t total[2]; /*!< The number of Bytes processed. */ - uint64_t state[8]; /*!< The intermediate digest state. */ - unsigned char buffer[128]; /*!< The data block being processed. */ - int is384; /*!< Determines which function to use: - 0: Use SHA-512, or 1: Use SHA-384. */ -} -mbedtls_sha512_context; - -#else /* MBEDTLS_SHA512_ALT */ -#include "sha512_alt.h" -#endif /* MBEDTLS_SHA512_ALT */ - -/** - * \brief This function initializes a SHA-512 context. - * - * \param ctx The SHA-512 context to initialize. This must - * not be \c NULL. - */ -void mbedtls_sha512_init( mbedtls_sha512_context *ctx ); - -/** - * \brief This function clears a SHA-512 context. - * - * \param ctx The SHA-512 context to clear. This may be \c NULL, - * in which case this function does nothing. If it - * is not \c NULL, it must point to an initialized - * SHA-512 context. - */ -void mbedtls_sha512_free( mbedtls_sha512_context *ctx ); - -/** - * \brief This function clones the state of a SHA-512 context. - * - * \param dst The destination context. This must be initialized. - * \param src The context to clone. This must be initialized. - */ -void mbedtls_sha512_clone( mbedtls_sha512_context *dst, - const mbedtls_sha512_context *src ); - -/** - * \brief This function starts a SHA-384 or SHA-512 checksum - * calculation. - * - * \param ctx The SHA-512 context to use. This must be initialized. - * \param is384 Determines which function to use. This must be - * either \c for SHA-512, or \c 1 for SHA-384. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ); - -/** - * \brief This function feeds an input buffer into an ongoing - * SHA-512 checksum calculation. - * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief This function finishes the SHA-512 operation, and writes - * the result to the output buffer. - * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. - * \param output The SHA-384 or SHA-512 checksum result. - * This must be a writable buffer of length \c 64 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, - unsigned char output[64] ); - -/** - * \brief This function processes a single data block within - * the ongoing SHA-512 computation. - * This function is for internal use only. - * - * \param ctx The SHA-512 context. This must be initialized. - * \param data The buffer holding one block of data. This - * must be a readable buffer of length \c 128 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, - const unsigned char data[128] ); -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif -/** - * \brief This function starts a SHA-384 or SHA-512 checksum - * calculation. - * - * \disabled_deprecated Superseded by mbedtls_sha512_starts_ret() in 2.7.0 - * - * \param ctx The SHA-512 context to use. This must be initialized. - * \param is384 Determines which function to use. This must be either - * \c 0 for SHA-512 or \c 1 for SHA-384. - */ -MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, - int is384 ); - -/** - * \brief This function feeds an input buffer into an ongoing - * SHA-512 checksum calculation. - * - * \disabled_deprecated Superseded by mbedtls_sha512_update_ret() in 2.7.0. - * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - */ -MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx, - const unsigned char *input, - size_t ilen ); - -/** - * \brief This function finishes the SHA-512 operation, and writes - * the result to the output buffer. - * - * \disabled_deprecated Superseded by mbedtls_sha512_finish_ret() in 2.7.0. - * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. - * \param output The SHA-384 or SHA-512 checksum result. This must - * be a writable buffer of size \c 64 Bytes. - */ -MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, - unsigned char output[64] ); - -/** - * \brief This function processes a single data block within - * the ongoing SHA-512 computation. This function is for - * internal use only. - * - * \disabled_deprecated Superseded by mbedtls_internal_sha512_process() in 2.7.0. - * - * \param ctx The SHA-512 context. This must be initialized. - * \param data The buffer holding one block of data. This must be - * a readable buffer of length \c 128 Bytes. - */ -MBEDTLS_DEPRECATED void mbedtls_sha512_process( - mbedtls_sha512_context *ctx, - const unsigned char data[128] ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief This function calculates the SHA-512 or SHA-384 - * checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-512 result is calculated as - * output = SHA-512(input buffer). - * - * \param input The buffer holding the input data. This must be - * a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-384 or SHA-512 checksum result. - * This must be a writable buffer of length \c 64 Bytes. - * \param is384 Determines which function to use. This must be either - * \c 0 for SHA-512, or \c 1 for SHA-384. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha512_ret( const unsigned char *input, - size_t ilen, - unsigned char output[64], - int is384 ); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif - -/** - * \brief This function calculates the SHA-512 or SHA-384 - * checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-512 result is calculated as - * output = SHA-512(input buffer). - * - * \disabled_deprecated Superseded by mbedtls_sha512_ret() in 2.7.0 - * - * \param input The buffer holding the data. This must be a - * readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-384 or SHA-512 checksum result. This must - * be a writable buffer of length \c 64 Bytes. - * \param is384 Determines which function to use. This must be either - * \c 0 for SHA-512, or \c 1 for SHA-384. - */ -MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input, - size_t ilen, - unsigned char output[64], - int is384 ); - -#undef MBEDTLS_DEPRECATED -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_SELF_TEST) - - /** - * \brief The SHA-384 or SHA-512 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_sha512_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_sha512.h */ diff --git a/mbedtls/ssl.h b/mbedtls/ssl.h deleted file mode 100644 index de13d83e7..000000000 --- a/mbedtls/ssl.h +++ /dev/null @@ -1,3294 +0,0 @@ -#pragma GCC system_header -/** - * \file ssl.h - * - * \brief SSL/TLS functions. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_SSL_H -#define MBEDTLS_SSL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "bignum.h" -#include "ecp.h" - -#include "ssl_ciphersuites.h" - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#include "x509_crt.h" -#include "x509_crl.h" -#endif - -#if defined(MBEDTLS_DHM_C) -#include "dhm.h" -#endif - -#if defined(MBEDTLS_ECDH_C) -#include "ecdh.h" -#endif - -#if defined(MBEDTLS_ZLIB_SUPPORT) - -#if defined(MBEDTLS_DEPRECATED_WARNING) -#warning "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and will be removed in the next major revision of the library" -#endif - -#if defined(MBEDTLS_DEPRECATED_REMOVED) -#error "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and cannot be used if MBEDTLS_DEPRECATED_REMOVED is set" -#endif - -#include "zlib.h" -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "platform_time.h" -#endif - -/* - * SSL Error codes - */ -#define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE -0x7080 /**< The requested feature is not available. */ -#define MBEDTLS_ERR_SSL_BAD_INPUT_DATA -0x7100 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_SSL_INVALID_MAC -0x7180 /**< Verification of the message MAC failed. */ -#define MBEDTLS_ERR_SSL_INVALID_RECORD -0x7200 /**< An invalid SSL record was received. */ -#define MBEDTLS_ERR_SSL_CONN_EOF -0x7280 /**< The connection indicated an EOF. */ -#define MBEDTLS_ERR_SSL_UNKNOWN_CIPHER -0x7300 /**< An unknown cipher was received. */ -#define MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN -0x7380 /**< The server has no ciphersuites in common with the client. */ -#define MBEDTLS_ERR_SSL_NO_RNG -0x7400 /**< No RNG was provided to the SSL module. */ -#define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE -0x7480 /**< No client certification received from the client, but required by the authentication mode. */ -#define MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE -0x7500 /**< Our own certificate(s) is/are too large to send in an SSL message. */ -#define MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED -0x7580 /**< The own certificate is not set, but needed by the server. */ -#define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED -0x7600 /**< The own private key or pre-shared key is not set, but needed. */ -#define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED -0x7680 /**< No CA Chain is set, but required to operate. */ -#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE -0x7700 /**< An unexpected message was received from our peer. */ -#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE -0x7780 /**< A fatal alert message was received from our peer. */ -#define MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED -0x7800 /**< Verification of our peer failed. */ -#define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY -0x7880 /**< The peer notified us that the connection is going to be closed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO -0x7900 /**< Processing of the ClientHello handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO -0x7980 /**< Processing of the ServerHello handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE -0x7A00 /**< Processing of the Certificate handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST -0x7A80 /**< Processing of the CertificateRequest handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE -0x7B00 /**< Processing of the ServerKeyExchange handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE -0x7B80 /**< Processing of the ServerHelloDone handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE -0x7C00 /**< Processing of the ClientKeyExchange handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP -0x7C80 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS -0x7D00 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY -0x7D80 /**< Processing of the CertificateVerify handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -0x7E00 /**< Processing of the ChangeCipherSpec handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_FINISHED -0x7E80 /**< Processing of the Finished handshake message failed. */ -#define MBEDTLS_ERR_SSL_ALLOC_FAILED -0x7F00 /**< Memory allocation failed */ -#define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED -0x7F80 /**< Hardware acceleration function returned with error */ -#define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH -0x6F80 /**< Hardware acceleration function skipped / left alone data */ -#define MBEDTLS_ERR_SSL_COMPRESSION_FAILED -0x6F00 /**< Processing of the compression / decompression failed */ -#define MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION -0x6E80 /**< Handshake protocol not within min/max boundaries */ -#define MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET -0x6E00 /**< Processing of the NewSessionTicket handshake message failed. */ -#define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED -0x6D80 /**< Session ticket has expired. */ -#define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH -0x6D00 /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */ -#define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY -0x6C80 /**< Unknown identity received (eg, PSK identity) */ -#define MBEDTLS_ERR_SSL_INTERNAL_ERROR -0x6C00 /**< Internal error (eg, unexpected failure in lower-level module) */ -#define MBEDTLS_ERR_SSL_COUNTER_WRAPPING -0x6B80 /**< A counter would wrap (eg, too many messages exchanged). */ -#define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 /**< Unexpected message at ServerHello in renegotiation. */ -#define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 /**< DTLS client must retry for hello verification */ -#define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 /**< A buffer is too small to receive or write a message */ -#define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6980 /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */ -#define MBEDTLS_ERR_SSL_WANT_READ -0x6900 /**< No data of requested type currently available on underlying transport. */ -#define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 /**< Connection requires a write call. */ -#define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 /**< The operation timed out. */ -#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 /**< The client initiated a reconnect from the same port. */ -#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 /**< Record header looks valid but is not expected. */ -#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */ -#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */ -#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */ -#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */ -#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */ -#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */ -#define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 /**< Invalid value in SSL config */ - -/* - * Various constants - */ -#define MBEDTLS_SSL_MAJOR_VERSION_3 3 -#define MBEDTLS_SSL_MINOR_VERSION_0 0 /*!< SSL v3.0 */ -#define MBEDTLS_SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */ -#define MBEDTLS_SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */ -#define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ - -#define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ -#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ - -#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */ -#define MBEDTLS_SSL_MAX_ALPN_NAME_LEN 255 /*!< Maximum size in bytes of a protocol name in alpn ext., RFC 7301 */ - -#define MBEDTLS_SSL_MAX_ALPN_LIST_LEN 65535 /*!< Maximum size in bytes of list in alpn ext., RFC 7301 */ - -/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c - * NONE must be zero so that memset()ing structure to zero works */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_512 1 /*!< MaxFragmentLength 2^9 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_1024 2 /*!< MaxFragmentLength 2^10 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_2048 3 /*!< MaxFragmentLength 2^11 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_4096 4 /*!< MaxFragmentLength 2^12 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_INVALID 5 /*!< first invalid value */ - -#define MBEDTLS_SSL_IS_CLIENT 0 -#define MBEDTLS_SSL_IS_SERVER 1 - -#define MBEDTLS_SSL_IS_NOT_FALLBACK 0 -#define MBEDTLS_SSL_IS_FALLBACK 1 - -#define MBEDTLS_SSL_EXTENDED_MS_DISABLED 0 -#define MBEDTLS_SSL_EXTENDED_MS_ENABLED 1 - -#define MBEDTLS_SSL_ETM_DISABLED 0 -#define MBEDTLS_SSL_ETM_ENABLED 1 - -#define MBEDTLS_SSL_COMPRESS_NULL 0 -#define MBEDTLS_SSL_COMPRESS_DEFLATE 1 - -#define MBEDTLS_SSL_VERIFY_NONE 0 -#define MBEDTLS_SSL_VERIFY_OPTIONAL 1 -#define MBEDTLS_SSL_VERIFY_REQUIRED 2 -#define MBEDTLS_SSL_VERIFY_UNSET 3 /* Used only for sni_authmode */ - -#define MBEDTLS_SSL_LEGACY_RENEGOTIATION 0 -#define MBEDTLS_SSL_SECURE_RENEGOTIATION 1 - -#define MBEDTLS_SSL_RENEGOTIATION_DISABLED 0 -#define MBEDTLS_SSL_RENEGOTIATION_ENABLED 1 - -#define MBEDTLS_SSL_ANTI_REPLAY_DISABLED 0 -#define MBEDTLS_SSL_ANTI_REPLAY_ENABLED 1 - -#define MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED -1 -#define MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT 16 - -#define MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION 0 -#define MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION 1 -#define MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE 2 - -#define MBEDTLS_SSL_TRUNC_HMAC_DISABLED 0 -#define MBEDTLS_SSL_TRUNC_HMAC_ENABLED 1 -#define MBEDTLS_SSL_TRUNCATED_HMAC_LEN 10 /* 80 bits, rfc 6066 section 7 */ - -#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED 0 -#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED 1 - -#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED 0 -#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED 1 - -#define MBEDTLS_SSL_ARC4_ENABLED 0 -#define MBEDTLS_SSL_ARC4_DISABLED 1 - -#define MBEDTLS_SSL_PRESET_DEFAULT 0 -#define MBEDTLS_SSL_PRESET_SUITEB 2 - -#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1 -#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0 - -/* - * Default range for DTLS retransmission timer value, in milliseconds. - * RFC 6347 4.2.4.1 says from 1 second to 60 seconds. - */ -#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN 1000 -#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX 60000 - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME) -#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ -#endif - -/* - * Maximum fragment length in bytes, - * determines the size of each of the two internal I/O buffers. - * - * Note: the RFC defines the default size of SSL / TLS messages. If you - * change the value here, other clients / servers may not be able to - * communicate with you anymore. Only change this value if you control - * both sides of the connection and have it reduced at both sides, or - * if you're using the Max Fragment Length extension and you know all your - * peers are using it too! - */ -#if !defined(MBEDTLS_SSL_MAX_CONTENT_LEN) -#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ -#endif - -#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN) -#define MBEDTLS_SSL_IN_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN -#endif - -#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN) -#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN -#endif - -/* - * Maximum number of heap-allocated bytes for the purpose of - * DTLS handshake message reassembly and future message buffering. - */ -#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING) -#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 -#endif - -/* \} name SECTION: Module settings */ - -/* - * Length of the verify data for secure renegotiation - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) -#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 36 -#else -#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 12 -#endif - -/* - * Signaling ciphersuite values (SCSV) - */ -#define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ -#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE 0x5600 /**< RFC 7507 section 2 */ - -/* - * Supported Signature and Hash algorithms (For TLS 1.2) - * RFC 5246 section 7.4.1.4.1 - */ -#define MBEDTLS_SSL_HASH_NONE 0 -#define MBEDTLS_SSL_HASH_MD5 1 -#define MBEDTLS_SSL_HASH_SHA1 2 -#define MBEDTLS_SSL_HASH_SHA224 3 -#define MBEDTLS_SSL_HASH_SHA256 4 -#define MBEDTLS_SSL_HASH_SHA384 5 -#define MBEDTLS_SSL_HASH_SHA512 6 - -#define MBEDTLS_SSL_SIG_ANON 0 -#define MBEDTLS_SSL_SIG_RSA 1 -#define MBEDTLS_SSL_SIG_ECDSA 3 - -/* - * Client Certificate Types - * RFC 5246 section 7.4.4 plus RFC 4492 section 5.5 - */ -#define MBEDTLS_SSL_CERT_TYPE_RSA_SIGN 1 -#define MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN 64 - -/* - * Message, alert and handshake types - */ -#define MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC 20 -#define MBEDTLS_SSL_MSG_ALERT 21 -#define MBEDTLS_SSL_MSG_HANDSHAKE 22 -#define MBEDTLS_SSL_MSG_APPLICATION_DATA 23 - -#define MBEDTLS_SSL_ALERT_LEVEL_WARNING 1 -#define MBEDTLS_SSL_ALERT_LEVEL_FATAL 2 - -#define MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY 0 /* 0x00 */ -#define MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE 10 /* 0x0A */ -#define MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC 20 /* 0x14 */ -#define MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED 21 /* 0x15 */ -#define MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW 22 /* 0x16 */ -#define MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30 /* 0x1E */ -#define MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE 40 /* 0x28 */ -#define MBEDTLS_SSL_ALERT_MSG_NO_CERT 41 /* 0x29 */ -#define MBEDTLS_SSL_ALERT_MSG_BAD_CERT 42 /* 0x2A */ -#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT 43 /* 0x2B */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED 44 /* 0x2C */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED 45 /* 0x2D */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN 46 /* 0x2E */ -#define MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER 47 /* 0x2F */ -#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA 48 /* 0x30 */ -#define MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED 49 /* 0x31 */ -#define MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR 50 /* 0x32 */ -#define MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR 51 /* 0x33 */ -#define MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION 60 /* 0x3C */ -#define MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION 70 /* 0x46 */ -#define MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71 /* 0x47 */ -#define MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR 80 /* 0x50 */ -#define MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK 86 /* 0x56 */ -#define MBEDTLS_SSL_ALERT_MSG_USER_CANCELED 90 /* 0x5A */ -#define MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */ -#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */ -#define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */ -#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */ -#define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */ - -#define MBEDTLS_SSL_HS_HELLO_REQUEST 0 -#define MBEDTLS_SSL_HS_CLIENT_HELLO 1 -#define MBEDTLS_SSL_HS_SERVER_HELLO 2 -#define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST 3 -#define MBEDTLS_SSL_HS_NEW_SESSION_TICKET 4 -#define MBEDTLS_SSL_HS_CERTIFICATE 11 -#define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE 12 -#define MBEDTLS_SSL_HS_CERTIFICATE_REQUEST 13 -#define MBEDTLS_SSL_HS_SERVER_HELLO_DONE 14 -#define MBEDTLS_SSL_HS_CERTIFICATE_VERIFY 15 -#define MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE 16 -#define MBEDTLS_SSL_HS_FINISHED 20 - -/* - * TLS extensions - */ -#define MBEDTLS_TLS_EXT_SERVERNAME 0 -#define MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME 0 - -#define MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH 1 - -#define MBEDTLS_TLS_EXT_TRUNCATED_HMAC 4 - -#define MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES 10 -#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS 11 - -#define MBEDTLS_TLS_EXT_SIG_ALG 13 - -#define MBEDTLS_TLS_EXT_ALPN 16 - -#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */ -#define MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET 0x0017 /* 23 */ - -#define MBEDTLS_TLS_EXT_SESSION_TICKET 35 - -#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */ - -#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 - -/* - * Size defines - */ -#if !defined(MBEDTLS_PSK_MAX_LEN) -#define MBEDTLS_PSK_MAX_LEN 32 /* 256 bits */ -#endif - -/* Dummy type used only for its size */ -union mbedtls_ssl_premaster_secret -{ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - unsigned char _pms_dhm[MBEDTLS_MPI_MAX_SIZE]; /* RFC 5246 8.1.2 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - unsigned char _pms_ecdh[MBEDTLS_ECP_MAX_BYTES]; /* RFC 4492 5.10 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - unsigned char _pms_psk[4 + 2 * MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 2 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - unsigned char _pms_dhe_psk[4 + MBEDTLS_MPI_MAX_SIZE - + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 3 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - unsigned char _pms_rsa_psk[52 + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 4 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES - + MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - unsigned char _pms_ecjpake[32]; /* Thread spec: SHA-256 output */ -#endif -}; - -#define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret ) - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * SSL state machine - */ -typedef enum -{ - MBEDTLS_SSL_HELLO_REQUEST, - MBEDTLS_SSL_CLIENT_HELLO, - MBEDTLS_SSL_SERVER_HELLO, - MBEDTLS_SSL_SERVER_CERTIFICATE, - MBEDTLS_SSL_SERVER_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_REQUEST, - MBEDTLS_SSL_SERVER_HELLO_DONE, - MBEDTLS_SSL_CLIENT_CERTIFICATE, - MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_VERIFY, - MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_CLIENT_FINISHED, - MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_SERVER_FINISHED, - MBEDTLS_SSL_FLUSH_BUFFERS, - MBEDTLS_SSL_HANDSHAKE_WRAPUP, - MBEDTLS_SSL_HANDSHAKE_OVER, - MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET, - MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, -} -mbedtls_ssl_states; - -/** - * \brief Callback type: send data on the network. - * - * \note That callback may be either blocking or non-blocking. - * - * \param ctx Context for the send callback (typically a file descriptor) - * \param buf Buffer holding the data to send - * \param len Length of the data to send - * - * \return The callback must return the number of bytes sent if any, - * or a non-zero error code. - * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_WRITE - * must be returned when the operation would block. - * - * \note The callback is allowed to send fewer bytes than requested. - * It must always return the number of bytes actually sent. - */ -typedef int mbedtls_ssl_send_t( void *ctx, - const unsigned char *buf, - size_t len ); - -/** - * \brief Callback type: receive data from the network. - * - * \note That callback may be either blocking or non-blocking. - * - * \param ctx Context for the receive callback (typically a file - * descriptor) - * \param buf Buffer to write the received data to - * \param len Length of the receive buffer - * - * \return The callback must return the number of bytes received, - * or a non-zero error code. - * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ - * must be returned when the operation would block. - * - * \note The callback may receive fewer bytes than the length of the - * buffer. It must always return the number of bytes actually - * received and written to the buffer. - */ -typedef int mbedtls_ssl_recv_t( void *ctx, - unsigned char *buf, - size_t len ); - -/** - * \brief Callback type: receive data from the network, with timeout - * - * \note That callback must block until data is received, or the - * timeout delay expires, or the operation is interrupted by a - * signal. - * - * \param ctx Context for the receive callback (typically a file descriptor) - * \param buf Buffer to write the received data to - * \param len Length of the receive buffer - * \param timeout Maximum nomber of millisecondes to wait for data - * 0 means no timeout (potentially waiting forever) - * - * \return The callback must return the number of bytes received, - * or a non-zero error code: - * \c MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, - * \c MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. - * - * \note The callback may receive fewer bytes than the length of the - * buffer. It must always return the number of bytes actually - * received and written to the buffer. - */ -typedef int mbedtls_ssl_recv_timeout_t( void *ctx, - unsigned char *buf, - size_t len, - uint32_t timeout ); -/** - * \brief Callback type: set a pair of timers/delays to watch - * - * \param ctx Context pointer - * \param int_ms Intermediate delay in milliseconds - * \param fin_ms Final delay in milliseconds - * 0 cancels the current timer. - * - * \note This callback must at least store the necessary information - * for the associated \c mbedtls_ssl_get_timer_t callback to - * return correct information. - * - * \note If using a event-driven style of programming, an event must - * be generated when the final delay is passed. The event must - * cause a call to \c mbedtls_ssl_handshake() with the proper - * SSL context to be scheduled. Care must be taken to ensure - * that at most one such call happens at a time. - * - * \note Only one timer at a time must be running. Calling this - * function while a timer is running must cancel it. Cancelled - * timers must not generate any event. - */ -typedef void mbedtls_ssl_set_timer_t( void * ctx, - uint32_t int_ms, - uint32_t fin_ms ); - -/** - * \brief Callback type: get status of timers/delays - * - * \param ctx Context pointer - * - * \return This callback must return: - * -1 if cancelled (fin_ms == 0), - * 0 if none of the delays have passed, - * 1 if only the intermediate delay has passed, - * 2 if the final delay has passed. - */ -typedef int mbedtls_ssl_get_timer_t( void * ctx ); - -/* Defined below */ -typedef struct mbedtls_ssl_session mbedtls_ssl_session; -typedef struct mbedtls_ssl_context mbedtls_ssl_context; -typedef struct mbedtls_ssl_config mbedtls_ssl_config; - -/* Defined in ssl_internal.h */ -typedef struct mbedtls_ssl_transform mbedtls_ssl_transform; -typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params; -typedef struct mbedtls_ssl_sig_hash_set_t mbedtls_ssl_sig_hash_set_t; -#if defined(MBEDTLS_X509_CRT_PARSE_C) -typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; -#endif -#if defined(MBEDTLS_SSL_PROTO_DTLS) -typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item; -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Callback type: start external signature operation. - * - * This callback is called during an SSL handshake to start - * a signature decryption operation using an - * external processor. The parameter \p cert contains - * the public key; it is up to the callback function to - * determine how to access the associated private key. - * - * This function typically sends or enqueues a request, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * The parameters \p ssl and \p cert are guaranteed to remain - * valid throughout the handshake. On the other hand, this - * function must save the contents of \p hash if the value - * is needed for later processing, because the \p hash buffer - * is no longer valid after this function returns. - * - * This function may call mbedtls_ssl_set_async_operation_data() - * to store an operation context for later retrieval - * by the resume or cancel callback. - * - * \note For RSA signatures, this function must produce output - * that is consistent with PKCS#1 v1.5 in the same way as - * mbedtls_rsa_pkcs1_sign(). Before the private key operation, - * apply the padding steps described in RFC 8017, section 9.2 - * "EMSA-PKCS1-v1_5" as follows. - * - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5 - * encoding, treating \p hash as the DigestInfo to be - * padded. In other words, apply EMSA-PKCS1-v1_5 starting - * from step 3, with `T = hash` and `tLen = hash_len`. - * - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5 - * encoding, treating \p hash as the hash to be encoded and - * padded. In other words, apply EMSA-PKCS1-v1_5 starting - * from step 2, with `digestAlgorithm` obtained by calling - * mbedtls_oid_get_oid_by_md() on \p md_alg. - * - * \note For ECDSA signatures, the output format is the DER encoding - * `Ecdsa-Sig-Value` defined in - * [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4). - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param cert Certificate containing the public key. - * In simple cases, this is one of the pointers passed to - * mbedtls_ssl_conf_own_cert() when configuring the SSL - * connection. However, if other callbacks are used, this - * property may not hold. For example, if an SNI callback - * is registered with mbedtls_ssl_conf_sni(), then - * this callback determines what certificate is used. - * \param md_alg Hash algorithm. - * \param hash Buffer containing the hash. This buffer is - * no longer valid when the function returns. - * \param hash_len Size of the \c hash buffer in bytes. - * - * \return 0 if the operation was started successfully and the SSL - * stack should call the resume callback immediately. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * was started successfully and the SSL stack should return - * immediately without calling the resume callback yet. - * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external - * processor does not support this key. The SSL stack will - * use the private key object instead. - * \return Any other error indicates a fatal failure and is - * propagated up the call chain. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *cert, - mbedtls_md_type_t md_alg, - const unsigned char *hash, - size_t hash_len ); - -/** - * \brief Callback type: start external decryption operation. - * - * This callback is called during an SSL handshake to start - * an RSA decryption operation using an - * external processor. The parameter \p cert contains - * the public key; it is up to the callback function to - * determine how to access the associated private key. - * - * This function typically sends or enqueues a request, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * The parameters \p ssl and \p cert are guaranteed to remain - * valid throughout the handshake. On the other hand, this - * function must save the contents of \p input if the value - * is needed for later processing, because the \p input buffer - * is no longer valid after this function returns. - * - * This function may call mbedtls_ssl_set_async_operation_data() - * to store an operation context for later retrieval - * by the resume or cancel callback. - * - * \warning RSA decryption as used in TLS is subject to a potential - * timing side channel attack first discovered by Bleichenbacher - * in 1998. This attack can be remotely exploitable - * in practice. To avoid this attack, you must ensure that - * if the callback performs an RSA decryption, the time it - * takes to execute and return the result does not depend - * on whether the RSA decryption succeeded or reported - * invalid padding. - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param cert Certificate containing the public key. - * In simple cases, this is one of the pointers passed to - * mbedtls_ssl_conf_own_cert() when configuring the SSL - * connection. However, if other callbacks are used, this - * property may not hold. For example, if an SNI callback - * is registered with mbedtls_ssl_conf_sni(), then - * this callback determines what certificate is used. - * \param input Buffer containing the input ciphertext. This buffer - * is no longer valid when the function returns. - * \param input_len Size of the \p input buffer in bytes. - * - * \return 0 if the operation was started successfully and the SSL - * stack should call the resume callback immediately. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * was started successfully and the SSL stack should return - * immediately without calling the resume callback yet. - * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external - * processor does not support this key. The SSL stack will - * use the private key object instead. - * \return Any other error indicates a fatal failure and is - * propagated up the call chain. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *cert, - const unsigned char *input, - size_t input_len ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Callback type: resume external operation. - * - * This callback is called during an SSL handshake to resume - * an external operation started by the - * ::mbedtls_ssl_async_sign_t or - * ::mbedtls_ssl_async_decrypt_t callback. - * - * This function typically checks the status of a pending - * request or causes the request queue to make progress, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * This function may call mbedtls_ssl_get_async_operation_data() - * to retrieve an operation context set by the start callback. - * It may call mbedtls_ssl_set_async_operation_data() to modify - * this context. - * - * Note that when this function returns a status other than - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any - * resources associated with the operation. - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param output Buffer containing the output (signature or decrypted - * data) on success. - * \param output_len On success, number of bytes written to \p output. - * \param output_size Size of the \p output buffer in bytes. - * - * \return 0 if output of the operation is available in the - * \p output buffer. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * is still in progress. Subsequent requests for progress - * on the SSL connection will call the resume callback - * again. - * \return Any other error means that the operation is aborted. - * The SSL handshake is aborted. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl, - unsigned char *output, - size_t *output_len, - size_t output_size ); - -/** - * \brief Callback type: cancel external operation. - * - * This callback is called if an SSL connection is closed - * while an asynchronous operation is in progress. Note that - * this callback is not called if the - * ::mbedtls_ssl_async_resume_t callback has run and has - * returned a value other than - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case - * the asynchronous operation has already completed. - * - * This function may call mbedtls_ssl_get_async_operation_data() - * to retrieve an operation context set by the start callback. - * - * \param ssl The SSL connection instance. It should not be - * modified. - */ -typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -/* - * This structure is used for storing current session data. - */ -struct mbedtls_ssl_session -{ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t start; /*!< starting time */ -#endif - int ciphersuite; /*!< chosen ciphersuite */ - int compression; /*!< chosen compression */ - size_t id_len; /*!< session id length */ - unsigned char id[32]; /*!< session identifier */ - unsigned char master[48]; /*!< the master secret */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - uint32_t verify_result; /*!< verification result */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - unsigned char *ticket; /*!< RFC 5077 session ticket */ - size_t ticket_len; /*!< session ticket length */ - uint32_t ticket_lifetime; /*!< ticket lifetime hint */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */ -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - int trunc_hmac; /*!< flag for truncated hmac activation */ -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - int encrypt_then_mac; /*!< flag for EtM activation */ -#endif -}; - -/** - * SSL/TLS configuration to be shared between mbedtls_ssl_context structures. - */ -struct mbedtls_ssl_config -{ - /* Group items by size (largest first) to minimize padding overhead */ - - /* - * Pointers - */ - - const int *ciphersuite_list[4]; /*!< allowed ciphersuites per version */ - - /** Callback for printing debug output */ - void (*f_dbg)(void *, int, const char *, int, const char *); - void *p_dbg; /*!< context for the debug function */ - - /** Callback for getting (pseudo-)random numbers */ - int (*f_rng)(void *, unsigned char *, size_t); - void *p_rng; /*!< context for the RNG function */ - - /** Callback to retrieve a session from the cache */ - int (*f_get_cache)(void *, mbedtls_ssl_session *); - /** Callback to store a session into the cache */ - int (*f_set_cache)(void *, const mbedtls_ssl_session *); - void *p_cache; /*!< context for cache callbacks */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - /** Callback for setting cert according to SNI extension */ - int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, size_t); - void *p_sni; /*!< context for SNI callback */ -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /** Callback to customize X.509 certificate chain verification */ - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); - void *p_vrfy; /*!< context for X.509 verify calllback */ -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - /** Callback to retrieve PSK key from identity */ - int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, size_t); - void *p_psk; /*!< context for PSK callback */ -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - /** Callback to create & write a cookie for ClientHello veirifcation */ - int (*f_cookie_write)( void *, unsigned char **, unsigned char *, - const unsigned char *, size_t ); - /** Callback to verify validity of a ClientHello cookie */ - int (*f_cookie_check)( void *, const unsigned char *, size_t, - const unsigned char *, size_t ); - void *p_cookie; /*!< context for the cookie callbacks */ -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) - /** Callback to create & write a session ticket */ - int (*f_ticket_write)( void *, const mbedtls_ssl_session *, - unsigned char *, const unsigned char *, size_t *, uint32_t * ); - /** Callback to parse a session ticket into a session structure */ - int (*f_ticket_parse)( void *, mbedtls_ssl_session *, unsigned char *, size_t); - void *p_ticket; /*!< context for the ticket callbacks */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) - /** Callback to export key block and master secret */ - int (*f_export_keys)( void *, const unsigned char *, - const unsigned char *, size_t, size_t, size_t ); - void *p_export_keys; /*!< context for key export callback */ -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ - mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ - mbedtls_x509_crt *ca_chain; /*!< trusted CAs */ - mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */ - mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */ - mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */ - void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */ -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - const int *sig_hashes; /*!< allowed signature hashes */ -#endif - -#if defined(MBEDTLS_ECP_C) - const mbedtls_ecp_group_id *curve_list; /*!< allowed curves */ -#endif - -#if defined(MBEDTLS_DHM_C) - mbedtls_mpi dhm_P; /*!< prime modulus for DHM */ - mbedtls_mpi dhm_G; /*!< generator for DHM */ -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - unsigned char *psk; /*!< pre-shared key. This field should - only be set via - mbedtls_ssl_conf_psk() */ - size_t psk_len; /*!< length of the pre-shared key. This - field should only be set via - mbedtls_ssl_conf_psk() */ - unsigned char *psk_identity; /*!< identity for PSK negotiation. This - field should only be set via - mbedtls_ssl_conf_psk() */ - size_t psk_identity_len;/*!< length of identity. This field should - only be set via - mbedtls_ssl_conf_psk() */ -#endif - -#if defined(MBEDTLS_SSL_ALPN) - const char **alpn_list; /*!< ordered list of protocols */ -#endif - - /* - * Numerical settings (int then char) - */ - - uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint32_t hs_timeout_min; /*!< initial value of the handshake - retransmission timeout (ms) */ - uint32_t hs_timeout_max; /*!< maximum value of the handshake - retransmission timeout (ms) */ -#endif - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renego_max_records; /*!< grace period for renegotiation */ - unsigned char renego_period[8]; /*!< value of the record counters - that triggers renegotiation */ -#endif - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - unsigned int badmac_limit; /*!< limit of records with a bad MAC */ -#endif - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) - unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */ -#endif - - unsigned char max_major_ver; /*!< max. major version used */ - unsigned char max_minor_ver; /*!< max. minor version used */ - unsigned char min_major_ver; /*!< min. major version used */ - unsigned char min_minor_ver; /*!< min. minor version used */ - - /* - * Flags (bitfields) - */ - - unsigned int endpoint : 1; /*!< 0: client, 1: server */ - unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */ - unsigned int authmode : 2; /*!< MBEDTLS_SSL_VERIFY_XXX */ - /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */ - unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX */ -#if defined(MBEDTLS_ARC4_C) - unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites? */ -#endif -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - unsigned int mfl_code : 3; /*!< desired fragment length */ -#endif -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac? */ -#endif -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - unsigned int extended_ms : 1; /*!< negotiate extended master secret? */ -#endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - unsigned int anti_replay : 1; /*!< detect and prevent replay? */ -#endif -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - unsigned int cbc_record_splitting : 1; /*!< do cbc record splitting */ -#endif -#if defined(MBEDTLS_SSL_RENEGOTIATION) - unsigned int disable_renegotiation : 1; /*!< disable renegotiation? */ -#endif -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - unsigned int trunc_hmac : 1; /*!< negotiate truncated hmac? */ -#endif -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - unsigned int session_tickets : 1; /*!< use session tickets? */ -#endif -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) - unsigned int fallback : 1; /*!< is this a fallback? */ -#endif -#if defined(MBEDTLS_SSL_SRV_C) - unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in - Certificate Request messages? */ -#endif -}; - - -struct mbedtls_ssl_context -{ - const mbedtls_ssl_config *conf; /*!< configuration information */ - - /* - * Miscellaneous - */ - int state; /*!< SSL handshake: current state */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renego_status; /*!< Initial, in progress, pending? */ - int renego_records_seen; /*!< Records since renego request, or with DTLS, - number of retransmissions of request if - renego_max_records is < 0 */ -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - int major_ver; /*!< equal to MBEDTLS_SSL_MAJOR_VERSION_3 */ - int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */ - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - unsigned badmac_seen; /*!< records with a bad MAC received */ -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ - - mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ - mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */ - mbedtls_ssl_recv_timeout_t *f_recv_timeout; - /*!< Callback for network receive with timeout */ - - void *p_bio; /*!< context for I/O operations */ - - /* - * Session layer - */ - mbedtls_ssl_session *session_in; /*!< current session data (in) */ - mbedtls_ssl_session *session_out; /*!< current session data (out) */ - mbedtls_ssl_session *session; /*!< negotiated session data */ - mbedtls_ssl_session *session_negotiate; /*!< session data in negotiation */ - - mbedtls_ssl_handshake_params *handshake; /*!< params required only during - the handshake process */ - - /* - * Record layer transformations - */ - mbedtls_ssl_transform *transform_in; /*!< current transform params (in) */ - mbedtls_ssl_transform *transform_out; /*!< current transform params (in) */ - mbedtls_ssl_transform *transform; /*!< negotiated transform params */ - mbedtls_ssl_transform *transform_negotiate; /*!< transform params in negotiation */ - - /* - * Timers - */ - void *p_timer; /*!< context for the timer callbacks */ - - mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */ - mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */ - - /* - * Record layer (incoming data) - */ - unsigned char *in_buf; /*!< input buffer */ - unsigned char *in_ctr; /*!< 64-bit incoming message counter - TLS: maintained by us - DTLS: read from peer */ - unsigned char *in_hdr; /*!< start of record header */ - unsigned char *in_len; /*!< two-bytes message length field */ - unsigned char *in_iv; /*!< ivlen-byte IV */ - unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */ - unsigned char *in_offt; /*!< read offset in application data */ - - int in_msgtype; /*!< record header: message type */ - size_t in_msglen; /*!< record header: message length */ - size_t in_left; /*!< amount of data read so far */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint16_t in_epoch; /*!< DTLS epoch for incoming records */ - size_t next_record_offset; /*!< offset of the next record in datagram - (equal to in_left if none) */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - uint64_t in_window_top; /*!< last validated record seq_num */ - uint64_t in_window; /*!< bitmask for replay detection */ -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - - size_t in_hslen; /*!< current handshake message length, - including the handshake header */ - int nb_zero; /*!< # of 0-length encrypted messages */ - - int keep_current_message; /*!< drop or reuse current message - on next call to record layer? */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint8_t disable_datagram_packing; /*!< Disable packing multiple records - * within a single datagram. */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * Record layer (outgoing data) - */ - unsigned char *out_buf; /*!< output buffer */ - unsigned char *out_ctr; /*!< 64-bit outgoing message counter */ - unsigned char *out_hdr; /*!< start of record header */ - unsigned char *out_len; /*!< two-bytes message length field */ - unsigned char *out_iv; /*!< ivlen-byte IV */ - unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */ - - int out_msgtype; /*!< record header: message type */ - size_t out_msglen; /*!< record header: message length */ - size_t out_left; /*!< amount of data not yet written */ - - unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_ZLIB_SUPPORT) - unsigned char *compress_buf; /*!< zlib data buffer */ -#endif /* MBEDTLS_ZLIB_SUPPORT */ -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - signed char split_done; /*!< current record already splitted? */ -#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ - - /* - * PKI layer - */ - int client_auth; /*!< flag for client auth. */ - - /* - * User settings - */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) - char *hostname; /*!< expected peer CN for verification - (and SNI if available) */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_ALPN) - const char *alpn_chosen; /*!< negotiated protocol */ -#endif /* MBEDTLS_SSL_ALPN */ - - /* - * Information for DTLS hello verify - */ -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - unsigned char *cli_id; /*!< transport-level ID of the client */ - size_t cli_id_len; /*!< length of cli_id */ -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ - - /* - * Secure renegotiation - */ - /* needed to know when to send extension on server */ - int secure_renegotiation; /*!< does peer support legacy or - secure renegotiation */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - size_t verify_data_len; /*!< length of verify data stored */ - char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ - char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ -#endif /* MBEDTLS_SSL_RENEGOTIATION */ -}; - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - -#define MBEDTLS_SSL_CHANNEL_OUTBOUND 0 -#define MBEDTLS_SSL_CHANNEL_INBOUND 1 - -extern int (*mbedtls_ssl_hw_record_init)(mbedtls_ssl_context *ssl, - const unsigned char *key_enc, const unsigned char *key_dec, - size_t keylen, - const unsigned char *iv_enc, const unsigned char *iv_dec, - size_t ivlen, - const unsigned char *mac_enc, const unsigned char *mac_dec, - size_t maclen); -extern int (*mbedtls_ssl_hw_record_activate)(mbedtls_ssl_context *ssl, int direction); -extern int (*mbedtls_ssl_hw_record_reset)(mbedtls_ssl_context *ssl); -extern int (*mbedtls_ssl_hw_record_write)(mbedtls_ssl_context *ssl); -extern int (*mbedtls_ssl_hw_record_read)(mbedtls_ssl_context *ssl); -extern int (*mbedtls_ssl_hw_record_finish)(mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - -/** - * \brief Return the name of the ciphersuite associated with the - * given ID - * - * \param ciphersuite_id SSL ciphersuite ID - * - * \return a string containing the ciphersuite name - */ -const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id ); - -/** - * \brief Return the ID of the ciphersuite associated with the - * given name - * - * \param ciphersuite_name SSL ciphersuite name - * - * \return the ID with the ciphersuite or 0 if not found - */ -int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name ); - -/** - * \brief Initialize an SSL context - * Just makes the context ready for mbedtls_ssl_setup() or - * mbedtls_ssl_free() - * - * \param ssl SSL context - */ -void mbedtls_ssl_init( mbedtls_ssl_context *ssl ); - -/** - * \brief Set up an SSL context for use - * - * \note No copy of the configuration context is made, it can be - * shared by many mbedtls_ssl_context structures. - * - * \warning The conf structure will be accessed during the session. - * It must not be modified or freed as long as the session - * is active. - * - * \warning This function must be called exactly once per context. - * Calling mbedtls_ssl_setup again is not supported, even - * if no session is active. - * - * \param ssl SSL context - * \param conf SSL configuration to use - * - * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED if - * memory allocation failed - */ -int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, - const mbedtls_ssl_config *conf ); - -/** - * \brief Reset an already initialized SSL context for re-use - * while retaining application-set variables, function - * pointers and data. - * - * \param ssl SSL context - * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED, - MBEDTLS_ERR_SSL_HW_ACCEL_FAILED or - * MBEDTLS_ERR_SSL_COMPRESSION_FAILED - */ -int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ); - -/** - * \brief Set the current endpoint type - * - * \param conf SSL configuration - * \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER - */ -void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ); - -/** - * \brief Set the transport type (TLS or DTLS). - * Default: TLS - * - * \note For DTLS, you must either provide a recv callback that - * doesn't block, or one that handles timeouts, see - * \c mbedtls_ssl_set_bio(). You also need to provide timer - * callbacks with \c mbedtls_ssl_set_timer_cb(). - * - * \param conf SSL configuration - * \param transport transport type: - * MBEDTLS_SSL_TRANSPORT_STREAM for TLS, - * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS. - */ -void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ); - -/** - * \brief Set the certificate verification mode - * Default: NONE on server, REQUIRED on client - * - * \param conf SSL configuration - * \param authmode can be: - * - * MBEDTLS_SSL_VERIFY_NONE: peer certificate is not checked - * (default on server) - * (insecure on client) - * - * MBEDTLS_SSL_VERIFY_OPTIONAL: peer certificate is checked, however the - * handshake continues even if verification failed; - * mbedtls_ssl_get_verify_result() can be called after the - * handshake is complete. - * - * MBEDTLS_SSL_VERIFY_REQUIRED: peer *must* present a valid certificate, - * handshake is aborted if verification failed. - * (default on client) - * - * \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode. - * With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at - * the right time(s), which may not be obvious, while REQUIRED always perform - * the verification as soon as possible. For example, REQUIRED was protecting - * against the "triple handshake" attack even before it was found. - */ -void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set the verification callback (Optional). - * - * If set, the verify callback is called for each - * certificate in the chain. For implementation - * information, please see \c mbedtls_x509_crt_verify() - * - * \param conf SSL configuration - * \param f_vrfy verification function - * \param p_vrfy verification parameter - */ -void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Set the random number generator callback - * - * \param conf SSL configuration - * \param f_rng RNG function - * \param p_rng RNG parameter - */ -void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief Set the debug callback - * - * The callback has the following argument: - * void * opaque context for the callback - * int debug level - * const char * file name - * int line number - * const char * message - * - * \param conf SSL configuration - * \param f_dbg debug function - * \param p_dbg debug parameter - */ -void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, - void (*f_dbg)(void *, int, const char *, int, const char *), - void *p_dbg ); - -/** - * \brief Set the underlying BIO callbacks for write, read and - * read-with-timeout. - * - * \param ssl SSL context - * \param p_bio parameter (context) shared by BIO callbacks - * \param f_send write callback - * \param f_recv read callback - * \param f_recv_timeout blocking read callback with timeout. - * - * \note One of f_recv or f_recv_timeout can be NULL, in which case - * the other is used. If both are non-NULL, f_recv_timeout is - * used and f_recv is ignored (as if it were NULL). - * - * \note The two most common use cases are: - * - non-blocking I/O, f_recv != NULL, f_recv_timeout == NULL - * - blocking I/O, f_recv == NULL, f_recv_timout != NULL - * - * \note For DTLS, you need to provide either a non-NULL - * f_recv_timeout callback, or a f_recv that doesn't block. - * - * \note See the documentations of \c mbedtls_ssl_send_t, - * \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for - * the conventions those callbacks must follow. - * - * \note On some platforms, net_sockets.c provides - * \c mbedtls_net_send(), \c mbedtls_net_recv() and - * \c mbedtls_net_recv_timeout() that are suitable to be used - * here. - */ -void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, - void *p_bio, - mbedtls_ssl_send_t *f_send, - mbedtls_ssl_recv_t *f_recv, - mbedtls_ssl_recv_timeout_t *f_recv_timeout ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -/** - * \brief Set the Maximum Tranport Unit (MTU). - * Special value: 0 means unset (no limit). - * This represents the maximum size of a datagram payload - * handled by the transport layer (usually UDP) as determined - * by the network link and stack. In practice, this controls - * the maximum size datagram the DTLS layer will pass to the - * \c f_send() callback set using \c mbedtls_ssl_set_bio(). - * - * \note The limit on datagram size is converted to a limit on - * record payload by subtracting the current overhead of - * encapsulation and encryption/authentication if any. - * - * \note This can be called at any point during the connection, for - * example when a Path Maximum Transfer Unit (PMTU) - * estimate becomes available from other sources, - * such as lower (or higher) protocol layers. - * - * \note This setting only controls the size of the packets we send, - * and does not restrict the size of the datagrams we're - * willing to receive. Client-side, you can request the - * server to use smaller records with \c - * mbedtls_ssl_conf_max_frag_len(). - * - * \note If both a MTU and a maximum fragment length have been - * configured (or negotiated with the peer), the resulting - * lower limit on record payload (see first note) is used. - * - * \note This can only be used to decrease the maximum size - * of datagrams (hence records, see first note) sent. It - * cannot be used to increase the maximum size of records over - * the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN. - * - * \note Values lower than the current record layer expansion will - * result in an error when trying to send data. - * - * \note Using record compression together with a non-zero MTU value - * will result in an error when trying to send data. - * - * \param ssl SSL context - * \param mtu Value of the path MTU in bytes - */ -void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -/** - * \brief Set the timeout period for mbedtls_ssl_read() - * (Default: no timeout.) - * - * \param conf SSL configuration context - * \param timeout Timeout value in milliseconds. - * Use 0 for no timeout (default). - * - * \note With blocking I/O, this will only work if a non-NULL - * \c f_recv_timeout was set with \c mbedtls_ssl_set_bio(). - * With non-blocking I/O, this will only work if timer - * callbacks were set with \c mbedtls_ssl_set_timer_cb(). - * - * \note With non-blocking I/O, you may also skip this function - * altogether and handle timeouts at the application layer. - */ -void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); - -/** - * \brief Set the timer callbacks (Mandatory for DTLS.) - * - * \param ssl SSL context - * \param p_timer parameter (context) shared by timer callbacks - * \param f_set_timer set timer callback - * \param f_get_timer get timer callback. Must return: - * - * \note See the documentation of \c mbedtls_ssl_set_timer_t and - * \c mbedtls_ssl_get_timer_t for the conventions this pair of - * callbacks must follow. - * - * \note On some platforms, timing.c provides - * \c mbedtls_timing_set_delay() and - * \c mbedtls_timing_get_delay() that are suitable for using - * here, except if using an event-driven style. - * - * \note See also the "DTLS tutorial" article in our knowledge base. - * https://tls.mbed.org/kb/how-to/dtls-tutorial - */ -void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, - void *p_timer, - mbedtls_ssl_set_timer_t *f_set_timer, - mbedtls_ssl_get_timer_t *f_get_timer ); - -/** - * \brief Callback type: generate and write session ticket - * - * \note This describes what a callback implementation should do. - * This callback should generate an encrypted and - * authenticated ticket for the session and write it to the - * output buffer. Here, ticket means the opaque ticket part - * of the NewSessionTicket structure of RFC 5077. - * - * \param p_ticket Context for the callback - * \param session SSL session to be written in the ticket - * \param start Start of the output buffer - * \param end End of the output buffer - * \param tlen On exit, holds the length written - * \param lifetime On exit, holds the lifetime of the ticket in seconds - * - * \return 0 if successful, or - * a specific MBEDTLS_ERR_XXX code. - */ -typedef int mbedtls_ssl_ticket_write_t( void *p_ticket, - const mbedtls_ssl_session *session, - unsigned char *start, - const unsigned char *end, - size_t *tlen, - uint32_t *lifetime ); - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) -/** - * \brief Callback type: Export key block and master secret - * - * \note This is required for certain uses of TLS, e.g. EAP-TLS - * (RFC 5216) and Thread. The key pointers are ephemeral and - * therefore must not be stored. The master secret and keys - * should not be used directly except as an input to a key - * derivation function. - * - * \param p_expkey Context for the callback - * \param ms Pointer to master secret (fixed length: 48 bytes) - * \param kb Pointer to key block, see RFC 5246 section 6.3 - * (variable length: 2 * maclen + 2 * keylen + 2 * ivlen). - * \param maclen MAC length - * \param keylen Key length - * \param ivlen IV length - * - * \return 0 if successful, or - * a specific MBEDTLS_ERR_XXX code. - */ -typedef int mbedtls_ssl_export_keys_t( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen ); -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ - -/** - * \brief Callback type: parse and load session ticket - * - * \note This describes what a callback implementation should do. - * This callback should parse a session ticket as generated - * by the corresponding mbedtls_ssl_ticket_write_t function, - * and, if the ticket is authentic and valid, load the - * session. - * - * \note The implementation is allowed to modify the first len - * bytes of the input buffer, eg to use it as a temporary - * area for the decrypted ticket contents. - * - * \param p_ticket Context for the callback - * \param session SSL session to be loaded - * \param buf Start of the buffer containing the ticket - * \param len Length of the ticket. - * - * \return 0 if successful, or - * MBEDTLS_ERR_SSL_INVALID_MAC if not authentic, or - * MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED if expired, or - * any other non-zero code for other failures. - */ -typedef int mbedtls_ssl_ticket_parse_t( void *p_ticket, - mbedtls_ssl_session *session, - unsigned char *buf, - size_t len ); - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Configure SSL session ticket callbacks (server only). - * (Default: none.) - * - * \note On server, session tickets are enabled by providing - * non-NULL callbacks. - * - * \note On client, use \c mbedtls_ssl_conf_session_tickets(). - * - * \param conf SSL configuration context - * \param f_ticket_write Callback for writing a ticket - * \param f_ticket_parse Callback for parsing a ticket - * \param p_ticket Context shared by the two callbacks - */ -void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_ticket_write_t *f_ticket_write, - mbedtls_ssl_ticket_parse_t *f_ticket_parse, - void *p_ticket ); -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) -/** - * \brief Configure key export callback. - * (Default: none.) - * - * \note See \c mbedtls_ssl_export_keys_t. - * - * \param conf SSL configuration context - * \param f_export_keys Callback for exporting keys - * \param p_export_keys Context for the callback - */ -void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys ); -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -/** - * \brief Configure asynchronous private key operation callbacks. - * - * \param conf SSL configuration context - * \param f_async_sign Callback to start a signature operation. See - * the description of ::mbedtls_ssl_async_sign_t - * for more information. This may be \c NULL if the - * external processor does not support any signature - * operation; in this case the private key object - * associated with the certificate will be used. - * \param f_async_decrypt Callback to start a decryption operation. See - * the description of ::mbedtls_ssl_async_decrypt_t - * for more information. This may be \c NULL if the - * external processor does not support any decryption - * operation; in this case the private key object - * associated with the certificate will be used. - * \param f_async_resume Callback to resume an asynchronous operation. See - * the description of ::mbedtls_ssl_async_resume_t - * for more information. This may not be \c NULL unless - * \p f_async_sign and \p f_async_decrypt are both - * \c NULL. - * \param f_async_cancel Callback to cancel an asynchronous operation. See - * the description of ::mbedtls_ssl_async_cancel_t - * for more information. This may be \c NULL if - * no cleanup is needed. - * \param config_data A pointer to configuration data which can be - * retrieved with - * mbedtls_ssl_conf_get_async_config_data(). The - * library stores this value without dereferencing it. - */ -void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_async_sign_t *f_async_sign, - mbedtls_ssl_async_decrypt_t *f_async_decrypt, - mbedtls_ssl_async_resume_t *f_async_resume, - mbedtls_ssl_async_cancel_t *f_async_cancel, - void *config_data ); - -/** - * \brief Retrieve the configuration data set by - * mbedtls_ssl_conf_async_private_cb(). - * - * \param conf SSL configuration context - * \return The configuration data set by - * mbedtls_ssl_conf_async_private_cb(). - */ -void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ); - -/** - * \brief Retrieve the asynchronous operation user context. - * - * \note This function may only be called while a handshake - * is in progress. - * - * \param ssl The SSL context to access. - * - * \return The asynchronous operation user context that was last - * set during the current handshake. If - * mbedtls_ssl_set_async_operation_data() has not yet been - * called during the current handshake, this function returns - * \c NULL. - */ -void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ); - -/** - * \brief Retrieve the asynchronous operation user context. - * - * \note This function may only be called while a handshake - * is in progress. - * - * \param ssl The SSL context to access. - * \param ctx The new value of the asynchronous operation user context. - * Call mbedtls_ssl_get_async_operation_data() later during the - * same handshake to retrieve this value. - */ -void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, - void *ctx ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -/** - * \brief Callback type: generate a cookie - * - * \param ctx Context for the callback - * \param p Buffer to write to, - * must be updated to point right after the cookie - * \param end Pointer to one past the end of the output buffer - * \param info Client ID info that was passed to - * \c mbedtls_ssl_set_client_transport_id() - * \param ilen Length of info in bytes - * - * \return The callback must return 0 on success, - * or a negative error code. - */ -typedef int mbedtls_ssl_cookie_write_t( void *ctx, - unsigned char **p, unsigned char *end, - const unsigned char *info, size_t ilen ); - -/** - * \brief Callback type: verify a cookie - * - * \param ctx Context for the callback - * \param cookie Cookie to verify - * \param clen Length of cookie - * \param info Client ID info that was passed to - * \c mbedtls_ssl_set_client_transport_id() - * \param ilen Length of info in bytes - * - * \return The callback must return 0 if cookie is valid, - * or a negative error code. - */ -typedef int mbedtls_ssl_cookie_check_t( void *ctx, - const unsigned char *cookie, size_t clen, - const unsigned char *info, size_t ilen ); - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Register callbacks for DTLS cookies - * (Server only. DTLS only.) - * - * Default: dummy callbacks that fail, in order to force you to - * register working callbacks (and initialize their context). - * - * To disable HelloVerifyRequest, register NULL callbacks. - * - * \warning Disabling hello verification allows your server to be used - * for amplification in DoS attacks against other hosts. - * Only disable if you known this can't happen in your - * particular environment. - * - * \note See comments on \c mbedtls_ssl_handshake() about handling - * the MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED that is expected - * on the first handshake attempt when this is enabled. - * - * \note This is also necessary to handle client reconnection from - * the same port as described in RFC 6347 section 4.2.8 (only - * the variant with cookies is supported currently). See - * comments on \c mbedtls_ssl_read() for details. - * - * \param conf SSL configuration - * \param f_cookie_write Cookie write callback - * \param f_cookie_check Cookie check callback - * \param p_cookie Context for both callbacks - */ -void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf, - mbedtls_ssl_cookie_write_t *f_cookie_write, - mbedtls_ssl_cookie_check_t *f_cookie_check, - void *p_cookie ); - -/** - * \brief Set client's transport-level identification info. - * (Server only. DTLS only.) - * - * This is usually the IP address (and port), but could be - * anything identify the client depending on the underlying - * network stack. Used for HelloVerifyRequest with DTLS. - * This is *not* used to route the actual packets. - * - * \param ssl SSL context - * \param info Transport-level info identifying the client (eg IP + port) - * \param ilen Length of info in bytes - * - * \note An internal copy is made, so the info buffer can be reused. - * - * \return 0 on success, - * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used on client, - * MBEDTLS_ERR_SSL_ALLOC_FAILED if out of memory. - */ -int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, - const unsigned char *info, - size_t ilen ); - -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -/** - * \brief Enable or disable anti-replay protection for DTLS. - * (DTLS only, no effect on TLS.) - * Default: enabled. - * - * \param conf SSL configuration - * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED. - * - * \warning Disabling this is a security risk unless the application - * protocol handles duplicated packets in a safe way. You - * should not disable this without careful consideration. - * However, if your application already detects duplicated - * packets and needs information about them to adjust its - * transmission strategy, then you'll want to disable this. - */ -void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ); -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) -/** - * \brief Set a limit on the number of records with a bad MAC - * before terminating the connection. - * (DTLS only, no effect on TLS.) - * Default: 0 (disabled). - * - * \param conf SSL configuration - * \param limit Limit, or 0 to disable. - * - * \note If the limit is N, then the connection is terminated when - * the Nth non-authentic record is seen. - * - * \note Records with an invalid header are not counted, only the - * ones going through the authentication-decryption phase. - * - * \note This is a security trade-off related to the fact that it's - * often relatively easy for an active attacker ot inject UDP - * datagrams. On one hand, setting a low limit here makes it - * easier for such an attacker to forcibly terminated a - * connection. On the other hand, a high limit or no limit - * might make us waste resources checking authentication on - * many bogus packets. - */ -void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ); -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -/** - * \brief Allow or disallow packing of multiple handshake records - * within a single datagram. - * - * \param ssl The SSL context to configure. - * \param allow_packing This determines whether datagram packing may - * be used or not. A value of \c 0 means that every - * record will be sent in a separate datagram; a - * value of \c 1 means that, if space permits, - * multiple handshake messages (including CCS) belonging to - * a single flight may be packed within a single datagram. - * - * \note This is enabled by default and should only be disabled - * for test purposes, or if datagram packing causes - * interoperability issues with peers that don't support it. - * - * \note Allowing datagram packing reduces the network load since - * there's less overhead if multiple messages share the same - * datagram. Also, it increases the handshake efficiency - * since messages belonging to a single datagram will not - * be reordered in transit, and so future message buffering - * or flight retransmission (if no buffering is used) as - * means to deal with reordering are needed less frequently. - * - * \note Application records are not affected by this option and - * are currently always sent in separate datagrams. - * - */ -void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, - unsigned allow_packing ); - -/** - * \brief Set retransmit timeout values for the DTLS handshake. - * (DTLS only, no effect on TLS.) - * - * \param conf SSL configuration - * \param min Initial timeout value in milliseconds. - * Default: 1000 (1 second). - * \param max Maximum timeout value in milliseconds. - * Default: 60000 (60 seconds). - * - * \note Default values are from RFC 6347 section 4.2.4.1. - * - * \note The 'min' value should typically be slightly above the - * expected round-trip time to your peer, plus whatever time - * it takes for the peer to process the message. For example, - * if your RTT is about 600ms and you peer needs up to 1s to - * do the cryptographic operations in the handshake, then you - * should set 'min' slightly above 1600. Lower values of 'min' - * might cause spurious resends which waste network resources, - * while larger value of 'min' will increase overall latency - * on unreliable network links. - * - * \note The more unreliable your network connection is, the larger - * your max / min ratio needs to be in order to achieve - * reliable handshakes. - * - * \note Messages are retransmitted up to log2(ceil(max/min)) times. - * For example, if min = 1s and max = 5s, the retransmit plan - * goes: send ... 1s -> resend ... 2s -> resend ... 4s -> - * resend ... 5s -> give up and return a timeout error. - */ -void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Set the session cache callbacks (server-side only) - * If not set, no session resuming is done (except if session - * tickets are enabled too). - * - * The session cache has the responsibility to check for stale - * entries based on timeout. See RFC 5246 for recommendations. - * - * Warning: session.peer_cert is cleared by the SSL/TLS layer on - * connection shutdown, so do not cache the pointer! Either set - * it to NULL or make a full copy of the certificate. - * - * The get callback is called once during the initial handshake - * to enable session resuming. The get function has the - * following parameters: (void *parameter, mbedtls_ssl_session *session) - * If a valid entry is found, it should fill the master of - * the session object with the cached values and return 0, - * return 1 otherwise. Optionally peer_cert can be set as well - * if it is properly present in cache entry. - * - * The set callback is called once during the initial handshake - * to enable session resuming after the entire handshake has - * been finished. The set function has the following parameters: - * (void *parameter, const mbedtls_ssl_session *session). The function - * should create a cache entry for future retrieval based on - * the data in the session structure and should keep in mind - * that the mbedtls_ssl_session object presented (and all its referenced - * data) is cleared by the SSL/TLS layer when the connection is - * terminated. It is recommended to add metadata to determine if - * an entry is still valid in the future. Return 0 if - * successfully cached, return 1 otherwise. - * - * \param conf SSL configuration - * \param p_cache parmater (context) for both callbacks - * \param f_get_cache session get callback - * \param f_set_cache session set callback - */ -void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, - void *p_cache, - int (*f_get_cache)(void *, mbedtls_ssl_session *), - int (*f_set_cache)(void *, const mbedtls_ssl_session *) ); -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Request resumption of session (client-side only) - * Session data is copied from presented session structure. - * - * \param ssl SSL context - * \param session session context - * - * \return 0 if successful, - * MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed, - * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or - * arguments are otherwise invalid - * - * \sa mbedtls_ssl_get_session() - */ -int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ); -#endif /* MBEDTLS_SSL_CLI_C */ - -/** - * \brief Set the list of allowed ciphersuites and the preference - * order. First in the list has the highest preference. - * (Overrides all version-specific lists) - * - * The ciphersuites array is not copied, and must remain - * valid for the lifetime of the ssl_config. - * - * Note: The server uses its own preferences - * over the preference of the client unless - * MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined! - * - * \param conf SSL configuration - * \param ciphersuites 0-terminated list of allowed ciphersuites - */ -void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, - const int *ciphersuites ); - -/** - * \brief Set the list of allowed ciphersuites and the - * preference order for a specific version of the protocol. - * (Only useful on the server side) - * - * The ciphersuites array is not copied, and must remain - * valid for the lifetime of the ssl_config. - * - * \param conf SSL configuration - * \param ciphersuites 0-terminated list of allowed ciphersuites - * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 - * supported) - * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, - * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, - * MBEDTLS_SSL_MINOR_VERSION_3 supported) - * - * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 - * and MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 - */ -void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, - const int *ciphersuites, - int major, int minor ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set the X.509 security profile used for verification - * - * \note The restrictions are enforced for all certificates in the - * chain. However, signatures in the handshake are not covered - * by this setting but by \b mbedtls_ssl_conf_sig_hashes(). - * - * \param conf SSL configuration - * \param profile Profile to use - */ -void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, - const mbedtls_x509_crt_profile *profile ); - -/** - * \brief Set the data required to verify peer certificate - * - * \note See \c mbedtls_x509_crt_verify() for notes regarding the - * parameters ca_chain (maps to trust_ca for that function) - * and ca_crl. - * - * \param conf SSL configuration - * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) - * \param ca_crl trusted CA CRLs - */ -void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl ); - -/** - * \brief Set own certificate chain and private key - * - * \note own_cert should contain in order from the bottom up your - * certificate chain. The top certificate (self-signed) - * can be omitted. - * - * \note On server, this function can be called multiple times to - * provision more than one cert/key pair (eg one ECDSA, one - * RSA with SHA-256, one RSA with SHA-1). An adequate - * certificate will be selected according to the client's - * advertised capabilities. In case multiple certificates are - * adequate, preference is given to the one set by the first - * call to this function, then second, etc. - * - * \note On client, only the first call has any effect. That is, - * only one client certificate can be provisioned. The - * server's preferences in its CertficateRequest message will - * be ignored and our only cert will be sent regardless of - * whether it matches those preferences - the server can then - * decide what it wants to do with it. - * - * \note The provided \p pk_key needs to match the public key in the - * first certificate in \p own_cert, or all handshakes using - * that certificate will fail. It is your responsibility - * to ensure that; this function will not perform any check. - * You may use mbedtls_pk_check_pair() in order to perform - * this check yourself, but be aware that this function can - * be computationally expensive on some key types. - * - * \param conf SSL configuration - * \param own_cert own public certificate chain - * \param pk_key own private key - * - * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED - */ -int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -/** - * \brief Set the Pre Shared Key (PSK) and the expected identity name - * - * \note This is mainly useful for clients. Servers will usually - * want to use \c mbedtls_ssl_conf_psk_cb() instead. - * - * \note Currently clients can only register one pre-shared key. - * In other words, the servers' identity hint is ignored. - * Support for setting multiple PSKs on clients and selecting - * one based on the identity hint is not a planned feature but - * feedback is welcomed. - * - * \param conf SSL configuration - * \param psk pointer to the pre-shared key - * \param psk_len pre-shared key length - * \param psk_identity pointer to the pre-shared key identity - * \param psk_identity_len identity key length - * - * \return 0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED - */ -int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, - const unsigned char *psk, size_t psk_len, - const unsigned char *psk_identity, size_t psk_identity_len ); - - -/** - * \brief Set the Pre Shared Key (PSK) for the current handshake - * - * \note This should only be called inside the PSK callback, - * ie the function passed to \c mbedtls_ssl_conf_psk_cb(). - * - * \param ssl SSL context - * \param psk pointer to the pre-shared key - * \param psk_len pre-shared key length - * - * \return 0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED - */ -int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, - const unsigned char *psk, size_t psk_len ); - -/** - * \brief Set the PSK callback (server-side only). - * - * If set, the PSK callback is called for each - * handshake where a PSK ciphersuite was negotiated. - * The caller provides the identity received and wants to - * receive the actual PSK data and length. - * - * The callback has the following parameters: (void *parameter, - * mbedtls_ssl_context *ssl, const unsigned char *psk_identity, - * size_t identity_len) - * If a valid PSK identity is found, the callback should use - * \c mbedtls_ssl_set_hs_psk() on the ssl context to set the - * correct PSK and return 0. - * Any other return value will result in a denied PSK identity. - * - * \note If you set a PSK callback using this function, then you - * don't need to set a PSK key and identity using - * \c mbedtls_ssl_conf_psk(). - * - * \param conf SSL configuration - * \param f_psk PSK identity function - * \param p_psk PSK identity parameter - */ -void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, - int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, - size_t), - void *p_psk ); -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif - -/** - * \brief Set the Diffie-Hellman public P and G values, - * read as hexadecimal strings (server-side only) - * (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]) - * - * \param conf SSL configuration - * \param dhm_P Diffie-Hellman-Merkle modulus - * \param dhm_G Diffie-Hellman-Merkle generator - * - * \disabled_deprecated Superseded by \c mbedtls_ssl_conf_dh_param_bin. - * - * \return 0 if successful - */ -MBEDTLS_DEPRECATED int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, - const char *dhm_P, - const char *dhm_G ); - -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Set the Diffie-Hellman public P and G values - * from big-endian binary presentations. - * (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]_BIN) - * - * \param conf SSL configuration - * \param dhm_P Diffie-Hellman-Merkle modulus in big-endian binary form - * \param P_len Length of DHM modulus - * \param dhm_G Diffie-Hellman-Merkle generator in big-endian binary form - * \param G_len Length of DHM generator - * - * \return 0 if successful - */ -int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf, - const unsigned char *dhm_P, size_t P_len, - const unsigned char *dhm_G, size_t G_len ); - -/** - * \brief Set the Diffie-Hellman public P and G values, - * read from existing context (server-side only) - * - * \param conf SSL configuration - * \param dhm_ctx Diffie-Hellman-Merkle context - * - * \return 0 if successful - */ -int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ); -#endif /* MBEDTLS_DHM_C && defined(MBEDTLS_SSL_SRV_C) */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Set the minimum length for Diffie-Hellman parameters. - * (Client-side only.) - * (Default: 1024 bits.) - * - * \param conf SSL configuration - * \param bitlen Minimum bit length of the DHM prime - */ -void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, - unsigned int bitlen ); -#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_ECP_C) -/** - * \brief Set the allowed curves in order of preference. - * (Default: all defined curves in order of decreasing size.) - * - * On server: this only affects selection of the ECDHE curve; - * the curves used for ECDH and ECDSA are determined by the - * list of available certificates instead. - * - * On client: this affects the list of curves offered for any - * use. The server can override our preference order. - * - * Both sides: limits the set of curves accepted for use in - * ECDHE and in the peer's end-entity certificate. - * - * \note This has no influence on which curves are allowed inside the - * certificate chains, see \c mbedtls_ssl_conf_cert_profile() - * for that. For the end-entity certificate however, the key - * will be accepted only if it is allowed both by this list - * and by the cert profile. - * - * \note This list should be ordered by decreasing preference - * (preferred curve first). - * - * \param conf SSL configuration - * \param curves Ordered list of allowed curves, - * terminated by MBEDTLS_ECP_DP_NONE. - */ -void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, - const mbedtls_ecp_group_id *curves ); -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -/** - * \brief Set the allowed hashes for signatures during the handshake. - * (Default: all SHA-2 hashes, largest first. Also SHA-1 if - * the compile-time option - * `MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE` is enabled.) - * - * \note This only affects which hashes are offered and can be used - * for signatures during the handshake. Hashes for message - * authentication and the TLS PRF are controlled by the - * ciphersuite, see \c mbedtls_ssl_conf_ciphersuites(). Hashes - * used for certificate signature are controlled by the - * verification profile, see \c mbedtls_ssl_conf_cert_profile(). - * - * \note This list should be ordered by decreasing preference - * (preferred hash first). - * - * \param conf SSL configuration - * \param hashes Ordered list of allowed signature hashes, - * terminated by \c MBEDTLS_MD_NONE. - */ -void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, - const int *hashes ); -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set or reset the hostname to check against the received - * server certificate. It sets the ServerName TLS extension, - * too, if that extension is enabled. (client-side only) - * - * \param ssl SSL context - * \param hostname the server hostname, may be NULL to clear hostname - - * \note Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN. - * - * \return 0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on - * allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on - * too long input hostname. - * - * Hostname set to the one provided on success (cleared - * when NULL). On allocation failure hostname is cleared. - * On too long input failure, old hostname is unchanged. - */ -int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -/** - * \brief Set own certificate and key for the current handshake - * - * \note Same as \c mbedtls_ssl_conf_own_cert() but for use within - * the SNI callback. - * - * \param ssl SSL context - * \param own_cert own public certificate chain - * \param pk_key own private key - * - * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED - */ -int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key ); - -/** - * \brief Set the data required to verify peer certificate for the - * current handshake - * - * \note Same as \c mbedtls_ssl_conf_ca_chain() but for use within - * the SNI callback. - * - * \param ssl SSL context - * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) - * \param ca_crl trusted CA CRLs - */ -void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl ); - -/** - * \brief Set authmode for the current handshake. - * - * \note Same as \c mbedtls_ssl_conf_authmode() but for use within - * the SNI callback. - * - * \param ssl SSL context - * \param authmode MBEDTLS_SSL_VERIFY_NONE, MBEDTLS_SSL_VERIFY_OPTIONAL or - * MBEDTLS_SSL_VERIFY_REQUIRED - */ -void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl, - int authmode ); - -/** - * \brief Set server side ServerName TLS extension callback - * (optional, server-side only). - * - * If set, the ServerName callback is called whenever the - * server receives a ServerName TLS extension from the client - * during a handshake. The ServerName callback has the - * following parameters: (void *parameter, mbedtls_ssl_context *ssl, - * const unsigned char *hostname, size_t len). If a suitable - * certificate is found, the callback must set the - * certificate(s) and key(s) to use with \c - * mbedtls_ssl_set_hs_own_cert() (can be called repeatedly), - * and may optionally adjust the CA and associated CRL with \c - * mbedtls_ssl_set_hs_ca_chain() as well as the client - * authentication mode with \c mbedtls_ssl_set_hs_authmode(), - * then must return 0. If no matching name is found, the - * callback must either set a default cert, or - * return non-zero to abort the handshake at this point. - * - * \param conf SSL configuration - * \param f_sni verification function - * \param p_sni verification parameter - */ -void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, - int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, - size_t), - void *p_sni ); -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -/** - * \brief Set the EC J-PAKE password for current handshake. - * - * \note An internal copy is made, and destroyed as soon as the - * handshake is completed, or when the SSL context is reset or - * freed. - * - * \note The SSL context needs to be already set up. The right place - * to call this function is between \c mbedtls_ssl_setup() or - * \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake(). - * - * \param ssl SSL context - * \param pw EC J-PAKE password (pre-shared secret) - * \param pw_len length of pw in bytes - * - * \return 0 on success, or a negative error code. - */ -int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, - const unsigned char *pw, - size_t pw_len ); -#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) -/** - * \brief Set the supported Application Layer Protocols. - * - * \param conf SSL configuration - * \param protos Pointer to a NULL-terminated list of supported protocols, - * in decreasing preference order. The pointer to the list is - * recorded by the library for later reference as required, so - * the lifetime of the table must be atleast as long as the - * lifetime of the SSL configuration structure. - * - * \return 0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA. - */ -int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos ); - -/** - * \brief Get the name of the negotiated Application Layer Protocol. - * This function should be called after the handshake is - * completed. - * - * \param ssl SSL context - * - * \return Protcol name, or NULL if no protocol was negotiated. - */ -const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_SSL_ALPN */ - -/** - * \brief Set the maximum supported version sent from the client side - * and/or accepted at the server side - * (Default: MBEDTLS_SSL_MAX_MAJOR_VERSION, MBEDTLS_SSL_MAX_MINOR_VERSION) - * - * \note This ignores ciphersuites from higher versions. - * - * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and - * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 - * - * \param conf SSL configuration - * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) - * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, - * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, - * MBEDTLS_SSL_MINOR_VERSION_3 supported) - */ -void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ); - -/** - * \brief Set the minimum accepted SSL/TLS protocol version - * (Default: TLS 1.0) - * - * \note Input outside of the SSL_MAX_XXXXX_VERSION and - * SSL_MIN_XXXXX_VERSION range is ignored. - * - * \note MBEDTLS_SSL_MINOR_VERSION_0 (SSL v3) should be avoided. - * - * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and - * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 - * - * \param conf SSL configuration - * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) - * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, - * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, - * MBEDTLS_SSL_MINOR_VERSION_3 supported) - */ -void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ); - -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Set the fallback flag (client-side only). - * (Default: MBEDTLS_SSL_IS_NOT_FALLBACK). - * - * \note Set to MBEDTLS_SSL_IS_FALLBACK when preparing a fallback - * connection, that is a connection with max_version set to a - * lower value than the value you're willing to use. Such - * fallback connections are not recommended but are sometimes - * necessary to interoperate with buggy (version-intolerant) - * servers. - * - * \warning You should NOT set this to MBEDTLS_SSL_IS_FALLBACK for - * non-fallback connections! This would appear to work for a - * while, then cause failures when the server is upgraded to - * support a newer TLS version. - * - * \param conf SSL configuration - * \param fallback MBEDTLS_SSL_IS_NOT_FALLBACK or MBEDTLS_SSL_IS_FALLBACK - */ -void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ); -#endif /* MBEDTLS_SSL_FALLBACK_SCSV && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -/** - * \brief Enable or disable Encrypt-then-MAC - * (Default: MBEDTLS_SSL_ETM_ENABLED) - * - * \note This should always be enabled, it is a security - * improvement, and should not cause any interoperability - * issue (used only if the peer supports it too). - * - * \param conf SSL configuration - * \param etm MBEDTLS_SSL_ETM_ENABLED or MBEDTLS_SSL_ETM_DISABLED - */ -void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ); -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -/** - * \brief Enable or disable Extended Master Secret negotiation. - * (Default: MBEDTLS_SSL_EXTENDED_MS_ENABLED) - * - * \note This should always be enabled, it is a security fix to the - * protocol, and should not cause any interoperability issue - * (used only if the peer supports it too). - * - * \param conf SSL configuration - * \param ems MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED - */ -void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ); -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_ARC4_C) -/** - * \brief Disable or enable support for RC4 - * (Default: MBEDTLS_SSL_ARC4_DISABLED) - * - * \warning Use of RC4 in DTLS/TLS has been prohibited by RFC 7465 - * for security reasons. Use at your own risk. - * - * \note This function is deprecated and will likely be removed in - * a future version of the library. - * RC4 is disabled by default at compile time and needs to be - * actively enabled for use with legacy systems. - * - * \param conf SSL configuration - * \param arc4 MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED - */ -void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ); -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Whether to send a list of acceptable CAs in - * CertificateRequest messages. - * (Default: do send) - * - * \param conf SSL configuration - * \param cert_req_ca_list MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or - * MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED - */ -void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, - char cert_req_ca_list ); -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -/** - * \brief Set the maximum fragment length to emit and/or negotiate. - * (Typical: the smaller of #MBEDTLS_SSL_IN_CONTENT_LEN and - * #MBEDTLS_SSL_OUT_CONTENT_LEN, usually `2^14` bytes) - * (Server: set maximum fragment length to emit, - * usually negotiated by the client during handshake) - * (Client: set maximum fragment length to emit *and* - * negotiate with the server during handshake) - * (Default: #MBEDTLS_SSL_MAX_FRAG_LEN_NONE) - * - * \note On the client side, the maximum fragment length extension - * *will not* be used, unless the maximum fragment length has - * been set via this function to a value different than - * #MBEDTLS_SSL_MAX_FRAG_LEN_NONE. - * - * \note This sets the maximum length for a record's payload, - * excluding record overhead that will be added to it, see - * \c mbedtls_ssl_get_record_expansion(). - * - * \note With TLS, this currently only affects ApplicationData (sent - * with \c mbedtls_ssl_read()), not handshake messages. - * With DTLS, this affects both ApplicationData and handshake. - * - * \note For DTLS, it is also possible to set a limit for the total - * size of daragrams passed to the transport layer, including - * record overhead, see \c mbedtls_ssl_set_mtu(). - * - * \param conf SSL configuration - * \param mfl_code Code for maximum fragment length (allowed values: - * MBEDTLS_SSL_MAX_FRAG_LEN_512, MBEDTLS_SSL_MAX_FRAG_LEN_1024, - * MBEDTLS_SSL_MAX_FRAG_LEN_2048, MBEDTLS_SSL_MAX_FRAG_LEN_4096) - * - * \return 0 if successful or MBEDTLS_ERR_SSL_BAD_INPUT_DATA - */ -int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ); -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -/** - * \brief Activate negotiation of truncated HMAC - * (Default: MBEDTLS_SSL_TRUNC_HMAC_DISABLED) - * - * \param conf SSL configuration - * \param truncate Enable or disable (MBEDTLS_SSL_TRUNC_HMAC_ENABLED or - * MBEDTLS_SSL_TRUNC_HMAC_DISABLED) - */ -void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate ); -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) -/** - * \brief Enable / Disable 1/n-1 record splitting - * (Default: MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED) - * - * \note Only affects SSLv3 and TLS 1.0, not higher versions. - * Does not affect non-CBC ciphersuites in any version. - * - * \param conf SSL configuration - * \param split MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED or - * MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED - */ -void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split ); -#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Enable / Disable session tickets (client only). - * (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED.) - * - * \note On server, use \c mbedtls_ssl_conf_session_tickets_cb(). - * - * \param conf SSL configuration - * \param use_tickets Enable or disable (MBEDTLS_SSL_SESSION_TICKETS_ENABLED or - * MBEDTLS_SSL_SESSION_TICKETS_DISABLED) - */ -void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets ); -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/** - * \brief Enable / Disable renegotiation support for connection when - * initiated by peer - * (Default: MBEDTLS_SSL_RENEGOTIATION_DISABLED) - * - * \warning It is recommended to always disable renegotation unless you - * know you need it and you know what you're doing. In the - * past, there have been several issues associated with - * renegotiation or a poor understanding of its properties. - * - * \note Server-side, enabling renegotiation also makes the server - * susceptible to a resource DoS by a malicious client. - * - * \param conf SSL configuration - * \param renegotiation Enable or disable (MBEDTLS_SSL_RENEGOTIATION_ENABLED or - * MBEDTLS_SSL_RENEGOTIATION_DISABLED) - */ -void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/** - * \brief Prevent or allow legacy renegotiation. - * (Default: MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) - * - * MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION allows connections to - * be established even if the peer does not support - * secure renegotiation, but does not allow renegotiation - * to take place if not secure. - * (Interoperable and secure option) - * - * MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION allows renegotiations - * with non-upgraded peers. Allowing legacy renegotiation - * makes the connection vulnerable to specific man in the - * middle attacks. (See RFC 5746) - * (Most interoperable and least secure option) - * - * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE breaks off connections - * if peer does not support secure renegotiation. Results - * in interoperability issues with non-upgraded peers - * that do not support renegotiation altogether. - * (Most secure option, interoperability issues) - * - * \param conf SSL configuration - * \param allow_legacy Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION, - * SSL_ALLOW_LEGACY_RENEGOTIATION or - * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) - */ -void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/** - * \brief Enforce renegotiation requests. - * (Default: enforced, max_records = 16) - * - * When we request a renegotiation, the peer can comply or - * ignore the request. This function allows us to decide - * whether to enforce our renegotiation requests by closing - * the connection if the peer doesn't comply. - * - * However, records could already be in transit from the peer - * when the request is emitted. In order to increase - * reliability, we can accept a number of records before the - * expected handshake records. - * - * The optimal value is highly dependent on the specific usage - * scenario. - * - * \note With DTLS and server-initiated renegotiation, the - * HelloRequest is retransmited every time mbedtls_ssl_read() times - * out or receives Application Data, until: - * - max_records records have beens seen, if it is >= 0, or - * - the number of retransmits that would happen during an - * actual handshake has been reached. - * Please remember the request might be lost a few times - * if you consider setting max_records to a really low value. - * - * \warning On client, the grace period can only happen during - * mbedtls_ssl_read(), as opposed to mbedtls_ssl_write() and mbedtls_ssl_renegotiate() - * which always behave as if max_record was 0. The reason is, - * if we receive application data from the server, we need a - * place to write it, which only happens during mbedtls_ssl_read(). - * - * \param conf SSL configuration - * \param max_records Use MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to - * enforce renegotiation, or a non-negative value to enforce - * it but allow for a grace period of max_records records. - */ -void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records ); - -/** - * \brief Set record counter threshold for periodic renegotiation. - * (Default: 2^48 - 1) - * - * Renegotiation is automatically triggered when a record - * counter (outgoing or ingoing) crosses the defined - * threshold. The default value is meant to prevent the - * connection from being closed when the counter is about to - * reached its maximal value (it is not allowed to wrap). - * - * Lower values can be used to enforce policies such as "keys - * must be refreshed every N packets with cipher X". - * - * The renegotiation period can be disabled by setting - * conf->disable_renegotiation to - * MBEDTLS_SSL_RENEGOTIATION_DISABLED. - * - * \note When the configured transport is - * MBEDTLS_SSL_TRANSPORT_DATAGRAM the maximum renegotiation - * period is 2^48 - 1, and for MBEDTLS_SSL_TRANSPORT_STREAM, - * the maximum renegotiation period is 2^64 - 1. - * - * \param conf SSL configuration - * \param period The threshold value: a big-endian 64-bit number. - */ -void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, - const unsigned char period[8] ); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/** - * \brief Check if there is data already read from the - * underlying transport but not yet processed. - * - * \param ssl SSL context - * - * \return 0 if nothing's pending, 1 otherwise. - * - * \note This is different in purpose and behaviour from - * \c mbedtls_ssl_get_bytes_avail in that it considers - * any kind of unprocessed data, not only unread - * application data. If \c mbedtls_ssl_get_bytes - * returns a non-zero value, this function will - * also signal pending data, but the converse does - * not hold. For example, in DTLS there might be - * further records waiting to be processed from - * the current underlying transport's datagram. - * - * \note If this function returns 1 (data pending), this - * does not imply that a subsequent call to - * \c mbedtls_ssl_read will provide any data; - * e.g., the unprocessed data might turn out - * to be an alert or a handshake message. - * - * \note This function is useful in the following situation: - * If the SSL/TLS module successfully returns from an - * operation - e.g. a handshake or an application record - * read - and you're awaiting incoming data next, you - * must not immediately idle on the underlying transport - * to have data ready, but you need to check the value - * of this function first. The reason is that the desired - * data might already be read but not yet processed. - * If, in contrast, a previous call to the SSL/TLS module - * returned MBEDTLS_ERR_SSL_WANT_READ, it is not necessary - * to call this function, as the latter error code entails - * that all internal data has been processed. - * - */ -int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the number of application data bytes - * remaining to be read from the current record. - * - * \param ssl SSL context - * - * \return How many bytes are available in the application - * data record read buffer. - * - * \note When working over a datagram transport, this is - * useful to detect the current datagram's boundary - * in case \c mbedtls_ssl_read has written the maximal - * amount of data fitting into the input buffer. - * - */ -size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the result of the certificate verification - * - * \param ssl The SSL context to use. - * - * \return \c 0 if the certificate verification was successful. - * \return \c -1u if the result is not available. This may happen - * e.g. if the handshake aborts early, or a verification - * callback returned a fatal error. - * \return A bitwise combination of \c MBEDTLS_X509_BADCERT_XXX - * and \c MBEDTLS_X509_BADCRL_XXX failure flags; see x509.h. - */ -uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the name of the current ciphersuite - * - * \param ssl SSL context - * - * \return a string containing the ciphersuite name - */ -const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the current SSL version (SSLv3/TLSv1/etc) - * - * \param ssl SSL context - * - * \return a string containing the SSL version - */ -const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the (maximum) number of bytes added by the record - * layer: header + encryption/MAC overhead (inc. padding) - * - * \note This function is not available (always returns an error) - * when record compression is enabled. - * - * \param ssl SSL context - * - * \return Current maximum record expansion in bytes, or - * MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if compression is - * enabled, which makes expansion much less predictable - */ -int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ); - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -/** - * \brief Return the maximum fragment length (payload, in bytes). - * This is the value negotiated with peer if any, - * or the locally configured value. - * - * \sa mbedtls_ssl_conf_max_frag_len() - * \sa mbedtls_ssl_get_max_record_payload() - * - * \param ssl SSL context - * - * \return Current maximum fragment length. - */ -size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -/** - * \brief Return the current maximum outgoing record payload in bytes. - * This takes into account the config.h setting \c - * MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated - * max fragment length extension if used, and for DTLS the - * path MTU as configured and current record expansion. - * - * \note With DTLS, \c mbedtls_ssl_write() will return an error if - * called with a larger length value. - * With TLS, \c mbedtls_ssl_write() will fragment the input if - * necessary and return the number of bytes written; it is up - * to the caller to call \c mbedtls_ssl_write() again in - * order to send the remaining bytes if any. - * - * \note This function is not available (always returns an error) - * when record compression is enabled. - * - * \sa mbedtls_ssl_set_mtu() - * \sa mbedtls_ssl_get_max_frag_len() - * \sa mbedtls_ssl_get_record_expansion() - * - * \param ssl SSL context - * - * \return Current maximum payload for an outgoing record, - * or a negative error code. - */ -int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Return the peer certificate from the current connection - * - * Note: Can be NULL in case no certificate was sent during - * the handshake. Different calls for the same connection can - * return the same or different pointers for the same - * certificate and even a different certificate altogether. - * The peer cert CAN change in a single connection if - * renegotiation is performed. - * - * \param ssl SSL context - * - * \return the current peer certificate - */ -const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Save session in order to resume it later (client-side only) - * Session data is copied to presented session structure. - * - * - * \param ssl SSL context - * \param session session context - * - * \return 0 if successful, - * MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed, - * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or - * arguments are otherwise invalid. - * - * \note Only the server certificate is copied, and not the full chain, - * so you should not attempt to validate the certificate again - * by calling \c mbedtls_x509_crt_verify() on it. - * Instead, you should use the results from the verification - * in the original handshake by calling \c mbedtls_ssl_get_verify_result() - * after loading the session again into a new SSL context - * using \c mbedtls_ssl_set_session(). - * - * \note Once the session object is not needed anymore, you should - * free it by calling \c mbedtls_ssl_session_free(). - * - * \sa mbedtls_ssl_set_session() - */ -int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *session ); -#endif /* MBEDTLS_SSL_CLI_C */ - -/** - * \brief Perform the SSL handshake - * - * \param ssl SSL context - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use - * and the client did not demonstrate reachability yet - in - * this case you must stop using the context (see below). - * \return Another SSL error code - in this case you must stop using - * the context (see below). - * - * \warning If this function returns something other than - * \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. - * - * \note If DTLS is in use, then you may choose to handle - * #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging - * purposes, as it is an expected return value rather than an - * actual error, but you still need to reset/free the context. - * - * \note Remarks regarding event-driven DTLS: - * If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram - * from the underlying transport layer is currently being processed, - * and it is safe to idle until the timer or the underlying transport - * signal a new event. This is not true for a successful handshake, - * in which case the datagram of the underlying transport that is - * currently being processed might or might not contain further - * DTLS records. - */ -int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); - -/** - * \brief Perform a single step of the SSL handshake - * - * \note The state of the context (ssl->state) will be at - * the next state after this function returns \c 0. Do not - * call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER. - * - * \param ssl SSL context - * - * \return See mbedtls_ssl_handshake(). - * - * \warning If this function returns something other than \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using - * the SSL context for reading or writing, and either free it - * or call \c mbedtls_ssl_session_reset() on it before - * re-using it for a new connection; the current connection - * must be closed. - */ -int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/** - * \brief Initiate an SSL renegotiation on the running connection. - * Client: perform the renegotiation right now. - * Server: request renegotiation, which will be performed - * during the next call to mbedtls_ssl_read() if honored by - * client. - * - * \param ssl SSL context - * - * \return 0 if successful, or any mbedtls_ssl_handshake() return - * value except #MBEDTLS_ERR_SSL_CLIENT_RECONNECT that can't - * happen during a renegotiation. - * - * \warning If this function returns something other than \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using - * the SSL context for reading or writing, and either free it - * or call \c mbedtls_ssl_session_reset() on it before - * re-using it for a new connection; the current connection - * must be closed. - * - */ -int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/** - * \brief Read at most 'len' application data bytes - * - * \param ssl SSL context - * \param buf buffer that will hold the data - * \param len maximum number of bytes to read - * - * \return The (positive) number of bytes read if successful. - * \return \c 0 if the read end of the underlying transport was closed - * - in this case you must stop using the context (see below). - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server - * side of a DTLS connection and the client is initiating a - * new connection using the same source port. See below. - * \return Another SSL error code - in this case you must stop using - * the context (see below). - * - * \warning If this function returns something other than - * a positive value, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CLIENT_RECONNECT, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. - * - * \note When this function returns #MBEDTLS_ERR_SSL_CLIENT_RECONNECT - * (which can only happen server-side), it means that a client - * is initiating a new connection using the same source port. - * You can either treat that as a connection close and wait - * for the client to resend a ClientHello, or directly - * continue with \c mbedtls_ssl_handshake() with the same - * context (as it has been reset internally). Either way, you - * must make sure this is seen by the application as a new - * connection: application state, if any, should be reset, and - * most importantly the identity of the client must be checked - * again. WARNING: not validating the identity of the client - * again, or not transmitting the new identity to the - * application layer, would allow authentication bypass! - * - * \note Remarks regarding event-driven DTLS: - * - If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram - * from the underlying transport layer is currently being processed, - * and it is safe to idle until the timer or the underlying transport - * signal a new event. - * - This function may return MBEDTLS_ERR_SSL_WANT_READ even if data was - * initially available on the underlying transport, as this data may have - * been only e.g. duplicated messages or a renegotiation request. - * Therefore, you must be prepared to receive MBEDTLS_ERR_SSL_WANT_READ even - * when reacting to an incoming-data event from the underlying transport. - * - On success, the datagram of the underlying transport that is currently - * being processed may contain further DTLS records. You should call - * \c mbedtls_ssl_check_pending to check for remaining records. - * - */ -int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ); - -/** - * \brief Try to write exactly 'len' application data bytes - * - * \warning This function will do partial writes in some cases. If the - * return value is non-negative but less than length, the - * function must be called again with updated arguments: - * buf + ret, len - ret (if ret is the return value) until - * it returns a value equal to the last 'len' argument. - * - * \param ssl SSL context - * \param buf buffer holding the data - * \param len how many bytes must be written - * - * \return The (non-negative) number of bytes actually written if - * successful (may be less than \p len). - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return Another SSL error code - in this case you must stop using - * the context (see below). - * - * \warning If this function returns something other than - * a non-negative value, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. - * - * \note When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ, - * it must be called later with the *same* arguments, - * until it returns a value greater that or equal to 0. When - * the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be - * some partial data in the output buffer, however this is not - * yet sent. - * - * \note If the requested length is greater than the maximum - * fragment length (either the built-in limit or the one set - * or negotiated with the peer), then: - * - with TLS, less bytes than requested are written. - * - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned. - * \c mbedtls_ssl_get_max_frag_len() may be used to query the - * active maximum fragment length. - * - * \note Attempting to write 0 bytes will result in an empty TLS - * application record being sent. - */ -int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ); - -/** - * \brief Send an alert message - * - * \param ssl SSL context - * \param level The alert level of the message - * (MBEDTLS_SSL_ALERT_LEVEL_WARNING or MBEDTLS_SSL_ALERT_LEVEL_FATAL) - * \param message The alert message (SSL_ALERT_MSG_*) - * - * \return 0 if successful, or a specific SSL error code. - * - * \note If this function returns something other than 0 or - * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using - * the SSL context for reading or writing, and either free it or - * call \c mbedtls_ssl_session_reset() on it before re-using it - * for a new connection; the current connection must be closed. - */ -int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, - unsigned char level, - unsigned char message ); -/** - * \brief Notify the peer that the connection is being closed - * - * \param ssl SSL context - * - * \return 0 if successful, or a specific SSL error code. - * - * \note If this function returns something other than 0 or - * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using - * the SSL context for reading or writing, and either free it or - * call \c mbedtls_ssl_session_reset() on it before re-using it - * for a new connection; the current connection must be closed. - */ -int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ); - -/** - * \brief Free referenced items in an SSL context and clear memory - * - * \param ssl SSL context - */ -void mbedtls_ssl_free( mbedtls_ssl_context *ssl ); - -/** - * \brief Initialize an SSL configuration context - * Just makes the context ready for - * mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free(). - * - * \note You need to call mbedtls_ssl_config_defaults() unless you - * manually set all of the relevant fields yourself. - * - * \param conf SSL configuration context - */ -void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ); - -/** - * \brief Load reasonnable default SSL configuration values. - * (You need to call mbedtls_ssl_config_init() first.) - * - * \param conf SSL configuration context - * \param endpoint MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER - * \param transport MBEDTLS_SSL_TRANSPORT_STREAM for TLS, or - * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS - * \param preset a MBEDTLS_SSL_PRESET_XXX value - * - * \note See \c mbedtls_ssl_conf_transport() for notes on DTLS. - * - * \return 0 if successful, or - * MBEDTLS_ERR_XXX_ALLOC_FAILED on memory allocation error. - */ -int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, - int endpoint, int transport, int preset ); - -/** - * \brief Free an SSL configuration context - * - * \param conf SSL configuration context - */ -void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ); - -/** - * \brief Initialize SSL session structure - * - * \param session SSL session - */ -void mbedtls_ssl_session_init( mbedtls_ssl_session *session ); - -/** - * \brief Free referenced items in an SSL session including the - * peer certificate and clear memory - * - * \note A session object can be freed even if the SSL context - * that was used to retrieve the session is still in use. - * - * \param session SSL session - */ -void mbedtls_ssl_session_free( mbedtls_ssl_session *session ); - -#ifdef __cplusplus -} -#endif - -#endif /* ssl.h */ diff --git a/mbedtls/ssl_cache.c b/mbedtls/ssl_cache.c deleted file mode 100644 index ddb75fb92..000000000 --- a/mbedtls/ssl_cache.c +++ /dev/null @@ -1,365 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * SSL session cache implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * These session callbacks use a simple chained list - * to store and retrieve the session information. - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_CACHE_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/ssl_cache.h" - -#include - -void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ) -{ - memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) ); - - cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT; - cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &cache->mutex ); -#endif -} - -int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ) -{ - int ret = 1; -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t = mbedtls_time( NULL ); -#endif - mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; - mbedtls_ssl_cache_entry *cur, *entry; - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &cache->mutex ) != 0 ) - return( 1 ); -#endif - - cur = cache->chain; - entry = NULL; - - while( cur != NULL ) - { - entry = cur; - cur = cur->next; - -#if defined(MBEDTLS_HAVE_TIME) - if( cache->timeout != 0 && - (int) ( t - entry->timestamp ) > cache->timeout ) - continue; -#endif - - if( session->ciphersuite != entry->session.ciphersuite || - session->compression != entry->session.compression || - session->id_len != entry->session.id_len ) - continue; - - if( memcmp( session->id, entry->session.id, - entry->session.id_len ) != 0 ) - continue; - - memcpy( session->master, entry->session.master, 48 ); - - session->verify_result = entry->session.verify_result; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /* - * Restore peer certificate (without rest of the original chain) - */ - if( entry->peer_cert.p != NULL ) - { - if( ( session->peer_cert = mbedtls_calloc( 1, - sizeof(mbedtls_x509_crt) ) ) == NULL ) - { - ret = 1; - goto exit; - } - - mbedtls_x509_crt_init( session->peer_cert ); - if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p, - entry->peer_cert.len ) != 0 ) - { - mbedtls_free( session->peer_cert ); - session->peer_cert = NULL; - ret = 1; - goto exit; - } - } -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - ret = 0; - goto exit; - } - -exit: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) - ret = 1; -#endif - - return( ret ); -} - -int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ) -{ - int ret = 1; -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t = mbedtls_time( NULL ), oldest = 0; - mbedtls_ssl_cache_entry *old = NULL; -#endif - mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; - mbedtls_ssl_cache_entry *cur, *prv; - int count = 0; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 ) - return( ret ); -#endif - - cur = cache->chain; - prv = NULL; - - while( cur != NULL ) - { - count++; - -#if defined(MBEDTLS_HAVE_TIME) - if( cache->timeout != 0 && - (int) ( t - cur->timestamp ) > cache->timeout ) - { - cur->timestamp = t; - break; /* expired, reuse this slot, update timestamp */ - } -#endif - - if( memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 ) - break; /* client reconnected, keep timestamp for session id */ - -#if defined(MBEDTLS_HAVE_TIME) - if( oldest == 0 || cur->timestamp < oldest ) - { - oldest = cur->timestamp; - old = cur; - } -#endif - - prv = cur; - cur = cur->next; - } - - if( cur == NULL ) - { -#if defined(MBEDTLS_HAVE_TIME) - /* - * Reuse oldest entry if max_entries reached - */ - if( count >= cache->max_entries ) - { - if( old == NULL ) - { - ret = 1; - goto exit; - } - - cur = old; - } -#else /* MBEDTLS_HAVE_TIME */ - /* - * Reuse first entry in chain if max_entries reached, - * but move to last place - */ - if( count >= cache->max_entries ) - { - if( cache->chain == NULL ) - { - ret = 1; - goto exit; - } - - cur = cache->chain; - cache->chain = cur->next; - cur->next = NULL; - prv->next = cur; - } -#endif /* MBEDTLS_HAVE_TIME */ - else - { - /* - * max_entries not reached, create new entry - */ - cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) ); - if( cur == NULL ) - { - ret = 1; - goto exit; - } - - if( prv == NULL ) - cache->chain = cur; - else - prv->next = cur; - } - -#if defined(MBEDTLS_HAVE_TIME) - cur->timestamp = t; -#endif - } - - memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /* - * If we're reusing an entry, free its certificate first - */ - if( cur->peer_cert.p != NULL ) - { - mbedtls_free( cur->peer_cert.p ); - memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) ); - } - - /* - * Store peer certificate - */ - if( session->peer_cert != NULL ) - { - cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len ); - if( cur->peer_cert.p == NULL ) - { - ret = 1; - goto exit; - } - - memcpy( cur->peer_cert.p, session->peer_cert->raw.p, - session->peer_cert->raw.len ); - cur->peer_cert.len = session->peer_cert->raw.len; - - cur->session.peer_cert = NULL; - } -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - ret = 0; - -exit: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) - ret = 1; -#endif - - return( ret ); -} - -#if defined(MBEDTLS_HAVE_TIME) -void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout ) -{ - if( timeout < 0 ) timeout = 0; - - cache->timeout = timeout; -} -#endif /* MBEDTLS_HAVE_TIME */ - -void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max ) -{ - if( max < 0 ) max = 0; - - cache->max_entries = max; -} - -void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache ) -{ - mbedtls_ssl_cache_entry *cur, *prv; - - cur = cache->chain; - - while( cur != NULL ) - { - prv = cur; - cur = cur->next; - - mbedtls_ssl_session_free( &prv->session ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_free( prv->peer_cert.p ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - mbedtls_free( prv ); - } - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &cache->mutex ); -#endif - cache->chain = NULL; -} - -#endif /* MBEDTLS_SSL_CACHE_C */ diff --git a/mbedtls/ssl_cache.h b/mbedtls/ssl_cache.h deleted file mode 100644 index 3e7808d14..000000000 --- a/mbedtls/ssl_cache.h +++ /dev/null @@ -1,176 +0,0 @@ -#pragma GCC system_header -/** - * \file ssl_cache.h - * - * \brief SSL session cache implementation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_SSL_CACHE_H -#define MBEDTLS_SSL_CACHE_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT) -#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */ -#endif - -#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES) -#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */ -#endif - -/* \} name SECTION: Module settings */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct mbedtls_ssl_cache_context mbedtls_ssl_cache_context; -typedef struct mbedtls_ssl_cache_entry mbedtls_ssl_cache_entry; - -/** - * \brief This structure is used for storing cache entries - */ -struct mbedtls_ssl_cache_entry -{ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t timestamp; /*!< entry timestamp */ -#endif - mbedtls_ssl_session session; /*!< entry session */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_x509_buf peer_cert; /*!< entry peer_cert */ -#endif - mbedtls_ssl_cache_entry *next; /*!< chain pointer */ -}; - -/** - * \brief Cache context - */ -struct mbedtls_ssl_cache_context -{ - mbedtls_ssl_cache_entry *chain; /*!< start of the chain */ - int timeout; /*!< cache entry timeout */ - int max_entries; /*!< maximum entries */ -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; /*!< mutex */ -#endif -}; - -/** - * \brief Initialize an SSL cache context - * - * \param cache SSL cache context - */ -void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ); - -/** - * \brief Cache get callback implementation - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param data SSL cache context - * \param session session to retrieve entry for - */ -int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ); - -/** - * \brief Cache set callback implementation - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param data SSL cache context - * \param session session to store entry for - */ -int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ); - -#if defined(MBEDTLS_HAVE_TIME) -/** - * \brief Set the cache timeout - * (Default: MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT (1 day)) - * - * A timeout of 0 indicates no timeout. - * - * \param cache SSL cache context - * \param timeout cache entry timeout in seconds - */ -void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout ); -#endif /* MBEDTLS_HAVE_TIME */ - -/** - * \brief Set the maximum number of cache entries - * (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50)) - * - * \param cache SSL cache context - * \param max cache entry maximum - */ -void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max ); - -/** - * \brief Free referenced items in a cache context and clear memory - * - * \param cache SSL cache context - */ -void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache ); - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_cache.h */ diff --git a/mbedtls/ssl_ciphersuites.c b/mbedtls/ssl_ciphersuites.c deleted file mode 100644 index 2ca4cbafb..000000000 --- a/mbedtls/ssl_ciphersuites.c +++ /dev/null @@ -1,2411 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/** - * \file ssl_ciphersuites.c - * - * \brief SSL ciphersuites for mbed TLS - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_TLS_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#endif - -#include "mbedtls/ssl_ciphersuites.h" -#include "mbedtls/ssl.h" - -#include - -/* - * Ordered from most preferred to least preferred in terms of security. - * - * Current rule (except RC4 and 3DES, weak and null which come last): - * 1. By key exchange: - * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK - * 2. By key length and cipher: - * ChaCha > AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128 - * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 - * 4. By hash function used when relevant - * 5. By key exchange/auth again: EC > non-EC - */ -static const int ciphersuite_preference[] = -{ -#if defined(MBEDTLS_SSL_CIPHERSUITES) - MBEDTLS_SSL_CIPHERSUITES, -#else - /* Chacha-Poly ephemeral suites */ - MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - - /* All AES-256 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, - - /* All CAMELLIA-256 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - - /* All ARIA-256 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, - - /* All AES-128 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, - - /* All CAMELLIA-128 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - - /* All ARIA-128 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, - - /* The PSK ephemeral suites */ - MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, - - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, - - /* The ECJPAKE suite */ - MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, - - /* All AES-256 suites */ - MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_AES_256_CCM, - MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, - - /* All CAMELLIA-256 suites */ - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - - /* All ARIA-256 suites */ - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384, - - /* All AES-128 suites */ - MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_128_CCM, - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, - - /* All CAMELLIA-128 suites */ - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - - /* All ARIA-128 suites */ - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256, - - /* The RSA PSK suites */ - MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, - - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, - - /* The PSK suites */ - MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_PSK_WITH_AES_256_CCM, - MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, - MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384, - - MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_PSK_WITH_AES_128_CCM, - MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, - MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256, - - /* 3DES suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, - - /* RC4 suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, - MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, - MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, - MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, - - /* Weak suites */ - MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, - - /* NULL suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, - MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, - - MBEDTLS_TLS_RSA_WITH_NULL_SHA256, - MBEDTLS_TLS_RSA_WITH_NULL_SHA, - MBEDTLS_TLS_RSA_WITH_NULL_MD5, - MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, - MBEDTLS_TLS_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_PSK_WITH_NULL_SHA, - -#endif /* MBEDTLS_SSL_CIPHERSUITES */ - 0 -}; - -static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = -{ -#if defined(MBEDTLS_CHACHAPOLY_C) && \ - defined(MBEDTLS_SHA256_C) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - { MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - { MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - { MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - { MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - { MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#endif /* MBEDTLS_CHACHAPOLY_C && - MBEDTLS_SHA256_C && - MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA512_C */ -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS-ECDHE-RSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { MBEDTLS_TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_MD5_C) - { MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, "TLS-PSK-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { MBEDTLS_TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, "TLS-PSK-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, "TLS-DHE-PSK-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#if defined(MBEDTLS_AES_C) - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, "TLS-ECDHE-PSK-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) -#if defined(MBEDTLS_MD5_C) - { MBEDTLS_TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS-DHE-RSA-WITH-DES-CBC-SHA", - MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, "TLS-RSA-WITH-DES-CBC-SHA", - MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ -#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ - -#if defined(MBEDTLS_ARIA_C) - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, - "TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, - "TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, - "TLS-PSK-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384,MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256, - "TLS-PSK-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDH-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDH-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, - "TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, - "TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#endif /* MBEDTLS_ARIA_C */ - - - { 0, "", - MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE, - 0, 0, 0, 0, 0 } -}; - -#if defined(MBEDTLS_SSL_CIPHERSUITES) -const int *mbedtls_ssl_list_ciphersuites( void ) -{ - return( ciphersuite_preference ); -} -#else -#define MAX_CIPHERSUITES sizeof( ciphersuite_definitions ) / \ - sizeof( ciphersuite_definitions[0] ) -static int supported_ciphersuites[MAX_CIPHERSUITES]; -static int supported_init = 0; - -static int ciphersuite_is_removed( const mbedtls_ssl_ciphersuite_t *cs_info ) -{ - (void)cs_info; - -#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) - if( cs_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) - return( 1 ); -#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ - -#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES) - if( cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_ECB || - cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_CBC ) - { - return( 1 ); - } -#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */ - - return( 0 ); -} - -const int *mbedtls_ssl_list_ciphersuites( void ) -{ - /* - * On initial call filter out all ciphersuites not supported by current - * build based on presence in the ciphersuite_definitions. - */ - if( supported_init == 0 ) - { - const int *p; - int *q; - - for( p = ciphersuite_preference, q = supported_ciphersuites; - *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1; - p++ ) - { - const mbedtls_ssl_ciphersuite_t *cs_info; - if( ( cs_info = mbedtls_ssl_ciphersuite_from_id( *p ) ) != NULL && - !ciphersuite_is_removed( cs_info ) ) - { - *(q++) = *p; - } - } - *q = 0; - - supported_init = 1; - } - - return( supported_ciphersuites ); -} -#endif /* MBEDTLS_SSL_CIPHERSUITES */ - -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( - const char *ciphersuite_name ) -{ - const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; - - if( NULL == ciphersuite_name ) - return( NULL ); - - while( cur->id != 0 ) - { - if( 0 == strcmp( cur->name, ciphersuite_name ) ) - return( cur ); - - cur++; - } - - return( NULL ); -} - -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite ) -{ - const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; - - while( cur->id != 0 ) - { - if( cur->id == ciphersuite ) - return( cur ); - - cur++; - } - - return( NULL ); -} - -const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id ) -{ - const mbedtls_ssl_ciphersuite_t *cur; - - cur = mbedtls_ssl_ciphersuite_from_id( ciphersuite_id ); - - if( cur == NULL ) - return( "unknown" ); - - return( cur->name ); -} - -int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name ) -{ - const mbedtls_ssl_ciphersuite_t *cur; - - cur = mbedtls_ssl_ciphersuite_from_string( ciphersuite_name ); - - if( cur == NULL ) - return( 0 ); - - return( cur->id ); -} - -#if defined(MBEDTLS_PK_C) -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return( MBEDTLS_PK_RSA ); - - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return( MBEDTLS_PK_ECDSA ); - - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return( MBEDTLS_PK_ECKEY ); - - default: - return( MBEDTLS_PK_NONE ); - } -} - -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - return( MBEDTLS_PK_RSA ); - - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return( MBEDTLS_PK_ECDSA ); - - default: - return( MBEDTLS_PK_NONE ); - } -} - -#endif /* MBEDTLS_PK_C */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/mbedtls/ssl_ciphersuites.h b/mbedtls/ssl_ciphersuites.h deleted file mode 100644 index cc6ca8aee..000000000 --- a/mbedtls/ssl_ciphersuites.h +++ /dev/null @@ -1,566 +0,0 @@ -#pragma GCC system_header -/** - * \file ssl_ciphersuites.h - * - * \brief SSL Ciphersuites for mbed TLS - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_SSL_CIPHERSUITES_H -#define MBEDTLS_SSL_CIPHERSUITES_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "pk.h" -#include "cipher.h" -#include "md.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Supported ciphersuites (Official IANA names) - */ -#define MBEDTLS_TLS_RSA_WITH_NULL_MD5 0x01 /**< Weak! */ -#define MBEDTLS_TLS_RSA_WITH_NULL_SHA 0x02 /**< Weak! */ - -#define MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 0x04 -#define MBEDTLS_TLS_RSA_WITH_RC4_128_SHA 0x05 -#define MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA 0x09 /**< Weak! Not in TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x0A - -#define MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA 0x15 /**< Weak! Not in TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x16 - -#define MBEDTLS_TLS_PSK_WITH_NULL_SHA 0x2C /**< Weak! */ -#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA 0x2D /**< Weak! */ -#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA 0x2E /**< Weak! */ -#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA 0x2F - -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33 -#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA 0x35 -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39 - -#define MBEDTLS_TLS_RSA_WITH_NULL_SHA256 0x3B /**< Weak! */ -#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41 -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45 - -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84 -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88 - -#define MBEDTLS_TLS_PSK_WITH_RC4_128_SHA 0x8A -#define MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA 0x8B -#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA 0x8C -#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA 0x8D - -#define MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA 0x8E -#define MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x8F -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x90 -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x91 - -#define MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA 0x92 -#define MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x93 -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA 0x94 -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA 0x95 - -#define MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 0xA8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 0xA9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 0xAA /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 0xAB /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 0xAC /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 0xAD /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE -#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF -#define MBEDTLS_TLS_PSK_WITH_NULL_SHA256 0xB0 /**< Weak! */ -#define MBEDTLS_TLS_PSK_WITH_NULL_SHA384 0xB1 /**< Weak! */ - -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2 -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3 -#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 0xB4 /**< Weak! */ -#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 0xB5 /**< Weak! */ - -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6 -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7 -#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 0xB8 /**< Weak! */ -#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 0xB9 /**< Weak! */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 /**< Weak! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /**< Not in SSL3! */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 /**< Weak! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /**< Not in SSL3! */ - -#define MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B /**< Weak! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /**< Not in SSL3! */ - -#define MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 /**< Weak! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /**< Not in SSL3! */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA 0xC033 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0xC034 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA 0xC039 /**< Weak! No SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A /**< Weak! No SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B /**< Weak! No SSL3! */ - -#define MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 0xC03C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 0xC03D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC044 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC045 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC048 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC049 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC04A /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC04B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC04C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC04D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 0xC04E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 0xC04F /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 0xC050 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 0xC051 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC052 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC053 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC060 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC061 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0xC062 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0xC063 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 0xC064 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 0xC065 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC066 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC067 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 0xC068 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 0xC069 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 0xC06A /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 0xC06B /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0xC06C /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0xC06D /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0xC06E /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0xC06F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC070 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC071 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC075 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC078 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC079 /**< Not in SSL3! */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07A /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07B /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07C /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC088 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC089 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08A /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08D /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08E /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC08F /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC090 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC091 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC092 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC093 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094 -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095 -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096 -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097 -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098 -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099 -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< Not in SSL3! */ - -#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM 0xC09C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM 0xC09D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM 0xC0A4 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM 0xC0A5 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM 0xC0A6 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM 0xC0A7 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8 0xC0A8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8 0xC0A9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8 0xC0AA /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8 0xC0AB /**< TLS 1.2 */ -/* The last two are named with PSK_DHE in the RFC, which looks like a typo */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */ - -/* RFC 7905 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE /**< TLS 1.2 */ - -/* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. - * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below - */ -typedef enum { - MBEDTLS_KEY_EXCHANGE_NONE = 0, - MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_KEY_EXCHANGE_ECJPAKE, -} mbedtls_key_exchange_type_t; - -/* Key exchanges using a certificate */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED -#endif - -/* Key exchanges allowing client certificate requests */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED -#endif - -/* Key exchanges involving server signature in ServerKeyExchange */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED -#endif - -/* Key exchanges using ECDH */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED -#endif - -/* Key exchanges that don't involve ephemeral keys */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED -#endif - -/* Key exchanges that involve ephemeral keys */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED -#endif - -/* Key exchanges using a PSK */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED -#endif - -/* Key exchanges using DHE */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED -#endif - -/* Key exchanges using ECDHE */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED -#endif - -typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t; - -#define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */ -#define MBEDTLS_CIPHERSUITE_SHORT_TAG 0x02 /**< Short authentication tag, - eg for CCM_8 */ -#define MBEDTLS_CIPHERSUITE_NODTLS 0x04 /**< Can't be used with DTLS */ - -/** - * \brief This structure is used for storing ciphersuite information - */ -struct mbedtls_ssl_ciphersuite_t -{ - int id; - const char * name; - - mbedtls_cipher_type_t cipher; - mbedtls_md_type_t mac; - mbedtls_key_exchange_type_t key_exchange; - - int min_major_ver; - int min_minor_ver; - int max_major_ver; - int max_minor_ver; - - unsigned char flags; -}; - -const int *mbedtls_ssl_list_ciphersuites( void ); - -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( const char *ciphersuite_name ); -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite_id ); - -#if defined(MBEDTLS_PK_C) -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ); -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ); -#endif - -int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ); -int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ); - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) -static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) -static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ - -static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return( 1 ); - - default: - return( 0 ); - } -} - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_ciphersuites.h */ diff --git a/mbedtls/ssl_cli.c b/mbedtls/ssl_cli.c deleted file mode 100644 index b34e4b689..000000000 --- a/mbedtls/ssl_cli.c +++ /dev/null @@ -1,3926 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * SSLv3/TLSv1 client-side functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_CLI_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/debug.h" -#include "mbedtls/ssl.h" -#include "mbedtls/ssl_internal.h" - -#include - -#include - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#include "mbedtls/platform_util.h" -#endif - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - size_t hostname_len; - - *olen = 0; - - if( ssl->hostname == NULL ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding server name extension: %s", - ssl->hostname ) ); - - hostname_len = strlen( ssl->hostname ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, hostname_len + 9 ); - - /* - * Sect. 3, RFC 6066 (TLS Extensions Definitions) - * - * In order to provide any of the server names, clients MAY include an - * extension of type "server_name" in the (extended) client hello. The - * "extension_data" field of this extension SHALL contain - * "ServerNameList" where: - * - * struct { - * NameType name_type; - * select (name_type) { - * case host_name: HostName; - * } name; - * } ServerName; - * - * enum { - * host_name(0), (255) - * } NameType; - * - * opaque HostName<1..2^16-1>; - * - * struct { - * ServerName server_name_list<1..2^16-1> - * } ServerNameList; - * - */ - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF ); - - *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF ); - - *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF ); - *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( hostname_len ) & 0xFF ); - - memcpy( p, ssl->hostname, hostname_len ); - - *olen = hostname_len + 9; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - - *olen = 0; - - /* We're always including an TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the - * initial ClientHello, in which case also adding the renegotiation - * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */ - if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding renegotiation extension" ) ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 5 + ssl->verify_data_len ); - - /* - * Secure renegotiation - */ - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) - & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) - & 0xFF ); - - *p++ = 0x00; - *p++ = ( ssl->verify_data_len + 1 ) & 0xFF; - *p++ = ssl->verify_data_len & 0xFF; - - memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); - - *olen = 5 + ssl->verify_data_len; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/* - * Only if we handle at least one key exchange that needs signatures. - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - size_t sig_alg_len = 0; - const int *md; - -#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) - unsigned char *sig_alg_list = buf + 6; -#endif - - *olen = 0; - - if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding signature_algorithms extension" ) ); - - if( ssl->conf->sig_hashes == NULL ) - return( MBEDTLS_ERR_SSL_BAD_CONFIG ); - - for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) - { -#if defined(MBEDTLS_ECDSA_C) - sig_alg_len += 2; -#endif -#if defined(MBEDTLS_RSA_C) - sig_alg_len += 2; -#endif - if( sig_alg_len > MBEDTLS_SSL_MAX_SIG_HASH_ALG_LIST_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "length in bytes of sig-hash-alg extension too big" ) ); - return( MBEDTLS_ERR_SSL_BAD_CONFIG ); - } - } - - /* Empty signature algorithms list, this is a configuration error. */ - if( sig_alg_len == 0 ) - return( MBEDTLS_ERR_SSL_BAD_CONFIG ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, sig_alg_len + 6 ); - - /* - * Prepare signature_algorithms extension (TLS 1.2) - */ - sig_alg_len = 0; - - for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) - { -#if defined(MBEDTLS_ECDSA_C) - sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; -#endif -#if defined(MBEDTLS_RSA_C) - sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; -#endif - } - - /* - * enum { - * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), - * sha512(6), (255) - * } HashAlgorithm; - * - * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } - * SignatureAlgorithm; - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * SignatureAndHashAlgorithm - * supported_signature_algorithms<2..2^16-2>; - */ - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF ); - - *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF ); - - *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF ); - - *olen = 6 + sig_alg_len; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - unsigned char *elliptic_curve_list = p + 6; - size_t elliptic_curve_len = 0; - const mbedtls_ecp_curve_info *info; - const mbedtls_ecp_group_id *grp_id; - - *olen = 0; - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding supported_elliptic_curves extension" ) ); - - if( ssl->conf->curve_list == NULL ) - return( MBEDTLS_ERR_SSL_BAD_CONFIG ); - - for( grp_id = ssl->conf->curve_list; - *grp_id != MBEDTLS_ECP_DP_NONE; - grp_id++ ) - { - info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); - if( info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "invalid curve in ssl configuration" ) ); - return( MBEDTLS_ERR_SSL_BAD_CONFIG ); - } - elliptic_curve_len += 2; - - if( elliptic_curve_len > MBEDTLS_SSL_MAX_CURVE_LIST_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "malformed supported_elliptic_curves extension in config" ) ); - return( MBEDTLS_ERR_SSL_BAD_CONFIG ); - } - } - - /* Empty elliptic curve list, this is a configuration error. */ - if( elliptic_curve_len == 0 ) - return( MBEDTLS_ERR_SSL_BAD_CONFIG ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 + elliptic_curve_len ); - - elliptic_curve_len = 0; - - for( grp_id = ssl->conf->curve_list; - *grp_id != MBEDTLS_ECP_DP_NONE; - grp_id++ ) - { - info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); - elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; - elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) - & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) - & 0xFF ); - - *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF ); - - *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF ); - - *olen = 6 + elliptic_curve_len; - - return( 0 ); -} - -static int ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - (void) ssl; /* ssl used for debugging only */ - - *olen = 0; - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding supported_point_formats extension" ) ); - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) - & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) - & 0xFF ); - - *p++ = 0x00; - *p++ = 2; - - *p++ = 1; - *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; - - *olen = 6; - - return( 0 ); -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - int ret; - unsigned char *p = buf; - size_t kkpp_len; - - *olen = 0; - - /* Skip costly extension if we can't use EC J-PAKE anyway */ - if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding ecjpake_kkpp extension" ) ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); - - /* - * We may need to send ClientHello multiple times for Hello verification. - * We don't want to compute fresh values every time (both for performance - * and consistency reasons), so cache the extension content. - */ - if( ssl->handshake->ecjpake_cache == NULL || - ssl->handshake->ecjpake_cache_len == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) ); - - ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, - p + 2, end - p - 2, &kkpp_len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1 , - "mbedtls_ecjpake_write_round_one", ret ); - return( ret ); - } - - ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len ); - if( ssl->handshake->ecjpake_cache == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len ); - ssl->handshake->ecjpake_cache_len = kkpp_len; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) ); - - kkpp_len = ssl->handshake->ecjpake_cache_len; - MBEDTLS_SSL_CHK_BUF_PTR( p + 2, end, kkpp_len ); - - memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len ); - } - - *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); - - *olen = kkpp_len + 4; - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - - *olen = 0; - - if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding max_fragment_length extension" ) ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 5 ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) - & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) - & 0xFF ); - - *p++ = 0x00; - *p++ = 1; - - *p++ = ssl->conf->mfl_code; - - *olen = 5; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - - *olen = 0; - - if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding truncated_hmac extension" ) ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - - *olen = 0; - - if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding encrypt_then_mac extension" ) ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static int ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - - *olen = 0; - - if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || - ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding extended_master_secret extension" ) ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) - & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) - & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - size_t tlen = ssl->session_negotiate->ticket_len; - - *olen = 0; - - if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, adding session ticket extension" ) ); - - /* The addition is safe here since the ticket length is 16 bit. */ - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 + tlen ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); - - *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( tlen ) & 0xFF ); - - *olen = 4; - - if( ssl->session_negotiate->ticket == NULL || tlen == 0 ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "sending session ticket of length %d", tlen ) ); - - memcpy( p, ssl->session_negotiate->ticket, tlen ); - - *olen += tlen; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_ALPN) -static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen ) -{ - unsigned char *p = buf; - size_t alpnlen = 0; - const char **cur; - - *olen = 0; - - if( ssl->conf->alpn_list == NULL ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); - - for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) - alpnlen += strlen( *cur ) + 1; - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 + alpnlen ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); - - /* - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - */ - - /* Skip writing extension and list length for now */ - p += 4; - - for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) - { - /* - * mbedtls_ssl_conf_set_alpn_protocols() checked that the length of - * protocol names is less than 255. - */ - *p = (unsigned char)strlen( *cur ); - memcpy( p + 1, *cur, *p ); - p += 1 + *p; - } - - *olen = p - buf; - - /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */ - buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); - buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); - - /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */ - buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); - buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_ALPN */ - -/* - * Generate random bytes for ClientHello - */ -static int ssl_generate_random( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *p = ssl->handshake->randbytes; -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t; -#endif - - /* - * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1) - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->verify_cookie != NULL ) - { - return( 0 ); - } -#endif - -#if defined(MBEDTLS_HAVE_TIME) - t = mbedtls_time( NULL ); - *p++ = (unsigned char)( t >> 24 ); - *p++ = (unsigned char)( t >> 16 ); - *p++ = (unsigned char)( t >> 8 ); - *p++ = (unsigned char)( t ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) ); -#else - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) - return( ret ); - - p += 4; -#endif /* MBEDTLS_HAVE_TIME */ - - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/** - * \brief Validate cipher suite against config in SSL context. - * - * \param suite_info cipher suite to validate - * \param ssl SSL context - * \param min_minor_ver Minimal minor version to accept a cipher suite - * \param max_minor_ver Maximal minor version to accept a cipher suite - * - * \return 0 if valid, else 1 - */ -static int ssl_validate_ciphersuite( - const mbedtls_ssl_ciphersuite_t * suite_info, - const mbedtls_ssl_context * ssl, - int min_minor_ver, int max_minor_ver ) -{ - (void) ssl; - if( suite_info == NULL ) - return( 1 ); - - if( suite_info->min_minor_ver > max_minor_ver || - suite_info->max_minor_ver < min_minor_ver ) - return( 1 ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) ) - return( 1 ); -#endif - -#if defined(MBEDTLS_ARC4_C) - if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED && - suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) - return( 1 ); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && - mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) - return( 1 ); -#endif - - return( 0 ); -} - -static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t i, n, olen, ext_len = 0; - - unsigned char *buf; - unsigned char *p, *q; - const unsigned char *end; - - unsigned char offer_compress; - const int *ciphersuites; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - int uses_ec = 0; -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) ); - - if( ssl->conf->f_rng == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); - return( MBEDTLS_ERR_SSL_NO_RNG ); - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif - { - ssl->major_ver = ssl->conf->min_major_ver; - ssl->minor_ver = ssl->conf->min_minor_ver; - } - - if( ssl->conf->max_major_ver == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "configured max major version is invalid, consider using mbedtls_ssl_config_defaults()" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - buf = ssl->out_msg; - end = buf + MBEDTLS_SSL_OUT_CONTENT_LEN; - - /* - * Check if there's enough space for the first part of the ClientHello - * consisting of the 38 bytes described below, the session identifier (at - * most 32 bytes) and its length (1 byte). - * - * Use static upper bounds instead of the actual values - * to allow the compiler to optimize this away. - */ - MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 38 + 1 + 32 ); - - /* - * The 38 first bytes of the ClientHello: - * 0 . 0 handshake type (written later) - * 1 . 3 handshake length (written later) - * 4 . 5 highest version supported - * 6 . 9 current UNIX time - * 10 . 37 random bytes - * - * The current UNIX time (4 bytes) and following 28 random bytes are written - * by ssl_generate_random() into ssl->handshake->randbytes buffer and then - * copied from there into the output buffer. - */ - - p = buf + 4; - mbedtls_ssl_write_version( ssl->conf->max_major_ver, - ssl->conf->max_minor_ver, - ssl->conf->transport, p ); - p += 2; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]", - buf[4], buf[5] ) ); - - if( ( ret = ssl_generate_random( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret ); - return( ret ); - } - - memcpy( p, ssl->handshake->randbytes, 32 ); - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 ); - p += 32; - - /* - * 38 . 38 session id length - * 39 . 39+n session id - * 39+n . 39+n DTLS only: cookie length (1 byte) - * 40+n . .. DTLS only: cookie - * .. . .. ciphersuitelist length (2 bytes) - * .. . .. ciphersuitelist - * .. . .. compression methods length (1 byte) - * .. . .. compression methods - * .. . .. extensions length (2 bytes) - * .. . .. extensions - */ - n = ssl->session_negotiate->id_len; - - if( n < 16 || n > 32 || -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || -#endif - ssl->handshake->resume == 0 ) - { - n = 0; - } - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - /* - * RFC 5077 section 3.4: "When presenting a ticket, the client MAY - * generate and include a Session ID in the TLS ClientHello." - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif - { - if( ssl->session_negotiate->ticket != NULL && - ssl->session_negotiate->ticket_len != 0 ) - { - ret = ssl->conf->f_rng( ssl->conf->p_rng, - ssl->session_negotiate->id, 32 ); - - if( ret != 0 ) - return( ret ); - - ssl->session_negotiate->id_len = n = 32; - } - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - /* - * The first check of the output buffer size above ( - * MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 38 + 1 + 32 );) - * has checked that there is enough space in the output buffer for the - * session identifier length byte and the session identifier (n <= 32). - */ - *p++ = (unsigned char) n; - - for( i = 0; i < n; i++ ) - *p++ = ssl->session_negotiate->id[i]; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n ); - - /* - * With 'n' being the length of the session identifier - * - * 39+n . 39+n DTLS only: cookie length (1 byte) - * 40+n . .. DTLS only: cookie - * .. . .. ciphersuitelist length (2 bytes) - * .. . .. ciphersuitelist - * .. . .. compression methods length (1 byte) - * .. . .. compression methods - * .. . .. extensions length (2 bytes) - * .. . .. extensions - */ - - /* - * DTLS cookie - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 1 ); - - if( ssl->handshake->verify_cookie == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) ); - *p++ = 0; - } - else - { - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie", - ssl->handshake->verify_cookie, - ssl->handshake->verify_cookie_len ); - - *p++ = ssl->handshake->verify_cookie_len; - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, - ssl->handshake->verify_cookie_len ); - memcpy( p, ssl->handshake->verify_cookie, - ssl->handshake->verify_cookie_len ); - p += ssl->handshake->verify_cookie_len; - } - } -#endif - - /* - * Ciphersuite list - */ - ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; - - /* Skip writing ciphersuite length for now */ - n = 0; - q = p; - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); - p += 2; - - for( i = 0; ciphersuites[i] != 0; i++ ) - { - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] ); - - if( ssl_validate_ciphersuite( ciphersuite_info, ssl, - ssl->conf->min_minor_ver, - ssl->conf->max_minor_ver ) != 0 ) - continue; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x", - ciphersuites[i] ) ); - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - uses_ec |= mbedtls_ssl_ciphersuite_uses_ec( ciphersuite_info ); -#endif - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); - - n++; - *p++ = (unsigned char)( ciphersuites[i] >> 8 ); - *p++ = (unsigned char)( ciphersuites[i] ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) ); - - /* - * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) ); - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); - *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); - *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ); - n++; - } - - /* Some versions of OpenSSL don't handle it correctly if not at end */ -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) - if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); - *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ); - *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ); - n++; - } -#endif - - *q++ = (unsigned char)( n >> 7 ); - *q++ = (unsigned char)( n << 1 ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - offer_compress = 1; -#else - offer_compress = 0; -#endif - - /* - * We don't support compression with DTLS right now: if many records come - * in the same datagram, uncompressing one could overwrite the next one. - * We don't want to add complexity for handling that case unless there is - * an actual need for it. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - offer_compress = 0; -#endif - - if( offer_compress ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d", - MBEDTLS_SSL_COMPRESS_DEFLATE, - MBEDTLS_SSL_COMPRESS_NULL ) ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 3 ); - *p++ = 2; - *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE; - *p++ = MBEDTLS_SSL_COMPRESS_NULL; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", - MBEDTLS_SSL_COMPRESS_NULL ) ); - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); - *p++ = 1; - *p++ = MBEDTLS_SSL_COMPRESS_NULL; - } - - /* First write extensions, then the total length */ - - MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ( ret = ssl_write_hostname_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_hostname_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - - /* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added - * even if MBEDTLS_SSL_RENEGOTIATION is not defined. */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ( ret = ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_renegotiation_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - if( ( ret = ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_signature_algorithms_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( uses_ec ) - { - if( ( ret = ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_supported_elliptic_curves_ext", ret ); - return( ret ); - } - ext_len += olen; - - if( ( ret = ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_supported_point_formats_ext", ret ); - return( ret ); - } - ext_len += olen; - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ( ret = ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_ecjpake_kkpp_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - if( ( ret = ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_max_fragment_length_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - if( ( ret = ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_truncated_hmac_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if( ( ret = ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_encrypt_then_mac_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - if( ( ret = ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_extended_ms_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_ALPN) - if( ( ret = ssl_write_alpn_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_alpn_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if( ( ret = ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, - end, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_session_ticket_ext", ret ); - return( ret ); - } - ext_len += olen; -#endif - - /* olen unused if all extensions are disabled */ - ((void) olen); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d", - ext_len ) ); - - if( ext_len > 0 ) - { - /* No need to check for space here, because the extension - * writing functions already took care of that. */ - *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ext_len ) & 0xFF ); - p += ext_len; - } - - ssl->out_msglen = p - buf; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO; - - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_send_flight_completed( ssl ); -#endif - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) ); - - return( 0 ); -} - -static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - /* Check verify-data in constant-time. The length OTOH is no secret */ - if( len != 1 + ssl->verify_data_len * 2 || - buf[0] != ssl->verify_data_len * 2 || - mbedtls_ssl_safer_memcmp( buf + 1, - ssl->own_verify_data, ssl->verify_data_len ) != 0 || - mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len, - ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - } - else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - if( len != 1 || buf[0] != 0x00 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "non-zero length renegotiation info" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - } - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - /* - * server should use the extension only if we did, - * and if so the server's value should match ours (and len is always 1) - */ - if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE || - len != 1 || - buf[0] != ssl->conf->mfl_code ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "non-matching max fragment length extension" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED || - len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "non-matching truncated HMAC extension" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ((void) buf); - - ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || - len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "non-matching encrypt-then-MAC extension" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ((void) buf); - - ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || - len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "non-matching extended master secret extension" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ((void) buf); - - ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED || - len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "non-matching session ticket extension" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ((void) buf); - - ssl->handshake->new_session_ticket = 1; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t list_size; - const unsigned char *p; - - if( len == 0 || (size_t)( buf[0] + 1 ) != len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - list_size = buf[0]; - - p = buf + 1; - while( list_size > 0 ) - { - if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || - p[0] == MBEDTLS_ECP_PF_COMPRESSED ) - { -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) - ssl->handshake->ecdh_ctx.point_format = p[0]; -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl->handshake->ecjpake_ctx.point_format = p[0]; -#endif - MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); - return( 0 ); - } - - list_size--; - p++; - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - int ret; - - if( ssl->transform_negotiate->ciphersuite_info->key_exchange != - MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); - return( 0 ); - } - - /* If we got here, we no longer need our cached extension */ - mbedtls_free( ssl->handshake->ecjpake_cache ); - ssl->handshake->ecjpake_cache = NULL; - ssl->handshake->ecjpake_cache_len = 0; - - if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, - buf, len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) -static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - size_t list_len, name_len; - const char **p; - - /* If we didn't send it, the server shouldn't send it */ - if( ssl->conf->alpn_list == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - /* - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - * - * the "ProtocolNameList" MUST contain exactly one "ProtocolName" - */ - - /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ - if( len < 4 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - list_len = ( buf[0] << 8 ) | buf[1]; - if( list_len != len - 2 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - name_len = buf[2]; - if( name_len != list_len - 1 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - /* Check that the server chosen protocol was in our list and save it */ - for( p = ssl->conf->alpn_list; *p != NULL; p++ ) - { - if( name_len == strlen( *p ) && - memcmp( buf + 3, *p, name_len ) == 0 ) - { - ssl->alpn_chosen = *p; - return( 0 ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); -} -#endif /* MBEDTLS_SSL_ALPN */ - -/* - * Parse HelloVerifyRequest. Only called after verifying the HS type. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) -{ - const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - int major_ver, minor_ver; - unsigned char cookie_len; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) ); - - /* Check that there is enough room for: - * - 2 bytes of version - * - 1 byte of cookie_len - */ - if( mbedtls_ssl_hs_hdr_len( ssl ) + 3 > ssl->in_msglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "incoming HelloVerifyRequest message is too short" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - /* - * struct { - * ProtocolVersion server_version; - * opaque cookie<0..2^8-1>; - * } HelloVerifyRequest; - */ - MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); - mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p ); - p += 2; - - /* - * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1) - * even is lower than our min version. - */ - if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 || - minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 || - major_ver > ssl->conf->max_major_ver || - minor_ver > ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - - cookie_len = *p++; - if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "cookie length does not match incoming message size" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); - - mbedtls_free( ssl->handshake->verify_cookie ); - - ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len ); - if( ssl->handshake->verify_cookie == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - memcpy( ssl->handshake->verify_cookie, p, cookie_len ); - ssl->handshake->verify_cookie_len = cookie_len; - - /* Start over at ClientHello */ - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; - mbedtls_ssl_reset_checksum( ssl ); - - mbedtls_ssl_recv_flight_completed( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) -{ - int ret, i; - size_t n; - size_t ext_len; - unsigned char *buf, *ext; - unsigned char comp; -#if defined(MBEDTLS_ZLIB_SUPPORT) - int accept_comp; -#endif -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renegotiation_info_seen = 0; -#endif - int handshake_failure = 0; - const mbedtls_ssl_ciphersuite_t *suite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) ); - - buf = ssl->in_msg; - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - /* No alert on a read error. */ - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - ssl->renego_records_seen++; - - if( ssl->conf->renego_max_records >= 0 && - ssl->renego_records_seen > ssl->conf->renego_max_records ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "renegotiation requested, but not honored by server" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "non-handshake message during renegotiation" ) ); - - ssl->keep_current_message = 1; - return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) ); - return( ssl_parse_hello_verify_request( ssl ) ); - } - else - { - /* We made it through the verification process */ - mbedtls_free( ssl->handshake->verify_cookie ); - ssl->handshake->verify_cookie = NULL; - ssl->handshake->verify_cookie_len = 0; - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) || - buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - /* - * 0 . 1 server_version - * 2 . 33 random (maybe including 4 bytes of Unix time) - * 34 . 34 session_id length = n - * 35 . 34+n session_id - * 35+n . 36+n cipher_suite - * 37+n . 37+n compression_method - * - * 38+n . 39+n extensions length (optional) - * 40+n . .. extensions - */ - buf += mbedtls_ssl_hs_hdr_len( ssl ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 ); - mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, - ssl->conf->transport, buf + 0 ); - - if( ssl->major_ver < ssl->conf->min_major_ver || - ssl->minor_ver < ssl->conf->min_minor_ver || - ssl->major_ver > ssl->conf->max_major_ver || - ssl->minor_ver > ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "server version out of bounds - min: [%d:%d], server: [%d:%d], max: [%d:%d]", - ssl->conf->min_major_ver, - ssl->conf->min_minor_ver, - ssl->major_ver, ssl->minor_ver, - ssl->conf->max_major_ver, - ssl->conf->max_minor_ver ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", - ( (uint32_t) buf[2] << 24 ) | - ( (uint32_t) buf[3] << 16 ) | - ( (uint32_t) buf[4] << 8 ) | - ( (uint32_t) buf[5] ) ) ); - - memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 ); - - n = buf[34]; - - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 ); - - if( n > 32 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n ) - { - ext_len = ( ( buf[38 + n] << 8 ) - | ( buf[39 + n] ) ); - - if( ( ext_len > 0 && ext_len < 4 ) || - ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - } - else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n ) - { - ext_len = 0; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - /* ciphersuite (used later) */ - i = ( buf[35 + n] << 8 ) | buf[36 + n]; - - /* - * Read and check compression - */ - comp = buf[37 + n]; - -#if defined(MBEDTLS_ZLIB_SUPPORT) - /* See comments in ssl_write_client_hello() */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - accept_comp = 0; - else -#endif - accept_comp = 1; - - if( comp != MBEDTLS_SSL_COMPRESS_NULL && - ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) ) -#else /* MBEDTLS_ZLIB_SUPPORT */ - if( comp != MBEDTLS_SSL_COMPRESS_NULL ) -#endif/* MBEDTLS_ZLIB_SUPPORT */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "server hello, bad compression: %d", comp ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } - - /* - * Initialize update checksum functions - */ - ssl->transform_negotiate->ciphersuite_info = - mbedtls_ssl_ciphersuite_from_id( i ); - - if( ssl->transform_negotiate->ciphersuite_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "ciphersuite info for %04x not found", i ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - mbedtls_ssl_optimize_checksum( ssl, - ssl->transform_negotiate->ciphersuite_info ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n ); - - /* - * Check if the session can be resumed - */ - if( ssl->handshake->resume == 0 || n == 0 || -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || -#endif - ssl->session_negotiate->ciphersuite != i || - ssl->session_negotiate->compression != comp || - ssl->session_negotiate->id_len != n || - memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 ) - { - ssl->state++; - ssl->handshake->resume = 0; -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time( NULL ); -#endif - ssl->session_negotiate->ciphersuite = i; - ssl->session_negotiate->compression = comp; - ssl->session_negotiate->id_len = n; - memcpy( ssl->session_negotiate->id, buf + 35, n ); - } - else - { - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( ret ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", - ssl->handshake->resume ? "a" : "no" ) ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", - buf[37 + n] ) ); - - /* - * Perform cipher suite validation in same way as in ssl_write_client_hello. - */ - i = 0; - while( 1 ) - { - if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] == - ssl->session_negotiate->ciphersuite ) - { - break; - } - } - - suite_info = mbedtls_ssl_ciphersuite_from_id( - ssl->session_negotiate->ciphersuite ); - if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, - ssl->minor_ver ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "server hello, chosen ciphersuite: %s", suite_info->name ) ); - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA && - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - ssl->handshake->ecrs_enabled = 1; - } -#endif - - if( comp != MBEDTLS_SSL_COMPRESS_NULL -#if defined(MBEDTLS_ZLIB_SUPPORT) - && comp != MBEDTLS_SSL_COMPRESS_DEFLATE -#endif - ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - ssl->session_negotiate->compression = comp; - - ext = buf + 40 + n; - - MBEDTLS_SSL_DEBUG_MSG( 2, - ( "server hello, total extension length: %d", ext_len ) ); - - while( ext_len ) - { - unsigned int ext_id = ( ( ext[0] << 8 ) - | ( ext[1] ) ); - unsigned int ext_size = ( ( ext[2] << 8 ) - | ( ext[3] ) ); - - if( ext_size + 4 > ext_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( - ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - switch( ext_id ) - { - case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - renegotiation_info_seen = 1; -#endif - - if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4, - ext_size ) ) != 0 ) - return( ret ); - - break; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "found max_fragment_length extension" ) ); - - if( ( ret = ssl_parse_max_fragment_length_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) ); - - if( ( ret = ssl_parse_truncated_hmac_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) ); - - if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "found extended_master_secret extension" ) ); - - if( ( ret = ssl_parse_extended_ms_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_TLS_EXT_SESSION_TICKET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) ); - - if( ( ret = ssl_parse_session_ticket_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "found supported_point_formats extension" ) ); - - if( ( ret = ssl_parse_supported_point_formats_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) ); - - if( ( ret = ssl_parse_ecjpake_kkpp( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) - case MBEDTLS_TLS_EXT_ALPN: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); - - if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 ) - return( ret ); - - break; -#endif /* MBEDTLS_SSL_ALPN */ - - default: - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "unknown extension found: %d (ignoring)", ext_id ) ); - } - - ext_len -= 4 + ext_size; - ext += 4 + ext_size; - - if( ext_len > 0 && ext_len < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - } - - /* - * Renegotiation security checks - */ - if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == - MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "legacy renegotiation, breaking off handshake" ) ); - handshake_failure = 1; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && - renegotiation_info_seen == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "renegotiation_info extension missing (secure)" ) ); - handshake_failure = 1; - } - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == - MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); - handshake_failure = 1; - } - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - renegotiation_info_seen == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "renegotiation_info extension present (legacy)" ) ); - handshake_failure = 1; - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - if( handshake_failure == 1 ) - { - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t dhm_actual_bitlen; - - /* - * Ephemeral DH parameters: - * - * struct { - * opaque dh_p<1..2^16-1>; - * opaque dh_g<1..2^16-1>; - * opaque dh_Ys<1..2^16-1>; - * } ServerDHParams; - */ - if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, - p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret ); - return( ret ); - } - - dhm_actual_bitlen = mbedtls_mpi_bitlen( &ssl->handshake->dhm_ctx.P ); - if( dhm_actual_bitlen < ssl->conf->dhm_min_bitlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %u < %u", - (unsigned) dhm_actual_bitlen, - ssl->conf->dhm_min_bitlen ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) -{ - const mbedtls_ecp_curve_info *curve_info; - mbedtls_ecp_group_id grp_id; -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - grp_id = ssl->handshake->ecdh_ctx.grp.id; -#else - grp_id = ssl->handshake->ecdh_ctx.grp_id; -#endif - - curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id ); - if( curve_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); - -#if defined(MBEDTLS_ECP_C) - if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 ) -#else - if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || - ssl->handshake->ecdh_ctx.grp.nbits > 521 ) -#endif - return( -1 ); - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP ); - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - /* - * Ephemeral ECDH parameters: - * - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ - if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx, - (const unsigned char **) p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - - if( ssl_check_server_ecdh_params( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "bad server key exchange message (ECDHE curve)" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t len; - ((void) ssl); - - /* - * PSK parameters: - * - * opaque psk_identity_hint<0..2^16-1>; - */ - if( end - (*p) < 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "bad server key exchange message (psk_identity_hint length)" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - len = (*p)[0] << 8 | (*p)[1]; - *p += 2; - - if( end - (*p) < (int) len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "bad server key exchange message (psk_identity_hint length)" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - /* - * Note: we currently ignore the PKS identity hint, as we only allow one - * PSK to be provisionned on the client. This could be changed later if - * someone needs that feature. - */ - *p += len; - ret = 0; - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -/* - * Generate a pre-master secret and encrypt it with the server's RSA key - */ -static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, - size_t offset, size_t *olen, - size_t pms_offset ) -{ - int ret; - size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2; - unsigned char *p = ssl->handshake->premaster + pms_offset; - - if( offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - /* - * Generate (part of) the pre-master as - * struct { - * ProtocolVersion client_version; - * opaque random[46]; - * } PreMasterSecret; - */ - mbedtls_ssl_write_version( ssl->conf->max_major_ver, - ssl->conf->max_minor_ver, - ssl->conf->transport, p ); - - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret ); - return( ret ); - } - - ssl->handshake->pmslen = 48; - - if( ssl->session_negotiate->peer_cert == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* - * Now write it out, encrypted - */ - if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, - MBEDTLS_PK_RSA ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); - } - - if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk, - p, ssl->handshake->pmslen, - ssl->out_msg + offset + len_bytes, olen, - MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( len_bytes == 2 ) - { - ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 ); - ssl->out_msg[offset+1] = (unsigned char)( *olen ); - *olen += 2; - } -#endif - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end, - mbedtls_md_type_t *md_alg, - mbedtls_pk_type_t *pk_alg ) -{ - ((void) ssl); - *md_alg = MBEDTLS_MD_NONE; - *pk_alg = MBEDTLS_PK_NONE; - - /* Only in TLS 1.2 */ - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - { - return( 0 ); - } - - if( (*p) + 2 > end ) - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - - /* - * Get hash algorithm - */ - if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) - == MBEDTLS_MD_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "Server used unsupported HashAlgorithm %d", *(p)[0] ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - /* - * Get signature algorithm - */ - if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) - == MBEDTLS_PK_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - /* - * Check if the hash is acceptable - */ - if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "server used HashAlgorithm %d that was not offered", *(p)[0] ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", - (*p)[1] ) ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", - (*p)[0] ) ); - *p += 2; - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) -{ - int ret; - const mbedtls_ecp_keypair *peer_key; - - if( ssl->session_negotiate->peer_cert == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, - MBEDTLS_PK_ECKEY ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); - } - - peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk ); - - if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key, - MBEDTLS_ECDH_THEIRS ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); - return( ret ); - } - - if( ssl_check_server_ecdh_params( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - unsigned char *p = NULL, *end = NULL; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); - ssl->state++; - return( 0 ); - } - ((void) p); - ((void) end); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); - ssl->state++; - return( 0 ); - } - ((void) p); - ((void) end); -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing ) - { - goto start_processing; - } -#endif - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* - * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server - * doesn't use a psk_identity_hint - */ - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE ) - { - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { - /* Current message is probably either - * CertificateRequest or ServerHelloDone */ - ssl->keep_current_message = 1; - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "server key exchange message must not be skipped" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing; - -start_processing: -#endif - p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - end = ssl->in_msg + ssl->in_hslen; - MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p ); - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { - if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } /* FALLTROUGH */ -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - ; /* nothing more to do */ - else -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) - { - if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) - { - if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, - p, end - p ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) - { - size_t sig_len, hashlen; - unsigned char hash[64]; - mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - size_t params_len = p - params; - void *rs_ctx = NULL; - - /* - * Handle the digitally-signed structure - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - if( ssl_parse_signature_algorithm( ssl, &p, end, - &md_alg, &pk_alg ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - if( pk_alg != - mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) - { - pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); - - /* Default hash for ECDSA is SHA-1 */ - if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE ) - md_alg = MBEDTLS_MD_SHA1; - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * Read signature - */ - - if( p > end - 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - sig_len = ( p[0] << 8 ) | p[1]; - p += 2; - - if( p != end - sig_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len ); - - /* - * Compute the hash that has been signed - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( md_alg == MBEDTLS_MD_NONE ) - { - hashlen = 36; - ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash, params, - params_len ); - if( ret != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( md_alg != MBEDTLS_MD_NONE ) - { - ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, - params, params_len, - md_alg ); - if( ret != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); - - if( ssl->session_negotiate->peer_cert == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* - * Verify signature - */ - if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, - pk_alg ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - rs_ctx = &ssl->handshake->ecrs_ctx.pk; -#endif - - if( ( ret = mbedtls_pk_verify_restartable( - &ssl->session_negotiate->peer_cert->pk, - md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 ) - { -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) -#endif - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - -exit: - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) ); - - return( 0 ); -} - -#if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) -static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); - - if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} -#else /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ -static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *buf; - size_t n = 0; - size_t cert_type_len = 0, dn_len = 0; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); - - if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); - ssl->state++; - return( 0 ); - } - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - ssl->state++; - ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request", - ssl->client_auth ? "a" : "no" ) ); - - if( ssl->client_auth == 0 ) - { - /* Current message is probably the ServerHelloDone */ - ssl->keep_current_message = 1; - goto exit; - } - - /* - * struct { - * ClientCertificateType certificate_types<1..2^8-1>; - * SignatureAndHashAlgorithm - * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only - * DistinguishedName certificate_authorities<0..2^16-1>; - * } CertificateRequest; - * - * Since we only support a single certificate on clients, let's just - * ignore all the information that's supposed to help us pick a - * certificate. - * - * We could check that our certificate matches the request, and bail out - * if it doesn't, but it's simpler to just send the certificate anyway, - * and give the server the opportunity to decide if it should terminate - * the connection when it doesn't like our certificate. - * - * Same goes for the hash in TLS 1.2's signature_algorithms: at this - * point we only have one hash available (see comments in - * write_certificate_verify), so let's just use what we have. - * - * However, we still minimally parse the message to check it is at least - * superficially sane. - */ - buf = ssl->in_msg; - - /* certificate_types */ - if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); - } - cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )]; - n = cert_type_len; - - /* - * In the subsequent code there are two paths that read from buf: - * * the length of the signature algorithms field (if minor version of - * SSL is 3), - * * distinguished name length otherwise. - * Both reach at most the index: - * ...hdr_len + 2 + n, - * therefore the buffer length at this point must be greater than that - * regardless of the actual code path. - */ - if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); - } - - /* supported_signature_algorithms */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - size_t sig_alg_len = - ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) - | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); -#if defined(MBEDTLS_DEBUG_C) - unsigned char* sig_alg; - size_t i; -#endif - - /* - * The furthest access in buf is in the loop few lines below: - * sig_alg[i + 1], - * where: - * sig_alg = buf + ...hdr_len + 3 + n, - * max(i) = sig_alg_len - 1. - * Therefore the furthest access is: - * buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1], - * which reduces to: - * buf[...hdr_len + 3 + n + sig_alg_len], - * which is one less than we need the buf to be. - */ - if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) - + 3 + n + sig_alg_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); - } - -#if defined(MBEDTLS_DEBUG_C) - sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n; - for( i = 0; i < sig_alg_len; i += 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "Supported Signature Algorithm found: %d,%d", - sig_alg[i], sig_alg[i + 1] ) ); - } -#endif - - n += 2 + sig_alg_len; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - /* certificate_authorities */ - dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) - | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); - - n += dn_len; - if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); - } - -exit: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ - -static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) || - ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE ); - } - - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_recv_flight_completed( ssl ); -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) ); - - return( 0 ); -} - -static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t i, n; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) ); - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) - { - /* - * DHM key exchange -- send G^X mod P - */ - n = ssl->handshake->dhm_ctx.len; - - ssl->out_msg[4] = (unsigned char)( n >> 8 ); - ssl->out_msg[5] = (unsigned char)( n ); - i = 6; - - ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - &ssl->out_msg[i], n, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); - - if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - /* - * ECDH key exchange -- send client public value - */ - i = 4; - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - { - if( ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret ) - goto ecdh_calc_secret; - - mbedtls_ecdh_enable_restart( &ssl->handshake->ecdh_ctx ); - } -#endif - - ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, - &n, - &ssl->out_msg[i], 1000, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q ); - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - { - ssl->handshake->ecrs_n = n; - ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret; - } - -ecdh_calc_secret: - if( ssl->handshake->ecrs_enabled ) - n = ssl->handshake->ecrs_n; -#endif - if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) - { - /* - * opaque psk_identity<0..2^16-1>; - */ - if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - i = 4; - n = ssl->conf->psk_identity_len; - - if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "psk identity too long or SSL buffer too short" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - ssl->out_msg[i++] = (unsigned char)( n >> 8 ); - ssl->out_msg[i++] = (unsigned char)( n ); - - memcpy( ssl->out_msg + i, - ssl->conf->psk_identity, - ssl->conf->psk_identity_len ); - i += ssl->conf->psk_identity_len; - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) - { - n = 0; - } - else -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { - if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 ) - return( ret ); - } - else -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) - { - /* - * ClientDiffieHellmanPublic public (DHM send G^X mod P) - */ - n = ssl->handshake->dhm_ctx.len; - - if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "psk identity or DHM size too long or SSL buffer too short" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - ssl->out_msg[i++] = (unsigned char)( n >> 8 ); - ssl->out_msg[i++] = (unsigned char)( n ); - - ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - &ssl->out_msg[i], n, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { - /* - * ClientECDiffieHellmanPublic public; - */ - ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n, - &ssl->out_msg[i], MBEDTLS_SSL_OUT_CONTENT_LEN - i, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, - "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) - { - i = 4; - if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - i = 4; - - ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, - ssl->out_msg + i, MBEDTLS_SSL_OUT_CONTENT_LEN - i, &n, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); - return( ret ); - } - - ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, - ssl->handshake->premaster, 32, &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - { - ((void) ciphersuite_info); - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->out_msglen = i + n; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} -#else -static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - size_t n = 0, offset = 0; - unsigned char hash[48]; - unsigned char *hash_start = hash; - mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; - unsigned int hashlen; - void *rs_ctx = NULL; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign ) - { - goto sign; - } -#endif - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state++; - return( 0 ); - } - - if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state++; - return( 0 ); - } - - if( mbedtls_ssl_own_key( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - /* - * Make a signature of the handshake digests - */ -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign; - -sign: -#endif - - ssl->handshake->calc_verify( ssl, hash ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - { - /* - * digitally-signed struct { - * opaque md5_hash[16]; - * opaque sha_hash[20]; - * }; - * - * md5_hash - * MD5(handshake_messages); - * - * sha_hash - * SHA(handshake_messages); - */ - hashlen = 36; - md_alg = MBEDTLS_MD_NONE; - - /* - * For ECDSA, default hash is SHA-1 only - */ - if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) ) - { - hash_start += 16; - hashlen -= 16; - md_alg = MBEDTLS_MD_SHA1; - } - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - /* - * digitally-signed struct { - * opaque handshake_messages[handshake_messages_length]; - * }; - * - * Taking shortcut here. We assume that the server always allows the - * PRF Hash function and has sent it in the allowed signature - * algorithms list received in the Certificate Request message. - * - * Until we encounter a server that does not, we will take this - * shortcut. - * - * Reason: Otherwise we should have running hashes for SHA512 and - * SHA224 in order to satisfy 'weird' needs from the server - * side. - */ - if( ssl->transform_negotiate->ciphersuite_info->mac == - MBEDTLS_MD_SHA384 ) - { - md_alg = MBEDTLS_MD_SHA384; - ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384; - } - else - { - md_alg = MBEDTLS_MD_SHA256; - ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256; - } - ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) ); - - /* Info from md_alg will be used instead */ - hashlen = 0; - offset = 2; - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - rs_ctx = &ssl->handshake->ecrs_ctx.pk; -#endif - - if( ( ret = mbedtls_pk_sign_restartable( mbedtls_ssl_own_key( ssl ), - md_alg, hash_start, hashlen, - ssl->out_msg + 6 + offset, &n, - ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - - ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 ); - ssl->out_msg[5 + offset] = (unsigned char)( n ); - - ssl->out_msglen = 6 + n + offset; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) ); - - return( ret ); -} -#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) -{ - int ret; - uint32_t lifetime; - size_t ticket_len; - unsigned char *ticket; - const unsigned char *msg; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) ); - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* - * struct { - * uint32 ticket_lifetime_hint; - * opaque ticket<0..2^16-1>; - * } NewSessionTicket; - * - * 0 . 3 ticket_lifetime_hint - * 4 . 5 ticket_len (n) - * 6 . 5+n ticket content - */ - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET || - ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); - } - - msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - - lifetime = ( ((uint32_t) msg[0]) << 24 ) | ( msg[1] << 16 ) | - ( msg[2] << 8 ) | ( msg[3] ); - - ticket_len = ( msg[4] << 8 ) | ( msg[5] ); - - if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) ); - - /* We're not waiting for a NewSessionTicket message any more */ - ssl->handshake->new_session_ticket = 0; - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - - /* - * Zero-length ticket means the server changed his mind and doesn't want - * to send a ticket after all, so just forget it - */ - if( ticket_len == 0 ) - return( 0 ); - - mbedtls_platform_zeroize( ssl->session_negotiate->ticket, - ssl->session_negotiate->ticket_len ); - mbedtls_free( ssl->session_negotiate->ticket ); - ssl->session_negotiate->ticket = NULL; - ssl->session_negotiate->ticket_len = 0; - - if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - memcpy( ticket, msg + 6, ticket_len ); - - ssl->session_negotiate->ticket = ticket; - ssl->session_negotiate->ticket_len = ticket_len; - ssl->session_negotiate->ticket_lifetime = lifetime; - - /* - * RFC 5077 section 3.4: - * "If the client receives a session ticket from the server, then it - * discards any Session ID that was sent in the ServerHello." - */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) ); - ssl->session_negotiate->id_len = 0; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -/* - * SSL handshake -- client side -- single step - */ -int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) ); - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) - { - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* Change state now, so that it is right in mbedtls_ssl_read_record(), used - * by DTLS for dropping out-of-sequence ChangeCipherSpec records */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC && - ssl->handshake->new_session_ticket != 0 ) - { - ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET; - } -#endif - - switch( ssl->state ) - { - case MBEDTLS_SSL_HELLO_REQUEST: - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; - break; - - /* - * ==> ClientHello - */ - case MBEDTLS_SSL_CLIENT_HELLO: - ret = ssl_write_client_hello( ssl ); - break; - - /* - * <== ServerHello - * Certificate - * ( ServerKeyExchange ) - * ( CertificateRequest ) - * ServerHelloDone - */ - case MBEDTLS_SSL_SERVER_HELLO: - ret = ssl_parse_server_hello( ssl ); - break; - - case MBEDTLS_SSL_SERVER_CERTIFICATE: - ret = mbedtls_ssl_parse_certificate( ssl ); - break; - - case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: - ret = ssl_parse_server_key_exchange( ssl ); - break; - - case MBEDTLS_SSL_CERTIFICATE_REQUEST: - ret = ssl_parse_certificate_request( ssl ); - break; - - case MBEDTLS_SSL_SERVER_HELLO_DONE: - ret = ssl_parse_server_hello_done( ssl ); - break; - - /* - * ==> ( Certificate/Alert ) - * ClientKeyExchange - * ( CertificateVerify ) - * ChangeCipherSpec - * Finished - */ - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - ret = mbedtls_ssl_write_certificate( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - ret = ssl_write_client_key_exchange( ssl ); - break; - - case MBEDTLS_SSL_CERTIFICATE_VERIFY: - ret = ssl_write_certificate_verify( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: - ret = mbedtls_ssl_write_change_cipher_spec( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_FINISHED: - ret = mbedtls_ssl_write_finished( ssl ); - break; - - /* - * <== ( NewSessionTicket ) - * ChangeCipherSpec - * Finished - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET: - ret = ssl_parse_new_session_ticket( ssl ); - break; -#endif - - case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: - ret = mbedtls_ssl_parse_change_cipher_spec( ssl ); - break; - - case MBEDTLS_SSL_SERVER_FINISHED: - ret = mbedtls_ssl_parse_finished( ssl ); - break; - - case MBEDTLS_SSL_FLUSH_BUFFERS: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; - break; - - case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - mbedtls_ssl_handshake_wrapup( ssl ); - break; - - default: - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - return( ret ); -} -#endif /* MBEDTLS_SSL_CLI_C */ diff --git a/mbedtls/ssl_cookie.c b/mbedtls/ssl_cookie.c deleted file mode 100644 index fe0aeba08..000000000 --- a/mbedtls/ssl_cookie.c +++ /dev/null @@ -1,292 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * DTLS cookie callbacks implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * These session callbacks use a simple chained list - * to store and retrieve the session information. - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_COOKIE_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/ssl_cookie.h" -#include "mbedtls/ssl_internal.h" -#include "mbedtls/platform_util.h" - -#include - -/* - * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is - * available. Try SHA-256 first, 512 wastes resources since we need to stay - * with max 32 bytes of cookie for DTLS 1.0 - */ -#if defined(MBEDTLS_SHA256_C) -#define COOKIE_MD MBEDTLS_MD_SHA224 -#define COOKIE_MD_OUTLEN 32 -#define COOKIE_HMAC_LEN 28 -#elif defined(MBEDTLS_SHA512_C) -#define COOKIE_MD MBEDTLS_MD_SHA384 -#define COOKIE_MD_OUTLEN 48 -#define COOKIE_HMAC_LEN 28 -#elif defined(MBEDTLS_SHA1_C) -#define COOKIE_MD MBEDTLS_MD_SHA1 -#define COOKIE_MD_OUTLEN 20 -#define COOKIE_HMAC_LEN 20 -#else -#error "DTLS hello verify needs SHA-1 or SHA-2" -#endif - -/* - * Cookies are formed of a 4-bytes timestamp (or serial number) and - * an HMAC of timestemp and client ID. - */ -#define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN ) - -void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ) -{ - mbedtls_md_init( &ctx->hmac_ctx ); -#if !defined(MBEDTLS_HAVE_TIME) - ctx->serial = 0; -#endif - ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif -} - -void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay ) -{ - ctx->timeout = delay; -} - -void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ) -{ - mbedtls_md_free( &ctx->hmac_ctx ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &ctx->mutex ); -#endif - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) ); -} - -int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - unsigned char key[COOKIE_MD_OUTLEN]; - - if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 ) - return( ret ); - - ret = mbedtls_md_setup( &ctx->hmac_ctx, mbedtls_md_info_from_type( COOKIE_MD ), 1 ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) ); - if( ret != 0 ) - return( ret ); - - mbedtls_platform_zeroize( key, sizeof( key ) ); - - return( 0 ); -} - -/* - * Generate the HMAC part of a cookie - */ -static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx, - const unsigned char time[4], - unsigned char **p, unsigned char *end, - const unsigned char *cli_id, size_t cli_id_len ) -{ - unsigned char hmac_out[COOKIE_MD_OUTLEN]; - - MBEDTLS_SSL_CHK_BUF_PTR( *p, end, COOKIE_HMAC_LEN ); - - if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 || - mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 || - mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 || - mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 ) - { - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - memcpy( *p, hmac_out, COOKIE_HMAC_LEN ); - *p += COOKIE_HMAC_LEN; - - return( 0 ); -} - -/* - * Generate cookie for DTLS ClientHello verification - */ -int mbedtls_ssl_cookie_write( void *p_ctx, - unsigned char **p, unsigned char *end, - const unsigned char *cli_id, size_t cli_id_len ) -{ - int ret; - mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; - unsigned long t; - - if( ctx == NULL || cli_id == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_CHK_BUF_PTR( *p, end, COOKIE_LEN ); - -#if defined(MBEDTLS_HAVE_TIME) - t = (unsigned long) mbedtls_time( NULL ); -#else - t = ctx->serial++; -#endif - - (*p)[0] = (unsigned char)( t >> 24 ); - (*p)[1] = (unsigned char)( t >> 16 ); - (*p)[2] = (unsigned char)( t >> 8 ); - (*p)[3] = (unsigned char)( t ); - *p += 4; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); -#endif - - ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4, - p, end, cli_id, cli_id_len ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + - MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -/* - * Check a cookie - */ -int mbedtls_ssl_cookie_check( void *p_ctx, - const unsigned char *cookie, size_t cookie_len, - const unsigned char *cli_id, size_t cli_id_len ) -{ - unsigned char ref_hmac[COOKIE_HMAC_LEN]; - int ret = 0; - unsigned char *p = ref_hmac; - mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; - unsigned long cur_time, cookie_time; - - if( ctx == NULL || cli_id == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( cookie_len != COOKIE_LEN ) - return( -1 ); - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); -#endif - - if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie, - &p, p + sizeof( ref_hmac ), - cli_id, cli_id_len ) != 0 ) - ret = -1; - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + - MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - if( ret != 0 ) - return( ret ); - - if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 ) - return( -1 ); - -#if defined(MBEDTLS_HAVE_TIME) - cur_time = (unsigned long) mbedtls_time( NULL ); -#else - cur_time = ctx->serial; -#endif - - cookie_time = ( (unsigned long) cookie[0] << 24 ) | - ( (unsigned long) cookie[1] << 16 ) | - ( (unsigned long) cookie[2] << 8 ) | - ( (unsigned long) cookie[3] ); - - if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout ) - return( -1 ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_COOKIE_C */ diff --git a/mbedtls/ssl_cookie.h b/mbedtls/ssl_cookie.h deleted file mode 100644 index 43d0e4bc7..000000000 --- a/mbedtls/ssl_cookie.h +++ /dev/null @@ -1,141 +0,0 @@ -#pragma GCC system_header -/** - * \file ssl_cookie.h - * - * \brief DTLS cookie callbacks implementation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_SSL_COOKIE_H -#define MBEDTLS_SSL_COOKIE_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ -#ifndef MBEDTLS_SSL_COOKIE_TIMEOUT -#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ -#endif - -/* \} name SECTION: Module settings */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Context for the default cookie functions. - */ -typedef struct mbedtls_ssl_cookie_ctx -{ - mbedtls_md_context_t hmac_ctx; /*!< context for the HMAC portion */ -#if !defined(MBEDTLS_HAVE_TIME) - unsigned long serial; /*!< serial number for expiration */ -#endif - unsigned long timeout; /*!< timeout delay, in seconds if HAVE_TIME, - or in number of tickets issued */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; -#endif -} mbedtls_ssl_cookie_ctx; - -/** - * \brief Initialize cookie context - */ -void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ); - -/** - * \brief Setup cookie context (generate keys) - */ -int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief Set expiration delay for cookies - * (Default MBEDTLS_SSL_COOKIE_TIMEOUT) - * - * \param ctx Cookie contex - * \param delay Delay, in seconds if HAVE_TIME, or in number of cookies - * issued in the meantime. - * 0 to disable expiration (NOT recommended) - */ -void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay ); - -/** - * \brief Free cookie context - */ -void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ); - -/** - * \brief Generate cookie, see \c mbedtls_ssl_cookie_write_t - */ -mbedtls_ssl_cookie_write_t mbedtls_ssl_cookie_write; - -/** - * \brief Verify cookie, see \c mbedtls_ssl_cookie_write_t - */ -mbedtls_ssl_cookie_check_t mbedtls_ssl_cookie_check; - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_cookie.h */ diff --git a/mbedtls/ssl_internal.h b/mbedtls/ssl_internal.h deleted file mode 100644 index 5b86e129c..000000000 --- a/mbedtls/ssl_internal.h +++ /dev/null @@ -1,934 +0,0 @@ -#pragma GCC system_header -/** - * \file ssl_internal.h - * - * \brief Internal functions shared by the SSL modules - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_SSL_INTERNAL_H -#define MBEDTLS_SSL_INTERNAL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" -#include "cipher.h" - -#if defined(MBEDTLS_MD5_C) -#include "md5.h" -#endif - -#if defined(MBEDTLS_SHA1_C) -#include "sha1.h" -#endif - -#if defined(MBEDTLS_SHA256_C) -#include "sha256.h" -#endif - -#if defined(MBEDTLS_SHA512_C) -#include "sha512.h" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#include "ecjpake.h" -#endif - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* Determine minimum supported version */ -#define MBEDTLS_SSL_MIN_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1) -#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) -#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3 -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1 */ -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#define MBEDTLS_SSL_MIN_VALID_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 -#define MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 - -/* Determine maximum supported version */ -#define MBEDTLS_SSL_MAX_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) -#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1) -#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 -#else -#if defined(MBEDTLS_SSL_PROTO_SSL3) -#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0 -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -/* Shorthand for restartable ECC */ -#if defined(MBEDTLS_ECP_RESTARTABLE) && \ - defined(MBEDTLS_SSL_CLI_C) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_SSL__ECP_RESTARTABLE -#endif - -#define MBEDTLS_SSL_INITIAL_HANDSHAKE 0 -#define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS 1 /* In progress */ -#define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */ -#define MBEDTLS_SSL_RENEGOTIATION_PENDING 3 /* Requested (server only) */ - -/* - * DTLS retransmission states, see RFC 6347 4.2.4 - * - * The SENDING state is merged in PREPARING for initial sends, - * but is distinct for resends. - * - * Note: initial state is wrong for server, but is not used anyway. - */ -#define MBEDTLS_SSL_RETRANS_PREPARING 0 -#define MBEDTLS_SSL_RETRANS_SENDING 1 -#define MBEDTLS_SSL_RETRANS_WAITING 2 -#define MBEDTLS_SSL_RETRANS_FINISHED 3 - -/* This macro determines whether CBC is supported. */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || \ - defined(MBEDTLS_CAMELLIA_C) || \ - defined(MBEDTLS_ARIA_C) || \ - defined(MBEDTLS_DES_C) ) -#define MBEDTLS_SSL_SOME_SUITES_USE_CBC -#endif - -/* This macro determines whether the CBC construct used in TLS 1.0-1.2 (as - * opposed to the very different CBC construct used in SSLv3) is supported. */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \ - ( defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) ) -#define MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC -#endif - -/* - * Allow extra bytes for record, authentication and encryption overhead: - * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256) - * and allow for a maximum of 1024 of compression expansion if - * enabled. - */ -#if defined(MBEDTLS_ZLIB_SUPPORT) -#define MBEDTLS_SSL_COMPRESSION_ADD 1024 -#else -#define MBEDTLS_SSL_COMPRESSION_ADD 0 -#endif - -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_MODE_CBC) -/* Ciphersuites using HMAC */ -#if defined(MBEDTLS_SHA512_C) -#define MBEDTLS_SSL_MAC_ADD 48 /* SHA-384 used for HMAC */ -#elif defined(MBEDTLS_SHA256_C) -#define MBEDTLS_SSL_MAC_ADD 32 /* SHA-256 used for HMAC */ -#else -#define MBEDTLS_SSL_MAC_ADD 20 /* SHA-1 used for HMAC */ -#endif -#else -/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */ -#define MBEDTLS_SSL_MAC_ADD 16 -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define MBEDTLS_SSL_PADDING_ADD 256 -#else -#define MBEDTLS_SSL_PADDING_ADD 0 -#endif - -#define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD + \ - MBEDTLS_MAX_IV_LENGTH + \ - MBEDTLS_SSL_MAC_ADD + \ - MBEDTLS_SSL_PADDING_ADD \ - ) - -#define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ - ( MBEDTLS_SSL_IN_CONTENT_LEN ) ) - -#define MBEDTLS_SSL_OUT_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ - ( MBEDTLS_SSL_OUT_CONTENT_LEN ) ) - -/* The maximum number of buffered handshake messages. */ -#define MBEDTLS_SSL_MAX_BUFFERED_HS 4 - -/* Maximum length we can advertise as our max content length for - RFC 6066 max_fragment_length extension negotiation purposes - (the lesser of both sizes, if they are unequal.) - */ -#define MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ( \ - (MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN) \ - ? ( MBEDTLS_SSL_OUT_CONTENT_LEN ) \ - : ( MBEDTLS_SSL_IN_CONTENT_LEN ) \ - ) - -/* Maximum size in bytes of list in sig-hash algorithm ext., RFC 5246 */ -#define MBEDTLS_SSL_MAX_SIG_HASH_ALG_LIST_LEN 65534 - -/* Maximum size in bytes of list in supported elliptic curve ext., RFC 4492 */ -#define MBEDTLS_SSL_MAX_CURVE_LIST_LEN 65535 - -/* - * Check that we obey the standard's message size bounds - */ - -#if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384 -#error "Bad configuration - record content too large." -#endif - -#if MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN -#error "Bad configuration - incoming record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." -#endif - -#if MBEDTLS_SSL_OUT_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN -#error "Bad configuration - outgoing record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." -#endif - -#if MBEDTLS_SSL_IN_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 -#error "Bad configuration - incoming protected record payload too large." -#endif - -#if MBEDTLS_SSL_OUT_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 -#error "Bad configuration - outgoing protected record payload too large." -#endif - -/* Calculate buffer sizes */ - -/* Note: Even though the TLS record header is only 5 bytes - long, we're internally using 8 bytes to store the - implicit sequence number. */ -#define MBEDTLS_SSL_HEADER_LEN 13 - -#define MBEDTLS_SSL_IN_BUFFER_LEN \ - ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) ) - -#define MBEDTLS_SSL_OUT_BUFFER_LEN \ - ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) ) - -#ifdef MBEDTLS_ZLIB_SUPPORT -/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */ -#define MBEDTLS_SSL_COMPRESS_BUFFER_LEN ( \ - ( MBEDTLS_SSL_IN_BUFFER_LEN > MBEDTLS_SSL_OUT_BUFFER_LEN ) \ - ? MBEDTLS_SSL_IN_BUFFER_LEN \ - : MBEDTLS_SSL_OUT_BUFFER_LEN \ - ) -#endif - -/* - * TLS extension flags (for extensions with outgoing ServerHello content - * that need it (e.g. for RENEGOTIATION_INFO the server already knows because - * of state of the renegotiation flag, so no indicator is required) - */ -#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) -#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1) - -/** - * \brief This function checks if the remaining size in a buffer is - * greater or equal than a needed space. - * - * \param cur Pointer to the current position in the buffer. - * \param end Pointer to one past the end of the buffer. - * \param need Needed space in bytes. - * - * \return Zero if the needed space is available in the buffer, non-zero - * otherwise. - */ -static inline int mbedtls_ssl_chk_buf_ptr( const uint8_t *cur, - const uint8_t *end, size_t need ) -{ - return( ( cur > end ) || ( need > (size_t)( end - cur ) ) ); -} - -/** - * \brief This macro checks if the remaining size in a buffer is - * greater or equal than a needed space. If it is not the case, - * it returns an SSL_BUFFER_TOO_SMALL error. - * - * \param cur Pointer to the current position in the buffer. - * \param end Pointer to one past the end of the buffer. - * \param need Needed space in bytes. - * - */ -#define MBEDTLS_SSL_CHK_BUF_PTR( cur, end, need ) \ - do { \ - if( mbedtls_ssl_chk_buf_ptr( ( cur ), ( end ), ( need ) ) != 0 ) \ - { \ - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); \ - } \ - } while( 0 ) - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -/* - * Abstraction for a grid of allowed signature-hash-algorithm pairs. - */ -struct mbedtls_ssl_sig_hash_set_t -{ - /* At the moment, we only need to remember a single suitable - * hash algorithm per signature algorithm. As long as that's - * the case - and we don't need a general lookup function - - * we can implement the sig-hash-set as a map from signatures - * to hash algorithms. */ - mbedtls_md_type_t rsa; - mbedtls_md_type_t ecdsa; -}; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -/* - * This structure contains the parameters only needed during handshake. - */ -struct mbedtls_ssl_handshake_params -{ - /* - * Handshake specific crypto variables - */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - mbedtls_ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */ -#endif -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ -#endif -#if defined(MBEDTLS_ECDH_C) - mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */ -#if defined(MBEDTLS_SSL_CLI_C) - unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */ - size_t ecjpake_cache_len; /*!< Length of cached data */ -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - unsigned char *psk; /*!< PSK from the callback */ - size_t psk_len; /*!< Length of PSK from callback */ -#endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */ -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - int sni_authmode; /*!< authmode from SNI callback */ - mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ - mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */ - mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - int ecrs_enabled; /*!< Handshake supports EC restart? */ - mbedtls_x509_crt_restart_ctx ecrs_ctx; /*!< restart context */ - enum { /* this complements ssl->state with info on intra-state operations */ - ssl_ecrs_none = 0, /*!< nothing going on (yet) */ - ssl_ecrs_crt_verify, /*!< Certificate: crt_verify() */ - ssl_ecrs_ske_start_processing, /*!< ServerKeyExchange: pk_verify() */ - ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */ - ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */ - } ecrs_state; /*!< current (or last) operation */ - size_t ecrs_n; /*!< place for saving a length */ -#endif -#if defined(MBEDTLS_SSL_PROTO_DTLS) - unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ - unsigned int in_msg_seq; /*!< Incoming handshake sequence number */ - - unsigned char *verify_cookie; /*!< Cli: HelloVerifyRequest cookie - Srv: unused */ - unsigned char verify_cookie_len; /*!< Cli: cookie length - Srv: flag for sending a cookie */ - - uint32_t retransmit_timeout; /*!< Current value of timeout */ - unsigned char retransmit_state; /*!< Retransmission state */ - mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */ - mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */ - unsigned char *cur_msg_p; /*!< Position in current message */ - unsigned int in_flight_start_seq; /*!< Minimum message sequence in the - flight being received */ - mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for - resending messages */ - unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter - for resending messages */ - - struct - { - size_t total_bytes_buffered; /*!< Cumulative size of heap allocated - * buffers used for message buffering. */ - - uint8_t seen_ccs; /*!< Indicates if a CCS message has - * been seen in the current flight. */ - - struct mbedtls_ssl_hs_buffer - { - unsigned is_valid : 1; - unsigned is_fragmented : 1; - unsigned is_complete : 1; - unsigned char *data; - size_t data_len; - } hs[MBEDTLS_SSL_MAX_BUFFERED_HS]; - - struct - { - unsigned char *data; - size_t len; - unsigned epoch; - } future_record; - - } buffering; - - uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * Checksum contexts - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_context fin_md5; - mbedtls_sha1_context fin_sha1; -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) - mbedtls_sha256_context fin_sha256; -#endif -#if defined(MBEDTLS_SHA512_C) - mbedtls_sha512_context fin_sha512; -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); - void (*calc_verify)(mbedtls_ssl_context *, unsigned char *); - void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); - int (*tls_prf)(const unsigned char *, size_t, const char *, - const unsigned char *, size_t, - unsigned char *, size_t); - - size_t pmslen; /*!< premaster length */ - - unsigned char randbytes[64]; /*!< random bytes */ - unsigned char premaster[MBEDTLS_PREMASTER_SIZE]; - /*!< premaster secret */ - - int resume; /*!< session resume indicator*/ - int max_major_ver; /*!< max. major version client*/ - int max_minor_ver; /*!< max. minor version client*/ - int cli_exts; /*!< client extension presence*/ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - int new_session_ticket; /*!< use NewSessionTicket? */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - int extended_ms; /*!< use Extended Master Secret? */ -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */ -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /** Asynchronous operation context. This field is meant for use by the - * asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start, - * mbedtls_ssl_config::f_async_decrypt_start, - * mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel). - * The library does not use it internally. */ - void *user_async_ctx; -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ -}; - -typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer; - -/* - * This structure contains a full set of runtime transform parameters - * either in negotiation or active. - */ -struct mbedtls_ssl_transform -{ - /* - * Session specific crypto layer - */ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - /*!< Chosen cipersuite_info */ - unsigned int keylen; /*!< symmetric key length (bytes) */ - size_t minlen; /*!< min. ciphertext length */ - size_t ivlen; /*!< IV length */ - size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */ - size_t maclen; /*!< MAC length */ - - unsigned char iv_enc[16]; /*!< IV (encryption) */ - unsigned char iv_dec[16]; /*!< IV (decryption) */ - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - /* Needed only for SSL v3.0 secret */ - unsigned char mac_enc[20]; /*!< SSL v3.0 secret (enc) */ - unsigned char mac_dec[20]; /*!< SSL v3.0 secret (dec) */ -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - - mbedtls_md_context_t md_ctx_enc; /*!< MAC (encryption) */ - mbedtls_md_context_t md_ctx_dec; /*!< MAC (decryption) */ - - mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */ - mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */ - - /* - * Session specific compression layer - */ -#if defined(MBEDTLS_ZLIB_SUPPORT) - z_stream ctx_deflate; /*!< compression context */ - z_stream ctx_inflate; /*!< decompression context */ -#endif -}; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/* - * List of certificate + private key pairs - */ -struct mbedtls_ssl_key_cert -{ - mbedtls_x509_crt *cert; /*!< cert */ - mbedtls_pk_context *key; /*!< private key */ - mbedtls_ssl_key_cert *next; /*!< next key/cert pair */ -}; -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -/* - * List of handshake messages kept around for resending - */ -struct mbedtls_ssl_flight_item -{ - unsigned char *p; /*!< message, including handshake headers */ - size_t len; /*!< length of p */ - unsigned char type; /*!< type of the message: handshake or CCS */ - mbedtls_ssl_flight_item *next; /*!< next handshake message(s) */ -}; -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - -/* Find an entry in a signature-hash set matching a given hash algorithm. */ -mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_pk_type_t sig_alg ); -/* Add a signature-hash-pair to a signature-hash set */ -void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_pk_type_t sig_alg, - mbedtls_md_type_t md_alg ); -/* Allow exactly one hash algorithm for each signature. */ -void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_md_type_t md_alg ); - -/* Setup an empty signature-hash set */ -static inline void mbedtls_ssl_sig_hash_set_init( mbedtls_ssl_sig_hash_set_t *set ) -{ - mbedtls_ssl_sig_hash_set_const_hash( set, MBEDTLS_MD_NONE ); -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2) && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -/** - * \brief Free referenced items in an SSL transform context and clear - * memory - * - * \param transform SSL transform context - */ -void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ); - -/** - * \brief Free referenced items in an SSL handshake context and clear - * memory - * - * \param ssl SSL context - */ -void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ); -void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ); - -void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ); -void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); - -/** - * \brief Update record layer - * - * This function roughly separates the implementation - * of the logic of (D)TLS from the implementation - * of the secure transport. - * - * \param ssl The SSL context to use. - * \param update_hs_digest This indicates if the handshake digest - * should be automatically updated in case - * a handshake message is found. - * - * \return 0 or non-zero error code. - * - * \note A clarification on what is called 'record layer' here - * is in order, as many sensible definitions are possible: - * - * The record layer takes as input an untrusted underlying - * transport (stream or datagram) and transforms it into - * a serially multiplexed, secure transport, which - * conceptually provides the following: - * - * (1) Three datagram based, content-agnostic transports - * for handshake, alert and CCS messages. - * (2) One stream- or datagram-based transport - * for application data. - * (3) Functionality for changing the underlying transform - * securing the contents. - * - * The interface to this functionality is given as follows: - * - * a Updating - * [Currently implemented by mbedtls_ssl_read_record] - * - * Check if and on which of the four 'ports' data is pending: - * Nothing, a controlling datagram of type (1), or application - * data (2). In any case data is present, internal buffers - * provide access to the data for the user to process it. - * Consumption of type (1) datagrams is done automatically - * on the next update, invalidating that the internal buffers - * for previous datagrams, while consumption of application - * data (2) is user-controlled. - * - * b Reading of application data - * [Currently manual adaption of ssl->in_offt pointer] - * - * As mentioned in the last paragraph, consumption of data - * is different from the automatic consumption of control - * datagrams (1) because application data is treated as a stream. - * - * c Tracking availability of application data - * [Currently manually through decreasing ssl->in_msglen] - * - * For efficiency and to retain datagram semantics for - * application data in case of DTLS, the record layer - * provides functionality for checking how much application - * data is still available in the internal buffer. - * - * d Changing the transformation securing the communication. - * - * Given an opaque implementation of the record layer in the - * above sense, it should be possible to implement the logic - * of (D)TLS on top of it without the need to know anything - * about the record layer's internals. This is done e.g. - * in all the handshake handling functions, and in the - * application data reading function mbedtls_ssl_read. - * - * \note The above tries to give a conceptual picture of the - * record layer, but the current implementation deviates - * from it in some places. For example, our implementation of - * the update functionality through mbedtls_ssl_read_record - * discards datagrams depending on the current state, which - * wouldn't fall under the record layer's responsibility - * following the above definition. - * - */ -int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, - unsigned update_hs_digest ); -int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); - -int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ); -int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ); - -void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t *ciphersuite_info ); - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ); -#endif - -#if defined(MBEDTLS_PK_C) -unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ); -unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type ); -mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); -#endif - -mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); -unsigned char mbedtls_ssl_hash_from_md_alg( int md ); -int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ); - -#if defined(MBEDTLS_ECP_C) -int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, - mbedtls_md_type_t md ); -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_key_cert *key_cert; - - if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL ) - key_cert = ssl->handshake->key_cert; - else - key_cert = ssl->conf->key_cert; - - return( key_cert == NULL ? NULL : key_cert->key ); -} - -static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_key_cert *key_cert; - - if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL ) - key_cert = ssl->handshake->key_cert; - else - key_cert = ssl->conf->key_cert; - - return( key_cert == NULL ? NULL : key_cert->cert ); -} - -/* - * Check usage of a certificate wrt extensions: - * keyUsage, extendedKeyUsage (later), and nSCertType (later). - * - * Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we - * check a cert we received from them)! - * - * Return 0 if everything is OK, -1 if not. - */ -int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, - const mbedtls_ssl_ciphersuite_t *ciphersuite, - int cert_endpoint, - uint32_t *flags ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -void mbedtls_ssl_write_version( int major, int minor, int transport, - unsigned char ver[2] ); -void mbedtls_ssl_read_version( int *major, int *minor, int transport, - const unsigned char ver[2] ); - -static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 13 ); -#else - ((void) ssl); -#endif - return( 5 ); -} - -static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 12 ); -#else - ((void) ssl); -#endif - return( 4 ); -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ); -void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ); -#endif - -/* Visible for testing purposes only */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ); -void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ); -#endif - -/* constant-time buffer comparison */ -static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n ) -{ - size_t i; - volatile const unsigned char *A = (volatile const unsigned char *) a; - volatile const unsigned char *B = (volatile const unsigned char *) b; - volatile unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - { - /* Read volatile data in order before computing diff. - * This avoids IAR compiler warning: - * 'the order of volatile accesses is undefined ..' */ - unsigned char x = A[i], y = B[i]; - diff |= x ^ y; - } - - return( diff ); -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, - unsigned char *output, - unsigned char *data, size_t data_len ); -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) -int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg ); -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) -/** \brief Compute the HMAC of variable-length data with constant flow. - * - * This function computes the HMAC of the concatenation of \p add_data and \p - * data, and does with a code flow and memory access pattern that does not - * depend on \p data_len_secret, but only on \p min_data_len and \p - * max_data_len. In particular, this function always reads exactly \p - * max_data_len bytes from \p data. - * - * \param ctx The HMAC context. It must have keys configured - * with mbedtls_md_hmac_starts() and use one of the - * following hashes: SHA-384, SHA-256, SHA-1 or MD-5. - * It is reset using mbedtls_md_hmac_reset() after - * the computation is complete to prepare for the - * next computation. - * \param add_data The additional data prepended to \p data. This - * must point to a readable buffer of \p add_data_len - * bytes. - * \param add_data_len The length of \p add_data in bytes. - * \param data The data appended to \p add_data. This must point - * to a readable buffer of \p max_data_len bytes. - * \param data_len_secret The length of the data to process in \p data. - * This must be no less than \p min_data_len and no - * greater than \p max_data_len. - * \param min_data_len The minimal length of \p data in bytes. - * \param max_data_len The maximal length of \p data in bytes. - * \param output The HMAC will be written here. This must point to - * a writable buffer of sufficient size to hold the - * HMAC value. - * - * \retval 0 - * Success. - * \retval MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED - * The hardware accelerator failed. - */ -int mbedtls_ssl_cf_hmac( - mbedtls_md_context_t *ctx, - const unsigned char *add_data, size_t add_data_len, - const unsigned char *data, size_t data_len_secret, - size_t min_data_len, size_t max_data_len, - unsigned char *output ); - -/** \brief Copy data from a secret position with constant flow. - * - * This function copies \p len bytes from \p src_base + \p offset_secret to \p - * dst, with a code flow and memory access pattern that does not depend on \p - * offset_secret, but only on \p offset_min, \p offset_max and \p len. - * - * \param dst The destination buffer. This must point to a writable - * buffer of at least \p len bytes. - * \param src_base The base of the source buffer. This must point to a - * readable buffer of at least \p offset_max + \p len - * bytes. - * \param offset_secret The offset in the source buffer from which to copy. - * This must be no less than \p offset_min and no greater - * than \p offset_max. - * \param offset_min The minimal value of \p offset_secret. - * \param offset_max The maximal value of \p offset_secret. - * \param len The number of bytes to copy. - */ -void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst, - const unsigned char *src_base, - size_t offset_secret, - size_t offset_min, size_t offset_max, - size_t len ); -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_internal.h */ diff --git a/mbedtls/ssl_srv.c b/mbedtls/ssl_srv.c deleted file mode 100644 index 937769fe2..000000000 --- a/mbedtls/ssl_srv.c +++ /dev/null @@ -1,4418 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * SSLv3/TLSv1 server-side functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_SRV_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/debug.h" -#include "mbedtls/ssl.h" -#include "mbedtls/ssl_internal.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, - const unsigned char *info, - size_t ilen ) -{ - if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - mbedtls_free( ssl->cli_id ); - - if( ( ssl->cli_id = mbedtls_calloc( 1, ilen ) ) == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - memcpy( ssl->cli_id, info, ilen ); - ssl->cli_id_len = ilen; - - return( 0 ); -} - -void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf, - mbedtls_ssl_cookie_write_t *f_cookie_write, - mbedtls_ssl_cookie_check_t *f_cookie_check, - void *p_cookie ) -{ - conf->f_cookie_write = f_cookie_write; - conf->f_cookie_check = f_cookie_check; - conf->p_cookie = p_cookie; -} -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - int ret; - size_t servername_list_size, hostname_len; - const unsigned char *p; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) ); - - if( len < 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); - if( servername_list_size + 2 != len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - p = buf + 2; - while( servername_list_size > 2 ) - { - hostname_len = ( ( p[1] << 8 ) | p[2] ); - if( hostname_len + 3 > servername_list_size ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) - { - ret = ssl->conf->f_sni( ssl->conf->p_sni, - ssl, p + 3, hostname_len ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - return( 0 ); - } - - servername_list_size -= hostname_len + 3; - p += hostname_len + 3; - } - - if( servername_list_size != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - /* Check verify-data in constant-time. The length OTOH is no secret */ - if( len != 1 + ssl->verify_data_len || - buf[0] != ssl->verify_data_len || - mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data, - ssl->verify_data_len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - } - else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - if( len != 1 || buf[0] != 0x0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - } - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - -/* - * Status of the implementation of signature-algorithms extension: - * - * Currently, we are only considering the signature-algorithm extension - * to pick a ciphersuite which allows us to send the ServerKeyExchange - * message with a signature-hash combination that the user allows. - * - * We do *not* check whether all certificates in our certificate - * chain are signed with an allowed signature-hash pair. - * This needs to be done at a later stage. - * - */ -static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t sig_alg_list_size; - - const unsigned char *p; - const unsigned char *end = buf + len; - - mbedtls_md_type_t md_cur; - mbedtls_pk_type_t sig_cur; - - if ( len < 2 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); - if( sig_alg_list_size + 2 != len || - sig_alg_list_size % 2 != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* Currently we only guarantee signing the ServerKeyExchange message according - * to the constraints specified in this extension (see above), so it suffices - * to remember only one suitable hash for each possible signature algorithm. - * - * This will change when we also consider certificate signatures, - * in which case we will need to remember the whole signature-hash - * pair list from the extension. - */ - - for( p = buf + 2; p < end; p += 2 ) - { - /* Silently ignore unknown signature or hash algorithms. */ - - if( ( sig_cur = mbedtls_ssl_pk_alg_from_sig( p[1] ) ) == MBEDTLS_PK_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext" - " unknown sig alg encoding %d", p[1] ) ); - continue; - } - - /* Check if we support the hash the user proposes */ - md_cur = mbedtls_ssl_md_alg_from_hash( p[0] ); - if( md_cur == MBEDTLS_MD_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:" - " unknown hash alg encoding %d", p[0] ) ); - continue; - } - - if( mbedtls_ssl_check_sig_hash( ssl, md_cur ) == 0 ) - { - mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:" - " match sig %d and hash %d", - sig_cur, md_cur ) ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: " - "hash alg %d not supported", md_cur ) ); - } - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t list_size, our_size; - const unsigned char *p; - const mbedtls_ecp_curve_info *curve_info, **curves; - - if ( len < 2 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); - if( list_size + 2 != len || - list_size % 2 != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* Should never happen unless client duplicates the extension */ - if( ssl->handshake->curves != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* Don't allow our peer to make us allocate too much memory, - * and leave room for a final 0 */ - our_size = list_size / 2 + 1; - if( our_size > MBEDTLS_ECP_DP_MAX ) - our_size = MBEDTLS_ECP_DP_MAX; - - if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - ssl->handshake->curves = curves; - - p = buf + 2; - while( list_size > 0 && our_size > 1 ) - { - curve_info = mbedtls_ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] ); - - if( curve_info != NULL ) - { - *curves++ = curve_info; - our_size--; - } - - list_size -= 2; - p += 2; - } - - return( 0 ); -} - -static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t list_size; - const unsigned char *p; - - if( len == 0 || (size_t)( buf[0] + 1 ) != len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - list_size = buf[0]; - - p = buf + 1; - while( list_size > 0 ) - { - if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || - p[0] == MBEDTLS_ECP_PF_COMPRESSED ) - { -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) - ssl->handshake->ecdh_ctx.point_format = p[0]; -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl->handshake->ecjpake_ctx.point_format = p[0]; -#endif - MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); - return( 0 ); - } - - list_size--; - p++; - } - - return( 0 ); -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - int ret; - - if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); - return( 0 ); - } - - if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, - buf, len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( ret ); - } - - /* Only mark the extension as OK when we're sure it is */ - ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK; - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->session_negotiate->mfl_code = buf[0]; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ((void) buf); - - if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) - ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ((void) buf); - - if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED && - ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) - { - ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ((void) buf); - - if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED && - ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) - { - ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t len ) -{ - int ret; - mbedtls_ssl_session session; - - mbedtls_ssl_session_init( &session ); - - if( ssl->conf->f_ticket_parse == NULL || - ssl->conf->f_ticket_write == NULL ) - { - return( 0 ); - } - - /* Remember the client asked us to send a new ticket */ - ssl->handshake->new_session_ticket = 1; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) ); - - if( len == 0 ) - return( 0 ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) ); - return( 0 ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - /* - * Failures are ok: just ignore the ticket and proceed. - */ - if( ( ret = ssl->conf->f_ticket_parse( ssl->conf->p_ticket, &session, - buf, len ) ) != 0 ) - { - mbedtls_ssl_session_free( &session ); - - if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is not authentic" ) ); - else if( ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED ) - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is expired" ) ); - else - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_parse", ret ); - - return( 0 ); - } - - /* - * Keep the session ID sent by the client, since we MUST send it back to - * inform them we're accepting the ticket (RFC 5077 section 3.4) - */ - session.id_len = ssl->session_negotiate->id_len; - memcpy( &session.id, ssl->session_negotiate->id, session.id_len ); - - mbedtls_ssl_session_free( ssl->session_negotiate ); - memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) ); - - /* Zeroize instead of free as we copied the content */ - mbedtls_platform_zeroize( &session, sizeof( mbedtls_ssl_session ) ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) ); - - ssl->handshake->resume = 1; - - /* Don't send a new ticket after all, this one is OK */ - ssl->handshake->new_session_ticket = 0; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_ALPN) -static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - size_t list_len, cur_len, ours_len; - const unsigned char *theirs, *start, *end; - const char **ours; - - /* If ALPN not configured, just ignore the extension */ - if( ssl->conf->alpn_list == NULL ) - return( 0 ); - - /* - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - */ - - /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ - if( len < 4 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - list_len = ( buf[0] << 8 ) | buf[1]; - if( list_len != len - 2 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* - * Validate peer's list (lengths) - */ - start = buf + 2; - end = buf + len; - for( theirs = start; theirs != end; theirs += cur_len ) - { - cur_len = *theirs++; - - /* Current identifier must fit in list */ - if( cur_len > (size_t)( end - theirs ) ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* Empty strings MUST NOT be included */ - if( cur_len == 0 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - } - - /* - * Use our order of preference - */ - for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ ) - { - ours_len = strlen( *ours ); - for( theirs = start; theirs != end; theirs += cur_len ) - { - cur_len = *theirs++; - - if( cur_len == ours_len && - memcmp( theirs, *ours, cur_len ) == 0 ) - { - ssl->alpn_chosen = *ours; - return( 0 ); - } - } - } - - /* If we get there, no match was found */ - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); -} -#endif /* MBEDTLS_SSL_ALPN */ - -/* - * Auxiliary functions for ServerHello parsing and related actions - */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/* - * Return 0 if the given key uses one of the acceptable curves, -1 otherwise - */ -#if defined(MBEDTLS_ECDSA_C) -static int ssl_check_key_curve( mbedtls_pk_context *pk, - const mbedtls_ecp_curve_info **curves ) -{ - const mbedtls_ecp_curve_info **crv = curves; - mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id; - - while( *crv != NULL ) - { - if( (*crv)->grp_id == grp_id ) - return( 0 ); - crv++; - } - - return( -1 ); -} -#endif /* MBEDTLS_ECDSA_C */ - -/* - * Try picking a certificate for this ciphersuite, - * return 0 on success and -1 on failure. - */ -static int ssl_pick_cert( mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t * ciphersuite_info ) -{ - mbedtls_ssl_key_cert *cur, *list, *fallback = NULL; - mbedtls_pk_type_t pk_alg = - mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); - uint32_t flags; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_key_cert != NULL ) - list = ssl->handshake->sni_key_cert; - else -#endif - list = ssl->conf->key_cert; - - if( pk_alg == MBEDTLS_PK_NONE ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite requires certificate" ) ); - - if( list == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server has no certificate" ) ); - return( -1 ); - } - - for( cur = list; cur != NULL; cur = cur->next ) - { - MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", - cur->cert ); - - if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) ); - continue; - } - - /* - * This avoids sending the client a cert it'll reject based on - * keyUsage or other extensions. - * - * It also allows the user to provision different certificates for - * different uses based on keyUsage, eg if they want to avoid signing - * and decrypting with the same RSA key. - */ - if( mbedtls_ssl_check_cert_usage( cur->cert, ciphersuite_info, - MBEDTLS_SSL_IS_SERVER, &flags ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: " - "(extended) key usage extension" ) ); - continue; - } - -#if defined(MBEDTLS_ECDSA_C) - if( pk_alg == MBEDTLS_PK_ECDSA && - ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); - continue; - } -#endif - - /* - * Try to select a SHA-1 certificate for pre-1.2 clients, but still - * present them a SHA-higher cert rather than failing if it's the only - * one we got that satisfies the other conditions. - */ - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 && - cur->cert->sig_md != MBEDTLS_MD_SHA1 ) - { - if( fallback == NULL ) - fallback = cur; - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: " - "sha-2 with pre-TLS 1.2 client" ) ); - continue; - } - } - - /* If we get there, we got a winner */ - break; - } - - if( cur == NULL ) - cur = fallback; - - /* Do not update ssl->handshake->key_cert unless there is a match */ - if( cur != NULL ) - { - ssl->handshake->key_cert = cur; - MBEDTLS_SSL_DEBUG_CRT( 3, "selected certificate chain, certificate", - ssl->handshake->key_cert->cert ); - return( 0 ); - } - - return( -1 ); -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/* - * Check if a given ciphersuite is suitable for use with our config/keys/etc - * Sets ciphersuite_info only if the suite matches. - */ -static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, - const mbedtls_ssl_ciphersuite_t **ciphersuite_info ) -{ - const mbedtls_ssl_ciphersuite_t *suite_info; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - mbedtls_pk_type_t sig_type; -#endif - - suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id ); - if( suite_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) ); - - if( suite_info->min_minor_ver > ssl->minor_ver || - suite_info->max_minor_ver < ssl->minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: version" ) ); - return( 0 ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) ) - return( 0 ); -#endif - -#if defined(MBEDTLS_ARC4_C) - if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED && - suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: rc4" ) ); - return( 0 ); - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && - ( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake " - "not configured or ext missing" ) ); - return( 0 ); - } -#endif - - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) - if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) && - ( ssl->handshake->curves == NULL || - ssl->handshake->curves[0] == NULL ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " - "no common elliptic curve" ) ); - return( 0 ); - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - /* If the ciphersuite requires a pre-shared key and we don't - * have one, skip it now rather than failing later */ - if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) && - ssl->conf->f_psk == NULL && - ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL || - ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) ); - return( 0 ); - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - /* If the ciphersuite requires signing, check whether - * a suitable hash algorithm is present. */ - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - sig_type = mbedtls_ssl_get_ciphersuite_sig_alg( suite_info ); - if( sig_type != MBEDTLS_PK_NONE && - mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm " - "for signature algorithm %d", sig_type ) ); - return( 0 ); - } - } - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /* - * Final check: if ciphersuite requires us to have a - * certificate/key of a particular type: - * - select the appropriate certificate if we have one, or - * - try the next ciphersuite if we don't - * This must be done last since we modify the key_cert list. - */ - if( ssl_pick_cert( ssl, suite_info ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " - "no suitable certificate" ) ); - return( 0 ); - } -#endif - - *ciphersuite_info = suite_info; - return( 0 ); -} - -#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) -static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) -{ - int ret, got_common_suite; - unsigned int i, j; - size_t n; - unsigned int ciph_len, sess_len, chal_len; - unsigned char *buf, *p; - const int *ciphersuites; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - buf = ssl->in_hdr; - - MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, 5 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d", - buf[2] ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d", - ( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]", - buf[3], buf[4] ) ); - - /* - * SSLv2 Client Hello - * - * Record layer: - * 0 . 1 message length - * - * SSL layer: - * 2 . 2 message type - * 3 . 4 protocol version - */ - if( buf[2] != MBEDTLS_SSL_HS_CLIENT_HELLO || - buf[3] != MBEDTLS_SSL_MAJOR_VERSION_3 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF; - - if( n < 17 || n > 512 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; - ssl->minor_ver = ( buf[4] <= ssl->conf->max_minor_ver ) - ? buf[4] : ssl->conf->max_minor_ver; - - if( ssl->minor_ver < ssl->conf->min_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" - " [%d:%d] < [%d:%d]", - ssl->major_ver, ssl->minor_ver, - ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - - ssl->handshake->max_major_ver = buf[3]; - ssl->handshake->max_minor_ver = buf[4]; - - if( ( ret = mbedtls_ssl_fetch_input( ssl, 2 + n ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - - ssl->handshake->update_checksum( ssl, buf + 2, n ); - - buf = ssl->in_msg; - n = ssl->in_left - 5; - - /* - * 0 . 1 ciphersuitelist length - * 2 . 3 session id length - * 4 . 5 challenge length - * 6 . .. ciphersuitelist - * .. . .. session id - * .. . .. challenge - */ - MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, n ); - - ciph_len = ( buf[0] << 8 ) | buf[1]; - sess_len = ( buf[2] << 8 ) | buf[3]; - chal_len = ( buf[4] << 8 ) | buf[5]; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d", - ciph_len, sess_len, chal_len ) ); - - /* - * Make sure each parameter length is valid - */ - if( ciph_len < 3 || ( ciph_len % 3 ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( sess_len > 32 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( chal_len < 8 || chal_len > 32 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( n != 6 + ciph_len + sess_len + chal_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", - buf + 6, ciph_len ); - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", - buf + 6 + ciph_len, sess_len ); - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, challenge", - buf + 6 + ciph_len + sess_len, chal_len ); - - p = buf + 6 + ciph_len; - ssl->session_negotiate->id_len = sess_len; - memset( ssl->session_negotiate->id, 0, - sizeof( ssl->session_negotiate->id ) ); - memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->id_len ); - - p += sess_len; - memset( ssl->handshake->randbytes, 0, 64 ); - memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ); - - /* - * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV - */ - for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) - { - if( p[0] == 0 && p[1] == 0 && p[2] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " - "during renegotiation" ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - break; - } - } - -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) - for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) - { - if( p[0] == 0 && - p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && - p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) ); - - if( ssl->minor_ver < ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); - - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - break; - } - } -#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ - - got_common_suite = 0; - ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; - ciphersuite_info = NULL; -#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) - for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) - for( i = 0; ciphersuites[i] != 0; i++ ) -#else - for( i = 0; ciphersuites[i] != 0; i++ ) - for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) -#endif - { - if( p[0] != 0 || - p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || - p[2] != ( ( ciphersuites[i] ) & 0xFF ) ) - continue; - - got_common_suite = 1; - - if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], - &ciphersuite_info ) ) != 0 ) - return( ret ); - - if( ciphersuite_info != NULL ) - goto have_ciphersuite_v2; - } - - if( got_common_suite ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " - "but none of them usable" ) ); - return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); - return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); - } - -have_ciphersuite_v2: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); - - ssl->session_negotiate->ciphersuite = ciphersuites[i]; - ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; - - /* - * SSLv2 Client Hello relevant renegotiation security checks - */ - if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->in_left = 0; - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ - -/* This function doesn't alert on errors that happen early during - ClientHello parsing because they might indicate that the client is - not talking SSL/TLS at all and would not understand our alert. */ -static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) -{ - int ret, got_common_suite; - size_t i, j; - size_t ciph_offset, comp_offset, ext_offset; - size_t msg_len, ciph_len, sess_len, comp_len, ext_len; -#if defined(MBEDTLS_SSL_PROTO_DTLS) - size_t cookie_offset, cookie_len; -#endif - unsigned char *buf, *p, *ext; -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renegotiation_info_seen = 0; -#endif - int handshake_failure = 0; - const int *ciphersuites; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - int major, minor; - - /* If there is no signature-algorithm extension present, - * we need to fall back to the default values for allowed - * signature-hash pairs. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - int sig_hash_alg_ext_present = 0; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -read_record_header: -#endif - /* - * If renegotiating, then the input was read with mbedtls_ssl_read_record(), - * otherwise read it ourselves manually in order to support SSLv2 - * ClientHello, which doesn't use the same record layer format. - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif - { - if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) - { - /* No alert on a read error. */ - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - } - - buf = ssl->in_hdr; - -#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM ) -#endif - if( ( buf[0] & 0x80 ) != 0 ) - return( ssl_parse_client_hello_v2( ssl ) ); -#endif - - MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) ); - - /* - * SSLv3/TLS Client Hello - * - * Record layer: - * 0 . 0 message type - * 1 . 2 protocol version - * 3 . 11 DTLS: epoch + record sequence number - * 3 . 4 message length - */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d", - buf[0] ) ); - - if( buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d", - ( ssl->in_len[0] << 8 ) | ssl->in_len[1] ) ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, protocol version: [%d:%d]", - buf[1], buf[2] ) ); - - mbedtls_ssl_read_version( &major, &minor, ssl->conf->transport, buf + 1 ); - - /* According to RFC 5246 Appendix E.1, the version here is typically - * "{03,00}, the lowest version number supported by the client, [or] the - * value of ClientHello.client_version", so the only meaningful check here - * is the major version shouldn't be less than 3 */ - if( major < MBEDTLS_SSL_MAJOR_VERSION_3 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* For DTLS if this is the initial handshake, remember the client sequence - * number to use it in our next message (RFC 6347 4.2.1) */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE -#endif - ) - { - /* Epoch should be 0 for initial handshakes */ - if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 ); - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record, discarding" ) ); - ssl->next_record_offset = 0; - ssl->in_left = 0; - goto read_record_header; - } - - /* No MAC to check yet, so we can update right now */ - mbedtls_ssl_dtls_replay_update( ssl ); -#endif - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - /* Set by mbedtls_ssl_read_record() */ - msg_len = ssl->in_hslen; - } - else -#endif - { - if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( ( ret = mbedtls_ssl_fetch_input( ssl, - mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - - /* Done reading this record, get ready for the next one */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl ); - else -#endif - ssl->in_left = 0; - } - - buf = ssl->in_msg; - - MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, msg_len ); - - ssl->handshake->update_checksum( ssl, buf, msg_len ); - - /* - * Handshake layer: - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 5 DTLS only: message seqence number - * 6 . 8 DTLS only: fragment offset - * 9 . 11 DTLS only: fragment length - */ - if( msg_len < mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) ); - - if( buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", - ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) ); - - /* We don't support fragmentation of ClientHello (yet?) */ - if( buf[1] != 0 || - msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* - * Copy the client's handshake message_seq on initial handshakes, - * check sequence number on renego. - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - /* This couldn't be done in ssl_prepare_handshake_record() */ - unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | - ssl->in_msg[5]; - - if( cli_msg_seq != ssl->handshake->in_msg_seq ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: " - "%d (expected %d)", cli_msg_seq, - ssl->handshake->in_msg_seq ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->handshake->in_msg_seq++; - } - else -#endif - { - unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | - ssl->in_msg[5]; - ssl->handshake->out_msg_seq = cli_msg_seq; - ssl->handshake->in_msg_seq = cli_msg_seq + 1; - } - - /* - * For now we don't support fragmentation, so make sure - * fragment_offset == 0 and fragment_length == length - */ - if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 || - memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - buf += mbedtls_ssl_hs_hdr_len( ssl ); - msg_len -= mbedtls_ssl_hs_hdr_len( ssl ); - - /* - * ClientHello layer: - * 0 . 1 protocol version - * 2 . 33 random bytes (starting with 4 bytes of Unix time) - * 34 . 35 session id length (1 byte) - * 35 . 34+x session id - * 35+x . 35+x DTLS only: cookie length (1 byte) - * 36+x . .. DTLS only: cookie - * .. . .. ciphersuite list length (2 bytes) - * .. . .. ciphersuite list - * .. . .. compression alg. list length (1 byte) - * .. . .. compression alg. list - * .. . .. extensions length (2 bytes, optional) - * .. . .. extensions (optional) - */ - - /* - * Minimal length (with everything empty and extensions omitted) is - * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can - * read at least up to session id length without worrying. - */ - if( msg_len < 38 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* - * Check and save the protocol version - */ - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, version", buf, 2 ); - - mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, - ssl->conf->transport, buf ); - - ssl->handshake->max_major_ver = ssl->major_ver; - ssl->handshake->max_minor_ver = ssl->minor_ver; - - if( ssl->major_ver < ssl->conf->min_major_ver || - ssl->minor_ver < ssl->conf->min_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" - " [%d:%d] < [%d:%d]", - ssl->major_ver, ssl->minor_ver, - ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - - if( ssl->major_ver > ssl->conf->max_major_ver ) - { - ssl->major_ver = ssl->conf->max_major_ver; - ssl->minor_ver = ssl->conf->max_minor_ver; - } - else if( ssl->minor_ver > ssl->conf->max_minor_ver ) - ssl->minor_ver = ssl->conf->max_minor_ver; - - /* - * Save client random (inc. Unix time) - */ - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 ); - - memcpy( ssl->handshake->randbytes, buf + 2, 32 ); - - /* - * Check the session ID length and save session ID - */ - sess_len = buf[34]; - - if( sess_len > sizeof( ssl->session_negotiate->id ) || - sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 35, sess_len ); - - ssl->session_negotiate->id_len = sess_len; - memset( ssl->session_negotiate->id, 0, - sizeof( ssl->session_negotiate->id ) ); - memcpy( ssl->session_negotiate->id, buf + 35, - ssl->session_negotiate->id_len ); - - /* - * Check the cookie length and content - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - cookie_offset = 35 + sess_len; - cookie_len = buf[cookie_offset]; - - if( cookie_offset + 1 + cookie_len + 2 > msg_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie", - buf + cookie_offset + 1, cookie_len ); - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - if( ssl->conf->f_cookie_check != NULL -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE -#endif - ) - { - if( ssl->conf->f_cookie_check( ssl->conf->p_cookie, - buf + cookie_offset + 1, cookie_len, - ssl->cli_id, ssl->cli_id_len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification failed" ) ); - ssl->handshake->verify_cookie_len = 1; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification passed" ) ); - ssl->handshake->verify_cookie_len = 0; - } - } - else -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - { - /* We know we didn't send a cookie, so it should be empty */ - if( cookie_len != 0 ) - { - /* This may be an attacker's probe, so don't send an alert */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification skipped" ) ); - } - - /* - * Check the ciphersuitelist length (will be parsed later) - */ - ciph_offset = cookie_offset + 1 + cookie_len; - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - ciph_offset = 35 + sess_len; - - ciph_len = ( buf[ciph_offset + 0] << 8 ) - | ( buf[ciph_offset + 1] ); - - if( ciph_len < 2 || - ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */ - ( ciph_len % 2 ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", - buf + ciph_offset + 2, ciph_len ); - - /* - * Check the compression algorithms length and pick one - */ - comp_offset = ciph_offset + 2 + ciph_len; - - comp_len = buf[comp_offset]; - - if( comp_len < 1 || - comp_len > 16 || - comp_len + comp_offset + 1 > msg_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, compression", - buf + comp_offset + 1, comp_len ); - - ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; -#if defined(MBEDTLS_ZLIB_SUPPORT) - for( i = 0; i < comp_len; ++i ) - { - if( buf[comp_offset + 1 + i] == MBEDTLS_SSL_COMPRESS_DEFLATE ) - { - ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_DEFLATE; - break; - } - } -#endif - - /* See comments in ssl_write_client_hello() */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; -#endif - - /* Do not parse the extensions if the protocol is SSLv3 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) - { -#endif - /* - * Check the extension length - */ - ext_offset = comp_offset + 1 + comp_len; - if( msg_len > ext_offset ) - { - if( msg_len < ext_offset + 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ext_len = ( buf[ext_offset + 0] << 8 ) - | ( buf[ext_offset + 1] ); - - if( ( ext_len > 0 && ext_len < 4 ) || - msg_len != ext_offset + 2 + ext_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - } - else - ext_len = 0; - - ext = buf + ext_offset + 2; - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len ); - - while( ext_len != 0 ) - { - unsigned int ext_id; - unsigned int ext_size; - if ( ext_len < 4 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - ext_id = ( ( ext[0] << 8 ) | ( ext[1] ) ); - ext_size = ( ( ext[2] << 8 ) | ( ext[3] ) ); - - if( ext_size + 4 > ext_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - switch( ext_id ) - { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - case MBEDTLS_TLS_EXT_SERVERNAME: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) ); - if( ssl->conf->f_sni == NULL ) - break; - - ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - - case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - renegotiation_info_seen = 1; -#endif - - ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - case MBEDTLS_TLS_EXT_SIG_ALG: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); - - ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - - sig_hash_alg_ext_present = 1; - break; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); - - ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; - - case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) ); - ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; - - ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) ); - - ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) ); - - ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) ); - - ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); - - ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) ); - - ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_TLS_EXT_SESSION_TICKET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) ); - - ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_ALPN) - case MBEDTLS_TLS_EXT_ALPN: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); - - ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - default: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", - ext_id ) ); - } - - ext_len -= 4 + ext_size; - ext += 4 + ext_size; - - if( ext_len > 0 && ext_len < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - } -#if defined(MBEDTLS_SSL_PROTO_SSL3) - } -#endif - -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) - for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 ) - { - if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && - p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) ); - - if( ssl->minor_ver < ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); - - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - break; - } - } -#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - - /* - * Try to fall back to default hash SHA1 if the client - * hasn't provided any preferred signature-hash combinations. - */ - if( sig_hash_alg_ext_present == 0 ) - { - mbedtls_md_type_t md_default = MBEDTLS_MD_SHA1; - - if( mbedtls_ssl_check_sig_hash( ssl, md_default ) != 0 ) - md_default = MBEDTLS_MD_NONE; - - mbedtls_ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs, md_default ); - } - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - - /* - * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV - */ - for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 ) - { - if( p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " - "during renegotiation" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } -#endif - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - break; - } - } - - /* - * Renegotiation security checks - */ - if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); - handshake_failure = 1; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && - renegotiation_info_seen == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); - handshake_failure = 1; - } - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); - handshake_failure = 1; - } - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - renegotiation_info_seen == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); - handshake_failure = 1; - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - if( handshake_failure == 1 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* - * Search for a matching ciphersuite - * (At the end because we need information from the EC-based extensions - * and certificate from the SNI callback triggered by the SNI extension.) - */ - got_common_suite = 0; - ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; - ciphersuite_info = NULL; -#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) - for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) - for( i = 0; ciphersuites[i] != 0; i++ ) -#else - for( i = 0; ciphersuites[i] != 0; i++ ) - for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) -#endif - { - if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || - p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) - continue; - - got_common_suite = 1; - - if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], - &ciphersuite_info ) ) != 0 ) - return( ret ); - - if( ciphersuite_info != NULL ) - goto have_ciphersuite; - } - - if( got_common_suite ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " - "but none of them usable" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); - } - -have_ciphersuite: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); - - ssl->session_negotiate->ciphersuite = ciphersuites[i]; - ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; - - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_recv_flight_completed( ssl ); -#endif - - /* Debugging-only output for testsuite */ -#if defined(MBEDTLS_DEBUG_C) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info ); - if( sig_alg != MBEDTLS_PK_NONE ) - { - mbedtls_md_type_t md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, - sig_alg ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d", - mbedtls_ssl_hash_from_md_alg( md_alg ) ) ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm " - "%d - should not happen", sig_alg ) ); - } - } -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->session_negotiate->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - const mbedtls_ssl_ciphersuite_t *suite = NULL; - const mbedtls_cipher_info_t *cipher = NULL; - - if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - *olen = 0; - return; - } - - /* - * RFC 7366: "If a server receives an encrypt-then-MAC request extension - * from a client and then selects a stream or Authenticated Encryption - * with Associated Data (AEAD) ciphersuite, it MUST NOT send an - * encrypt-then-MAC response extension back to the client." - */ - if( ( suite = mbedtls_ssl_ciphersuite_from_id( - ssl->session_negotiate->ciphersuite ) ) == NULL || - ( cipher = mbedtls_cipher_info_from_type( suite->cipher ) ) == NULL || - cipher->mode != MBEDTLS_MODE_CBC ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret " - "extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->handshake->new_session_ticket == 0 ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - *p++ = 0x00; - *p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF; - *p++ = ssl->verify_data_len * 2 & 0xFF; - - memcpy( p, ssl->peer_verify_data, ssl->verify_data_len ); - p += ssl->verify_data_len; - memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); - p += ssl->verify_data_len; - } - else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - *p++ = 0x00; - *p++ = 0x01; - *p++ = 0x00; - } - - *olen = p - buf; -} - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); - - *p++ = 0x00; - *p++ = 1; - - *p++ = ssl->session_negotiate->mfl_code; - - *olen = 5; -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - ((void) ssl); - - if( ( ssl->handshake->cli_exts & - MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT ) == 0 ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); - - *p++ = 0x00; - *p++ = 2; - - *p++ = 1; - *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; - - *olen = 6; -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - int ret; - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t kkpp_len; - - *olen = 0; - - /* Skip costly computation if not needed */ - if( ssl->transform_negotiate->ciphersuite_info->key_exchange != - MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, ecjpake kkpp extension" ) ); - - if( end - p < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); - - ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, - p + 2, end - p - 2, &kkpp_len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); - return; - } - - *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); - - *olen = kkpp_len + 4; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN ) -static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) -{ - if( ssl->alpn_chosen == NULL ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) ); - - /* - * 0 . 1 ext identifier - * 2 . 3 ext length - * 4 . 5 protocol list length - * 6 . 6 protocol name length - * 7 . 7+n protocol name - */ - buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); - buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); - - *olen = 7 + strlen( ssl->alpn_chosen ); - - buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); - buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); - - buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); - buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); - - buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF ); - - memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 ); -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *p = ssl->out_msg + 4; - unsigned char *cookie_len_byte; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello verify request" ) ); - - /* - * struct { - * ProtocolVersion server_version; - * opaque cookie<0..2^8-1>; - * } HelloVerifyRequest; - */ - - /* The RFC is not clear on this point, but sending the actual negotiated - * version looks like the most interoperable thing to do. */ - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, p ); - MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); - p += 2; - - /* If we get here, f_cookie_check is not null */ - if( ssl->conf->f_cookie_write == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "inconsistent cookie callbacks" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* Skip length byte until we know the length */ - cookie_len_byte = p++; - - if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie, - &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN, - ssl->cli_id, ssl->cli_id_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret ); - return( ret ); - } - - *cookie_len_byte = (unsigned char)( p - ( cookie_len_byte + 1 ) ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte ); - - ssl->out_msglen = p - ssl->out_msg; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; - - ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - -static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t; -#endif - int ret; - size_t olen, ext_len = 0, n; - unsigned char *buf, *p; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->verify_cookie_len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); - - return( ssl_write_hello_verify_request( ssl ) ); - } -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - - if( ssl->conf->f_rng == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); - return( MBEDTLS_ERR_SSL_NO_RNG ); - } - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 5 protocol version - * 6 . 9 UNIX time() - * 10 . 37 random bytes - */ - buf = ssl->out_msg; - p = buf + 4; - - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, p ); - p += 2; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]", - buf[4], buf[5] ) ); - -#if defined(MBEDTLS_HAVE_TIME) - t = mbedtls_time( NULL ); - *p++ = (unsigned char)( t >> 24 ); - *p++ = (unsigned char)( t >> 16 ); - *p++ = (unsigned char)( t >> 8 ); - *p++ = (unsigned char)( t ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); -#else - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) - return( ret ); - - p += 4; -#endif /* MBEDTLS_HAVE_TIME */ - - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) - return( ret ); - - p += 28; - - memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); - - /* - * Resume is 0 by default, see ssl_handshake_init(). - * It may be already set to 1 by ssl_parse_session_ticket_ext(). - * If not, try looking up session ID in our cache. - */ - if( ssl->handshake->resume == 0 && -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE && -#endif - ssl->session_negotiate->id_len != 0 && - ssl->conf->f_get_cache != NULL && - ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); - ssl->handshake->resume = 1; - } - - if( ssl->handshake->resume == 0 ) - { - /* - * New session, create a new session id, - * unless we're about to issue a session ticket - */ - ssl->state++; - -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time( NULL ); -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if( ssl->handshake->new_session_ticket != 0 ) - { - ssl->session_negotiate->id_len = n = 0; - memset( ssl->session_negotiate->id, 0, 32 ); - } - else -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - { - ssl->session_negotiate->id_len = n = 32; - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, - n ) ) != 0 ) - return( ret ); - } - } - else - { - /* - * Resuming a session - */ - n = ssl->session_negotiate->id_len; - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - } - - /* - * 38 . 38 session id length - * 39 . 38+n session id - * 39+n . 40+n chosen ciphersuite - * 41+n . 41+n chosen compression alg. - * 42+n . 43+n extensions length - * 44+n . 43+n+m extensions - */ - *p++ = (unsigned char) ssl->session_negotiate->id_len; - memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len ); - p += ssl->session_negotiate->id_len; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", - ssl->handshake->resume ? "a" : "no" ) ); - - *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 ); - *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite ); - *p++ = (unsigned char)( ssl->session_negotiate->compression ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", - mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X", - ssl->session_negotiate->compression ) ); - - /* Do not write the extensions if the protocol is SSLv3 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) - { -#endif - - /* - * First write extensions, then the total length - */ - ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if ( mbedtls_ssl_ciphersuite_uses_ec( - mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ) ) ) - { - ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_ALPN) - ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); - - if( ext_len > 0 ) - { - *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ext_len ) & 0xFF ); - p += ext_len; - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - } -#endif - - ssl->out_msglen = p - buf; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; - - ret = mbedtls_ssl_write_handshake_msg( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); - - return( ret ); -} - -#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} -#else -static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - size_t dn_size, total_dn_size; /* excluding length bytes */ - size_t ct_len, sa_len; /* including length bytes */ - unsigned char *buf, *p; - const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - const mbedtls_x509_crt *crt; - int authmode; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); - - ssl->state++; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET ) - authmode = ssl->handshake->sni_authmode; - else -#endif - authmode = ssl->conf->authmode; - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || - authmode == MBEDTLS_SSL_VERIFY_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); - return( 0 ); - } - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 4 cert type count - * 5 .. m-1 cert types - * m .. m+1 sig alg length (TLS 1.2 only) - * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) - * n .. n+1 length of all DNs - * n+2 .. n+3 length of DN 1 - * n+4 .. ... Distinguished Name #1 - * ... .. ... length of DN 2, etc. - */ - buf = ssl->out_msg; - p = buf + 4; - - /* - * Supported certificate types - * - * ClientCertificateType certificate_types<1..2^8-1>; - * enum { (255) } ClientCertificateType; - */ - ct_len = 0; - -#if defined(MBEDTLS_RSA_C) - p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN; -#endif -#if defined(MBEDTLS_ECDSA_C) - p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN; -#endif - - p[0] = (unsigned char) ct_len++; - p += ct_len; - - sa_len = 0; -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * Add signature_algorithms for verify (TLS 1.2) - * - * SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>; - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * enum { (255) } HashAlgorithm; - * enum { (255) } SignatureAlgorithm; - */ - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - const int *cur; - - /* - * Supported signature algorithms - */ - for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) - { - unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur ); - - if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) ) - continue; - -#if defined(MBEDTLS_RSA_C) - p[2 + sa_len++] = hash; - p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA; -#endif -#if defined(MBEDTLS_ECDSA_C) - p[2 + sa_len++] = hash; - p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA; -#endif - } - - p[0] = (unsigned char)( sa_len >> 8 ); - p[1] = (unsigned char)( sa_len ); - sa_len += 2; - p += sa_len; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - /* - * DistinguishedName certificate_authorities<0..2^16-1>; - * opaque DistinguishedName<1..2^16-1>; - */ - p += 2; - - total_dn_size = 0; - - if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED ) - { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_ca_chain != NULL ) - crt = ssl->handshake->sni_ca_chain; - else -#endif - crt = ssl->conf->ca_chain; - - while( crt != NULL && crt->version != 0 ) - { - dn_size = crt->subject_raw.len; - - if( end < p || - (size_t)( end - p ) < dn_size || - (size_t)( end - p ) < 2 + dn_size ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); - break; - } - - *p++ = (unsigned char)( dn_size >> 8 ); - *p++ = (unsigned char)( dn_size ); - memcpy( p, crt->subject_raw.p, dn_size ); - p += dn_size; - - MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size ); - - total_dn_size += 2 + dn_size; - crt = crt->next; - } - } - - ssl->out_msglen = p - buf; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST; - ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 ); - ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size ); - - ret = mbedtls_ssl_write_handshake_msg( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) ); - - return( ret ); -} -#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) -{ - int ret; - - if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); - } - - if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, - mbedtls_pk_ec( *mbedtls_ssl_own_key( ssl ) ), - MBEDTLS_ECDH_OURS ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ - defined(MBEDTLS_SSL_ASYNC_PRIVATE) -static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl, - size_t *signature_len ) -{ - /* Append the signature to ssl->out_msg, leaving 2 bytes for the - * signature length which will be added in ssl_write_server_key_exchange - * after the call to ssl_prepare_server_key_exchange. - * ssl_write_server_key_exchange also takes care of incrementing - * ssl->out_msglen. */ - unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2; - size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN - - sig_start ); - int ret = ssl->conf->f_async_resume( ssl, - sig_start, signature_len, sig_max_len ); - if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - { - ssl->handshake->async_in_progress = 0; - mbedtls_ssl_set_async_operation_data( ssl, NULL ); - } - MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret ); - return( ret ); -} -#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && - defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ - -/* Prepare the ServerKeyExchange message, up to and including - * calculating the signature if any, but excluding formatting the - * signature and sending the message. */ -static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, - size_t *signature_len ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - unsigned char *dig_signed = NULL; -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ - - (void) ciphersuite_info; /* unused in some configurations */ -#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - (void) signature_len; -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - - ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */ - - /* - * - * Part 1: Provide key exchange parameters for chosen ciphersuite. - * - */ - - /* - * - ECJPAKE key exchanges - */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - int ret; - size_t len = 0; - - ret = mbedtls_ecjpake_write_round_two( - &ssl->handshake->ecjpake_ctx, - ssl->out_msg + ssl->out_msglen, - MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); - return( ret ); - } - - ssl->out_msglen += len; - } -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - - /* - * For (EC)DHE key exchanges with PSK, parameters are prefixed by support - * identity hint (RFC 4279, Sec. 3). Until someone needs this feature, - * we use empty support identity hints here. - **/ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { - ssl->out_msg[ssl->out_msglen++] = 0x00; - ssl->out_msg[ssl->out_msglen++] = 0x00; - } -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - - /* - * - DHE key exchanges - */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) ) - { - int ret; - size_t len = 0; - - if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* - * Ephemeral DH parameters: - * - * struct { - * opaque dh_p<1..2^16-1>; - * opaque dh_g<1..2^16-1>; - * opaque dh_Ys<1..2^16-1>; - * } ServerDHParams; - */ - if( ( ret = mbedtls_dhm_set_group( &ssl->handshake->dhm_ctx, - &ssl->conf->dhm_P, - &ssl->conf->dhm_G ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_set_group", ret ); - return( ret ); - } - - if( ( ret = mbedtls_dhm_make_params( - &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - ssl->out_msg + ssl->out_msglen, &len, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret ); - return( ret ); - } - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - dig_signed = ssl->out_msg + ssl->out_msglen; -#endif - - ssl->out_msglen += len; - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED */ - - /* - * - ECDHE key exchanges - */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_ecdhe( ciphersuite_info ) ) - { - /* - * Ephemeral ECDH parameters: - * - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ - const mbedtls_ecp_curve_info **curve = NULL; - const mbedtls_ecp_group_id *gid; - int ret; - size_t len = 0; - - /* Match our preference list against the offered curves */ - for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) - for( curve = ssl->handshake->curves; *curve != NULL; curve++ ) - if( (*curve)->grp_id == *gid ) - goto curve_matching_done; - -curve_matching_done: - if( curve == NULL || *curve == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) ); - return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) ); - - if( ( ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx, - (*curve)->grp_id ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret ); - return( ret ); - } - - if( ( ret = mbedtls_ecdh_make_params( - &ssl->handshake->ecdh_ctx, &len, - ssl->out_msg + ssl->out_msglen, - MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret ); - return( ret ); - } - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - dig_signed = ssl->out_msg + ssl->out_msglen; -#endif - - ssl->out_msglen += len; - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ - - /* - * - * Part 2: For key exchanges involving the server signing the - * exchange parameters, compute and add the signature here. - * - */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) - { - size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed; - size_t hashlen = 0; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - int ret; - - /* - * 2.1: Choose hash algorithm: - * A: For TLS 1.2, obey signature-hash-algorithm extension - * to choose appropriate hash. - * B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1 - * (RFC 4492, Sec. 5.4) - * C: Otherwise, use MD5 + SHA1 (RFC 4346, Sec. 7.4.3) - */ - - mbedtls_md_type_t md_alg; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - mbedtls_pk_type_t sig_alg = - mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - /* A: For TLS 1.2, obey signature-hash-algorithm extension - * (RFC 5246, Sec. 7.4.1.4.1). */ - if( sig_alg == MBEDTLS_PK_NONE || - ( md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, - sig_alg ) ) == MBEDTLS_MD_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - /* (... because we choose a cipher suite - * only if there is a matching hash.) */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) - { - /* B: Default hash SHA1 */ - md_alg = MBEDTLS_MD_SHA1; - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ - { - /* C: MD5 + SHA1 */ - md_alg = MBEDTLS_MD_NONE; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) ); - - /* - * 2.2: Compute the hash to be signed - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( md_alg == MBEDTLS_MD_NONE ) - { - hashlen = 36; - ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash, - dig_signed, - dig_signed_len ); - if( ret != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( md_alg != MBEDTLS_MD_NONE ) - { - ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, - dig_signed, - dig_signed_len, - md_alg ); - if( ret != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); - - /* - * 2.3: Compute and add the signature - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - /* - * For TLS 1.2, we need to specify signature and hash algorithm - * explicitly through a prefix to the signature. - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * struct { - * SignatureAndHashAlgorithm algorithm; - * opaque signature<0..2^16-1>; - * } DigitallySigned; - * - */ - - ssl->out_msg[ssl->out_msglen++] = - mbedtls_ssl_hash_from_md_alg( md_alg ); - ssl->out_msg[ssl->out_msglen++] = - mbedtls_ssl_sig_from_pk_alg( sig_alg ); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if( ssl->conf->f_async_sign_start != NULL ) - { - ret = ssl->conf->f_async_sign_start( ssl, - mbedtls_ssl_own_cert( ssl ), - md_alg, hash, hashlen ); - switch( ret ) - { - case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: - /* act as if f_async_sign was null */ - break; - case 0: - ssl->handshake->async_in_progress = 1; - return( ssl_resume_server_key_exchange( ssl, signature_len ) ); - case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: - ssl->handshake->async_in_progress = 1; - return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); - default: - MBEDTLS_SSL_DEBUG_RET( 1, "f_async_sign_start", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if( mbedtls_ssl_own_key( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - /* Append the signature to ssl->out_msg, leaving 2 bytes for the - * signature length which will be added in ssl_write_server_key_exchange - * after the call to ssl_prepare_server_key_exchange. - * ssl_write_server_key_exchange also takes care of incrementing - * ssl->out_msglen. */ - if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), - md_alg, hash, hashlen, - ssl->out_msg + ssl->out_msglen + 2, - signature_len, - ssl->conf->f_rng, - ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - - return( 0 ); -} - -/* Prepare the ServerKeyExchange message and send it. For ciphersuites - * that do not include a ServerKeyExchange message, do nothing. Either - * way, if successful, move on to the next step in the SSL state - * machine. */ -static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t signature_len = 0; -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) - /* Extract static ECDH parameters and abort if ServerKeyExchange - * is not needed. */ - if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) ) - { - /* For suites involving ECDH, extract DH parameters - * from certificate at this point. */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) ) - { - ssl_get_ecdh_params_from_cert( ssl ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ - - /* Key exchanges not involving ephemeral keys don't use - * ServerKeyExchange, so end here. */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); - ssl->state++; - return( 0 ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ - defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /* If we have already prepared the message and there is an ongoing - * signature operation, resume signing. */ - if( ssl->handshake->async_in_progress != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) ); - ret = ssl_resume_server_key_exchange( ssl, &signature_len ); - } - else -#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && - defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ - { - /* ServerKeyExchange is needed. Prepare the message. */ - ret = ssl_prepare_server_key_exchange( ssl, &signature_len ); - } - - if( ret != 0 ) - { - /* If we're starting to write a new message, set ssl->out_msglen - * to 0. But if we're resuming after an asynchronous message, - * out_msglen is the amount of data written so far and mst be - * preserved. */ - if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) ); - else - ssl->out_msglen = 0; - return( ret ); - } - - /* If there is a signature, write its length. - * ssl_prepare_server_key_exchange already wrote the signature - * itself at its proper place in the output buffer. */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - if( signature_len != 0 ) - { - ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 ); - ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", - ssl->out_msg + ssl->out_msglen, - signature_len ); - - /* Skip over the already-written signature */ - ssl->out_msglen += signature_len; - } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - - /* Add header and send. */ - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) ); - return( 0 ); -} - -static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) ); - - ssl->out_msglen = 4; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE; - - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_send_flight_completed( ssl ); -#endif - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char **p, - const unsigned char *end ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t n; - - /* - * Receive G^Y mod P, premaster = (G^Y)^X mod P - */ - if( *p + 2 > end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - n = ( (*p)[0] << 8 ) | (*p)[1]; - *p += 2; - - if( *p + n > end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ( ret = mbedtls_dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_read_public", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); - } - - *p += n; - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl, - unsigned char *peer_pms, - size_t *peer_pmslen, - size_t peer_pmssize ) -{ - int ret = ssl->conf->f_async_resume( ssl, - peer_pms, peer_pmslen, peer_pmssize ); - if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - { - ssl->handshake->async_in_progress = 0; - mbedtls_ssl_set_async_operation_data( ssl, NULL ); - } - MBEDTLS_SSL_DEBUG_RET( 2, "ssl_decrypt_encrypted_pms", ret ); - return( ret ); -} -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, - const unsigned char *p, - const unsigned char *end, - unsigned char *peer_pms, - size_t *peer_pmslen, - size_t peer_pmssize ) -{ - int ret; - mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl ); - mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk; - size_t len = mbedtls_pk_get_len( public_key ); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /* If we have already started decoding the message and there is an ongoing - * decryption operation, resume signing. */ - if( ssl->handshake->async_in_progress != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) ); - return( ssl_resume_decrypt_pms( ssl, - peer_pms, peer_pmslen, peer_pmssize ) ); - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - /* - * Prepare to decrypt the premaster using own private RSA key - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) - { - if ( p + 2 > end ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - if( *p++ != ( ( len >> 8 ) & 0xFF ) || - *p++ != ( ( len ) & 0xFF ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - } -#endif - - if( p + len != end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - /* - * Decrypt the premaster secret - */ -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if( ssl->conf->f_async_decrypt_start != NULL ) - { - ret = ssl->conf->f_async_decrypt_start( ssl, - mbedtls_ssl_own_cert( ssl ), - p, len ); - switch( ret ) - { - case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: - /* act as if f_async_decrypt_start was null */ - break; - case 0: - ssl->handshake->async_in_progress = 1; - return( ssl_resume_decrypt_pms( ssl, - peer_pms, - peer_pmslen, - peer_pmssize ) ); - case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: - ssl->handshake->async_in_progress = 1; - return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); - default: - MBEDTLS_SSL_DEBUG_RET( 1, "f_async_decrypt_start", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_RSA ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - ret = mbedtls_pk_decrypt( private_key, p, len, - peer_pms, peer_pmslen, peer_pmssize, - ssl->conf->f_rng, ssl->conf->p_rng ); - return( ret ); -} - -static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, - const unsigned char *p, - const unsigned char *end, - size_t pms_offset ) -{ - int ret; - unsigned char *pms = ssl->handshake->premaster + pms_offset; - unsigned char ver[2]; - unsigned char fake_pms[48], peer_pms[48]; - unsigned char mask; - size_t i, peer_pmslen; - unsigned int diff; - - /* In case of a failure in decryption, the decryption may write less than - * 2 bytes of output, but we always read the first two bytes. It doesn't - * matter in the end because diff will be nonzero in that case due to - * ret being nonzero, and we only care whether diff is 0. - * But do initialize peer_pms and peer_pmslen for robustness anyway. This - * also makes memory analyzers happy (don't access uninitialized memory, - * even if it's an unsigned char). */ - peer_pms[0] = peer_pms[1] = ~0; - peer_pmslen = 0; - - ret = ssl_decrypt_encrypted_pms( ssl, p, end, - peer_pms, - &peer_pmslen, - sizeof( peer_pms ) ); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - return( ret ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - mbedtls_ssl_write_version( ssl->handshake->max_major_ver, - ssl->handshake->max_minor_ver, - ssl->conf->transport, ver ); - - /* Avoid data-dependent branches while checking for invalid - * padding, to protect against timing-based Bleichenbacher-type - * attacks. */ - diff = (unsigned int) ret; - diff |= peer_pmslen ^ 48; - diff |= peer_pms[0] ^ ver[0]; - diff |= peer_pms[1] ^ ver[1]; - - /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) ); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - /* - * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding - * must not cause the connection to end immediately; instead, send a - * bad_record_mac later in the handshake. - * To protect against timing-based variants of the attack, we must - * not have any branch that depends on whether the decryption was - * successful. In particular, always generate the fake premaster secret, - * regardless of whether it will ultimately influence the output or not. - */ - ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) ); - if( ret != 0 ) - { - /* It's ok to abort on an RNG failure, since this does not reveal - * anything about the RSA decryption. */ - return( ret ); - } - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - if( diff != 0 ) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); -#endif - - if( sizeof( ssl->handshake->premaster ) < pms_offset || - sizeof( ssl->handshake->premaster ) - pms_offset < 48 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - ssl->handshake->pmslen = 48; - - /* Set pms to either the true or the fake PMS, without - * data-dependent branches. */ - for( i = 0; i < ssl->handshake->pmslen; i++ ) - pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] ); - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p, - const unsigned char *end ) -{ - int ret = 0; - size_t n; - - if( ssl->conf->f_psk == NULL && - ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL || - ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - /* - * Receive client pre-shared key identity name - */ - if( end - *p < 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - n = ( (*p)[0] << 8 ) | (*p)[1]; - *p += 2; - - if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ssl->conf->f_psk != NULL ) - { - if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 ) - ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; - } - else - { - /* Identity is not a big secret since clients send it in the clear, - * but treat it carefully anyway, just in case */ - if( n != ssl->conf->psk_identity_len || - mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 ) - { - ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; - } - } - - if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ) - { - MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ); - return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ); - } - - *p += n; - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - unsigned char *p, *end; - - ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) ) - if( ( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) && - ( ssl->handshake->async_in_progress != 0 ) ) - { - /* We've already read a record and there is an asynchronous - * operation in progress to decrypt it. So skip reading the - * record. */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "will resume decryption of previously-read record" ) ); - } - else -#endif - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - end = ssl->in_msg + ssl->in_hslen; - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) - { - if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); - return( ret ); - } - - if( p != end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, - p, end - p) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP ); - - if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) - { - if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); - return( ret ); - } - - if( p != end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if ( ssl->handshake->async_in_progress != 0 ) - { - /* There is an asynchronous operation in progress to - * decrypt the encrypted premaster secret, so skip - * directly to resuming this operation. */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK identity already parsed" ) ); - /* Update p to skip the PSK identity. ssl_parse_encrypted_pms - * won't actually use it, but maintain p anyway for robustness. */ - p += ssl->conf->psk_identity_len + 2; - } - else -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); - return( ret ); - } - - if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret ); - return( ret ); - } - - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) - { - if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); - return( ret ); - } - if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); - return( ret ); - } - - if( p != end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { - if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); - return( ret ); - } - - if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, - p, end - p ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP ); - - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) - { - if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 0 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_parse_encrypted_pms_secret" ), ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, - p, end - p ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, - ssl->handshake->premaster, 32, &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} -#else -static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t i, sig_len; - unsigned char hash[48]; - unsigned char *hash_start = hash; - size_t hashlen; -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - mbedtls_pk_type_t pk_alg; -#endif - mbedtls_md_type_t md_alg; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || - ssl->session_negotiate->peer_cert == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state++; - return( 0 ); - } - - /* Read the message without adding it to the checksum */ - ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ ); - if( 0 != ret ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record" ), ret ); - return( ret ); - } - - ssl->state++; - - /* Process the message contents */ - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || - ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - i = mbedtls_ssl_hs_hdr_len( ssl ); - - /* - * struct { - * SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only - * opaque signature<0..2^16-1>; - * } DigitallySigned; - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - { - md_alg = MBEDTLS_MD_NONE; - hashlen = 36; - - /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */ - if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, - MBEDTLS_PK_ECDSA ) ) - { - hash_start += 16; - hashlen -= 16; - md_alg = MBEDTLS_MD_SHA1; - } - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || - MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - if( i + 2 > ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - /* - * Hash - */ - md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] ); - - if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" - " for verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - -#if !defined(MBEDTLS_MD_SHA1) - if( MBEDTLS_MD_SHA1 == md_alg ) - hash_start += 16; -#endif - - /* Info from md_alg will be used instead */ - hashlen = 0; - - i++; - - /* - * Signature - */ - if( ( pk_alg = mbedtls_ssl_pk_alg_from_sig( ssl->in_msg[i] ) ) - == MBEDTLS_PK_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" - " for verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - /* - * Check the certificate's key type matches the signature alg - */ - if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - i++; - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - if( i + 2 > ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1]; - i += 2; - - if( i + sig_len != ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - /* Calculate hash and verify signature */ - ssl->handshake->calc_verify( ssl, hash ); - - if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, - md_alg, hash_start, hashlen, - ssl->in_msg + i, sig_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); - return( ret ); - } - - mbedtls_ssl_update_handshake_status( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); - - return( ret ); -} -#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t tlen; - uint32_t lifetime; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write new session ticket" ) ); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_NEW_SESSION_TICKET; - - /* - * struct { - * uint32 ticket_lifetime_hint; - * opaque ticket<0..2^16-1>; - * } NewSessionTicket; - * - * 4 . 7 ticket_lifetime_hint (0 = unspecified) - * 8 . 9 ticket_len (n) - * 10 . 9+n ticket content - */ - - if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket, - ssl->session_negotiate, - ssl->out_msg + 10, - ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN, - &tlen, &lifetime ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret ); - tlen = 0; - } - - ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF; - ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF; - ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF; - ssl->out_msg[7] = ( lifetime ) & 0xFF; - - ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF ); - ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF ); - - ssl->out_msglen = 10 + tlen; - - /* - * Morally equivalent to updating ssl->state, but NewSessionTicket and - * ChangeCipherSpec share the same state. - */ - ssl->handshake->new_session_ticket = 0; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -/* - * SSL handshake -- server side -- single step - */ -int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) ); - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) - { - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - switch( ssl->state ) - { - case MBEDTLS_SSL_HELLO_REQUEST: - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; - break; - - /* - * <== ClientHello - */ - case MBEDTLS_SSL_CLIENT_HELLO: - ret = ssl_parse_client_hello( ssl ); - break; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: - return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); -#endif - - /* - * ==> ServerHello - * Certificate - * ( ServerKeyExchange ) - * ( CertificateRequest ) - * ServerHelloDone - */ - case MBEDTLS_SSL_SERVER_HELLO: - ret = ssl_write_server_hello( ssl ); - break; - - case MBEDTLS_SSL_SERVER_CERTIFICATE: - ret = mbedtls_ssl_write_certificate( ssl ); - break; - - case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: - ret = ssl_write_server_key_exchange( ssl ); - break; - - case MBEDTLS_SSL_CERTIFICATE_REQUEST: - ret = ssl_write_certificate_request( ssl ); - break; - - case MBEDTLS_SSL_SERVER_HELLO_DONE: - ret = ssl_write_server_hello_done( ssl ); - break; - - /* - * <== ( Certificate/Alert ) - * ClientKeyExchange - * ( CertificateVerify ) - * ChangeCipherSpec - * Finished - */ - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - ret = mbedtls_ssl_parse_certificate( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - ret = ssl_parse_client_key_exchange( ssl ); - break; - - case MBEDTLS_SSL_CERTIFICATE_VERIFY: - ret = ssl_parse_certificate_verify( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: - ret = mbedtls_ssl_parse_change_cipher_spec( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_FINISHED: - ret = mbedtls_ssl_parse_finished( ssl ); - break; - - /* - * ==> ( NewSessionTicket ) - * ChangeCipherSpec - * Finished - */ - case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if( ssl->handshake->new_session_ticket != 0 ) - ret = ssl_write_new_session_ticket( ssl ); - else -#endif - ret = mbedtls_ssl_write_change_cipher_spec( ssl ); - break; - - case MBEDTLS_SSL_SERVER_FINISHED: - ret = mbedtls_ssl_write_finished( ssl ); - break; - - case MBEDTLS_SSL_FLUSH_BUFFERS: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; - break; - - case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - mbedtls_ssl_handshake_wrapup( ssl ); - break; - - default: - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - return( ret ); -} -#endif /* MBEDTLS_SSL_SRV_C */ diff --git a/mbedtls/ssl_ticket.c b/mbedtls/ssl_ticket.c deleted file mode 100644 index 54cbf83ea..000000000 --- a/mbedtls/ssl_ticket.c +++ /dev/null @@ -1,543 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * TLS server tickets callbacks implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_TICKET_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/ssl_internal.h" -#include "mbedtls/ssl_ticket.h" -#include "mbedtls/platform_util.h" - -#include - -/* - * Initialze context - */ -void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_ssl_ticket_context ) ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif -} - -#define MAX_KEY_BYTES 32 /* 256 bits */ - -#define TICKET_KEY_NAME_BYTES 4 -#define TICKET_IV_BYTES 12 -#define TICKET_CRYPT_LEN_BYTES 2 -#define TICKET_AUTH_TAG_BYTES 16 - -#define TICKET_MIN_LEN ( TICKET_KEY_NAME_BYTES + \ - TICKET_IV_BYTES + \ - TICKET_CRYPT_LEN_BYTES + \ - TICKET_AUTH_TAG_BYTES ) -#define TICKET_ADD_DATA_LEN ( TICKET_KEY_NAME_BYTES + \ - TICKET_IV_BYTES + \ - TICKET_CRYPT_LEN_BYTES ) - -/* - * Generate/update a key - */ -static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx, - unsigned char index ) -{ - int ret; - unsigned char buf[MAX_KEY_BYTES]; - mbedtls_ssl_ticket_key *key = ctx->keys + index; - -#if defined(MBEDTLS_HAVE_TIME) - key->generation_time = (uint32_t) mbedtls_time( NULL ); -#endif - - if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 ) - return( ret ); - - if( ( ret = ctx->f_rng( ctx->p_rng, buf, sizeof( buf ) ) ) != 0 ) - return( ret ); - - /* With GCM and CCM, same context can encrypt & decrypt */ - ret = mbedtls_cipher_setkey( &key->ctx, buf, - mbedtls_cipher_get_key_bitlen( &key->ctx ), - MBEDTLS_ENCRYPT ); - - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - return( ret ); -} - -/* - * Rotate/generate keys if necessary - */ -static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx ) -{ -#if !defined(MBEDTLS_HAVE_TIME) - ((void) ctx); -#else - if( ctx->ticket_lifetime != 0 ) - { - uint32_t current_time = (uint32_t) mbedtls_time( NULL ); - uint32_t key_time = ctx->keys[ctx->active].generation_time; - - if( current_time >= key_time && - current_time - key_time < ctx->ticket_lifetime ) - { - return( 0 ); - } - - ctx->active = 1 - ctx->active; - - return( ssl_ticket_gen_key( ctx, ctx->active ) ); - } - else -#endif /* MBEDTLS_HAVE_TIME */ - return( 0 ); -} - -/* - * Setup context for actual use - */ -int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_cipher_type_t cipher, - uint32_t lifetime ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - ctx->f_rng = f_rng; - ctx->p_rng = p_rng; - - ctx->ticket_lifetime = lifetime; - - cipher_info = mbedtls_cipher_info_from_type( cipher); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( cipher_info->mode != MBEDTLS_MODE_GCM && - cipher_info->mode != MBEDTLS_MODE_CCM ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 || - ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 || - ( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Serialize a session in the following format: - * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session) - * n . n+2 peer_cert length = m (0 if no certificate) - * n+3 . n+2+m peer cert ASN.1 - */ -static int ssl_save_session( const mbedtls_ssl_session *session, - unsigned char *buf, size_t buf_len, - size_t *olen ) -{ - unsigned char *p = buf; - size_t left = buf_len; -#if defined(MBEDTLS_X509_CRT_PARSE_C) - size_t cert_len; -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - if( left < sizeof( mbedtls_ssl_session ) ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - memcpy( p, session, sizeof( mbedtls_ssl_session ) ); - p += sizeof( mbedtls_ssl_session ); - left -= sizeof( mbedtls_ssl_session ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - if( session->peer_cert == NULL ) - cert_len = 0; - else - cert_len = session->peer_cert->raw.len; - - if( left < 3 + cert_len ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - *p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF ); - *p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( cert_len ) & 0xFF ); - - if( session->peer_cert != NULL ) - memcpy( p, session->peer_cert->raw.p, cert_len ); - - p += cert_len; -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - *olen = p - buf; - - return( 0 ); -} - -/* - * Unserialise session, see ssl_save_session() - */ -static int ssl_load_session( mbedtls_ssl_session *session, - const unsigned char *buf, size_t len ) -{ - const unsigned char *p = buf; - const unsigned char * const end = buf + len; -#if defined(MBEDTLS_X509_CRT_PARSE_C) - size_t cert_len; -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - memcpy( session, p, sizeof( mbedtls_ssl_session ) ); - p += sizeof( mbedtls_ssl_session ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - if( 3 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2]; - p += 3; - - if( cert_len == 0 ) - { - session->peer_cert = NULL; - } - else - { - int ret; - - if( cert_len > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); - - if( session->peer_cert == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - mbedtls_x509_crt_init( session->peer_cert ); - - if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert, - p, cert_len ) ) != 0 ) - { - mbedtls_x509_crt_free( session->peer_cert ); - mbedtls_free( session->peer_cert ); - session->peer_cert = NULL; - return( ret ); - } - - p += cert_len; - } -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - if( p != end ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - return( 0 ); -} - -/* - * Create session ticket, with the following structure: - * - * struct { - * opaque key_name[4]; - * opaque iv[12]; - * opaque encrypted_state<0..2^16-1>; - * opaque tag[16]; - * } ticket; - * - * The key_name, iv, and length of encrypted_state are the additional - * authenticated data. - */ - -int mbedtls_ssl_ticket_write( void *p_ticket, - const mbedtls_ssl_session *session, - unsigned char *start, - const unsigned char *end, - size_t *tlen, - uint32_t *ticket_lifetime ) -{ - int ret; - mbedtls_ssl_ticket_context *ctx = p_ticket; - mbedtls_ssl_ticket_key *key; - unsigned char *key_name = start; - unsigned char *iv = start + TICKET_KEY_NAME_BYTES; - unsigned char *state_len_bytes = iv + TICKET_IV_BYTES; - unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES; - unsigned char *tag; - size_t clear_len, ciph_len; - - *tlen = 0; - - if( ctx == NULL || ctx->f_rng == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag, - * in addition to session itself, that will be checked when writing it. */ - MBEDTLS_SSL_CHK_BUF_PTR( start, end, TICKET_MIN_LEN ); - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 ) - goto cleanup; - - key = &ctx->keys[ctx->active]; - - *ticket_lifetime = ctx->ticket_lifetime; - - memcpy( key_name, key->name, TICKET_KEY_NAME_BYTES ); - - if( ( ret = ctx->f_rng( ctx->p_rng, iv, TICKET_IV_BYTES ) ) != 0 ) - goto cleanup; - - /* Dump session state */ - if( ( ret = ssl_save_session( session, - state, end - state, &clear_len ) ) != 0 || - (unsigned long) clear_len > 65535 ) - { - goto cleanup; - } - state_len_bytes[0] = ( clear_len >> 8 ) & 0xff; - state_len_bytes[1] = ( clear_len ) & 0xff; - - /* Encrypt and authenticate */ - tag = state + clear_len; - if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx, - iv, TICKET_IV_BYTES, - /* Additional data: key name, IV and length */ - key_name, TICKET_ADD_DATA_LEN, - state, clear_len, state, &ciph_len, - tag, TICKET_AUTH_TAG_BYTES ) ) != 0 ) - { - goto cleanup; - } - if( ciph_len != clear_len ) - { - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - - *tlen = TICKET_MIN_LEN + ciph_len; - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -/* - * Select key based on name - */ -static mbedtls_ssl_ticket_key *ssl_ticket_select_key( - mbedtls_ssl_ticket_context *ctx, - const unsigned char name[4] ) -{ - unsigned char i; - - for( i = 0; i < sizeof( ctx->keys ) / sizeof( *ctx->keys ); i++ ) - if( memcmp( name, ctx->keys[i].name, 4 ) == 0 ) - return( &ctx->keys[i] ); - - return( NULL ); -} - -/* - * Load session ticket (see mbedtls_ssl_ticket_write for structure) - */ -int mbedtls_ssl_ticket_parse( void *p_ticket, - mbedtls_ssl_session *session, - unsigned char *buf, - size_t len ) -{ - int ret; - mbedtls_ssl_ticket_context *ctx = p_ticket; - mbedtls_ssl_ticket_key *key; - unsigned char *key_name = buf; - unsigned char *iv = buf + TICKET_KEY_NAME_BYTES; - unsigned char *enc_len_p = iv + TICKET_IV_BYTES; - unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES; - unsigned char *tag; - size_t enc_len, clear_len; - - if( ctx == NULL || ctx->f_rng == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( len < TICKET_MIN_LEN ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); -#endif - - if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 ) - goto cleanup; - - enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1]; - tag = ticket + enc_len; - - if( len != TICKET_MIN_LEN + enc_len ) - { - ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - goto cleanup; - } - - /* Select key */ - if( ( key = ssl_ticket_select_key( ctx, key_name ) ) == NULL ) - { - /* We can't know for sure but this is a likely option unless we're - * under attack - this is only informative anyway */ - ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; - goto cleanup; - } - - /* Decrypt and authenticate */ - if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx, - iv, TICKET_IV_BYTES, - /* Additional data: key name, IV and length */ - key_name, TICKET_ADD_DATA_LEN, - ticket, enc_len, - ticket, &clear_len, - tag, TICKET_AUTH_TAG_BYTES ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) - ret = MBEDTLS_ERR_SSL_INVALID_MAC; - - goto cleanup; - } - if( clear_len != enc_len ) - { - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - - /* Actually load session */ - if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 ) - goto cleanup; - -#if defined(MBEDTLS_HAVE_TIME) - { - /* Check for expiration */ - mbedtls_time_t current_time = mbedtls_time( NULL ); - - if( current_time < session->start || - (uint32_t)( current_time - session->start ) > ctx->ticket_lifetime ) - { - ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; - goto cleanup; - } - } -#endif - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - return( ret ); -} - -/* - * Free context - */ -void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx ) -{ - mbedtls_cipher_free( &ctx->keys[0].ctx ); - mbedtls_cipher_free( &ctx->keys[1].ctx ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &ctx->mutex ); -#endif - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) ); -} - -#endif /* MBEDTLS_SSL_TICKET_C */ diff --git a/mbedtls/ssl_ticket.h b/mbedtls/ssl_ticket.h deleted file mode 100644 index c8ffda010..000000000 --- a/mbedtls/ssl_ticket.h +++ /dev/null @@ -1,168 +0,0 @@ -#pragma GCC system_header -/** - * \file ssl_ticket.h - * - * \brief TLS server ticket callbacks implementation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_SSL_TICKET_H -#define MBEDTLS_SSL_TICKET_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -/* - * This implementation of the session ticket callbacks includes key - * management, rotating the keys periodically in order to preserve forward - * secrecy, when MBEDTLS_HAVE_TIME is defined. - */ - -#include "ssl.h" -#include "cipher.h" - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Information for session ticket protection - */ -typedef struct mbedtls_ssl_ticket_key -{ - unsigned char name[4]; /*!< random key identifier */ - uint32_t generation_time; /*!< key generation timestamp (seconds) */ - mbedtls_cipher_context_t ctx; /*!< context for auth enc/decryption */ -} -mbedtls_ssl_ticket_key; - -/** - * \brief Context for session ticket handling functions - */ -typedef struct mbedtls_ssl_ticket_context -{ - mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys */ - unsigned char active; /*!< index of the currently active key */ - - uint32_t ticket_lifetime; /*!< lifetime of tickets in seconds */ - - /** Callback for getting (pseudo-)random numbers */ - int (*f_rng)(void *, unsigned char *, size_t); - void *p_rng; /*!< context for the RNG function */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; -#endif -} -mbedtls_ssl_ticket_context; - -/** - * \brief Initialize a ticket context. - * (Just make it ready for mbedtls_ssl_ticket_setup() - * or mbedtls_ssl_ticket_free().) - * - * \param ctx Context to be initialized - */ -void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx ); - -/** - * \brief Prepare context to be actually used - * - * \param ctx Context to be set up - * \param f_rng RNG callback function - * \param p_rng RNG callback context - * \param cipher AEAD cipher to use for ticket protection. - * Recommended value: MBEDTLS_CIPHER_AES_256_GCM. - * \param lifetime Tickets lifetime in seconds - * Recommended value: 86400 (one day). - * - * \note It is highly recommended to select a cipher that is at - * least as strong as the strongest ciphersuite - * supported. Usually that means a 256-bit key. - * - * \note The lifetime of the keys is twice the lifetime of tickets. - * It is recommended to pick a reasonnable lifetime so as not - * to negate the benefits of forward secrecy. - * - * \return 0 if successful, - * or a specific MBEDTLS_ERR_XXX error code - */ -int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_cipher_type_t cipher, - uint32_t lifetime ); - -/** - * \brief Implementation of the ticket write callback - * - * \note See \c mbedtls_ssl_ticket_write_t for description - */ -mbedtls_ssl_ticket_write_t mbedtls_ssl_ticket_write; - -/** - * \brief Implementation of the ticket parse callback - * - * \note See \c mbedtls_ssl_ticket_parse_t for description - */ -mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse; - -/** - * \brief Free a context's content and zeroize it. - * - * \param ctx Context to be cleaned up - */ -void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx ); - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_ticket.h */ diff --git a/mbedtls/ssl_tls.c b/mbedtls/ssl_tls.c deleted file mode 100644 index 6770572a9..000000000 --- a/mbedtls/ssl_tls.c +++ /dev/null @@ -1,9933 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * SSLv3/TLSv1 shared functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The SSL 3.0 specification was drafted by Netscape in 1996, - * and became an IETF standard in 1999. - * - * http://wp.netscape.com/eng/ssl3/ - * http://www.ietf.org/rfc/rfc2246.txt - * http://www.ietf.org/rfc/rfc4346.txt - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_TLS_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/debug.h" -#include "mbedtls/ssl.h" -#include "mbedtls/ssl_internal.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#include "mbedtls/oid.h" -#endif - -static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ); -static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ); - -/* Length of the "epoch" field in the record header */ -static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 2 ); -#else - ((void) ssl); -#endif - return( 0 ); -} - -/* - * Start a timer. - * Passing millisecs = 0 cancels a running timer. - */ -static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs ) -{ - if( ssl->f_set_timer == NULL ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) ); - ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs ); -} - -/* - * Return -1 is timer is expired, 0 if it isn't. - */ -static int ssl_check_timer( mbedtls_ssl_context *ssl ) -{ - if( ssl->f_get_timer == NULL ) - return( 0 ); - - if( ssl->f_get_timer( ssl->p_timer ) == 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) ); - return( -1 ); - } - - return( 0 ); -} - -static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ); -static void ssl_update_in_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ); - -#define SSL_DONT_FORCE_FLUSH 0 -#define SSL_FORCE_FLUSH 1 - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -/* Forward declarations for functions related to message buffering. */ -static void ssl_buffering_free( mbedtls_ssl_context *ssl ); -static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, - uint8_t slot ); -static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ); -static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ); -static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ); -static int ssl_buffer_message( mbedtls_ssl_context *ssl ); -static int ssl_buffer_future_record( mbedtls_ssl_context *ssl ); -static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ); - -static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl ); -static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl ) -{ - size_t mtu = ssl_get_current_mtu( ssl ); - - if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN ) - return( mtu ); - - return( MBEDTLS_SSL_OUT_BUFFER_LEN ); -} - -static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl ) -{ - size_t const bytes_written = ssl->out_left; - size_t const mtu = ssl_get_maximum_datagram_size( ssl ); - - /* Double-check that the write-index hasn't gone - * past what we can transmit in a single datagram. */ - if( bytes_written > mtu ) - { - /* Should never happen... */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - return( (int) ( mtu - bytes_written ) ); -} - -static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl ) -{ - int ret; - size_t remaining, expansion; - size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl ); - - if( max_len > mfl ) - max_len = mfl; - - /* By the standard (RFC 6066 Sect. 4), the MFL extension - * only limits the maximum record payload size, so in theory - * we would be allowed to pack multiple records of payload size - * MFL into a single datagram. However, this would mean that there's - * no way to explicitly communicate MTU restrictions to the peer. - * - * The following reduction of max_len makes sure that we never - * write datagrams larger than MFL + Record Expansion Overhead. - */ - if( max_len <= ssl->out_left ) - return( 0 ); - - max_len -= ssl->out_left; -#endif - - ret = ssl_get_remaining_space_in_datagram( ssl ); - if( ret < 0 ) - return( ret ); - remaining = (size_t) ret; - - ret = mbedtls_ssl_get_record_expansion( ssl ); - if( ret < 0 ) - return( ret ); - expansion = (size_t) ret; - - if( remaining <= expansion ) - return( 0 ); - - remaining -= expansion; - if( remaining >= max_len ) - remaining = max_len; - - return( (int) remaining ); -} - -/* - * Double the retransmit timeout value, within the allowed range, - * returning -1 if the maximum value has already been reached. - */ -static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) -{ - uint32_t new_timeout; - - if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) - return( -1 ); - - /* Implement the final paragraph of RFC 6347 section 4.1.1.1 - * in the following way: after the initial transmission and a first - * retransmission, back off to a temporary estimated MTU of 508 bytes. - * This value is guaranteed to be deliverable (if not guaranteed to be - * delivered) of any compliant IPv4 (and IPv6) network, and should work - * on most non-IP stacks too. */ - if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min ) - { - ssl->handshake->mtu = 508; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) ); - } - - new_timeout = 2 * ssl->handshake->retransmit_timeout; - - /* Avoid arithmetic overflow and range overflow */ - if( new_timeout < ssl->handshake->retransmit_timeout || - new_timeout > ssl->conf->hs_timeout_max ) - { - new_timeout = ssl->conf->hs_timeout_max; - } - - ssl->handshake->retransmit_timeout = new_timeout; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", - ssl->handshake->retransmit_timeout ) ); - - return( 0 ); -} - -static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) -{ - ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", - ssl->handshake->retransmit_timeout ) ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -/* - * Convert max_fragment_length codes to length. - * RFC 6066 says: - * enum{ - * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255) - * } MaxFragmentLength; - * and we add 0 -> extension unused - */ -static unsigned int ssl_mfl_code_to_length( int mfl ) -{ - switch( mfl ) - { - case MBEDTLS_SSL_MAX_FRAG_LEN_NONE: - return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); - case MBEDTLS_SSL_MAX_FRAG_LEN_512: - return 512; - case MBEDTLS_SSL_MAX_FRAG_LEN_1024: - return 1024; - case MBEDTLS_SSL_MAX_FRAG_LEN_2048: - return 2048; - case MBEDTLS_SSL_MAX_FRAG_LEN_4096: - return 4096; - default: - return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); - } -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_CLI_C) -static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src ) -{ - mbedtls_ssl_session_free( dst ); - memcpy( dst, src, sizeof( mbedtls_ssl_session ) ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - if( src->peer_cert != NULL ) - { - int ret; - - dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) ); - if( dst->peer_cert == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - mbedtls_x509_crt_init( dst->peer_cert ); - - if( ( ret = mbedtls_x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p, - src->peer_cert->raw.len ) ) != 0 ) - { - mbedtls_free( dst->peer_cert ); - dst->peer_cert = NULL; - return( ret ); - } - } -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - if( src->ticket != NULL ) - { - dst->ticket = mbedtls_calloc( 1, src->ticket_len ); - if( dst->ticket == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - memcpy( dst->ticket, src->ticket, src->ticket_len ); - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - - return( 0 ); -} -#endif /* MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) -int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl, - const unsigned char *key_enc, const unsigned char *key_dec, - size_t keylen, - const unsigned char *iv_enc, const unsigned char *iv_dec, - size_t ivlen, - const unsigned char *mac_enc, const unsigned char *mac_dec, - size_t maclen ) = NULL; -int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL; -int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL; -int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL; -int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL; -int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL; -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - -/* - * Key material generation - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) -static int ssl3_prf( const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - int ret = 0; - size_t i; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - unsigned char padding[16]; - unsigned char sha1sum[20]; - ((void)label); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - /* - * SSLv3: - * block = - * MD5( secret + SHA1( 'A' + secret + random ) ) + - * MD5( secret + SHA1( 'BB' + secret + random ) ) + - * MD5( secret + SHA1( 'CCC' + secret + random ) ) + - * ... - */ - for( i = 0; i < dlen / 16; i++ ) - { - memset( padding, (unsigned char) ('A' + i), 1 + i ); - - if( ( ret = mbedtls_sha1_starts_ret( &sha1 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha1_update_ret( &sha1, padding, 1 + i ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha1_update_ret( &sha1, secret, slen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha1_update_ret( &sha1, random, rlen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha1_finish_ret( &sha1, sha1sum ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md5_starts_ret( &md5 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5, secret, slen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5, sha1sum, 20 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_finish_ret( &md5, dstbuf + i * 16 ) ) != 0 ) - goto exit; - } - -exit: - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padding, sizeof( padding ) ); - mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); - - return( ret ); -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static int tls1_prf( const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - size_t nb, hs; - size_t i, j, k; - const unsigned char *S1, *S2; - unsigned char tmp[128]; - unsigned char h_i[20]; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - int ret; - - mbedtls_md_init( &md_ctx ); - - if( sizeof( tmp ) < 20 + strlen( label ) + rlen ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - hs = ( slen + 1 ) / 2; - S1 = secret; - S2 = secret + slen - hs; - - nb = strlen( label ); - memcpy( tmp + 20, label, nb ); - memcpy( tmp + 20 + nb, random, rlen ); - nb += rlen; - - /* - * First compute P_md5(secret,label+random)[0..dlen] - */ - if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - - mbedtls_md_hmac_starts( &md_ctx, S1, hs ); - mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); - mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); - - for( i = 0; i < dlen; i += 16 ) - { - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb ); - mbedtls_md_hmac_finish( &md_ctx, h_i ); - - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 ); - mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); - - k = ( i + 16 > dlen ) ? dlen % 16 : 16; - - for( j = 0; j < k; j++ ) - dstbuf[i + j] = h_i[j]; - } - - mbedtls_md_free( &md_ctx ); - - /* - * XOR out with P_sha1(secret,label+random)[0..dlen] - */ - if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - - mbedtls_md_hmac_starts( &md_ctx, S2, hs ); - mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); - mbedtls_md_hmac_finish( &md_ctx, tmp ); - - for( i = 0; i < dlen; i += 20 ) - { - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb ); - mbedtls_md_hmac_finish( &md_ctx, h_i ); - - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, tmp, 20 ); - mbedtls_md_hmac_finish( &md_ctx, tmp ); - - k = ( i + 20 > dlen ) ? dlen % 20 : 20; - - for( j = 0; j < k; j++ ) - dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] ); - } - - mbedtls_md_free( &md_ctx ); - - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -static int tls_prf_generic( mbedtls_md_type_t md_type, - const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - size_t nb; - size_t i, j, k, md_len; - unsigned char tmp[128]; - unsigned char h_i[MBEDTLS_MD_MAX_SIZE]; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - int ret; - - mbedtls_md_init( &md_ctx ); - - if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - - md_len = mbedtls_md_get_size( md_info ); - - if( sizeof( tmp ) < md_len + strlen( label ) + rlen ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - nb = strlen( label ); - memcpy( tmp + md_len, label, nb ); - memcpy( tmp + md_len + nb, random, rlen ); - nb += rlen; - - /* - * Compute P_(secret, label + random)[0..dlen] - */ - if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - - mbedtls_md_hmac_starts( &md_ctx, secret, slen ); - mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb ); - mbedtls_md_hmac_finish( &md_ctx, tmp ); - - for( i = 0; i < dlen; i += md_len ) - { - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb ); - mbedtls_md_hmac_finish( &md_ctx, h_i ); - - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, tmp, md_len ); - mbedtls_md_hmac_finish( &md_ctx, tmp ); - - k = ( i + md_len > dlen ) ? dlen % md_len : md_len; - - for( j = 0; j < k; j++ ) - dstbuf[i + j] = h_i[j]; - } - - mbedtls_md_free( &md_ctx ); - - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SHA256_C) -static int tls_prf_sha256( const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen, - label, random, rlen, dstbuf, dlen ) ); -} -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) -static int tls_prf_sha384( const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen, - label, random, rlen, dstbuf, dlen ) ); -} -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t ); -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * ); -static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int ); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * ); -static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int ); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t ); -static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *, unsigned char * ); -static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int ); -#endif - -#if defined(MBEDTLS_SHA512_C) -static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t ); -static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * ); -static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int ); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - unsigned char tmp[64]; - unsigned char keyblk[256]; - unsigned char *key1; - unsigned char *key2; - unsigned char *mac_enc; - unsigned char *mac_dec; - size_t mac_key_len; - size_t iv_copy_len; - const mbedtls_cipher_info_t *cipher_info; - const mbedtls_md_info_t *md_info; - - mbedtls_ssl_session *session = ssl->session_negotiate; - mbedtls_ssl_transform *transform = ssl->transform_negotiate; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); - - cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher ); - if( cipher_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found", - transform->ciphersuite_info->cipher ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac ); - if( md_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found", - transform->ciphersuite_info->mac ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* - * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - handshake->tls_prf = ssl3_prf; - handshake->calc_verify = ssl_calc_verify_ssl; - handshake->calc_finished = ssl_calc_finished_ssl; - } - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) - { - handshake->tls_prf = tls1_prf; - handshake->calc_verify = ssl_calc_verify_tls; - handshake->calc_finished = ssl_calc_finished_tls; - } - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && - transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) - { - handshake->tls_prf = tls_prf_sha384; - handshake->calc_verify = ssl_calc_verify_tls_sha384; - handshake->calc_finished = ssl_calc_finished_tls_sha384; - } - else -#endif -#if defined(MBEDTLS_SHA256_C) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - handshake->tls_prf = tls_prf_sha256; - handshake->calc_verify = ssl_calc_verify_tls_sha256; - handshake->calc_finished = ssl_calc_finished_tls_sha256; - } - else -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * SSLv3: - * master = - * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) + - * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) + - * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) ) - * - * TLSv1+: - * master = PRF( premaster, "master secret", randbytes )[0..47] - */ - if( handshake->resume == 0 ) - { - MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster, - handshake->pmslen ); - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED ) - { - unsigned char session_hash[48]; - size_t hash_len; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) ); - - ssl->handshake->calc_verify( ssl, session_hash ); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { -#if defined(MBEDTLS_SHA512_C) - if( ssl->transform_negotiate->ciphersuite_info->mac == - MBEDTLS_MD_SHA384 ) - { - hash_len = 48; - } - else -#endif - hash_len = 32; - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - hash_len = 36; - - MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len ); - - ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, - "extended master secret", - session_hash, hash_len, - session->master, 48 ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); - return( ret ); - } - - } - else -#endif - ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, - "master secret", - handshake->randbytes, 64, - session->master, 48 ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); - return( ret ); - } - - mbedtls_platform_zeroize( handshake->premaster, - sizeof(handshake->premaster) ); - } - else - MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); - - /* - * Swap the client and server random values. - */ - memcpy( tmp, handshake->randbytes, 64 ); - memcpy( handshake->randbytes, tmp + 32, 32 ); - memcpy( handshake->randbytes + 32, tmp, 32 ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - - /* - * SSLv3: - * key block = - * MD5( master + SHA1( 'A' + master + randbytes ) ) + - * MD5( master + SHA1( 'BB' + master + randbytes ) ) + - * MD5( master + SHA1( 'CCC' + master + randbytes ) ) + - * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) + - * ... - * - * TLSv1: - * key block = PRF( master, "key expansion", randbytes ) - */ - ret = handshake->tls_prf( session->master, 48, "key expansion", - handshake->randbytes, 64, keyblk, 256 ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s", - mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 ); - MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 ); - MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 ); - - mbedtls_platform_zeroize( handshake->randbytes, - sizeof( handshake->randbytes ) ); - - /* - * Determine the appropriate key, IV and MAC length. - */ - - transform->keylen = cipher_info->key_bitlen / 8; - - if( cipher_info->mode == MBEDTLS_MODE_GCM || - cipher_info->mode == MBEDTLS_MODE_CCM || - cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) - { - size_t taglen, explicit_ivlen; - - transform->maclen = 0; - mac_key_len = 0; - - /* All modes haves 96-bit IVs; - * GCM and CCM has 4 implicit and 8 explicit bytes - * ChachaPoly has all 12 bytes implicit - */ - transform->ivlen = 12; - if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) - transform->fixed_ivlen = 12; - else - transform->fixed_ivlen = 4; - - /* All modes have 128-bit tags, except CCM_8 (ciphersuite flag) */ - taglen = transform->ciphersuite_info->flags & - MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - - - /* Minimum length of encrypted record */ - explicit_ivlen = transform->ivlen - transform->fixed_ivlen; - transform->minlen = explicit_ivlen + taglen; - } - else - { - /* Initialize HMAC contexts */ - if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 || - ( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); - return( ret ); - } - - /* Get MAC length */ - mac_key_len = mbedtls_md_get_size( md_info ); - transform->maclen = mac_key_len; - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - /* - * If HMAC is to be truncated, we shall keep the leftmost bytes, - * (rfc 6066 page 13 or rfc 2104 section 4), - * so we only need to adjust the length here. - */ - if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) - { - transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN; - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) - /* Fall back to old, non-compliant version of the truncated - * HMAC implementation which also truncates the key - * (Mbed TLS versions from 1.3 to 2.6.0) */ - mac_key_len = transform->maclen; -#endif - } -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - - /* IV length */ - transform->ivlen = cipher_info->iv_size; - - /* Minimum length */ - if( cipher_info->mode == MBEDTLS_MODE_STREAM ) - transform->minlen = transform->maclen; - else - { - /* - * GenericBlockCipher: - * 1. if EtM is in use: one block plus MAC - * otherwise: * first multiple of blocklen greater than maclen - * 2. IV except for SSL3 and TLS 1.0 - */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) - { - transform->minlen = transform->maclen - + cipher_info->block_size; - } - else -#endif - { - transform->minlen = transform->maclen - + cipher_info->block_size - - transform->maclen % cipher_info->block_size; - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 ) - ; /* No need to adjust minlen */ - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - transform->minlen += transform->ivlen; - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d", - transform->keylen, transform->minlen, transform->ivlen, - transform->maclen ) ); - - /* - * Finally setup the cipher contexts, IVs and MAC secrets. - */ -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - { - key1 = keyblk + mac_key_len * 2; - key2 = keyblk + mac_key_len * 2 + transform->keylen; - - mac_enc = keyblk; - mac_dec = keyblk + mac_key_len; - - /* - * This is not used in TLS v1.1. - */ - iv_copy_len = ( transform->fixed_ivlen ) ? - transform->fixed_ivlen : transform->ivlen; - memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len ); - memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len, - iv_copy_len ); - } - else -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - { - key1 = keyblk + mac_key_len * 2 + transform->keylen; - key2 = keyblk + mac_key_len * 2; - - mac_enc = keyblk + mac_key_len; - mac_dec = keyblk; - - /* - * This is not used in TLS v1.1. - */ - iv_copy_len = ( transform->fixed_ivlen ) ? - transform->fixed_ivlen : transform->ivlen; - memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len ); - memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len, - iv_copy_len ); - } - else -#endif /* MBEDTLS_SSL_SRV_C */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - if( mac_key_len > sizeof transform->mac_enc ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - memcpy( transform->mac_enc, mac_enc, mac_key_len ); - memcpy( transform->mac_dec, mac_dec, mac_key_len ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) - { - /* For HMAC-based ciphersuites, initialize the HMAC transforms. - For AEAD-based ciphersuites, there is nothing to do here. */ - if( mac_key_len != 0 ) - { - mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len ); - mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len ); - } - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_init != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) ); - - if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen, - transform->iv_enc, transform->iv_dec, - iv_copy_len, - mac_enc, mac_dec, - mac_key_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) - if( ssl->conf->f_export_keys != NULL ) - { - ssl->conf->f_export_keys( ssl->conf->p_export_keys, - session->master, keyblk, - mac_key_len, transform->keylen, - iv_copy_len ); - } -#endif - - if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, - cipher_info ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); - return( ret ); - } - - if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec, - cipher_info ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); - return( ret ); - } - - if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1, - cipher_info->key_bitlen, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); - return( ret ); - } - - if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2, - cipher_info->key_bitlen, - MBEDTLS_DECRYPT ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); - return( ret ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( cipher_info->mode == MBEDTLS_MODE_CBC ) - { - if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc, - MBEDTLS_PADDING_NONE ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); - return( ret ); - } - - if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec, - MBEDTLS_PADDING_NONE ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - // Initialize compression - // - if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) - { - if( ssl->compress_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) ); - ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); - if( ssl->compress_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", - MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) ); - - memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) ); - memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) ); - - if( deflateInit( &transform->ctx_deflate, - Z_DEFAULT_COMPRESSION ) != Z_OK || - inflateInit( &transform->ctx_inflate ) != Z_OK ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) ); - return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); - } - } -#endif /* MBEDTLS_ZLIB_SUPPORT */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char *hash ) -{ - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - unsigned char pad_1[48]; - unsigned char pad_2[48]; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - memset( pad_1, 0x36, 48 ); - memset( pad_2, 0x5C, 48 ); - - mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); - mbedtls_md5_update_ret( &md5, pad_1, 48 ); - mbedtls_md5_finish_ret( &md5, hash ); - - mbedtls_md5_starts_ret( &md5 ); - mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); - mbedtls_md5_update_ret( &md5, pad_2, 48 ); - mbedtls_md5_update_ret( &md5, hash, 16 ); - mbedtls_md5_finish_ret( &md5, hash ); - - mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); - mbedtls_sha1_update_ret( &sha1, pad_1, 40 ); - mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - - mbedtls_sha1_starts_ret( &sha1 ); - mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); - mbedtls_sha1_update_ret( &sha1, pad_2, 40 ); - mbedtls_sha1_update_ret( &sha1, hash + 16, 20 ); - mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - return; -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char *hash ) -{ - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - mbedtls_md5_finish_ret( &md5, hash ); - mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - return; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char *hash ) -{ - mbedtls_sha256_context sha256; - - mbedtls_sha256_init( &sha256 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) ); - - mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); - mbedtls_sha256_finish_ret( &sha256, hash ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_sha256_free( &sha256 ); - - return; -} -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) -void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *hash ) -{ - mbedtls_sha512_context sha512; - - mbedtls_sha512_init( &sha512 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) ); - - mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); - mbedtls_sha512_finish_ret( &sha512, hash ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_sha512_free( &sha512 ); - - return; -} -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ) -{ - unsigned char *p = ssl->handshake->premaster; - unsigned char *end = p + sizeof( ssl->handshake->premaster ); - const unsigned char *psk = ssl->conf->psk; - size_t psk_len = ssl->conf->psk_len; - - /* If the psk callback was called, use its result */ - if( ssl->handshake->psk != NULL ) - { - psk = ssl->handshake->psk; - psk_len = ssl->handshake->psk_len; - } - - /* - * PMS = struct { - * opaque other_secret<0..2^16-1>; - * opaque psk<0..2^16-1>; - * }; - * with "other_secret" depending on the particular key exchange - */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK ) - { - if( end - p < 2 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - *(p++) = (unsigned char)( psk_len >> 8 ); - *(p++) = (unsigned char)( psk_len ); - - if( end < p || (size_t)( end - p ) < psk_len ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - memset( p, 0, psk_len ); - p += psk_len; - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { - /* - * other_secret already set by the ClientKeyExchange message, - * and is 48 bytes long - */ - if( end - p < 2 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - *p++ = 0; - *p++ = 48; - p += 48; - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) - { - int ret; - size_t len; - - /* Write length only when we know the actual value */ - if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - p + 2, end - ( p + 2 ), &len, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); - return( ret ); - } - *(p++) = (unsigned char)( len >> 8 ); - *(p++) = (unsigned char)( len ); - p += len; - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { - int ret; - size_t zlen; - - if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen, - p + 2, end - ( p + 2 ), - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); - return( ret ); - } - - *(p++) = (unsigned char)( zlen >> 8 ); - *(p++) = (unsigned char)( zlen ); - p += zlen; - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* opaque psk<0..2^16-1>; */ - if( end - p < 2 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - *(p++) = (unsigned char)( psk_len >> 8 ); - *(p++) = (unsigned char)( psk_len ); - - if( end < p || (size_t)( end - p ) < psk_len ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - memcpy( p, psk, psk_len ); - p += psk_len; - - ssl->handshake->pmslen = p - ssl->handshake->premaster; - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -/* - * SSLv3.0 MAC functions - */ -#define SSL_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */ -static void ssl_mac( mbedtls_md_context_t *md_ctx, - const unsigned char *secret, - const unsigned char *buf, size_t len, - const unsigned char *ctr, int type, - unsigned char out[SSL_MAC_MAX_BYTES] ) -{ - unsigned char header[11]; - unsigned char padding[48]; - int padlen; - int md_size = mbedtls_md_get_size( md_ctx->md_info ); - int md_type = mbedtls_md_get_type( md_ctx->md_info ); - - /* Only MD5 and SHA-1 supported */ - if( md_type == MBEDTLS_MD_MD5 ) - padlen = 48; - else - padlen = 40; - - memcpy( header, ctr, 8 ); - header[ 8] = (unsigned char) type; - header[ 9] = (unsigned char)( len >> 8 ); - header[10] = (unsigned char)( len ); - - memset( padding, 0x36, padlen ); - mbedtls_md_starts( md_ctx ); - mbedtls_md_update( md_ctx, secret, md_size ); - mbedtls_md_update( md_ctx, padding, padlen ); - mbedtls_md_update( md_ctx, header, 11 ); - mbedtls_md_update( md_ctx, buf, len ); - mbedtls_md_finish( md_ctx, out ); - - memset( padding, 0x5C, padlen ); - mbedtls_md_starts( md_ctx ); - mbedtls_md_update( md_ctx, secret, md_size ); - mbedtls_md_update( md_ctx, padding, padlen ); - mbedtls_md_update( md_ctx, out, md_size ); - mbedtls_md_finish( md_ctx, out ); -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ - defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) -#define SSL_SOME_MODES_USE_MAC -#endif - -/* - * Encryption/decryption functions - */ -static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) -{ - mbedtls_cipher_mode_t mode; - int auth_done = 0; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) ); - - if( ssl->session_out == NULL || ssl->transform_out == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", - ssl->out_msg, ssl->out_msglen ); - - /* - * Add MAC before if needed - */ -#if defined(SSL_SOME_MODES_USE_MAC) - if( mode == MBEDTLS_MODE_STREAM || - ( mode == MBEDTLS_MODE_CBC -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - && ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED -#endif - ) ) - { -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - unsigned char mac[SSL_MAC_MAX_BYTES]; - - ssl_mac( &ssl->transform_out->md_ctx_enc, - ssl->transform_out->mac_enc, - ssl->out_msg, ssl->out_msglen, - ssl->out_ctr, ssl->out_msgtype, - mac ); - - memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen ); - } - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) - { - unsigned char mac[MBEDTLS_SSL_MAC_ADD]; - - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 ); - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 ); - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 ); - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, - ssl->out_msg, ssl->out_msglen ); - mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac ); - mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); - - memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen ); - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", - ssl->out_msg + ssl->out_msglen, - ssl->transform_out->maclen ); - - ssl->out_msglen += ssl->transform_out->maclen; - auth_done++; - } -#endif /* AEAD not the only option */ - - /* - * Encrypt - */ -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) - if( mode == MBEDTLS_MODE_STREAM ) - { - int ret; - size_t olen = 0; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " - "including %d bytes of padding", - ssl->out_msglen, 0 ) ); - - if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, - ssl->transform_out->iv_enc, - ssl->transform_out->ivlen, - ssl->out_msg, ssl->out_msglen, - ssl->out_msg, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } - - if( ssl->out_msglen != olen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - else -#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ -#if defined(MBEDTLS_GCM_C) || \ - defined(MBEDTLS_CCM_C) || \ - defined(MBEDTLS_CHACHAPOLY_C) - if( mode == MBEDTLS_MODE_GCM || - mode == MBEDTLS_MODE_CCM || - mode == MBEDTLS_MODE_CHACHAPOLY ) - { - int ret; - size_t enc_msglen, olen; - unsigned char *enc_msg; - unsigned char add_data[13]; - unsigned char iv[12]; - mbedtls_ssl_transform *transform = ssl->transform_out; - unsigned char taglen = transform->ciphersuite_info->flags & - MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - size_t explicit_ivlen = transform->ivlen - transform->fixed_ivlen; - - /* - * Prepare additional authenticated data - */ - memcpy( add_data, ssl->out_ctr, 8 ); - add_data[8] = ssl->out_msgtype; - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, add_data + 9 ); - add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF; - add_data[12] = ssl->out_msglen & 0xFF; - - MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 ); - - /* - * Generate IV - */ - if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) - { - /* GCM and CCM: fixed || explicit (=seqnum) */ - memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); - memcpy( iv + transform->fixed_ivlen, ssl->out_ctr, 8 ); - memcpy( ssl->out_iv, ssl->out_ctr, 8 ); - - } - else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) - { - /* ChachaPoly: fixed XOR sequence number */ - unsigned char i; - - memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); - - for( i = 0; i < 8; i++ ) - iv[i+4] ^= ssl->out_ctr[i]; - } - else - { - /* Reminder if we ever add an AEAD mode with a different size */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", - iv, transform->ivlen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)", - ssl->out_iv, explicit_ivlen ); - - /* - * Fix message length with added IV - */ - enc_msg = ssl->out_msg; - enc_msglen = ssl->out_msglen; - ssl->out_msglen += explicit_ivlen; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " - "including 0 bytes of padding", - ssl->out_msglen ) ); - - /* - * Encrypt and authenticate - */ - if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc, - iv, transform->ivlen, - add_data, 13, - enc_msg, enc_msglen, - enc_msg, &olen, - enc_msg + enc_msglen, taglen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); - return( ret ); - } - - if( olen != enc_msglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->out_msglen += taglen; - auth_done++; - - MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen ); - } - else -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) - if( mode == MBEDTLS_MODE_CBC ) - { - int ret; - unsigned char *enc_msg; - size_t enc_msglen, padlen, olen = 0, i; - - padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) % - ssl->transform_out->ivlen; - if( padlen == ssl->transform_out->ivlen ) - padlen = 0; - - for( i = 0; i <= padlen; i++ ) - ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen; - - ssl->out_msglen += padlen + 1; - - enc_msglen = ssl->out_msglen; - enc_msg = ssl->out_msg; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * Prepend per-record IV for block cipher in TLS v1.1 and up as per - * Method 1 (6.2.3.2. in RFC4346 and RFC5246) - */ - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - /* - * Generate IV - */ - ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc, - ssl->transform_out->ivlen ); - if( ret != 0 ) - return( ret ); - - memcpy( ssl->out_iv, ssl->transform_out->iv_enc, - ssl->transform_out->ivlen ); - - /* - * Fix pointer positions and message length with added IV - */ - enc_msg = ssl->out_msg; - enc_msglen = ssl->out_msglen; - ssl->out_msglen += ssl->transform_out->ivlen; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " - "including %d bytes of IV and %d bytes of padding", - ssl->out_msglen, ssl->transform_out->ivlen, - padlen + 1 ) ); - - if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, - ssl->transform_out->iv_enc, - ssl->transform_out->ivlen, - enc_msg, enc_msglen, - enc_msg, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } - - if( enc_msglen != olen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) - { - /* - * Save IV in SSL3 and TLS1 - */ - memcpy( ssl->transform_out->iv_enc, - ssl->transform_out->cipher_ctx_enc.iv, - ssl->transform_out->ivlen ); - } -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if( auth_done == 0 ) - { - unsigned char mac[MBEDTLS_SSL_MAC_ADD]; - - /* - * MAC(MAC_write_key, seq_num + - * TLSCipherText.type + - * TLSCipherText.version + - * length_of( (IV +) ENC(...) ) + - * IV + // except for TLS 1.0 - * ENC(content + padding + padding_length)); - */ - unsigned char pseudo_hdr[13]; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); - - memcpy( pseudo_hdr + 0, ssl->out_ctr, 8 ); - memcpy( pseudo_hdr + 8, ssl->out_hdr, 3 ); - pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF ); - pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen ) & 0xFF ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); - - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 ); - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, - ssl->out_iv, ssl->out_msglen ); - mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac ); - mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); - - memcpy( ssl->out_iv + ssl->out_msglen, mac, - ssl->transform_out->maclen ); - - ssl->out_msglen += ssl->transform_out->maclen; - auth_done++; - } -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - } - else -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* Make extra sure authentication was performed, exactly once */ - if( auth_done != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) -/* - * Constant-flow conditional memcpy: - * - if c1 == c2, equivalent to memcpy(dst, src, len), - * - otherwise, a no-op, - * but with execution flow independent of the values of c1 and c2. - * - * Use only bit operations to avoid branches that could be used by some - * compilers on some platforms to translate comparison operators. - */ -static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst, - const unsigned char *src, - size_t len, - size_t c1, size_t c2 ) -{ - /* diff = 0 if c1 == c2, non-zero otherwise */ - const size_t diff = c1 ^ c2; - - /* MSVC has a warning about unary minus on unsigned integer types, - * but this is well-defined and precisely what we want to do here. */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - - /* diff_msb's most significant bit is equal to c1 != c2 */ - const size_t diff_msb = ( diff | -diff ); - - /* diff1 = c1 != c2 */ - const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 ); - - /* mask = c1 != c2 ? 0xff : 0x00 */ - const unsigned char mask = (unsigned char) -diff1; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - /* dst[i] = c1 != c2 ? dst[i] : src[i] */ - size_t i; - for( i = 0; i < len; i++ ) - dst[i] = ( dst[i] & mask ) | ( src[i] & ~mask ); -} - -/* - * Compute HMAC of variable-length data with constant flow. - * - * Only works with MD-5, SHA-1, SHA-256 and SHA-384. - * (Otherwise, computation of block_size needs to be adapted.) - */ -int mbedtls_ssl_cf_hmac( - mbedtls_md_context_t *ctx, - const unsigned char *add_data, size_t add_data_len, - const unsigned char *data, size_t data_len_secret, - size_t min_data_len, size_t max_data_len, - unsigned char *output ) -{ - /* - * This function breaks the HMAC abstraction and uses the md_clone() - * extension to the MD API in order to get constant-flow behaviour. - * - * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means - * concatenation, and okey/ikey are the XOR of the key with some fixed bit - * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx. - * - * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to - * minlen, then cloning the context, and for each byte up to maxlen - * finishing up the hash computation, keeping only the correct result. - * - * Then we only need to compute HASH(okey + inner_hash) and we're done. - */ - const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info ); - /* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5, - * all of which have the same block size except SHA-384. */ - const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64; - const unsigned char * const ikey = ctx->hmac_ctx; - const unsigned char * const okey = ikey + block_size; - const size_t hash_size = mbedtls_md_get_size( ctx->md_info ); - - unsigned char aux_out[MBEDTLS_MD_MAX_SIZE]; - mbedtls_md_context_t aux; - size_t offset; - int ret; - - mbedtls_md_init( &aux ); - -#define MD_CHK( func_call ) \ - do { \ - ret = (func_call); \ - if( ret != 0 ) \ - goto cleanup; \ - } while( 0 ) - - MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) ); - - /* After hmac_start() of hmac_reset(), ikey has already been hashed, - * so we can start directly with the message */ - MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) ); - MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) ); - - /* For each possible length, compute the hash up to that point */ - for( offset = min_data_len; offset <= max_data_len; offset++ ) - { - MD_CHK( mbedtls_md_clone( &aux, ctx ) ); - MD_CHK( mbedtls_md_finish( &aux, aux_out ) ); - /* Keep only the correct inner_hash in the output buffer */ - mbedtls_ssl_cf_memcpy_if_eq( output, aux_out, hash_size, - offset, data_len_secret ); - - if( offset < max_data_len ) - MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) ); - } - - /* The context needs to finish() before it starts() again */ - MD_CHK( mbedtls_md_finish( ctx, aux_out ) ); - - /* Now compute HASH(okey + inner_hash) */ - MD_CHK( mbedtls_md_starts( ctx ) ); - MD_CHK( mbedtls_md_update( ctx, okey, block_size ) ); - MD_CHK( mbedtls_md_update( ctx, output, hash_size ) ); - MD_CHK( mbedtls_md_finish( ctx, output ) ); - - /* Done, get ready for next time */ - MD_CHK( mbedtls_md_hmac_reset( ctx ) ); - -#undef MD_CHK - -cleanup: - mbedtls_md_free( &aux ); - return( ret ); -} - -/* - * Constant-flow memcpy from variable position in buffer. - * - functionally equivalent to memcpy(dst, src + offset_secret, len) - * - but with execution flow independent from the value of offset_secret. - */ -void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst, - const unsigned char *src_base, - size_t offset_secret, - size_t offset_min, size_t offset_max, - size_t len ) -{ - size_t offset; - - for( offset = offset_min; offset <= offset_max; offset++ ) - { - mbedtls_ssl_cf_memcpy_if_eq( dst, src_base + offset, len, - offset, offset_secret ); - } -} -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ - -static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) -{ - mbedtls_cipher_mode_t mode; - int auth_done = 0; -#if defined(SSL_SOME_MODES_USE_MAC) - size_t padlen = 0, correct = 1; -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) ); - - if( ssl->session_in == NULL || ssl->transform_in == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec ); - - if( ssl->in_msglen < ssl->transform_in->minlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)", - ssl->in_msglen, ssl->transform_in->minlen ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) - if( mode == MBEDTLS_MODE_STREAM ) - { - int ret; - size_t olen = 0; - - padlen = 0; - - if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, - ssl->transform_in->iv_dec, - ssl->transform_in->ivlen, - ssl->in_msg, ssl->in_msglen, - ssl->in_msg, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } - - if( ssl->in_msglen != olen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - else -#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ -#if defined(MBEDTLS_GCM_C) || \ - defined(MBEDTLS_CCM_C) || \ - defined(MBEDTLS_CHACHAPOLY_C) - if( mode == MBEDTLS_MODE_GCM || - mode == MBEDTLS_MODE_CCM || - mode == MBEDTLS_MODE_CHACHAPOLY ) - { - int ret; - size_t dec_msglen, olen; - unsigned char *dec_msg; - unsigned char *dec_msg_result; - unsigned char add_data[13]; - unsigned char iv[12]; - mbedtls_ssl_transform *transform = ssl->transform_in; - unsigned char taglen = transform->ciphersuite_info->flags & - MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen; - - /* - * Compute and update sizes - */ - if( ssl->in_msglen < explicit_iv_len + taglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " - "+ taglen (%d)", ssl->in_msglen, - explicit_iv_len, taglen ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - dec_msglen = ssl->in_msglen - explicit_iv_len - taglen; - - dec_msg = ssl->in_msg; - dec_msg_result = ssl->in_msg; - ssl->in_msglen = dec_msglen; - - /* - * Prepare additional authenticated data - */ - memcpy( add_data, ssl->in_ctr, 8 ); - add_data[8] = ssl->in_msgtype; - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, add_data + 9 ); - add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF; - add_data[12] = ssl->in_msglen & 0xFF; - - MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 ); - - /* - * Prepare IV - */ - if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) - { - /* GCM and CCM: fixed || explicit (transmitted) */ - memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); - memcpy( iv + transform->fixed_ivlen, ssl->in_iv, 8 ); - - } - else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) - { - /* ChachaPoly: fixed XOR sequence number */ - unsigned char i; - - memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); - - for( i = 0; i < 8; i++ ) - iv[i+4] ^= ssl->in_ctr[i]; - } - else - { - /* Reminder if we ever add an AEAD mode with a different size */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen ); - - /* - * Decrypt and authenticate - */ - if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec, - iv, transform->ivlen, - add_data, 13, - dec_msg, dec_msglen, - dec_msg_result, &olen, - dec_msg + dec_msglen, taglen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret ); - - if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - - return( ret ); - } - auth_done++; - - if( olen != dec_msglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - else -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) - if( mode == MBEDTLS_MODE_CBC ) - { - /* - * Decrypt and check the padding - */ - int ret; - unsigned char *dec_msg; - unsigned char *dec_msg_result; - size_t dec_msglen; - size_t minlen = 0; - size_t olen = 0; - - /* - * Check immediate ciphertext sanity - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - minlen += ssl->transform_in->ivlen; -#endif - - if( ssl->in_msglen < minlen + ssl->transform_in->ivlen || - ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) " - "+ 1 ) ( + expl IV )", ssl->in_msglen, - ssl->transform_in->ivlen, - ssl->transform_in->maclen ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - - dec_msglen = ssl->in_msglen; - dec_msg = ssl->in_msg; - dec_msg_result = ssl->in_msg; - - /* - * Authenticate before decrypt if enabled - */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) - { - unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; - unsigned char pseudo_hdr[13]; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); - - dec_msglen -= ssl->transform_in->maclen; - ssl->in_msglen -= ssl->transform_in->maclen; - - memcpy( pseudo_hdr + 0, ssl->in_ctr, 8 ); - memcpy( pseudo_hdr + 8, ssl->in_hdr, 3 ); - pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF ); - pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen ) & 0xFF ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); - - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 ); - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, - ssl->in_iv, ssl->in_msglen ); - mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect ); - mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen, - ssl->transform_in->maclen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, - ssl->transform_in->maclen ); - - if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, mac_expect, - ssl->transform_in->maclen ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); - - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - auth_done++; - } -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - - /* - * Check length sanity - */ - if( ssl->in_msglen % ssl->transform_in->ivlen != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0", - ssl->in_msglen, ssl->transform_in->ivlen ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * Initialize for prepended IV for block cipher in TLS v1.1 and up - */ - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - unsigned char i; - dec_msglen -= ssl->transform_in->ivlen; - ssl->in_msglen -= ssl->transform_in->ivlen; - - for( i = 0; i < ssl->transform_in->ivlen; i++ ) - ssl->transform_in->iv_dec[i] = ssl->in_iv[i]; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ - - if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, - ssl->transform_in->iv_dec, - ssl->transform_in->ivlen, - dec_msg, dec_msglen, - dec_msg_result, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } - - if( dec_msglen != olen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) - { - /* - * Save IV in SSL3 and TLS1 - */ - memcpy( ssl->transform_in->iv_dec, - ssl->transform_in->cipher_ctx_dec.iv, - ssl->transform_in->ivlen ); - } -#endif - - padlen = 1 + ssl->in_msg[ssl->in_msglen - 1]; - - if( ssl->in_msglen < ssl->transform_in->maclen + padlen && - auth_done == 0 ) - { -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)", - ssl->in_msglen, ssl->transform_in->maclen, padlen ) ); -#endif - padlen = 0; - correct = 0; - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - if( padlen > ssl->transform_in->ivlen ) - { -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, " - "should be no more than %d", - padlen, ssl->transform_in->ivlen ) ); -#endif - correct = 0; - } - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) - { - /* - * TLSv1+: always check the padding up to the first failure - * and fake check up to 256 bytes of padding - */ - size_t pad_count = 0, real_count = 1; - size_t padding_idx = ssl->in_msglen - padlen; - size_t i; - - /* - * Padding is guaranteed to be incorrect if: - * 1. padlen > ssl->in_msglen - * - * 2. padding_idx > MBEDTLS_SSL_IN_CONTENT_LEN + - * ssl->transform_in->maclen - * - * In both cases we reset padding_idx to a safe value (0) to - * prevent out-of-buffer reads. - */ - correct &= ( padlen <= ssl->in_msglen ); - correct &= ( padding_idx <= MBEDTLS_SSL_IN_CONTENT_LEN + - ssl->transform_in->maclen ); - - padding_idx *= correct; - - for( i = 0; i < 256; i++ ) - { - real_count &= ( i < padlen ); - pad_count += real_count * - ( ssl->in_msg[padding_idx + i] == padlen - 1 ); - } - - correct &= ( pad_count == padlen ); /* Only 1 on correct padding */ - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - if( padlen > 0 && correct == 0 ) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) ); -#endif - padlen &= correct * 0x1FF; - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->in_msglen -= padlen; - } - else -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption", - ssl->in_msg, ssl->in_msglen ); -#endif - - /* - * Authenticate if not done yet. - * Compute the MAC regardless of the padding result (RFC4346, CBCTIME). - */ -#if defined(SSL_SOME_MODES_USE_MAC) - if( auth_done == 0 ) - { - unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; - unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD]; - - ssl->in_msglen -= ssl->transform_in->maclen; - - ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 ); - ssl->in_len[1] = (unsigned char)( ssl->in_msglen ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - ssl_mac( &ssl->transform_in->md_ctx_dec, - ssl->transform_in->mac_dec, - ssl->in_msg, ssl->in_msglen, - ssl->in_ctr, ssl->in_msgtype, - mac_expect ); - memcpy( mac_peer, ssl->in_msg + ssl->in_msglen, - ssl->transform_in->maclen ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) - { - int ret; - unsigned char add_data[13]; - - /* - * The next two sizes are the minimum and maximum values of - * in_msglen over all padlen values. - * - * They're independent of padlen, since we previously did - * in_msglen -= padlen. - * - * Note that max_len + maclen is never more than the buffer - * length, as we previously did in_msglen -= maclen too. - */ - const size_t max_len = ssl->in_msglen + padlen; - const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0; - - memcpy( add_data + 0, ssl->in_ctr, 8 ); - memcpy( add_data + 8, ssl->in_hdr, 3 ); - memcpy( add_data + 11, ssl->in_len, 2 ); - - ret = mbedtls_ssl_cf_hmac( &ssl->transform_in->md_ctx_dec, - add_data, sizeof( add_data ), - ssl->in_msg, ssl->in_msglen, - min_len, max_len, - mac_expect ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cf_hmac", ret ); - return( ret ); - } - - mbedtls_ssl_cf_memcpy_offset( mac_peer, ssl->in_msg, - ssl->in_msglen, - min_len, max_len, - ssl->transform_in->maclen ); - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, ssl->transform_in->maclen ); -#endif - - if( mbedtls_ssl_safer_memcmp( mac_peer, mac_expect, - ssl->transform_in->maclen ) != 0 ) - { -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); -#endif - correct = 0; - } - auth_done++; - } - - /* - * Finally check the correct flag - */ - if( correct == 0 ) - return( MBEDTLS_ERR_SSL_INVALID_MAC ); -#endif /* SSL_SOME_MODES_USE_MAC */ - - /* Make extra sure authentication was performed, exactly once */ - if( auth_done != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - if( ssl->in_msglen == 0 ) - { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 - && ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - /* TLS v1.2 explicitly disallows zero-length messages which are not application data */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - ssl->nb_zero++; - - /* - * Three or more empty messages may be a DoS attack - * (excessive CPU consumption). - */ - if( ssl->nb_zero > 3 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty " - "messages, possible DoS attack" ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - } - else - ssl->nb_zero = 0; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ; /* in_ctr read from peer, not maintained internally */ - } - else -#endif - { - unsigned char i; - for( i = 8; i > ssl_ep_len( ssl ); i-- ) - if( ++ssl->in_ctr[i - 1] != 0 ) - break; - - /* The loop goes to its end iff the counter is wrapping */ - if( i == ssl_ep_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); - - return( 0 ); -} - -#undef MAC_NONE -#undef MAC_PLAINTEXT -#undef MAC_CIPHERTEXT - -#if defined(MBEDTLS_ZLIB_SUPPORT) -/* - * Compression/decompression functions - */ -static int ssl_compress_buf( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *msg_post = ssl->out_msg; - ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf; - size_t len_pre = ssl->out_msglen; - unsigned char *msg_pre = ssl->compress_buf; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) ); - - if( len_pre == 0 ) - return( 0 ); - - memcpy( msg_pre, ssl->out_msg, len_pre ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ", - ssl->out_msglen ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload", - ssl->out_msg, ssl->out_msglen ); - - ssl->transform_out->ctx_deflate.next_in = msg_pre; - ssl->transform_out->ctx_deflate.avail_in = len_pre; - ssl->transform_out->ctx_deflate.next_out = msg_post; - ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_OUT_BUFFER_LEN - bytes_written; - - ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH ); - if( ret != Z_OK ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) ); - return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); - } - - ssl->out_msglen = MBEDTLS_SSL_OUT_BUFFER_LEN - - ssl->transform_out->ctx_deflate.avail_out - bytes_written; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ", - ssl->out_msglen ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload", - ssl->out_msg, ssl->out_msglen ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) ); - - return( 0 ); -} - -static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *msg_post = ssl->in_msg; - ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf; - size_t len_pre = ssl->in_msglen; - unsigned char *msg_pre = ssl->compress_buf; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) ); - - if( len_pre == 0 ) - return( 0 ); - - memcpy( msg_pre, ssl->in_msg, len_pre ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ", - ssl->in_msglen ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload", - ssl->in_msg, ssl->in_msglen ); - - ssl->transform_in->ctx_inflate.next_in = msg_pre; - ssl->transform_in->ctx_inflate.avail_in = len_pre; - ssl->transform_in->ctx_inflate.next_out = msg_post; - ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_IN_BUFFER_LEN - - header_bytes; - - ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH ); - if( ret != Z_OK ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) ); - return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); - } - - ssl->in_msglen = MBEDTLS_SSL_IN_BUFFER_LEN - - ssl->transform_in->ctx_inflate.avail_out - header_bytes; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ", - ssl->in_msglen ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload", - ssl->in_msg, ssl->in_msglen ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_ZLIB_SUPPORT */ - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) -static int ssl_write_hello_request( mbedtls_ssl_context *ssl ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static int ssl_resend_hello_request( mbedtls_ssl_context *ssl ) -{ - /* If renegotiation is not enforced, retransmit until we would reach max - * timeout if we were using the usual handshake doubling scheme */ - if( ssl->conf->renego_max_records < 0 ) - { - uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1; - unsigned char doublings = 1; - - while( ratio != 0 ) - { - ++doublings; - ratio >>= 1; - } - - if( ++ssl->renego_records_seen > doublings ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) ); - return( 0 ); - } - } - - return( ssl_write_hello_request( ssl ) ); -} -#endif -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ - -/* - * Fill the input message buffer by appending data to it. - * The amount of data already fetched is in ssl->in_left. - * - * If we return 0, is it guaranteed that (at least) nb_want bytes are - * available (from this read and/or a previous one). Otherwise, an error code - * is returned (possibly EOF or WANT_READ). - * - * With stream transport (TLS) on success ssl->in_left == nb_want, but - * with datagram transport (DTLS) on success ssl->in_left >= nb_want, - * since we always read a whole datagram at once. - * - * For DTLS, it is up to the caller to set ssl->next_record_offset when - * they're done reading a record. - */ -int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) -{ - int ret; - size_t len; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); - - if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " - "or mbedtls_ssl_set_bio()" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - if( nb_want > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - uint32_t timeout; - - /* Just to be sure */ - if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use " - "mbedtls_ssl_set_timer_cb() for DTLS" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* - * The point is, we need to always read a full datagram at once, so we - * sometimes read more then requested, and handle the additional data. - * It could be the rest of the current record (while fetching the - * header) and/or some other records in the same datagram. - */ - - /* - * Move to the next record in the already read datagram if applicable - */ - if( ssl->next_record_offset != 0 ) - { - if( ssl->in_left < ssl->next_record_offset ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->in_left -= ssl->next_record_offset; - - if( ssl->in_left != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d", - ssl->next_record_offset ) ); - memmove( ssl->in_hdr, - ssl->in_hdr + ssl->next_record_offset, - ssl->in_left ); - } - - ssl->next_record_offset = 0; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", - ssl->in_left, nb_want ) ); - - /* - * Done if we already have enough data. - */ - if( nb_want <= ssl->in_left) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); - return( 0 ); - } - - /* - * A record can't be split across datagrams. If we need to read but - * are not at the beginning of a new record, the caller did something - * wrong. - */ - if( ssl->in_left != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * Don't even try to read if time's out already. - * This avoids by-passing the timer when repeatedly receiving messages - * that will end up being dropped. - */ - if( ssl_check_timer( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) ); - ret = MBEDTLS_ERR_SSL_TIMEOUT; - } - else - { - len = MBEDTLS_SSL_IN_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf ); - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - timeout = ssl->handshake->retransmit_timeout; - else - timeout = ssl->conf->read_timeout; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) ); - - if( ssl->f_recv_timeout != NULL ) - ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len, - timeout ); - else - ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len ); - - MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); - - if( ret == 0 ) - return( MBEDTLS_ERR_SSL_CONN_EOF ); - } - - if( ret == MBEDTLS_ERR_SSL_TIMEOUT ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) ); - ssl_set_timer( ssl, 0 ); - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - { - if( ssl_double_retransmit_timeout( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) ); - return( MBEDTLS_ERR_SSL_TIMEOUT ); - } - - if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); - return( ret ); - } - - return( MBEDTLS_ERR_SSL_WANT_READ ); - } -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) - { - if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret ); - return( ret ); - } - - return( MBEDTLS_ERR_SSL_WANT_READ ); - } -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ - } - - if( ret < 0 ) - return( ret ); - - ssl->in_left = ret; - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", - ssl->in_left, nb_want ) ); - - while( ssl->in_left < nb_want ) - { - len = nb_want - ssl->in_left; - - if( ssl_check_timer( ssl ) != 0 ) - ret = MBEDTLS_ERR_SSL_TIMEOUT; - else - { - if( ssl->f_recv_timeout != NULL ) - { - ret = ssl->f_recv_timeout( ssl->p_bio, - ssl->in_hdr + ssl->in_left, len, - ssl->conf->read_timeout ); - } - else - { - ret = ssl->f_recv( ssl->p_bio, - ssl->in_hdr + ssl->in_left, len ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", - ssl->in_left, nb_want ) ); - MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); - - if( ret == 0 ) - return( MBEDTLS_ERR_SSL_CONN_EOF ); - - if( ret < 0 ) - return( ret ); - - if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "f_recv returned %d bytes but only %lu were requested", - ret, (unsigned long)len ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->in_left += ret; - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); - - return( 0 ); -} - -/* - * Flush any data not yet written - */ -int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *buf; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); - - if( ssl->f_send == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " - "or mbedtls_ssl_set_bio()" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* Avoid incrementing counter if data is flushed */ - if( ssl->out_left == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); - return( 0 ); - } - - while( ssl->out_left > 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d", - mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); - - buf = ssl->out_hdr - ssl->out_left; - ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); - - MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret ); - - if( ret <= 0 ) - return( ret ); - - if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "f_send returned %d bytes but only %lu bytes were sent", - ret, (unsigned long)ssl->out_left ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->out_left -= ret; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->out_hdr = ssl->out_buf; - } - else -#endif - { - ssl->out_hdr = ssl->out_buf + 8; - } - ssl_update_out_pointers( ssl, ssl->transform_out ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); - - return( 0 ); -} - -/* - * Functions to handle the DTLS retransmission state machine - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) -/* - * Append current handshake message to current outgoing flight - */ -static int ssl_flight_append( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_flight_item *msg; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) ); - MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight", - ssl->out_msg, ssl->out_msglen ); - - /* Allocate space for current message */ - if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", - sizeof( mbedtls_ssl_flight_item ) ) ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) ); - mbedtls_free( msg ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - /* Copy current handshake message with headers */ - memcpy( msg->p, ssl->out_msg, ssl->out_msglen ); - msg->len = ssl->out_msglen; - msg->type = ssl->out_msgtype; - msg->next = NULL; - - /* Append to the current flight */ - if( ssl->handshake->flight == NULL ) - ssl->handshake->flight = msg; - else - { - mbedtls_ssl_flight_item *cur = ssl->handshake->flight; - while( cur->next != NULL ) - cur = cur->next; - cur->next = msg; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) ); - return( 0 ); -} - -/* - * Free the current flight of handshake messages - */ -static void ssl_flight_free( mbedtls_ssl_flight_item *flight ) -{ - mbedtls_ssl_flight_item *cur = flight; - mbedtls_ssl_flight_item *next; - - while( cur != NULL ) - { - next = cur->next; - - mbedtls_free( cur->p ); - mbedtls_free( cur ); - - cur = next; - } -} - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ); -#endif - -/* - * Swap transform_out and out_ctr with the alternative ones - */ -static int ssl_swap_epochs( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_transform *tmp_transform; - unsigned char tmp_out_ctr[8]; -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - int ret; -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - - if( ssl->transform_out == ssl->handshake->alt_transform_out ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) ); - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) ); - - /* Swap transforms */ - tmp_transform = ssl->transform_out; - ssl->transform_out = ssl->handshake->alt_transform_out; - ssl->handshake->alt_transform_out = tmp_transform; - - /* Swap epoch + sequence_number */ - memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 ); - memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 ); - memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); - - /* Adjust to the newly activated transform */ - ssl_update_out_pointers( ssl, ssl->transform_out ); - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_activate != NULL ) - { - if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - - return( 0 ); -} - -/* - * Retransmit the current flight of messages. - */ -int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) ); - - ret = mbedtls_ssl_flight_transmit( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) ); - - return( ret ); -} - -/* - * Transmit or retransmit the current flight of messages. - * - * Need to remember the current message in case flush_output returns - * WANT_WRITE, causing us to exit this function and come back later. - * This function must be called until state is no longer SENDING. - */ -int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) -{ - int ret; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) ); - - if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) ); - - ssl->handshake->cur_msg = ssl->handshake->flight; - ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; - if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) - return( ret ); - - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; - } - - while( ssl->handshake->cur_msg != NULL ) - { - size_t max_frag_len; - const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg; - - int const is_finished = - ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && - cur->p[0] == MBEDTLS_SSL_HS_FINISHED ); - - uint8_t const force_flush = ssl->disable_datagram_packing == 1 ? - SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH; - - /* Swap epochs before sending Finished: we can't do it after - * sending ChangeCipherSpec, in case write returns WANT_READ. - * Must be done before copying, may change out_msg pointer */ - if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) ); - if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) - return( ret ); - } - - ret = ssl_get_remaining_payload_in_datagram( ssl ); - if( ret < 0 ) - return( ret ); - max_frag_len = (size_t) ret; - - /* CCS is copied as is, while HS messages may need fragmentation */ - if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - if( max_frag_len == 0 ) - { - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - continue; - } - - memcpy( ssl->out_msg, cur->p, cur->len ); - ssl->out_msglen = cur->len; - ssl->out_msgtype = cur->type; - - /* Update position inside current message */ - ssl->handshake->cur_msg_p += cur->len; - } - else - { - const unsigned char * const p = ssl->handshake->cur_msg_p; - const size_t hs_len = cur->len - 12; - const size_t frag_off = p - ( cur->p + 12 ); - const size_t rem_len = hs_len - frag_off; - size_t cur_hs_frag_len, max_hs_frag_len; - - if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) ) - { - if( is_finished ) - { - if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) - return( ret ); - } - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - continue; - } - max_hs_frag_len = max_frag_len - 12; - - cur_hs_frag_len = rem_len > max_hs_frag_len ? - max_hs_frag_len : rem_len; - - if( frag_off == 0 && cur_hs_frag_len != hs_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)", - (unsigned) cur_hs_frag_len, - (unsigned) max_hs_frag_len ) ); - } - - /* Messages are stored with handshake headers as if not fragmented, - * copy beginning of headers then fill fragmentation fields. - * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */ - memcpy( ssl->out_msg, cur->p, 6 ); - - ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff ); - ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff ); - ssl->out_msg[8] = ( ( frag_off ) & 0xff ); - - ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff ); - ssl->out_msg[10] = ( ( cur_hs_frag_len >> 8 ) & 0xff ); - ssl->out_msg[11] = ( ( cur_hs_frag_len ) & 0xff ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 ); - - /* Copy the handshake message content and set records fields */ - memcpy( ssl->out_msg + 12, p, cur_hs_frag_len ); - ssl->out_msglen = cur_hs_frag_len + 12; - ssl->out_msgtype = cur->type; - - /* Update position inside current message */ - ssl->handshake->cur_msg_p += cur_hs_frag_len; - } - - /* If done with the current message move to the next one if any */ - if( ssl->handshake->cur_msg_p >= cur->p + cur->len ) - { - if( cur->next != NULL ) - { - ssl->handshake->cur_msg = cur->next; - ssl->handshake->cur_msg_p = cur->next->p + 12; - } - else - { - ssl->handshake->cur_msg = NULL; - ssl->handshake->cur_msg_p = NULL; - } - } - - /* Actually send the message out */ - if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); - return( ret ); - } - } - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - /* Update state and set timer */ - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - else - { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; - ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) ); - - return( 0 ); -} - -/* - * To be called when the last message of an incoming flight is received. - */ -void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ) -{ - /* We won't need to resend that one any more */ - ssl_flight_free( ssl->handshake->flight ); - ssl->handshake->flight = NULL; - ssl->handshake->cur_msg = NULL; - - /* The next incoming flight will start with this msg_seq */ - ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; - - /* We don't want to remember CCS's across flight boundaries. */ - ssl->handshake->buffering.seen_ccs = 0; - - /* Clear future message buffering structure. */ - ssl_buffering_free( ssl ); - - /* Cancel timer */ - ssl_set_timer( ssl, 0 ); - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) - { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - } - else - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; -} - -/* - * To be called when the last message of an outgoing flight is send. - */ -void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ) -{ - ssl_reset_retransmit_timeout( ssl ); - ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) - { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - } - else - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -/* - * Handshake layer functions - */ - -/* - * Write (DTLS: or queue) current handshake (including CCS) message. - * - * - fill in handshake headers - * - update handshake checksum - * - DTLS: save message for resending - * - then pass to the record layer - * - * DTLS: except for HelloRequest, messages are only queued, and will only be - * actually sent when calling flight_transmit() or resend(). - * - * Inputs: - * - ssl->out_msglen: 4 + actual handshake message len - * (4 is the size of handshake headers for TLS) - * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc) - * - ssl->out_msg + 4: the handshake message body - * - * Outputs, ie state before passing to flight_append() or write_record(): - * - ssl->out_msglen: the length of the record contents - * (including handshake headers but excluding record headers) - * - ssl->out_msg: the record contents (handshake headers + content) - */ -int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) -{ - int ret; - const size_t hs_len = ssl->out_msglen - 4; - const unsigned char hs_type = ssl->out_msg[0]; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) ); - - /* - * Sanity checks - */ - if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - /* In SSLv3, the client might send a NoCertificate alert. */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) - if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && - ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ) -#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - - /* Whenever we send anything different from a - * HelloRequest we should be in a handshake - double check. */ - if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) && - ssl->handshake == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake != NULL && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } -#endif - - /* Double-check that we did not exceed the bounds - * of the outgoing record buffer. - * This should never fail as the various message - * writing functions must obey the bounds of the - * outgoing record buffer, but better be safe. - * - * Note: We deliberately do not check for the MTU or MFL here. - */ - if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: " - "size %u, maximum %u", - (unsigned) ssl->out_msglen, - (unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * Fill handshake headers - */ - if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) - { - ssl->out_msg[1] = (unsigned char)( hs_len >> 16 ); - ssl->out_msg[2] = (unsigned char)( hs_len >> 8 ); - ssl->out_msg[3] = (unsigned char)( hs_len ); - - /* - * DTLS has additional fields in the Handshake layer, - * between the length field and the actual payload: - * uint16 message_seq; - * uint24 fragment_offset; - * uint24 fragment_length; - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* Make room for the additional DTLS fields */ - if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: " - "size %u, maximum %u", - (unsigned) ( hs_len ), - (unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len ); - ssl->out_msglen += 8; - - /* Write message_seq and update it, except for HelloRequest */ - if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) - { - ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF; - ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF; - ++( ssl->handshake->out_msg_seq ); - } - else - { - ssl->out_msg[4] = 0; - ssl->out_msg[5] = 0; - } - - /* Handshake hashes are computed without fragmentation, - * so set frag_offset = 0 and frag_len = hs_len for now */ - memset( ssl->out_msg + 6, 0x00, 3 ); - memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* Update running hashes of handshake messages seen */ - if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) - ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen ); - } - - /* Either send now, or just save to be sent (and resent) later */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) ) - { - if( ( ret = ssl_flight_append( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret ); - return( ret ); - } - } - else -#endif - { - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret ); - return( ret ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) ); - - return( 0 ); -} - -/* - * Record layer functions - */ - -/* - * Write current record. - * - * Uses: - * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS) - * - ssl->out_msglen: length of the record content (excl headers) - * - ssl->out_msg: record content - */ -int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) -{ - int ret, done = 0; - size_t len = ssl->out_msglen; - uint8_t flush = force_flush; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->transform_out != NULL && - ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) - { - if( ( ret = ssl_compress_buf( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret ); - return( ret ); - } - - len = ssl->out_msglen; - } -#endif /*MBEDTLS_ZLIB_SUPPORT */ - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_write != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) ); - - ret = mbedtls_ssl_hw_record_write( ssl ); - if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - if( ret == 0 ) - done = 1; - } -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - if( !done ) - { - unsigned i; - size_t protected_record_size; - - ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, ssl->out_hdr + 1 ); - - memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 ); - ssl->out_len[0] = (unsigned char)( len >> 8 ); - ssl->out_len[1] = (unsigned char)( len ); - - if( ssl->transform_out != NULL ) - { - if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); - return( ret ); - } - - len = ssl->out_msglen; - ssl->out_len[0] = (unsigned char)( len >> 8 ); - ssl->out_len[1] = (unsigned char)( len ); - } - - protected_record_size = len + mbedtls_ssl_hdr_len( ssl ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* In case of DTLS, double-check that we don't exceed - * the remaining space in the datagram. */ - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ret = ssl_get_remaining_space_in_datagram( ssl ); - if( ret < 0 ) - return( ret ); - - if( protected_record_size > (size_t) ret ) - { - /* Should never happen */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " - "version = [%d:%d], msglen = %d", - ssl->out_hdr[0], ssl->out_hdr[1], - ssl->out_hdr[2], len ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", - ssl->out_hdr, protected_record_size ); - - ssl->out_left += protected_record_size; - ssl->out_hdr += protected_record_size; - ssl_update_out_pointers( ssl, ssl->transform_out ); - - for( i = 8; i > ssl_ep_len( ssl ); i-- ) - if( ++ssl->cur_out_ctr[i - 1] != 0 ) - break; - - /* The loop goes to its end iff the counter is wrapping */ - if( i == ssl_ep_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - flush == SSL_DONT_FORCE_FLUSH ) - { - size_t remaining; - ret = ssl_get_remaining_payload_in_datagram( ssl ); - if( ret < 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram", - ret ); - return( ret ); - } - - remaining = (size_t) ret; - if( remaining == 0 ) - { - flush = SSL_FORCE_FLUSH; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if( ( flush == SSL_FORCE_FLUSH ) && - ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl ) -{ - if( ssl->in_msglen < ssl->in_hslen || - memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || - memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 ) - { - return( 1 ); - } - return( 0 ); -} - -static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl ) -{ - return( ( ssl->in_msg[9] << 16 ) | - ( ssl->in_msg[10] << 8 ) | - ssl->in_msg[11] ); -} - -static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl ) -{ - return( ( ssl->in_msg[6] << 16 ) | - ( ssl->in_msg[7] << 8 ) | - ssl->in_msg[8] ); -} - -static int ssl_check_hs_header( mbedtls_ssl_context const *ssl ) -{ - uint32_t msg_len, frag_off, frag_len; - - msg_len = ssl_get_hs_total_len( ssl ); - frag_off = ssl_get_hs_frag_off( ssl ); - frag_len = ssl_get_hs_frag_len( ssl ); - - if( frag_off > msg_len ) - return( -1 ); - - if( frag_len > msg_len - frag_off ) - return( -1 ); - - if( frag_len + 12 > ssl->in_msglen ) - return( -1 ); - - return( 0 ); -} - -/* - * Mark bits in bitmask (used for DTLS HS reassembly) - */ -static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len ) -{ - unsigned int start_bits, end_bits; - - start_bits = 8 - ( offset % 8 ); - if( start_bits != 8 ) - { - size_t first_byte_idx = offset / 8; - - /* Special case */ - if( len <= start_bits ) - { - for( ; len != 0; len-- ) - mask[first_byte_idx] |= 1 << ( start_bits - len ); - - /* Avoid potential issues with offset or len becoming invalid */ - return; - } - - offset += start_bits; /* Now offset % 8 == 0 */ - len -= start_bits; - - for( ; start_bits != 0; start_bits-- ) - mask[first_byte_idx] |= 1 << ( start_bits - 1 ); - } - - end_bits = len % 8; - if( end_bits != 0 ) - { - size_t last_byte_idx = ( offset + len ) / 8; - - len -= end_bits; /* Now len % 8 == 0 */ - - for( ; end_bits != 0; end_bits-- ) - mask[last_byte_idx] |= 1 << ( 8 - end_bits ); - } - - memset( mask + offset / 8, 0xFF, len / 8 ); -} - -/* - * Check that bitmask is full - */ -static int ssl_bitmask_check( unsigned char *mask, size_t len ) -{ - size_t i; - - for( i = 0; i < len / 8; i++ ) - if( mask[i] != 0xFF ) - return( -1 ); - - for( i = 0; i < len % 8; i++ ) - if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 ) - return( -1 ); - - return( 0 ); -} - -/* msg_len does not include the handshake header */ -static size_t ssl_get_reassembly_buffer_size( size_t msg_len, - unsigned add_bitmap ) -{ - size_t alloc_len; - - alloc_len = 12; /* Handshake header */ - alloc_len += msg_len; /* Content buffer */ - - if( add_bitmap ) - alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */ - - return( alloc_len ); -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ) -{ - return( ( ssl->in_msg[1] << 16 ) | - ( ssl->in_msg[2] << 8 ) | - ssl->in_msg[3] ); -} - -int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) -{ - if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d", - ssl->in_msglen ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen =" - " %d, type = %d, hslen = %d", - ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - int ret; - unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; - - if( ssl_check_hs_header( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - if( ssl->handshake != NULL && - ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && - recv_msg_seq != ssl->handshake->in_msg_seq ) || - ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && - ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) - { - if( recv_msg_seq > ssl->handshake->in_msg_seq ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)", - recv_msg_seq, - ssl->handshake->in_msg_seq ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } - - /* Retransmit only on last message from previous flight, to avoid - * too many retransmissions. - * Besides, No sane server ever retransmits HelloVerifyRequest */ - if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 && - ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, " - "message_seq = %d, start_of_flight = %d", - recv_msg_seq, - ssl->handshake->in_flight_start_seq ) ); - - if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); - return( ret ); - } - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: " - "message_seq = %d, expected = %d", - recv_msg_seq, - ssl->handshake->in_msg_seq ) ); - } - - return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); - } - /* Wait until message completion to increment in_msg_seq */ - - /* Message reassembly is handled alongside buffering of future - * messages; the commonality is that both handshake fragments and - * future messages cannot be forwarded immediately to the - * handshake logic layer. */ - if( ssl_hs_is_proper_fragment( ssl ) == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - /* With TLS we don't handle fragmentation (for now) */ - if( ssl->in_msglen < ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } - - return( 0 ); -} - -void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) - { - ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); - } - - /* Handshake message is complete, increment counter */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake != NULL ) - { - unsigned offset; - mbedtls_ssl_hs_buffer *hs_buf; - - /* Increment handshake sequence number */ - hs->in_msg_seq++; - - /* - * Clear up handshake buffering and reassembly structure. - */ - - /* Free first entry */ - ssl_buffering_free_slot( ssl, 0 ); - - /* Shift all other entries */ - for( offset = 0, hs_buf = &hs->buffering.hs[0]; - offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; - offset++, hs_buf++ ) - { - *hs_buf = *(hs_buf + 1); - } - - /* Create a fresh last entry */ - memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); - } -#endif -} - -/* - * DTLS anti-replay: RFC 6347 4.1.2.6 - * - * in_window is a field of bits numbered from 0 (lsb) to 63 (msb). - * Bit n is set iff record number in_window_top - n has been seen. - * - * Usually, in_window_top is the last record number seen and the lsb of - * in_window is set. The only exception is the initial state (record number 0 - * not seen yet). - */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ) -{ - ssl->in_window_top = 0; - ssl->in_window = 0; -} - -static inline uint64_t ssl_load_six_bytes( unsigned char *buf ) -{ - return( ( (uint64_t) buf[0] << 40 ) | - ( (uint64_t) buf[1] << 32 ) | - ( (uint64_t) buf[2] << 24 ) | - ( (uint64_t) buf[3] << 16 ) | - ( (uint64_t) buf[4] << 8 ) | - ( (uint64_t) buf[5] ) ); -} - -/* - * Return 0 if sequence number is acceptable, -1 otherwise - */ -int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ) -{ - uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); - uint64_t bit; - - if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) - return( 0 ); - - if( rec_seqnum > ssl->in_window_top ) - return( 0 ); - - bit = ssl->in_window_top - rec_seqnum; - - if( bit >= 64 ) - return( -1 ); - - if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 ) - return( -1 ); - - return( 0 ); -} - -/* - * Update replay window on new validated record - */ -void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) -{ - uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); - - if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) - return; - - if( rec_seqnum > ssl->in_window_top ) - { - /* Update window_top and the contents of the window */ - uint64_t shift = rec_seqnum - ssl->in_window_top; - - if( shift >= 64 ) - ssl->in_window = 1; - else - { - ssl->in_window <<= shift; - ssl->in_window |= 1; - } - - ssl->in_window_top = rec_seqnum; - } - else - { - /* Mark that number as seen in the current window */ - uint64_t bit = ssl->in_window_top - rec_seqnum; - - if( bit < 64 ) /* Always true, but be extra sure */ - ssl->in_window |= (uint64_t) 1 << bit; - } -} -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) -/* Forward declaration */ -static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); - -/* - * Without any SSL context, check if a datagram looks like a ClientHello with - * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message. - * Both input and output include full DTLS headers. - * - * - if cookie is valid, return 0 - * - if ClientHello looks superficially valid but cookie is not, - * fill obuf and set olen, then - * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED - * - otherwise return a specific error code - */ -static int ssl_check_dtls_clihlo_cookie( - mbedtls_ssl_cookie_write_t *f_cookie_write, - mbedtls_ssl_cookie_check_t *f_cookie_check, - void *p_cookie, - const unsigned char *cli_id, size_t cli_id_len, - const unsigned char *in, size_t in_len, - unsigned char *obuf, size_t buf_len, size_t *olen ) -{ - size_t sid_len, cookie_len; - unsigned char *p; - - if( f_cookie_write == NULL || f_cookie_check == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - /* - * Structure of ClientHello with record and handshake headers, - * and expected values. We don't need to check a lot, more checks will be - * done when actually parsing the ClientHello - skipping those checks - * avoids code duplication and does not make cookie forging any easier. - * - * 0-0 ContentType type; copied, must be handshake - * 1-2 ProtocolVersion version; copied - * 3-4 uint16 epoch; copied, must be 0 - * 5-10 uint48 sequence_number; copied - * 11-12 uint16 length; (ignored) - * - * 13-13 HandshakeType msg_type; (ignored) - * 14-16 uint24 length; (ignored) - * 17-18 uint16 message_seq; copied - * 19-21 uint24 fragment_offset; copied, must be 0 - * 22-24 uint24 fragment_length; (ignored) - * - * 25-26 ProtocolVersion client_version; (ignored) - * 27-58 Random random; (ignored) - * 59-xx SessionID session_id; 1 byte len + sid_len content - * 60+ opaque cookie<0..2^8-1>; 1 byte len + content - * ... - * - * Minimum length is 61 bytes. - */ - if( in_len < 61 || - in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || - in[3] != 0 || in[4] != 0 || - in[19] != 0 || in[20] != 0 || in[21] != 0 ) - { - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - sid_len = in[59]; - if( sid_len > in_len - 61 ) - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - - cookie_len = in[60 + sid_len]; - if( cookie_len > in_len - 60 ) - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - - if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len, - cli_id, cli_id_len ) == 0 ) - { - /* Valid cookie */ - return( 0 ); - } - - /* - * If we get here, we've got an invalid cookie, let's prepare HVR. - * - * 0-0 ContentType type; copied - * 1-2 ProtocolVersion version; copied - * 3-4 uint16 epoch; copied - * 5-10 uint48 sequence_number; copied - * 11-12 uint16 length; olen - 13 - * - * 13-13 HandshakeType msg_type; hello_verify_request - * 14-16 uint24 length; olen - 25 - * 17-18 uint16 message_seq; copied - * 19-21 uint24 fragment_offset; copied - * 22-24 uint24 fragment_length; olen - 25 - * - * 25-26 ProtocolVersion server_version; 0xfe 0xff - * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie - * - * Minimum length is 28. - */ - if( buf_len < 28 ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - /* Copy most fields and adapt others */ - memcpy( obuf, in, 25 ); - obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; - obuf[25] = 0xfe; - obuf[26] = 0xff; - - /* Generate and write actual cookie */ - p = obuf + 28; - if( f_cookie_write( p_cookie, - &p, obuf + buf_len, cli_id, cli_id_len ) != 0 ) - { - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - *olen = p - obuf; - - /* Go back and fill length fields */ - obuf[27] = (unsigned char)( *olen - 28 ); - - obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 ); - obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 ); - obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) ); - - obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 ); - obuf[12] = (unsigned char)( ( *olen - 13 ) ); - - return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); -} - -/* - * Handle possible client reconnect with the same UDP quadruplet - * (RFC 6347 Section 4.2.8). - * - * Called by ssl_parse_record_header() in case we receive an epoch 0 record - * that looks like a ClientHello. - * - * - if the input looks like a ClientHello without cookies, - * send back HelloVerifyRequest, then - * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED - * - if the input looks like a ClientHello with a valid cookie, - * reset the session of the current context, and - * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT - * - if anything goes wrong, return a specific error code - * - * mbedtls_ssl_read_record() will ignore the record if anything else than - * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function - * cannot not return 0. - */ -static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t len; - - ret = ssl_check_dtls_clihlo_cookie( - ssl->conf->f_cookie_write, - ssl->conf->f_cookie_check, - ssl->conf->p_cookie, - ssl->cli_id, ssl->cli_id_len, - ssl->in_buf, ssl->in_left, - ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len ); - - MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret ); - - if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) - { - int send_ret; - MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) ); - MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", - ssl->out_buf, len ); - /* Don't check write errors as we can't do anything here. - * If the error is permanent we'll catch it later, - * if it's not, then hopefully it'll work next time. */ - send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len ); - MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret ); - (void) send_ret; - - return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); - } - - if( ret == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) ); - if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); - return( ret ); - } - - return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT ); - } - - return( ret ); -} -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - -/* - * ContentType type; - * ProtocolVersion version; - * uint16 epoch; // DTLS only - * uint48 sequence_number; // DTLS only - * uint16 length; - * - * Return 0 if header looks sane (and, for DTLS, the record is expected) - * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad, - * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected. - * - * With DTLS, mbedtls_ssl_read_record() will: - * 1. proceed with the record if this function returns 0 - * 2. drop only the current record if this function returns UNEXPECTED_RECORD - * 3. return CLIENT_RECONNECT if this function return that value - * 4. drop the whole datagram if this function returns anything else. - * Point 2 is needed when the peer is resending, and we have already received - * the first record from a datagram but are still waiting for the others. - */ -static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) -{ - int major_ver, minor_ver; - - MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) ); - - ssl->in_msgtype = ssl->in_hdr[0]; - ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; - mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, " - "version = [%d:%d], msglen = %d", - ssl->in_msgtype, - major_ver, minor_ver, ssl->in_msglen ) ); - - /* Check record type */ - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT && - ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && - ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* Silently ignore invalid DTLS records as recommended by RFC 6347 - * Section 4.1.2.7 */ - if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - /* Check version */ - if( major_ver != ssl->major_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - if( minor_ver > ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - /* Check length against the size of our buffer */ - if( ssl->in_msglen > MBEDTLS_SSL_IN_BUFFER_LEN - - (size_t)( ssl->in_msg - ssl->in_buf ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - /* - * DTLS-related tests. - * Check epoch before checking length constraint because - * the latter varies with the epoch. E.g., if a ChangeCipherSpec - * message gets duplicated before the corresponding Finished message, - * the second ChangeCipherSpec should be discarded because it belongs - * to an old epoch, but not because its length is shorter than - * the minimum record length for packets using the new record transform. - * Note that these two kinds of failures are handled differently, - * as an unexpected record is silently skipped but an invalid - * record leads to the entire datagram being dropped. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1]; - - /* Check epoch (and sequence number) with DTLS */ - if( rec_epoch != ssl->in_epoch ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: " - "expected %d, received %d", - ssl->in_epoch, rec_epoch ) ); - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) - /* - * Check for an epoch 0 ClientHello. We can't use in_msg here to - * access the first byte of record content (handshake type), as we - * have an active transform (possibly iv_len != 0), so use the - * fact that the record header len is 13 instead. - */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && - rec_epoch == 0 && - ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_left > 13 && - ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " - "from the same port" ) ); - return( ssl_handle_possible_reconnect( ssl ) ); - } - else -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - { - /* Consider buffering the record. */ - if( rec_epoch == (unsigned int) ssl->in_epoch + 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } - - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } - } - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - /* Replay detection only works for the current epoch */ - if( rec_epoch == ssl->in_epoch && - mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } -#endif - - /* Drop unexpected ApplicationData records, - * except at the beginning of renegotiations */ - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && - ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->state == MBEDTLS_SSL_SERVER_HELLO ) -#endif - ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - - /* Check length against bounds of the current transform and version */ - if( ssl->transform_in == NULL ) - { - if( ssl->in_msglen < 1 || - ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - } - else - { - if( ssl->in_msglen < ssl->transform_in->minlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && - ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * TLS encrypted messages can have up to 256 bytes of padding - */ - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 && - ssl->in_msglen > ssl->transform_in->minlen + - MBEDTLS_SSL_IN_CONTENT_LEN + 256 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } -#endif - } - - return( 0 ); -} - -/* - * If applicable, decrypt (and decompress) record content - */ -static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) -{ - int ret, done = 0; - - MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network", - ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ); - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_read != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) ); - - ret = mbedtls_ssl_hw_record_read( ssl ); - if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - if( ret == 0 ) - done = 1; - } -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - if( !done && ssl->transform_in != NULL ) - { - if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt", - ssl->in_msg, ssl->in_msglen ); - - if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - } - -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->transform_in != NULL && - ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) - { - if( ( ret = ssl_decompress_buf( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_ZLIB_SUPPORT */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - mbedtls_ssl_dtls_replay_update( ssl ); - } -#endif - - return( 0 ); -} - -static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ); - -/* - * Read a record. - * - * Silently ignore non-fatal alert (and for DTLS, invalid records as well, - * RFC 6347 4.1.2.7) and continue reading until a valid record is found. - * - */ - -/* Helper functions for mbedtls_ssl_read_record(). */ -static int ssl_consume_current_message( mbedtls_ssl_context *ssl ); -static int ssl_get_next_record( mbedtls_ssl_context *ssl ); -static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, - unsigned update_hs_digest ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) ); - - if( ssl->keep_current_message == 0 ) - { - do { - - ret = ssl_consume_current_message( ssl ); - if( ret != 0 ) - return( ret ); - - if( ssl_record_is_in_progress( ssl ) == 0 ) - { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - int have_buffered = 0; - - /* We only check for buffered messages if the - * current datagram is fully consumed. */ - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl_next_record_is_in_datagram( ssl ) == 0 ) - { - if( ssl_load_buffered_message( ssl ) == 0 ) - have_buffered = 1; - } - - if( have_buffered == 0 ) -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - ret = ssl_get_next_record( ssl ); - if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ) - continue; - - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret ); - return( ret ); - } - } - } - - ret = mbedtls_ssl_handle_message_type( ssl ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) - { - /* Buffer future message */ - ret = ssl_buffer_message( ssl ); - if( ret != 0 ) - return( ret ); - - ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - } while( MBEDTLS_ERR_SSL_NON_FATAL == ret || - MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret ); - - if( 0 != ret ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); - return( ret ); - } - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - update_hs_digest == 1 ) - { - mbedtls_ssl_update_handshake_status( ssl ); - } - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) ); - ssl->keep_current_message = 0; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ) -{ - if( ssl->in_left > ssl->next_record_offset ) - return( 1 ); - - return( 0 ); -} - -static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - mbedtls_ssl_hs_buffer * hs_buf; - int ret = 0; - - if( hs == NULL ) - return( -1 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) ); - - if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC || - ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) - { - /* Check if we have seen a ChangeCipherSpec before. - * If yes, synthesize a CCS record. */ - if( !hs->buffering.seen_ccs ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) ); - ret = -1; - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) ); - ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; - ssl->in_msglen = 1; - ssl->in_msg[0] = 1; - - /* As long as they are equal, the exact value doesn't matter. */ - ssl->in_left = 0; - ssl->next_record_offset = 0; - - hs->buffering.seen_ccs = 0; - goto exit; - } - -#if defined(MBEDTLS_DEBUG_C) - /* Debug only */ - { - unsigned offset; - for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) - { - hs_buf = &hs->buffering.hs[offset]; - if( hs_buf->is_valid == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.", - hs->in_msg_seq + offset, - hs_buf->is_complete ? "fully" : "partially" ) ); - } - } - } -#endif /* MBEDTLS_DEBUG_C */ - - /* Check if we have buffered and/or fully reassembled the - * next handshake message. */ - hs_buf = &hs->buffering.hs[0]; - if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) ) - { - /* Synthesize a record containing the buffered HS message. */ - size_t msg_len = ( hs_buf->data[1] << 16 ) | - ( hs_buf->data[2] << 8 ) | - hs_buf->data[3]; - - /* Double-check that we haven't accidentally buffered - * a message that doesn't fit into the input buffer. */ - if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)", - hs_buf->data, msg_len + 12 ); - - ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->in_hslen = msg_len + 12; - ssl->in_msglen = msg_len + 12; - memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen ); - - ret = 0; - goto exit; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered", - hs->in_msg_seq ) ); - } - - ret = -1; - -exit: - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) ); - return( ret ); -} - -static int ssl_buffer_make_space( mbedtls_ssl_context *ssl, - size_t desired ) -{ - int offset; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available", - (unsigned) desired ) ); - - /* Get rid of future records epoch first, if such exist. */ - ssl_free_buffered_record( ssl ); - - /* Check if we have enough space available now. */ - if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) ); - return( 0 ); - } - - /* We don't have enough space to buffer the next expected handshake - * message. Remove buffers used for future messages to gain space, - * starting with the most distant one. */ - for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1; - offset >= 0; offset-- ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message", - offset ) ); - - ssl_buffering_free_slot( ssl, (uint8_t) offset ); - - /* Check if we have enough space available now. */ - if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) ); - return( 0 ); - } - } - - return( -1 ); -} - -static int ssl_buffer_message( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if( hs == NULL ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) ); - - switch( ssl->in_msgtype ) - { - case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) ); - - hs->buffering.seen_ccs = 1; - break; - - case MBEDTLS_SSL_MSG_HANDSHAKE: - { - unsigned recv_msg_seq_offset; - unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; - mbedtls_ssl_hs_buffer *hs_buf; - size_t msg_len = ssl->in_hslen - 12; - - /* We should never receive an old handshake - * message - double-check nonetheless. */ - if( recv_msg_seq < ssl->handshake->in_msg_seq ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq; - if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS ) - { - /* Silently ignore -- message too far in the future */ - MBEDTLS_SSL_DEBUG_MSG( 2, - ( "Ignore future HS message with sequence number %u, " - "buffering window %u - %u", - recv_msg_seq, ssl->handshake->in_msg_seq, - ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) ); - - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ", - recv_msg_seq, recv_msg_seq_offset ) ); - - hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ]; - - /* Check if the buffering for this seq nr has already commenced. */ - if( !hs_buf->is_valid ) - { - size_t reassembly_buf_sz; - - hs_buf->is_fragmented = - ( ssl_hs_is_proper_fragment( ssl ) == 1 ); - - /* We copy the message back into the input buffer - * after reassembly, so check that it's not too large. - * This is an implementation-specific limitation - * and not one from the standard, hence it is not - * checked in ssl_check_hs_header(). */ - if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - /* Ignore message */ - goto exit; - } - - /* Check if we have enough space to buffer the message. */ - if( hs->buffering.total_bytes_buffered > - MBEDTLS_SSL_DTLS_MAX_BUFFERING ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len, - hs_buf->is_fragmented ); - - if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - if( recv_msg_seq_offset > 0 ) - { - /* If we can't buffer a future message because - * of space limitations -- ignore. */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n", - (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - goto exit; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- attempt to make space by freeing buffered future messages\n", - (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - } - - if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %u (%u with bitmap) would exceed the compile-time limit %u (already %u bytes buffered) -- fail\n", - (unsigned) msg_len, - (unsigned) reassembly_buf_sz, - MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - goto exit; - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d", - msg_len ) ); - - hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz ); - if( hs_buf->data == NULL ) - { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - hs_buf->data_len = reassembly_buf_sz; - - /* Prepare final header: copy msg_type, length and message_seq, - * then add standardised fragment_offset and fragment_length */ - memcpy( hs_buf->data, ssl->in_msg, 6 ); - memset( hs_buf->data + 6, 0, 3 ); - memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 ); - - hs_buf->is_valid = 1; - - hs->buffering.total_bytes_buffered += reassembly_buf_sz; - } - else - { - /* Make sure msg_type and length are consistent */ - if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) ); - /* Ignore */ - goto exit; - } - } - - if( !hs_buf->is_complete ) - { - size_t frag_len, frag_off; - unsigned char * const msg = hs_buf->data + 12; - - /* - * Check and copy current fragment - */ - - /* Validation of header fields already done in - * mbedtls_ssl_prepare_handshake_record(). */ - frag_off = ssl_get_hs_frag_off( ssl ); - frag_len = ssl_get_hs_frag_len( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d", - frag_off, frag_len ) ); - memcpy( msg + frag_off, ssl->in_msg + 12, frag_len ); - - if( hs_buf->is_fragmented ) - { - unsigned char * const bitmask = msg + msg_len; - ssl_bitmask_set( bitmask, frag_off, frag_len ); - hs_buf->is_complete = ( ssl_bitmask_check( bitmask, - msg_len ) == 0 ); - } - else - { - hs_buf->is_complete = 1; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete", - hs_buf->is_complete ? "" : "not yet " ) ); - } - - break; - } - - default: - /* We don't buffer other types of messages. */ - break; - } - -exit: - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) ); - return( ret ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static int ssl_consume_current_message( mbedtls_ssl_context *ssl ) -{ - /* - * Consume last content-layer message and potentially - * update in_msglen which keeps track of the contents' - * consumption state. - * - * (1) Handshake messages: - * Remove last handshake message, move content - * and adapt in_msglen. - * - * (2) Alert messages: - * Consume whole record content, in_msglen = 0. - * - * (3) Change cipher spec: - * Consume whole record content, in_msglen = 0. - * - * (4) Application data: - * Don't do anything - the record layer provides - * the application data as a stream transport - * and consumes through mbedtls_ssl_read only. - * - */ - - /* Case (1): Handshake messages */ - if( ssl->in_hslen != 0 ) - { - /* Hard assertion to be sure that no application data - * is in flight, as corrupting ssl->in_msglen during - * ssl->in_offt != NULL is fatal. */ - if( ssl->in_offt != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * Get next Handshake message in the current record - */ - - /* Notes: - * (1) in_hslen is not necessarily the size of the - * current handshake content: If DTLS handshake - * fragmentation is used, that's the fragment - * size instead. Using the total handshake message - * size here is faulty and should be changed at - * some point. - * (2) While it doesn't seem to cause problems, one - * has to be very careful not to assume that in_hslen - * is always <= in_msglen in a sensible communication. - * Again, it's wrong for DTLS handshake fragmentation. - * The following check is therefore mandatory, and - * should not be treated as a silently corrected assertion. - * Additionally, ssl->in_hslen might be arbitrarily out of - * bounds after handling a DTLS message with an unexpected - * sequence number, see mbedtls_ssl_prepare_handshake_record. - */ - if( ssl->in_hslen < ssl->in_msglen ) - { - ssl->in_msglen -= ssl->in_hslen; - memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen, - ssl->in_msglen ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record", - ssl->in_msg, ssl->in_msglen ); - } - else - { - ssl->in_msglen = 0; - } - - ssl->in_hslen = 0; - } - /* Case (4): Application data */ - else if( ssl->in_offt != NULL ) - { - return( 0 ); - } - /* Everything else (CCS & Alerts) */ - else - { - ssl->in_msglen = 0; - } - - return( 0 ); -} - -static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ) -{ - if( ssl->in_msglen > 0 ) - return( 1 ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - if( hs == NULL ) - return; - - if( hs->buffering.future_record.data != NULL ) - { - hs->buffering.total_bytes_buffered -= - hs->buffering.future_record.len; - - mbedtls_free( hs->buffering.future_record.data ); - hs->buffering.future_record.data = NULL; - } -} - -static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - unsigned char * rec; - size_t rec_len; - unsigned rec_epoch; - - if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 0 ); - - if( hs == NULL ) - return( 0 ); - - rec = hs->buffering.future_record.data; - rec_len = hs->buffering.future_record.len; - rec_epoch = hs->buffering.future_record.epoch; - - if( rec == NULL ) - return( 0 ); - - /* Only consider loading future records if the - * input buffer is empty. */ - if( ssl_next_record_is_in_datagram( ssl ) == 1 ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) ); - - if( rec_epoch != ssl->in_epoch ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) ); - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) ); - - /* Double-check that the record is not too large */ - if( rec_len > MBEDTLS_SSL_IN_BUFFER_LEN - - (size_t)( ssl->in_hdr - ssl->in_buf ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - memcpy( ssl->in_hdr, rec, rec_len ); - ssl->in_left = rec_len; - ssl->next_record_offset = 0; - - ssl_free_buffered_record( ssl ); - -exit: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) ); - return( 0 ); -} - -static int ssl_buffer_future_record( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - size_t const rec_hdr_len = 13; - size_t const total_buf_sz = rec_hdr_len + ssl->in_msglen; - - /* Don't buffer future records outside handshakes. */ - if( hs == NULL ) - return( 0 ); - - /* Only buffer handshake records (we are only interested - * in Finished messages). */ - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - return( 0 ); - - /* Don't buffer more than one future epoch record. */ - if( hs->buffering.future_record.data != NULL ) - return( 0 ); - - /* Don't buffer record if there's not enough buffering space remaining. */ - if( total_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n", - (unsigned) total_buf_sz, MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - return( 0 ); - } - - /* Buffer record */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u", - ssl->in_epoch + 1 ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", ssl->in_hdr, - rec_hdr_len + ssl->in_msglen ); - - /* ssl_parse_record_header() only considers records - * of the next epoch as candidates for buffering. */ - hs->buffering.future_record.epoch = ssl->in_epoch + 1; - hs->buffering.future_record.len = total_buf_sz; - - hs->buffering.future_record.data = - mbedtls_calloc( 1, hs->buffering.future_record.len ); - if( hs->buffering.future_record.data == NULL ) - { - /* If we run out of RAM trying to buffer a - * record from the next epoch, just ignore. */ - return( 0 ); - } - - memcpy( hs->buffering.future_record.data, ssl->in_hdr, total_buf_sz ); - - hs->buffering.total_bytes_buffered += total_buf_sz; - return( 0 ); -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static int ssl_get_next_record( mbedtls_ssl_context *ssl ) -{ - int ret; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* We might have buffered a future record; if so, - * and if the epoch matches now, load it. - * On success, this call will set ssl->in_left to - * the length of the buffered record, so that - * the calls to ssl_fetch_input() below will - * essentially be no-ops. */ - ret = ssl_load_buffered_record( ssl ); - if( ret != 0 ) - return( ret ); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - - if( ( ret = ssl_parse_record_header( ssl ) ) != 0 ) - { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) - { - if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) - { - ret = ssl_buffer_future_record( ssl ); - if( ret != 0 ) - return( ret ); - - /* Fall through to handling of unexpected records */ - ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; - } - - if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ) - { - /* Skip unexpected record (but not whole datagram) */ - ssl->next_record_offset = ssl->in_msglen - + mbedtls_ssl_hdr_len( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record " - "(header)" ) ); - } - else - { - /* Skip invalid record and the rest of the datagram */ - ssl->next_record_offset = 0; - ssl->in_left = 0; - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record " - "(header)" ) ); - } - - /* Get next record */ - return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); - } -#endif - return( ret ); - } - - /* - * Read and optionally decrypt the message contents - */ - if( ( ret = mbedtls_ssl_fetch_input( ssl, - mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - - /* Done reading this record, get ready for the next one */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl ); - if( ssl->next_record_offset < ssl->in_left ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) ); - } - } - else -#endif - ssl->in_left = 0; - - if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 ) - { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* Silently discard invalid records */ - if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD || - ret == MBEDTLS_ERR_SSL_INVALID_MAC ) - { - /* Except when waiting for Finished as a bad mac here - * probably means something went wrong in the handshake - * (eg wrong psk used, mitm downgrade attempt, etc.) */ - if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED || - ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) - { -#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) - if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) - { - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); - } -#endif - return( ret ); - } - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - if( ssl->conf->badmac_limit != 0 && - ++ssl->badmac_seen >= ssl->conf->badmac_limit ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } -#endif - - /* As above, invalid records cause - * dismissal of the whole datagram. */ - - ssl->next_record_offset = 0; - ssl->in_left = 0; - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) ); - return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); - } - - return( ret ); - } - else -#endif - { - /* Error out (and send alert) on invalid records */ -#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) - if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) - { - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); - } -#endif - return( ret ); - } - } - - return( 0 ); -} - -int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) -{ - int ret; - - /* - * Handle particular types of records - */ - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) - { - if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 ) - { - return( ret ); - } - } - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - if( ssl->in_msglen != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %d", - ssl->in_msglen ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - if( ssl->in_msg[0] != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x", - ssl->in_msg[0] ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && - ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) - { - if( ssl->handshake == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } -#endif - } - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) - { - if( ssl->in_msglen != 2 ) - { - /* Note: Standard allows for more than one 2 byte alert - to be packed in a single message, but Mbed TLS doesn't - currently support this. */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d", - ssl->in_msglen ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]", - ssl->in_msg[0], ssl->in_msg[1] ) ); - - /* - * Ignore non-fatal alerts, except close_notify and no_renegotiation - */ - if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)", - ssl->in_msg[1] ) ); - return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE ); - } - - if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) ); - return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ); - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED) - if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) ); - /* Will be handled when trying to parse ServerHello */ - return( 0 ); - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && - ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) ); - /* Will be handled in mbedtls_ssl_parse_certificate() */ - return( 0 ); - } -#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ - - /* Silently ignore: fetch new message */ - return MBEDTLS_ERR_SSL_NON_FATAL; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake != NULL && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - { - ssl_handshake_wrapup_free_hs_transform( ssl ); - } -#endif - - return( 0 ); -} - -int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ) -{ - int ret; - - if( ( ret = mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, - unsigned char level, - unsigned char message ) -{ - int ret; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message )); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; - ssl->out_msglen = 2; - ssl->out_msg[0] = level; - ssl->out_msg[1] = message; - - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); - return( ret ); - } - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) ); - - return( 0 ); -} - -/* - * Handshake functions - */ -#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -/* No certificate support -> dummy functions */ -int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} - -int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} - -#else -/* Some certificate support -> implement write and parse */ - -int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t i, n; - const mbedtls_x509_crt *crt; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - ssl->state++; - return( 0 ); - } - -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - { - if( ssl->client_auth == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - ssl->state++; - return( 0 ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - /* - * If using SSLv3 and got no cert, send an Alert message - * (otherwise an empty Certificate message will be sent). - */ - if( mbedtls_ssl_own_cert( ssl ) == NULL && - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - ssl->out_msglen = 2; - ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; - ssl->out_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING; - ssl->out_msg[1] = MBEDTLS_SSL_ALERT_MSG_NO_CERT; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) ); - goto write_msg; - } -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - } -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - { - if( mbedtls_ssl_own_cert( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) ); - return( MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED ); - } - } -#endif - - MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) ); - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 6 length of all certs - * 7 . 9 length of cert. 1 - * 10 . n-1 peer certificate - * n . n+2 length of cert. 2 - * n+3 . ... upper level cert, etc. - */ - i = 7; - crt = mbedtls_ssl_own_cert( ssl ); - - while( crt != NULL ) - { - n = crt->raw.len; - if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d", - i + 3 + n, MBEDTLS_SSL_OUT_CONTENT_LEN ) ); - return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE ); - } - - ssl->out_msg[i ] = (unsigned char)( n >> 16 ); - ssl->out_msg[i + 1] = (unsigned char)( n >> 8 ); - ssl->out_msg[i + 2] = (unsigned char)( n ); - - i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n ); - i += n; crt = crt->next; - } - - ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 ); - ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 ); - ssl->out_msg[6] = (unsigned char)( ( i - 7 ) ); - - ssl->out_msglen = i; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE; - -#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) -write_msg: -#endif - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) ); - - return( ret ); -} - -/* - * Once the certificate message is read, parse it into a cert chain and - * perform basic checks, but leave actual verification to the caller - */ -static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t i, n; - uint8_t alert; - -#if defined(MBEDTLS_SSL_SRV_C) -#if defined(MBEDTLS_SSL_PROTO_SSL3) - /* - * Check if the client sent an empty certificate - */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - if( ssl->in_msglen == 2 && - ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT && - ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) ); - - /* The client was asked for a certificate but didn't send - one. The client should know what's going on, so we - don't send an alert. */ - ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; - return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE ); - } - } -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) - { - if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) && - ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE && - memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) ); - - /* The client was asked for a certificate but didn't send - one. The client should know what's going on, so we - don't send an alert. */ - ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; - return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE ); - } - } -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ -#endif /* MBEDTLS_SSL_SRV_C */ - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE || - ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - i = mbedtls_ssl_hs_hdr_len( ssl ); - - /* - * Same message structure as in mbedtls_ssl_write_certificate() - */ - n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2]; - - if( ssl->in_msg[i] != 0 || - ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - /* In case we tried to reuse a session but it failed */ - if( ssl->session_negotiate->peer_cert != NULL ) - { - mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert ); - mbedtls_free( ssl->session_negotiate->peer_cert ); - } - - if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1, - sizeof( mbedtls_x509_crt ) ) ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", - sizeof( mbedtls_x509_crt ) ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert ); - - i += 3; - - while( i < ssl->in_hslen ) - { - if ( i + 3 > ssl->in_hslen ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - if( ssl->in_msg[i] != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - n = ( (unsigned int) ssl->in_msg[i + 1] << 8 ) - | (unsigned int) ssl->in_msg[i + 2]; - i += 3; - - if( n < 128 || i + n > ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert, - ssl->in_msg + i, n ); - switch( ret ) - { - case 0: /*ok*/ - case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND: - /* Ignore certificate with an unknown algorithm: maybe a - prior certificate was already trusted. */ - break; - - case MBEDTLS_ERR_X509_ALLOC_FAILED: - alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR; - goto crt_parse_der_failed; - - case MBEDTLS_ERR_X509_UNKNOWN_VERSION: - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - goto crt_parse_der_failed; - - default: - alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; - crt_parse_der_failed: - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert ); - MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret ); - return( ret ); - } - - i += n; - } - - MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert ); - - /* - * On client, make sure the server cert doesn't change during renego to - * avoid "triple handshake" attack: https://secure-resumption.com/ - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - if( ssl->session->peer_cert == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - if( ssl->session->peer_cert->raw.len != - ssl->session_negotiate->peer_cert->raw.len || - memcmp( ssl->session->peer_cert->raw.p, - ssl->session_negotiate->peer_cert->raw.p, - ssl->session->peer_cert->raw.len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - } -#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ - - return( 0 ); -} - -int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) -{ - int ret; - const mbedtls_ssl_ciphersuite_t * const ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET - ? ssl->handshake->sni_authmode - : ssl->conf->authmode; -#else - const int authmode = ssl->conf->authmode; -#endif - void *rs_ctx = NULL; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); - - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); - ssl->state++; - return( 0 ); - } - -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); - ssl->state++; - return( 0 ); - } - - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - authmode == MBEDTLS_SSL_VERIFY_NONE ) - { - ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); - - ssl->state++; - return( 0 ); - } -#endif - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_crt_verify ) - { - goto crt_verify; - } -#endif - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - /* mbedtls_ssl_read_record may have sent an alert already. We - let it decide whether to alert. */ - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ( ret = ssl_parse_certificate_chain( ssl ) ) != 0 ) - { -#if defined(MBEDTLS_SSL_SRV_C) - if( ret == MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE && - authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) - { - ret = 0; - } -#endif - - ssl->state++; - return( ret ); - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled) - ssl->handshake->ecrs_state = ssl_ecrs_crt_verify; - -crt_verify: - if( ssl->handshake->ecrs_enabled) - rs_ctx = &ssl->handshake->ecrs_ctx; -#endif - - if( authmode != MBEDTLS_SSL_VERIFY_NONE ) - { - mbedtls_x509_crt *ca_chain; - mbedtls_x509_crl *ca_crl; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_ca_chain != NULL ) - { - ca_chain = ssl->handshake->sni_ca_chain; - ca_crl = ssl->handshake->sni_ca_crl; - } - else -#endif - { - ca_chain = ssl->conf->ca_chain; - ca_crl = ssl->conf->ca_crl; - } - - /* - * Main check: verify certificate - */ - ret = mbedtls_x509_crt_verify_restartable( - ssl->session_negotiate->peer_cert, - ca_chain, ca_crl, - ssl->conf->cert_profile, - ssl->hostname, - &ssl->session_negotiate->verify_result, - ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx ); - - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ); -#endif - - /* - * Secondary checks: always done, but change 'ret' only if it was 0 - */ - -#if defined(MBEDTLS_ECP_C) - { - const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk; - - /* If certificate uses an EC key, make sure the curve is OK */ - if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) && - mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 ) - { - ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY; - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); - if( ret == 0 ) - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; - } - } -#endif /* MBEDTLS_ECP_C */ - - if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert, - ciphersuite_info, - ! ssl->conf->endpoint, - &ssl->session_negotiate->verify_result ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); - if( ret == 0 ) - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; - } - - /* mbedtls_x509_crt_verify_with_profile is supposed to report a - * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED, - * with details encoded in the verification flags. All other kinds - * of error codes, including those from the user provided f_vrfy - * functions, are treated as fatal and lead to a failure of - * ssl_parse_certificate even if verification was optional. */ - if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL && - ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || - ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) - { - ret = 0; - } - - if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); - ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; - } - - if( ret != 0 ) - { - uint8_t alert; - - /* The certificate may have been rejected for several reasons. - Pick one and send the corresponding alert. Which alert to send - may be a subject of debate in some cases. */ - if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER ) - alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH ) - alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED ) - alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED ) - alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED ) - alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA; - else - alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN; - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - alert ); - } - -#if defined(MBEDTLS_DEBUG_C) - if( ssl->session_negotiate->verify_result != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x", - ssl->session_negotiate->verify_result ) ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) ); - } -#endif /* MBEDTLS_DEBUG_C */ - } - - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) ); - - return( ret ); -} -#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - !MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) ); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; - ssl->out_msglen = 1; - ssl->out_msg[0] = 1; - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) ); - - return( 0 ); -} - -int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) ); - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* CCS records are only accepted if they have length 1 and content '1', - * so we don't need to check this here. */ - - /* - * Switch to our negotiated transform and session parameters for inbound - * data. - */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) ); - ssl->transform_in = ssl->transform_negotiate; - ssl->session_in = ssl->session_negotiate; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - ssl_dtls_replay_reset( ssl ); -#endif - - /* Increment epoch */ - if( ++ssl->in_epoch == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); - /* This is highly unlikely to happen for legitimate reasons, so - treat it as an attack and don't send an alert. */ - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - memset( ssl->in_ctr, 0, 8 ); - - ssl_update_in_pointers( ssl, ssl->transform_negotiate ); - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_activate != NULL ) - { - if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif - - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) ); - - return( 0 ); -} - -void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t *ciphersuite_info ) -{ - ((void) ciphersuite_info); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) - ssl->handshake->update_checksum = ssl_update_checksum_md5sha1; - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) - if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) - ssl->handshake->update_checksum = ssl_update_checksum_sha384; - else -#endif -#if defined(MBEDTLS_SHA256_C) - if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 ) - ssl->handshake->update_checksum = ssl_update_checksum_sha256; - else -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return; - } -} - -void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_starts_ret( &ssl->handshake->fin_md5 ); - mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) - mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 ); -#endif -#if defined(MBEDTLS_SHA512_C) - mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 ); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -} - -static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); - mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) - mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); -#endif -#if defined(MBEDTLS_SHA512_C) - mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); - mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); -} -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); -} -#endif - -#if defined(MBEDTLS_SHA512_C) -static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); -} -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -static void ssl_calc_finished_ssl( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - const char *sender; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - - unsigned char padbuf[48]; - unsigned char md5sum[16]; - unsigned char sha1sum[20]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - /* - * SSLv3: - * hash = - * MD5( master + pad2 + - * MD5( handshake + sender + master + pad1 ) ) - * + SHA1( master + pad2 + - * SHA1( handshake + sender + master + pad1 ) ) - */ - -#if !defined(MBEDTLS_MD5_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) - md5.state, sizeof( md5.state ) ); -#endif - -#if !defined(MBEDTLS_SHA1_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) - sha1.state, sizeof( sha1.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT" - : "SRVR"; - - memset( padbuf, 0x36, 48 ); - - mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 ); - mbedtls_md5_update_ret( &md5, session->master, 48 ); - mbedtls_md5_update_ret( &md5, padbuf, 48 ); - mbedtls_md5_finish_ret( &md5, md5sum ); - - mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 ); - mbedtls_sha1_update_ret( &sha1, session->master, 48 ); - mbedtls_sha1_update_ret( &sha1, padbuf, 40 ); - mbedtls_sha1_finish_ret( &sha1, sha1sum ); - - memset( padbuf, 0x5C, 48 ); - - mbedtls_md5_starts_ret( &md5 ); - mbedtls_md5_update_ret( &md5, session->master, 48 ); - mbedtls_md5_update_ret( &md5, padbuf, 48 ); - mbedtls_md5_update_ret( &md5, md5sum, 16 ); - mbedtls_md5_finish_ret( &md5, buf ); - - mbedtls_sha1_starts_ret( &sha1 ); - mbedtls_sha1_update_ret( &sha1, session->master, 48 ); - mbedtls_sha1_update_ret( &sha1, padbuf , 40 ); - mbedtls_sha1_update_ret( &sha1, sha1sum, 20 ); - mbedtls_sha1_finish_ret( &sha1, buf + 16 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - mbedtls_platform_zeroize( md5sum, sizeof( md5sum ) ); - mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_calc_finished_tls( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - unsigned char padbuf[36]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - /* - * TLSv1: - * hash = PRF( master, finished_label, - * MD5( handshake ) + SHA1( handshake ) )[0..11] - */ - -#if !defined(MBEDTLS_MD5_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) - md5.state, sizeof( md5.state ) ); -#endif - -#if !defined(MBEDTLS_SHA1_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) - sha1.state, sizeof( sha1.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - - mbedtls_md5_finish_ret( &md5, padbuf ); - mbedtls_sha1_finish_ret( &sha1, padbuf + 16 ); - - ssl->handshake->tls_prf( session->master, 48, sender, - padbuf, 36, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -static void ssl_calc_finished_tls_sha256( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_sha256_context sha256; - unsigned char padbuf[32]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - mbedtls_sha256_init( &sha256 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) ); - - mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); - - /* - * TLSv1.2: - * hash = PRF( master, finished_label, - * Hash( handshake ) )[0.11] - */ - -#if !defined(MBEDTLS_SHA256_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) - sha256.state, sizeof( sha256.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - - mbedtls_sha256_finish_ret( &sha256, padbuf ); - - ssl->handshake->tls_prf( session->master, 48, sender, - padbuf, 32, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_sha256_free( &sha256 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - -static void ssl_calc_finished_tls_sha384( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_sha512_context sha512; - unsigned char padbuf[48]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - mbedtls_sha512_init( &sha512 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) ); - - mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); - - /* - * TLSv1.2: - * hash = PRF( master, finished_label, - * Hash( handshake ) )[0.11] - */ - -#if !defined(MBEDTLS_SHA512_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) - sha512.state, sizeof( sha512.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - /* mbedtls_sha512_finish_ret's output parameter is declared as a - * 64-byte buffer, but sice we're using SHA-384, we know that the - * output fits in 48 bytes. This is correct C, but GCC 11.1 warns - * about it. - */ -#if defined(__GNUC__) && __GNUC__ >= 11 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif - mbedtls_sha512_finish_ret( &sha512, padbuf ); -#if defined(__GNUC__) && __GNUC__ >= 11 -#pragma GCC diagnostic pop -#endif - - ssl->handshake->tls_prf( session->master, 48, sender, - padbuf, 48, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_sha512_free( &sha512 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) -{ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) ); - - /* - * Free our handshake params - */ - mbedtls_ssl_handshake_free( ssl ); - mbedtls_free( ssl->handshake ); - ssl->handshake = NULL; - - /* - * Free the previous transform and swith in the current one - */ - if( ssl->transform ) - { - mbedtls_ssl_transform_free( ssl->transform ); - mbedtls_free( ssl->transform ); - } - ssl->transform = ssl->transform_negotiate; - ssl->transform_negotiate = NULL; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) ); -} - -void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) -{ - int resume = ssl->handshake->resume; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE; - ssl->renego_records_seen = 0; - } -#endif - - /* - * Free the previous session and switch in the current one - */ - if( ssl->session ) - { -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - /* RFC 7366 3.1: keep the EtM state */ - ssl->session_negotiate->encrypt_then_mac = - ssl->session->encrypt_then_mac; -#endif - - mbedtls_ssl_session_free( ssl->session ); - mbedtls_free( ssl->session ); - } - ssl->session = ssl->session_negotiate; - ssl->session_negotiate = NULL; - - /* - * Add cache entry - */ - if( ssl->conf->f_set_cache != NULL && - ssl->session->id_len != 0 && - resume == 0 ) - { - if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 ) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->flight != NULL ) - { - /* Cancel handshake timer */ - ssl_set_timer( ssl, 0 ); - - /* Keep last flight around in case we need to resend it: - * we need the handshake and transform structures for that */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) ); - } - else -#endif - ssl_handshake_wrapup_free_hs_transform( ssl ); - - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) ); -} - -int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) -{ - int ret, hash_len; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); - - ssl_update_out_pointers( ssl, ssl->transform_negotiate ); - - ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint ); - - /* - * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites - * may define some other value. Currently (early 2016), no defined - * ciphersuite does this (and this is unlikely to change as activity has - * moved to TLS 1.3 now) so we can keep the hardcoded 12 here. - */ - hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12; - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->verify_data_len = hash_len; - memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len ); -#endif - - ssl->out_msglen = 4 + hash_len; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED; - - /* - * In case of session resuming, invert the client and server - * ChangeCipherSpec messages order. - */ - if( ssl->handshake->resume != 0 ) - { -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; -#endif -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; -#endif - } - else - ssl->state++; - - /* - * Switch to our negotiated transform and session parameters for outbound - * data. - */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - unsigned char i; - - /* Remember current epoch settings for resending */ - ssl->handshake->alt_transform_out = ssl->transform_out; - memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 ); - - /* Set sequence_number to zero */ - memset( ssl->cur_out_ctr + 2, 0, 6 ); - - /* Increment epoch */ - for( i = 2; i > 0; i-- ) - if( ++ssl->cur_out_ctr[i - 1] != 0 ) - break; - - /* The loop goes to its end iff the counter is wrapping */ - if( i == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - memset( ssl->cur_out_ctr, 0, 8 ); - - ssl->transform_out = ssl->transform_negotiate; - ssl->session_out = ssl->session_negotiate; - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_activate != NULL ) - { - if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_send_flight_completed( ssl ); -#endif - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -#define SSL_MAX_HASH_LEN 36 -#else -#define SSL_MAX_HASH_LEN 12 -#endif - -int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned int hash_len; - unsigned char buf[SSL_MAX_HASH_LEN]; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); - - ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 ); - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* There is currently no ciphersuite using another length with TLS 1.2 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - hash_len = 36; - else -#endif - hash_len = 12; - - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED || - ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); - } - - if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), - buf, hash_len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->verify_data_len = hash_len; - memcpy( ssl->peer_verify_data, buf, hash_len ); -#endif - - if( ssl->handshake->resume != 0 ) - { -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; -#endif -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; -#endif - } - else - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_recv_flight_completed( ssl ); -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) ); - - return( 0 ); -} - -static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) -{ - memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_init( &handshake->fin_md5 ); - mbedtls_sha1_init( &handshake->fin_sha1 ); - mbedtls_md5_starts_ret( &handshake->fin_md5 ); - mbedtls_sha1_starts_ret( &handshake->fin_sha1 ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) - mbedtls_sha256_init( &handshake->fin_sha256 ); - mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 ); -#endif -#if defined(MBEDTLS_SHA512_C) - mbedtls_sha512_init( &handshake->fin_sha512 ); - mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 ); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - handshake->update_checksum = ssl_update_checksum_start; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs ); -#endif - -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_init( &handshake->dhm_ctx ); -#endif -#if defined(MBEDTLS_ECDH_C) - mbedtls_ecdh_init( &handshake->ecdh_ctx ); -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - mbedtls_ecjpake_init( &handshake->ecjpake_ctx ); -#if defined(MBEDTLS_SSL_CLI_C) - handshake->ecjpake_cache = NULL; - handshake->ecjpake_cache_len = 0; -#endif -#endif - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx ); -#endif - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET; -#endif -} - -static void ssl_transform_init( mbedtls_ssl_transform *transform ) -{ - memset( transform, 0, sizeof(mbedtls_ssl_transform) ); - - mbedtls_cipher_init( &transform->cipher_ctx_enc ); - mbedtls_cipher_init( &transform->cipher_ctx_dec ); - - mbedtls_md_init( &transform->md_ctx_enc ); - mbedtls_md_init( &transform->md_ctx_dec ); -} - -void mbedtls_ssl_session_init( mbedtls_ssl_session *session ) -{ - memset( session, 0, sizeof(mbedtls_ssl_session) ); -} - -static int ssl_handshake_init( mbedtls_ssl_context *ssl ) -{ - /* Clear old handshake information if present */ - if( ssl->transform_negotiate ) - mbedtls_ssl_transform_free( ssl->transform_negotiate ); - if( ssl->session_negotiate ) - mbedtls_ssl_session_free( ssl->session_negotiate ); - if( ssl->handshake ) - mbedtls_ssl_handshake_free( ssl ); - - /* - * Either the pointers are now NULL or cleared properly and can be freed. - * Now allocate missing structures. - */ - if( ssl->transform_negotiate == NULL ) - { - ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) ); - } - - if( ssl->session_negotiate == NULL ) - { - ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) ); - } - - if( ssl->handshake == NULL ) - { - ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) ); - } - - /* All pointers should exist and can be directly freed without issue */ - if( ssl->handshake == NULL || - ssl->transform_negotiate == NULL || - ssl->session_negotiate == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc() of ssl sub-contexts failed" ) ); - - mbedtls_free( ssl->handshake ); - mbedtls_free( ssl->transform_negotiate ); - mbedtls_free( ssl->session_negotiate ); - - ssl->handshake = NULL; - ssl->transform_negotiate = NULL; - ssl->session_negotiate = NULL; - - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - /* Initialize structures */ - mbedtls_ssl_session_init( ssl->session_negotiate ); - ssl_transform_init( ssl->transform_negotiate ); - ssl_handshake_params_init( ssl->handshake ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->handshake->alt_transform_out = ssl->transform_out; - - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; - else - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; - - ssl_set_timer( ssl, 0 ); - } -#endif - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) -/* Dummy cookie callbacks for defaults */ -static int ssl_cookie_write_dummy( void *ctx, - unsigned char **p, unsigned char *end, - const unsigned char *cli_id, size_t cli_id_len ) -{ - ((void) ctx); - ((void) p); - ((void) end); - ((void) cli_id); - ((void) cli_id_len); - - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -} - -static int ssl_cookie_check_dummy( void *ctx, - const unsigned char *cookie, size_t cookie_len, - const unsigned char *cli_id, size_t cli_id_len ) -{ - ((void) ctx); - ((void) cookie); - ((void) cookie_len); - ((void) cli_id); - ((void) cli_id_len); - - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -} -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ - -/* Once ssl->out_hdr as the address of the beginning of the - * next outgoing record is set, deduce the other pointers. - * - * Note: For TLS, we save the implicit record sequence number - * (entering MAC computation) in the 8 bytes before ssl->out_hdr, - * and the caller has to make sure there's space for this. - */ - -static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->out_ctr = ssl->out_hdr + 3; - ssl->out_len = ssl->out_hdr + 11; - ssl->out_iv = ssl->out_hdr + 13; - } - else -#endif - { - ssl->out_ctr = ssl->out_hdr - 8; - ssl->out_len = ssl->out_hdr + 3; - ssl->out_iv = ssl->out_hdr + 5; - } - - /* Adjust out_msg to make space for explicit IV, if used. */ - if( transform != NULL && - ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen; - } - else - ssl->out_msg = ssl->out_iv; -} - -/* Once ssl->in_hdr as the address of the beginning of the - * next incoming record is set, deduce the other pointers. - * - * Note: For TLS, we save the implicit record sequence number - * (entering MAC computation) in the 8 bytes before ssl->in_hdr, - * and the caller has to make sure there's space for this. - */ - -static void ssl_update_in_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->in_ctr = ssl->in_hdr + 3; - ssl->in_len = ssl->in_hdr + 11; - ssl->in_iv = ssl->in_hdr + 13; - } - else -#endif - { - ssl->in_ctr = ssl->in_hdr - 8; - ssl->in_len = ssl->in_hdr + 3; - ssl->in_iv = ssl->in_hdr + 5; - } - - /* Offset in_msg from in_iv to allow space for explicit IV, if used. */ - if( transform != NULL && - ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - ssl->in_msg = ssl->in_iv + transform->ivlen - transform->fixed_ivlen; - } - else - ssl->in_msg = ssl->in_iv; -} - -/* - * Initialize an SSL context - */ -void mbedtls_ssl_init( mbedtls_ssl_context *ssl ) -{ - memset( ssl, 0, sizeof( mbedtls_ssl_context ) ); -} - -/* - * Setup an SSL context - */ - -static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ) -{ - /* Set the incoming and outgoing record pointers. */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->out_hdr = ssl->out_buf; - ssl->in_hdr = ssl->in_buf; - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - ssl->out_hdr = ssl->out_buf + 8; - ssl->in_hdr = ssl->in_buf + 8; - } - - /* Derive other internal pointers. */ - ssl_update_out_pointers( ssl, NULL /* no transform enabled */ ); - ssl_update_in_pointers ( ssl, NULL /* no transform enabled */ ); -} - -int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, - const mbedtls_ssl_config *conf ) -{ - int ret; - - ssl->conf = conf; - - /* - * Prepare base structures - */ - - /* Set to NULL in case of an error condition */ - ssl->out_buf = NULL; - - ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN ); - if( ssl->in_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) ); - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto error; - } - - ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN ); - if( ssl->out_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) ); - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto error; - } - - ssl_reset_in_out_pointers( ssl ); - - if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) - goto error; - - return( 0 ); - -error: - mbedtls_free( ssl->in_buf ); - mbedtls_free( ssl->out_buf ); - - ssl->conf = NULL; - - ssl->in_buf = NULL; - ssl->out_buf = NULL; - - ssl->in_hdr = NULL; - ssl->in_ctr = NULL; - ssl->in_len = NULL; - ssl->in_iv = NULL; - ssl->in_msg = NULL; - - ssl->out_hdr = NULL; - ssl->out_ctr = NULL; - ssl->out_len = NULL; - ssl->out_iv = NULL; - ssl->out_msg = NULL; - - return( ret ); -} - -/* - * Reset an initialized and used SSL context for re-use while retaining - * all application-set variables, function pointers and data. - * - * If partial is non-zero, keep data in the input buffer and client ID. - * (Use when a DTLS client reconnects from the same port.) - */ -static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) -{ - int ret; - -#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \ - !defined(MBEDTLS_SSL_SRV_C) - ((void) partial); -#endif - - ssl->state = MBEDTLS_SSL_HELLO_REQUEST; - - /* Cancel any possibly running timer */ - ssl_set_timer( ssl, 0 ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE; - ssl->renego_records_seen = 0; - - ssl->verify_data_len = 0; - memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); - memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); -#endif - ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION; - - ssl->in_offt = NULL; - ssl_reset_in_out_pointers( ssl ); - - ssl->in_msgtype = 0; - ssl->in_msglen = 0; -#if defined(MBEDTLS_SSL_PROTO_DTLS) - ssl->next_record_offset = 0; - ssl->in_epoch = 0; -#endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - ssl_dtls_replay_reset( ssl ); -#endif - - ssl->in_hslen = 0; - ssl->nb_zero = 0; - - ssl->keep_current_message = 0; - - ssl->out_msgtype = 0; - ssl->out_msglen = 0; - ssl->out_left = 0; -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - if( ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ) - ssl->split_done = 0; -#endif - - memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) ); - - ssl->transform_in = NULL; - ssl->transform_out = NULL; - - ssl->session_in = NULL; - ssl->session_out = NULL; - - memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN ); - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) - if( partial == 0 ) -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - { - ssl->in_left = 0; - memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN ); - } - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_reset != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_reset()" ) ); - if( ( ret = mbedtls_ssl_hw_record_reset( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_reset", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif - - if( ssl->transform ) - { - mbedtls_ssl_transform_free( ssl->transform ); - mbedtls_free( ssl->transform ); - ssl->transform = NULL; - } - - if( ssl->session ) - { - mbedtls_ssl_session_free( ssl->session ); - mbedtls_free( ssl->session ); - ssl->session = NULL; - } - -#if defined(MBEDTLS_SSL_ALPN) - ssl->alpn_chosen = NULL; -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) - if( partial == 0 ) -#endif - { - mbedtls_free( ssl->cli_id ); - ssl->cli_id = NULL; - ssl->cli_id_len = 0; - } -#endif - - if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * Reset an initialized and used SSL context for re-use while retaining - * all application-set variables, function pointers and data. - */ -int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) -{ - return( ssl_session_reset_int( ssl, 0 ) ); -} - -/* - * SSL set accessors - */ -void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ) -{ - conf->endpoint = endpoint; -} - -void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ) -{ - conf->transport = transport; -} - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ) -{ - conf->anti_replay = mode; -} -#endif - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) -void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ) -{ - conf->badmac_limit = limit; -} -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, - unsigned allow_packing ) -{ - ssl->disable_datagram_packing = !allow_packing; -} - -void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, - uint32_t min, uint32_t max ) -{ - conf->hs_timeout_min = min; - conf->hs_timeout_max = max; -} -#endif - -void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ) -{ - conf->authmode = authmode; -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - conf->f_vrfy = f_vrfy; - conf->p_vrfy = p_vrfy; -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - conf->f_rng = f_rng; - conf->p_rng = p_rng; -} - -void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, - void (*f_dbg)(void *, int, const char *, int, const char *), - void *p_dbg ) -{ - conf->f_dbg = f_dbg; - conf->p_dbg = p_dbg; -} - -void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, - void *p_bio, - mbedtls_ssl_send_t *f_send, - mbedtls_ssl_recv_t *f_recv, - mbedtls_ssl_recv_timeout_t *f_recv_timeout ) -{ - ssl->p_bio = p_bio; - ssl->f_send = f_send; - ssl->f_recv = f_recv; - ssl->f_recv_timeout = f_recv_timeout; -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ) -{ - ssl->mtu = mtu; -} -#endif - -void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) -{ - conf->read_timeout = timeout; -} - -void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, - void *p_timer, - mbedtls_ssl_set_timer_t *f_set_timer, - mbedtls_ssl_get_timer_t *f_get_timer ) -{ - ssl->p_timer = p_timer; - ssl->f_set_timer = f_set_timer; - ssl->f_get_timer = f_get_timer; - - /* Make sure we start with no timer running */ - ssl_set_timer( ssl, 0 ); -} - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, - void *p_cache, - int (*f_get_cache)(void *, mbedtls_ssl_session *), - int (*f_set_cache)(void *, const mbedtls_ssl_session *) ) -{ - conf->p_cache = p_cache; - conf->f_get_cache = f_get_cache; - conf->f_set_cache = f_set_cache; -} -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ) -{ - int ret; - - if( ssl == NULL || - session == NULL || - ssl->session_negotiate == NULL || - ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 ) - return( ret ); - - ssl->handshake->resume = 1; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_CLI_C */ - -void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, - const int *ciphersuites ) -{ - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites; - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites; - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites; - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites; -} - -void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, - const int *ciphersuites, - int major, int minor ) -{ - if( major != MBEDTLS_SSL_MAJOR_VERSION_3 ) - return; - - if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 ) - return; - - conf->ciphersuite_list[minor] = ciphersuites; -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, - const mbedtls_x509_crt_profile *profile ) -{ - conf->cert_profile = profile; -} - -/* Append a new keycert entry to a (possibly empty) list */ -static int ssl_append_key_cert( mbedtls_ssl_key_cert **head, - mbedtls_x509_crt *cert, - mbedtls_pk_context *key ) -{ - mbedtls_ssl_key_cert *new_cert; - - new_cert = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) ); - if( new_cert == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - new_cert->cert = cert; - new_cert->key = key; - new_cert->next = NULL; - - /* Update head is the list was null, else add to the end */ - if( *head == NULL ) - { - *head = new_cert; - } - else - { - mbedtls_ssl_key_cert *cur = *head; - while( cur->next != NULL ) - cur = cur->next; - cur->next = new_cert; - } - - return( 0 ); -} - -int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key ) -{ - return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) ); -} - -void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl ) -{ - conf->ca_chain = ca_chain; - conf->ca_crl = ca_crl; -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key ) -{ - return( ssl_append_key_cert( &ssl->handshake->sni_key_cert, - own_cert, pk_key ) ); -} - -void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl ) -{ - ssl->handshake->sni_ca_chain = ca_chain; - ssl->handshake->sni_ca_crl = ca_crl; -} - -void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl, - int authmode ) -{ - ssl->handshake->sni_authmode = authmode; -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -/* - * Set EC J-PAKE password for current handshake - */ -int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, - const unsigned char *pw, - size_t pw_len ) -{ - mbedtls_ecjpake_role role; - - if( ssl->handshake == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - role = MBEDTLS_ECJPAKE_SERVER; - else - role = MBEDTLS_ECJPAKE_CLIENT; - - return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx, - role, - MBEDTLS_MD_SHA256, - MBEDTLS_ECP_DP_SECP256R1, - pw, pw_len ) ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, - const unsigned char *psk, size_t psk_len, - const unsigned char *psk_identity, size_t psk_identity_len ) -{ - if( psk == NULL || psk_identity == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( psk_len > MBEDTLS_PSK_MAX_LEN ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - /* Identity len will be encoded on two bytes */ - if( ( psk_identity_len >> 16 ) != 0 || - psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - if( conf->psk != NULL ) - { - mbedtls_platform_zeroize( conf->psk, conf->psk_len ); - - mbedtls_free( conf->psk ); - conf->psk = NULL; - conf->psk_len = 0; - } - if( conf->psk_identity != NULL ) - { - mbedtls_free( conf->psk_identity ); - conf->psk_identity = NULL; - conf->psk_identity_len = 0; - } - - if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL || - ( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL ) - { - mbedtls_free( conf->psk ); - mbedtls_free( conf->psk_identity ); - conf->psk = NULL; - conf->psk_identity = NULL; - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - conf->psk_len = psk_len; - conf->psk_identity_len = psk_identity_len; - - memcpy( conf->psk, psk, conf->psk_len ); - memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len ); - - return( 0 ); -} - -int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, - const unsigned char *psk, size_t psk_len ) -{ - if( psk == NULL || ssl->handshake == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( psk_len > MBEDTLS_PSK_MAX_LEN ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( ssl->handshake->psk != NULL ) - { - mbedtls_platform_zeroize( ssl->handshake->psk, - ssl->handshake->psk_len ); - mbedtls_free( ssl->handshake->psk ); - ssl->handshake->psk_len = 0; - } - - if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - ssl->handshake->psk_len = psk_len; - memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len ); - - return( 0 ); -} - -void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, - int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, - size_t), - void *p_psk ) -{ - conf->f_psk = f_psk; - conf->p_psk = p_psk; -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G ) -{ - int ret; - - if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 || - ( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 ) - { - mbedtls_mpi_free( &conf->dhm_P ); - mbedtls_mpi_free( &conf->dhm_G ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf, - const unsigned char *dhm_P, size_t P_len, - const unsigned char *dhm_G, size_t G_len ) -{ - int ret; - - if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 || - ( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 ) - { - mbedtls_mpi_free( &conf->dhm_P ); - mbedtls_mpi_free( &conf->dhm_G ); - return( ret ); - } - - return( 0 ); -} - -int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ) -{ - int ret; - - if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 || - ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 ) - { - mbedtls_mpi_free( &conf->dhm_P ); - mbedtls_mpi_free( &conf->dhm_G ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) -/* - * Set the minimum length for Diffie-Hellman parameters - */ -void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, - unsigned int bitlen ) -{ - conf->dhm_min_bitlen = bitlen; -} -#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -/* - * Set allowed/preferred hashes for handshake signatures - */ -void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, - const int *hashes ) -{ - conf->sig_hashes = hashes; -} -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_ECP_C) -/* - * Set the allowed elliptic curves - */ -void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, - const mbedtls_ecp_group_id *curve_list ) -{ - conf->curve_list = curve_list; -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) -{ - /* Initialize to suppress unnecessary compiler warning */ - size_t hostname_len = 0; - - /* Check if new hostname is valid before - * making any change to current one */ - if( hostname != NULL ) - { - hostname_len = strlen( hostname ); - - if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* Now it's clear that we will overwrite the old hostname, - * so we can free it safely */ - - if( ssl->hostname != NULL ) - { - mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) ); - mbedtls_free( ssl->hostname ); - } - - /* Passing NULL as hostname shall clear the old one */ - - if( hostname == NULL ) - { - ssl->hostname = NULL; - } - else - { - ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 ); - if( ssl->hostname == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - memcpy( ssl->hostname, hostname, hostname_len ); - - ssl->hostname[hostname_len] = '\0'; - } - - return( 0 ); -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, - int (*f_sni)(void *, mbedtls_ssl_context *, - const unsigned char *, size_t), - void *p_sni ) -{ - conf->f_sni = f_sni; - conf->p_sni = p_sni; -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_ALPN) -int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos ) -{ - size_t cur_len, tot_len; - const char **p; - - /* - * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings - * MUST NOT be truncated." - * We check lengths now rather than later. - */ - tot_len = 0; - for( p = protos; *p != NULL; p++ ) - { - cur_len = strlen( *p ); - tot_len += cur_len; - - if( ( cur_len == 0 ) || - ( cur_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN ) || - ( tot_len > MBEDTLS_SSL_MAX_ALPN_LIST_LEN ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - conf->alpn_list = protos; - - return( 0 ); -} - -const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ) -{ - return( ssl->alpn_chosen ); -} -#endif /* MBEDTLS_SSL_ALPN */ - -void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ) -{ - conf->max_major_ver = major; - conf->max_minor_ver = minor; -} - -void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ) -{ - conf->min_major_ver = major; - conf->min_minor_ver = minor; -} - -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) -void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ) -{ - conf->fallback = fallback; -} -#endif - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, - char cert_req_ca_list ) -{ - conf->cert_req_ca_list = cert_req_ca_list; -} -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ) -{ - conf->encrypt_then_mac = etm; -} -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ) -{ - conf->extended_ms = ems; -} -#endif - -#if defined(MBEDTLS_ARC4_C) -void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ) -{ - conf->arc4_disabled = arc4; -} -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ) -{ - if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID || - ssl_mfl_code_to_length( mfl_code ) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - conf->mfl_code = mfl_code; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate ) -{ - conf->trunc_hmac = truncate; -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) -void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split ) -{ - conf->cbc_record_splitting = split; -} -#endif - -void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ) -{ - conf->allow_legacy_renegotiation = allow_legacy; -} - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ) -{ - conf->disable_renegotiation = renegotiation; -} - -void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records ) -{ - conf->renego_max_records = max_records; -} - -void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, - const unsigned char period[8] ) -{ - memcpy( conf->renego_period, period, 8 ); -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#if defined(MBEDTLS_SSL_CLI_C) -void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets ) -{ - conf->session_tickets = use_tickets; -} -#endif - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_ticket_write_t *f_ticket_write, - mbedtls_ssl_ticket_parse_t *f_ticket_parse, - void *p_ticket ) -{ - conf->f_ticket_write = f_ticket_write; - conf->f_ticket_parse = f_ticket_parse; - conf->p_ticket = p_ticket; -} -#endif -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) -void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys ) -{ - conf->f_export_keys = f_export_keys; - conf->p_export_keys = p_export_keys; -} -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -void mbedtls_ssl_conf_async_private_cb( - mbedtls_ssl_config *conf, - mbedtls_ssl_async_sign_t *f_async_sign, - mbedtls_ssl_async_decrypt_t *f_async_decrypt, - mbedtls_ssl_async_resume_t *f_async_resume, - mbedtls_ssl_async_cancel_t *f_async_cancel, - void *async_config_data ) -{ - conf->f_async_sign_start = f_async_sign; - conf->f_async_decrypt_start = f_async_decrypt; - conf->f_async_resume = f_async_resume; - conf->f_async_cancel = f_async_cancel; - conf->p_async_config_data = async_config_data; -} - -void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ) -{ - return( conf->p_async_config_data ); -} - -void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ) -{ - if( ssl->handshake == NULL ) - return( NULL ); - else - return( ssl->handshake->user_async_ctx ); -} - -void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, - void *ctx ) -{ - if( ssl->handshake != NULL ) - ssl->handshake->user_async_ctx = ctx; -} -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -/* - * SSL get accessors - */ -size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ) -{ - return( ssl->in_offt == NULL ? 0 : ssl->in_msglen ); -} - -int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ) -{ - /* - * Case A: We're currently holding back - * a message for further processing. - */ - - if( ssl->keep_current_message == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) ); - return( 1 ); - } - - /* - * Case B: Further records are pending in the current datagram. - */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->in_left > ssl->next_record_offset ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) ); - return( 1 ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * Case C: A handshake message is being processed. - */ - - if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) ); - return( 1 ); - } - - /* - * Case D: An application data message is being processed - */ - if( ssl->in_offt != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) ); - return( 1 ); - } - - /* - * In all other cases, the rest of the message can be dropped. - * As in ssl_get_next_record, this needs to be adapted if - * we implement support for multiple alerts in single records. - */ - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) ); - return( 0 ); -} - -uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ) -{ - if( ssl->session != NULL ) - return( ssl->session->verify_result ); - - if( ssl->session_negotiate != NULL ) - return( ssl->session_negotiate->verify_result ); - - return( 0xFFFFFFFF ); -} - -const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl ) -{ - if( ssl == NULL || ssl->session == NULL ) - return( NULL ); - - return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite ); -} - -const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - switch( ssl->minor_ver ) - { - case MBEDTLS_SSL_MINOR_VERSION_2: - return( "DTLSv1.0" ); - - case MBEDTLS_SSL_MINOR_VERSION_3: - return( "DTLSv1.2" ); - - default: - return( "unknown (DTLS)" ); - } - } -#endif - - switch( ssl->minor_ver ) - { - case MBEDTLS_SSL_MINOR_VERSION_0: - return( "SSLv3.0" ); - - case MBEDTLS_SSL_MINOR_VERSION_1: - return( "TLSv1.0" ); - - case MBEDTLS_SSL_MINOR_VERSION_2: - return( "TLSv1.1" ); - - case MBEDTLS_SSL_MINOR_VERSION_3: - return( "TLSv1.2" ); - - default: - return( "unknown" ); - } -} - -int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) -{ - size_t transform_expansion = 0; - const mbedtls_ssl_transform *transform = ssl->transform_out; - unsigned block_size; - - if( transform == NULL ) - return( (int) mbedtls_ssl_hdr_len( ssl ) ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL ) - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -#endif - - switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) ) - { - case MBEDTLS_MODE_GCM: - case MBEDTLS_MODE_CCM: - case MBEDTLS_MODE_CHACHAPOLY: - case MBEDTLS_MODE_STREAM: - transform_expansion = transform->minlen; - break; - - case MBEDTLS_MODE_CBC: - - block_size = mbedtls_cipher_get_block_size( - &transform->cipher_ctx_enc ); - - /* Expansion due to the addition of the MAC. */ - transform_expansion += transform->maclen; - - /* Expansion due to the addition of CBC padding; - * Theoretically up to 256 bytes, but we never use - * more than the block size of the underlying cipher. */ - transform_expansion += block_size; - - /* For TLS 1.1 or higher, an explicit IV is added - * after the record header. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - transform_expansion += block_size; -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ - - break; - - default: - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) ); -} - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ) -{ - size_t max_len; - - /* - * Assume mfl_code is correct since it was checked when set - */ - max_len = ssl_mfl_code_to_length( ssl->conf->mfl_code ); - - /* Check if a smaller max length was negotiated */ - if( ssl->session_out != NULL && - ssl_mfl_code_to_length( ssl->session_out->mfl_code ) < max_len ) - { - max_len = ssl_mfl_code_to_length( ssl->session_out->mfl_code ); - } - - /* During a handshake, use the value being negotiated */ - if( ssl->session_negotiate != NULL && - ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ) < max_len ) - { - max_len = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ); - } - - return( max_len ); -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl ) -{ - /* Return unlimited mtu for client hello messages to avoid fragmentation. */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - ( ssl->state == MBEDTLS_SSL_CLIENT_HELLO || - ssl->state == MBEDTLS_SSL_SERVER_HELLO ) ) - return ( 0 ); - - if( ssl->handshake == NULL || ssl->handshake->mtu == 0 ) - return( ssl->mtu ); - - if( ssl->mtu == 0 ) - return( ssl->handshake->mtu ); - - return( ssl->mtu < ssl->handshake->mtu ? - ssl->mtu : ssl->handshake->mtu ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ) -{ - size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; - -#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ - !defined(MBEDTLS_SSL_PROTO_DTLS) - (void) ssl; -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl ); - - if( max_len > mfl ) - max_len = mfl; -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl_get_current_mtu( ssl ) != 0 ) - { - const size_t mtu = ssl_get_current_mtu( ssl ); - const int ret = mbedtls_ssl_get_record_expansion( ssl ); - const size_t overhead = (size_t) ret; - - if( ret < 0 ) - return( ret ); - - if( mtu <= overhead ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "MTU too low for record expansion" ) ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } - - if( max_len > mtu - overhead ) - max_len = mtu - overhead; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ - !defined(MBEDTLS_SSL_PROTO_DTLS) - ((void) ssl); -#endif - - return( (int) max_len ); -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ) -{ - if( ssl == NULL || ssl->session == NULL ) - return( NULL ); - - return( ssl->session->peer_cert ); -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *dst ) -{ - if( ssl == NULL || - dst == NULL || - ssl->session == NULL || - ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - return( ssl_session_copy( dst, ssl->session ) ); -} -#endif /* MBEDTLS_SSL_CLI_C */ - -/* - * Perform a single step of the SSL handshake - */ -int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - ret = mbedtls_ssl_handshake_client_step( ssl ); -#endif -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - ret = mbedtls_ssl_handshake_server_step( ssl ); -#endif - - return( ret ); -} - -/* - * Perform the SSL handshake - */ -int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) ); - - while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - { - ret = mbedtls_ssl_handshake_step( ssl ); - - if( ret != 0 ) - break; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= handshake" ) ); - - return( ret ); -} - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -#if defined(MBEDTLS_SSL_SRV_C) -/* - * Write HelloRequest to request renegotiation on server - */ -static int ssl_write_hello_request( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) ); - - ssl->out_msglen = 4; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello request" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SRV_C */ - -/* - * Actually renegotiate current connection, triggered by either: - * - any side: calling mbedtls_ssl_renegotiate(), - * - client: receiving a HelloRequest during mbedtls_ssl_read(), - * - server: receiving any handshake message on server during mbedtls_ssl_read() after - * the initial handshake is completed. - * If the handshake doesn't complete due to waiting for I/O, it will continue - * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively. - */ -static int ssl_start_renegotiation( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) ); - - if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) - return( ret ); - - /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and - * the ServerHello will have message_seq = 1" */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) - { - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - ssl->handshake->out_msg_seq = 1; - else - ssl->handshake->in_msg_seq = 1; - } -#endif - - ssl->state = MBEDTLS_SSL_HELLO_REQUEST; - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS; - - if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) ); - - return( 0 ); -} - -/* - * Renegotiate current connection on client, - * or request renegotiation on server - */ -int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_SSL_SRV_C) - /* On server, just send the request */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - { - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; - - /* Did we already try/start sending HelloRequest? */ - if( ssl->out_left != 0 ) - return( mbedtls_ssl_flush_output( ssl ) ); - - return( ssl_write_hello_request( ssl ) ); - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) - /* - * On client, either start the renegotiation process or, - * if already in progress, continue the handshake - */ - if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); - return( ret ); - } - } - else - { - if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_CLI_C */ - - return( ret ); -} - -/* - * Check record counters and renegotiate if they're above the limit. - */ -static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) -{ - size_t ep_len = ssl_ep_len( ssl ); - int in_ctr_cmp; - int out_ctr_cmp; - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || - ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) - { - return( 0 ); - } - - in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, - ssl->conf->renego_period + ep_len, 8 - ep_len ); - out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len, - ssl->conf->renego_period + ep_len, 8 - ep_len ); - - if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) - { - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) ); - return( mbedtls_ssl_renegotiate( ssl ) ); -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/* - * Receive application data decrypted from the SSL layer - */ -int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) -{ - int ret; - size_t n; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - if( ssl->handshake != NULL && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) - { - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - return( ret ); - } - } -#endif - - /* - * Check if renegotiation is necessary and/or handshake is - * in process. If yes, perform/continue, and fall through - * if an unexpected packet is received while the client - * is waiting for the ServerHello. - * - * (There is no equivalent to the last condition on - * the server-side as it is not treated as within - * a handshake while waiting for the ClientHello - * after a renegotiation request.) - */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ret = ssl_check_ctr_renegotiate( ssl ); - if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && - ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); - return( ret ); - } -#endif - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - { - ret = mbedtls_ssl_handshake( ssl ); - if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && - ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); - return( ret ); - } - } - - /* Loop as long as no application data record is available */ - while( ssl->in_offt == NULL ) - { - /* Start timer if not already running */ - if( ssl->f_get_timer != NULL && - ssl->f_get_timer( ssl->p_timer ) == -1 ) - { - ssl_set_timer( ssl, ssl->conf->read_timeout ); - } - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msglen == 0 && - ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - /* - * OpenSSL sends empty messages to randomize the IV - */ - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - } - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); - - /* - * - For client-side, expect SERVER_HELLO_REQUEST. - * - For server-side, expect CLIENT_HELLO. - * - Fail (TLS) or silently drop record (DTLS) in other cases. - */ - -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || - ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) ); - - /* With DTLS, drop the packet (probably from last handshake) */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - continue; - } -#endif - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } -#endif /* MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) ); - - /* With DTLS, drop the packet (probably from last handshake) */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - continue; - } -#endif - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - /* Determine whether renegotiation attempt should be accepted */ - if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || - ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == - MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) ) - { - /* - * Accept renegotiation request - */ - - /* DTLS clients need to know renego is server-initiated */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - { - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; - } -#endif - ret = ssl_start_renegotiation( ssl ); - if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && - ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - /* - * Refuse renegotiation - */ - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - /* SSLv3 does not have a "no_renegotiation" warning, so - we send a fatal alert and abort the connection. */ - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) - { - if( ( ret = mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_WARNING, - MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 ) - { - return( ret ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - - /* At this point, we don't know whether the renegotiation has been - * completed or not. The cases to consider are the following: - * 1) The renegotiation is complete. In this case, no new record - * has been read yet. - * 2) The renegotiation is incomplete because the client received - * an application data record while awaiting the ServerHello. - * 3) The renegotiation is incomplete because the client received - * a non-handshake, non-application data message while awaiting - * the ServerHello. - * In each of these case, looping will be the proper action: - * - For 1), the next iteration will read a new record and check - * if it's application data. - * - For 2), the loop condition isn't satisfied as application data - * is present, hence continue is the same as break - * - For 3), the loop condition is satisfied and read_record - * will re-deliver the message that was held back by the client - * when expecting the ServerHello. - */ - continue; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) - { - if( ssl->conf->renego_max_records >= 0 ) - { - if( ++ssl->renego_records_seen > ssl->conf->renego_max_records ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " - "but not honored by client" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - } - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */ - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) ); - return( MBEDTLS_ERR_SSL_WANT_READ ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - ssl->in_offt = ssl->in_msg; - - /* We're going to return something now, cancel timer, - * except if handshake (renegotiation) is in progress */ - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - ssl_set_timer( ssl, 0 ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* If we requested renego but received AppData, resend HelloRequest. - * Do it now, after setting in_offt, to avoid taking this branch - * again if ssl_write_hello_request() returns WANT_WRITE */ -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) - { - if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - } - - n = ( len < ssl->in_msglen ) - ? len : ssl->in_msglen; - - memcpy( buf, ssl->in_offt, n ); - ssl->in_msglen -= n; - - /* Zeroising the plaintext buffer to erase unused application data - from the memory. */ - mbedtls_platform_zeroize( ssl->in_offt, n ); - - if( ssl->in_msglen == 0 ) - { - /* all bytes consumed */ - ssl->in_offt = NULL; - ssl->keep_current_message = 0; - } - else - { - /* more data available */ - ssl->in_offt += n; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) ); - - return( (int) n ); -} - -/* - * Send application data to be encrypted by the SSL layer, taking care of max - * fragment length and buffer size. - * - * According to RFC 5246 Section 6.2.1: - * - * Zero-length fragments of Application data MAY be sent as they are - * potentially useful as a traffic analysis countermeasure. - * - * Therefore, it is possible that the input message length is 0 and the - * corresponding return code is 0 on success. - */ -static int ssl_write_real( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - int ret = mbedtls_ssl_get_max_out_record_payload( ssl ); - const size_t max_len = (size_t) ret; - - if( ret < 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret ); - return( ret ); - } - - if( len > max_len ) - { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) " - "maximum fragment length: %d > %d", - len, max_len ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - else -#endif - len = max_len; - } - - if( ssl->out_left != 0 ) - { - /* - * The user has previously tried to send the data and - * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially - * written. In this case, we expect the high-level write function - * (e.g. mbedtls_ssl_write()) to be called with the same parameters - */ - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); - return( ret ); - } - } - else - { - /* - * The user is trying to send a message the first time, so we need to - * copy the data into the internal buffers and setup the data structure - * to keep track of partial writes - */ - ssl->out_msglen = len; - ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; - memcpy( ssl->out_msg, buf, len ); - - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); - return( ret ); - } - } - - return( (int) len ); -} - -/* - * Write application data, doing 1/n-1 splitting if necessary. - * - * With non-blocking I/O, ssl_write_real() may return WANT_WRITE, - * then the caller will call us again with the same arguments, so - * remember whether we already did the split or not. - */ -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) -static int ssl_write_split( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - int ret; - - if( ssl->conf->cbc_record_splitting == - MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED || - len <= 1 || - ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 || - mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ) - != MBEDTLS_MODE_CBC ) - { - return( ssl_write_real( ssl, buf, len ) ); - } - - if( ssl->split_done == 0 ) - { - if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 ) - return( ret ); - ssl->split_done = 1; - } - - if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 ) - return( ret ); - ssl->split_done = 0; - - return( ret + 1 ); -} -#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ - -/* - * Write application data (public-facing wrapper) - */ -int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) ); - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); - return( ret ); - } -#endif - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - { - if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); - return( ret ); - } - } - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - ret = ssl_write_split( ssl, buf, len ); -#else - ret = ssl_write_real( ssl, buf, len ); -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) ); - - return( ret ); -} - -/* - * Notify the peer that the connection is being closed - */ -int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ) -{ - int ret; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) ); - - if( ssl->out_left != 0 ) - return( mbedtls_ssl_flush_output( ssl ) ); - - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - { - if( ( ret = mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_WARNING, - MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret ); - return( ret ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) ); - - return( 0 ); -} - -void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ) -{ - if( transform == NULL ) - return; - -#if defined(MBEDTLS_ZLIB_SUPPORT) - deflateEnd( &transform->ctx_deflate ); - inflateEnd( &transform->ctx_inflate ); -#endif - - mbedtls_cipher_free( &transform->cipher_ctx_enc ); - mbedtls_cipher_free( &transform->cipher_ctx_dec ); - - mbedtls_md_free( &transform->md_ctx_enc ); - mbedtls_md_free( &transform->md_ctx_dec ); - - mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) ); -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert ) -{ - mbedtls_ssl_key_cert *cur = key_cert, *next; - - while( cur != NULL ) - { - next = cur->next; - mbedtls_free( cur ); - cur = next; - } -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -static void ssl_buffering_free( mbedtls_ssl_context *ssl ) -{ - unsigned offset; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if( hs == NULL ) - return; - - ssl_free_buffered_record( ssl ); - - for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) - ssl_buffering_free_slot( ssl, offset ); -} - -static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, - uint8_t slot ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot]; - - if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS ) - return; - - if( hs_buf->is_valid == 1 ) - { - hs->buffering.total_bytes_buffered -= hs_buf->data_len; - mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len ); - mbedtls_free( hs_buf->data ); - memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); - } -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - if( handshake == NULL ) - return; - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 ) - { - ssl->conf->f_async_cancel( ssl ); - handshake->async_in_progress = 0; - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_free( &handshake->fin_md5 ); - mbedtls_sha1_free( &handshake->fin_sha1 ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) - mbedtls_sha256_free( &handshake->fin_sha256 ); -#endif -#if defined(MBEDTLS_SHA512_C) - mbedtls_sha512_free( &handshake->fin_sha512 ); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_free( &handshake->dhm_ctx ); -#endif -#if defined(MBEDTLS_ECDH_C) - mbedtls_ecdh_free( &handshake->ecdh_ctx ); -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - mbedtls_ecjpake_free( &handshake->ecjpake_ctx ); -#if defined(MBEDTLS_SSL_CLI_C) - mbedtls_free( handshake->ecjpake_cache ); - handshake->ecjpake_cache = NULL; - handshake->ecjpake_cache_len = 0; -#endif -#endif - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - /* explicit void pointer cast for buggy MS compiler */ - mbedtls_free( (void *) handshake->curves ); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( handshake->psk != NULL ) - { - mbedtls_platform_zeroize( handshake->psk, handshake->psk_len ); - mbedtls_free( handshake->psk ); - } -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - /* - * Free only the linked list wrapper, not the keys themselves - * since the belong to the SNI callback - */ - if( handshake->sni_key_cert != NULL ) - { - mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next; - - while( cur != NULL ) - { - next = cur->next; - mbedtls_free( cur ); - cur = next; - } - } -#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx ); -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - mbedtls_free( handshake->verify_cookie ); - ssl_flight_free( handshake->flight ); - ssl_buffering_free( ssl ); -#endif - - mbedtls_platform_zeroize( handshake, - sizeof( mbedtls_ssl_handshake_params ) ); -} - -void mbedtls_ssl_session_free( mbedtls_ssl_session *session ) -{ - if( session == NULL ) - return; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - if( session->peer_cert != NULL ) - { - mbedtls_x509_crt_free( session->peer_cert ); - mbedtls_free( session->peer_cert ); - } -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - mbedtls_free( session->ticket ); -#endif - - mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) ); -} - -/* - * Free an SSL context - */ -void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) -{ - if( ssl == NULL ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> free" ) ); - - if( ssl->out_buf != NULL ) - { - mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN ); - mbedtls_free( ssl->out_buf ); - } - - if( ssl->in_buf != NULL ) - { - mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN ); - mbedtls_free( ssl->in_buf ); - } - -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->compress_buf != NULL ) - { - mbedtls_platform_zeroize( ssl->compress_buf, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); - mbedtls_free( ssl->compress_buf ); - } -#endif - - if( ssl->transform ) - { - mbedtls_ssl_transform_free( ssl->transform ); - mbedtls_free( ssl->transform ); - } - - if( ssl->handshake ) - { - mbedtls_ssl_handshake_free( ssl ); - mbedtls_ssl_transform_free( ssl->transform_negotiate ); - mbedtls_ssl_session_free( ssl->session_negotiate ); - - mbedtls_free( ssl->handshake ); - mbedtls_free( ssl->transform_negotiate ); - mbedtls_free( ssl->session_negotiate ); - } - - if( ssl->session ) - { - mbedtls_ssl_session_free( ssl->session ); - mbedtls_free( ssl->session ); - } - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - if( ssl->hostname != NULL ) - { - mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) ); - mbedtls_free( ssl->hostname ); - } -#endif - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_finish != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_finish()" ) ); - mbedtls_ssl_hw_record_finish( ssl ); - } -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - mbedtls_free( ssl->cli_id ); -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) ); - - /* Actually clear after last debug message */ - mbedtls_platform_zeroize( ssl, sizeof( mbedtls_ssl_context ) ); -} - -/* - * Initialze mbedtls_ssl_config - */ -void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ) -{ - memset( conf, 0, sizeof( mbedtls_ssl_config ) ); -} - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -static int ssl_preset_default_hashes[] = { -#if defined(MBEDTLS_SHA512_C) - MBEDTLS_MD_SHA512, - MBEDTLS_MD_SHA384, -#endif -#if defined(MBEDTLS_SHA256_C) - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA224, -#endif -#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE) - MBEDTLS_MD_SHA1, -#endif - MBEDTLS_MD_NONE -}; -#endif - -static int ssl_preset_suiteb_ciphersuites[] = { - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - 0 -}; - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -static int ssl_preset_suiteb_hashes[] = { - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA384, - MBEDTLS_MD_NONE -}; -#endif - -#if defined(MBEDTLS_ECP_C) -static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - MBEDTLS_ECP_DP_SECP256R1, -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - MBEDTLS_ECP_DP_SECP384R1, -#endif - MBEDTLS_ECP_DP_NONE -}; -#endif - -/* - * Load default in mbedtls_ssl_config - */ -int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, - int endpoint, int transport, int preset ) -{ -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - int ret; -#endif - - /* Use the functions here so that they are covered in tests, - * but otherwise access member directly for efficiency */ - mbedtls_ssl_conf_endpoint( conf, endpoint ); - mbedtls_ssl_conf_transport( conf, transport ); - - /* - * Things that are common to all presets - */ -#if defined(MBEDTLS_SSL_CLI_C) - if( endpoint == MBEDTLS_SSL_IS_CLIENT ) - { - conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED; -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED; -#endif - } -#endif - -#if defined(MBEDTLS_ARC4_C) - conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - conf->f_cookie_write = ssl_cookie_write_dummy; - conf->f_cookie_check = ssl_cookie_check_dummy; -#endif - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_SRV_C) - conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN; - conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX; -#endif - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT; - memset( conf->renego_period, 0x00, 2 ); - memset( conf->renego_period + 2, 0xFF, 6 ); -#endif - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - if( endpoint == MBEDTLS_SSL_IS_SERVER ) - { - const unsigned char dhm_p[] = - MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN; - const unsigned char dhm_g[] = - MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN; - - if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf, - dhm_p, sizeof( dhm_p ), - dhm_g, sizeof( dhm_g ) ) ) != 0 ) - { - return( ret ); - } - } -#endif - - /* - * Preset-specific defaults - */ - switch( preset ) - { - /* - * NSA Suite B - */ - case MBEDTLS_SSL_PRESET_SUITEB: - conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; - conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ - conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; - conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; - - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = - ssl_preset_suiteb_ciphersuites; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - conf->cert_profile = &mbedtls_x509_crt_profile_suiteb; -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - conf->sig_hashes = ssl_preset_suiteb_hashes; -#endif - -#if defined(MBEDTLS_ECP_C) - conf->curve_list = ssl_preset_suiteb_curves; -#endif - break; - - /* - * Default - */ - default: - conf->min_major_ver = ( MBEDTLS_SSL_MIN_MAJOR_VERSION > - MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION ) ? - MBEDTLS_SSL_MIN_MAJOR_VERSION : - MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION; - conf->min_minor_ver = ( MBEDTLS_SSL_MIN_MINOR_VERSION > - MBEDTLS_SSL_MIN_VALID_MINOR_VERSION ) ? - MBEDTLS_SSL_MIN_MINOR_VERSION : - MBEDTLS_SSL_MIN_VALID_MINOR_VERSION; - conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; - conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2; -#endif - - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = - mbedtls_ssl_list_ciphersuites(); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - conf->cert_profile = &mbedtls_x509_crt_profile_default; -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - conf->sig_hashes = ssl_preset_default_hashes; -#endif - -#if defined(MBEDTLS_ECP_C) - conf->curve_list = mbedtls_ecp_grp_id_list(); -#endif - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) - conf->dhm_min_bitlen = 1024; -#endif - } - - return( 0 ); -} - -/* - * Free mbedtls_ssl_config - */ -void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ) -{ -#if defined(MBEDTLS_DHM_C) - mbedtls_mpi_free( &conf->dhm_P ); - mbedtls_mpi_free( &conf->dhm_G ); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( conf->psk != NULL ) - { - mbedtls_platform_zeroize( conf->psk, conf->psk_len ); - mbedtls_free( conf->psk ); - conf->psk = NULL; - conf->psk_len = 0; - } - - if( conf->psk_identity != NULL ) - { - mbedtls_platform_zeroize( conf->psk_identity, conf->psk_identity_len ); - mbedtls_free( conf->psk_identity ); - conf->psk_identity = NULL; - conf->psk_identity_len = 0; - } -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - ssl_key_cert_free( conf->key_cert ); -#endif - - mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) ); -} - -#if defined(MBEDTLS_PK_C) && \ - ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) ) -/* - * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX - */ -unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ) -{ -#if defined(MBEDTLS_RSA_C) - if( mbedtls_pk_can_do( pk, MBEDTLS_PK_RSA ) ) - return( MBEDTLS_SSL_SIG_RSA ); -#endif -#if defined(MBEDTLS_ECDSA_C) - if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECDSA ) ) - return( MBEDTLS_SSL_SIG_ECDSA ); -#endif - return( MBEDTLS_SSL_SIG_ANON ); -} - -unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type ) -{ - switch( type ) { - case MBEDTLS_PK_RSA: - return( MBEDTLS_SSL_SIG_RSA ); - case MBEDTLS_PK_ECDSA: - case MBEDTLS_PK_ECKEY: - return( MBEDTLS_SSL_SIG_ECDSA ); - default: - return( MBEDTLS_SSL_SIG_ANON ); - } -} - -mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ) -{ - switch( sig ) - { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_SSL_SIG_RSA: - return( MBEDTLS_PK_RSA ); -#endif -#if defined(MBEDTLS_ECDSA_C) - case MBEDTLS_SSL_SIG_ECDSA: - return( MBEDTLS_PK_ECDSA ); -#endif - default: - return( MBEDTLS_PK_NONE ); - } -} -#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - -/* Find an entry in a signature-hash set matching a given hash algorithm. */ -mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_pk_type_t sig_alg ) -{ - switch( sig_alg ) - { - case MBEDTLS_PK_RSA: - return( set->rsa ); - case MBEDTLS_PK_ECDSA: - return( set->ecdsa ); - default: - return( MBEDTLS_MD_NONE ); - } -} - -/* Add a signature-hash-pair to a signature-hash set */ -void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_pk_type_t sig_alg, - mbedtls_md_type_t md_alg ) -{ - switch( sig_alg ) - { - case MBEDTLS_PK_RSA: - if( set->rsa == MBEDTLS_MD_NONE ) - set->rsa = md_alg; - break; - - case MBEDTLS_PK_ECDSA: - if( set->ecdsa == MBEDTLS_MD_NONE ) - set->ecdsa = md_alg; - break; - - default: - break; - } -} - -/* Allow exactly one hash algorithm for each signature. */ -void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_md_type_t md_alg ) -{ - set->rsa = md_alg; - set->ecdsa = md_alg; -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2) && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -/* - * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX - */ -mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ) -{ - switch( hash ) - { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_SSL_HASH_MD5: - return( MBEDTLS_MD_MD5 ); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_SSL_HASH_SHA1: - return( MBEDTLS_MD_SHA1 ); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_SSL_HASH_SHA224: - return( MBEDTLS_MD_SHA224 ); - case MBEDTLS_SSL_HASH_SHA256: - return( MBEDTLS_MD_SHA256 ); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_SSL_HASH_SHA384: - return( MBEDTLS_MD_SHA384 ); - case MBEDTLS_SSL_HASH_SHA512: - return( MBEDTLS_MD_SHA512 ); -#endif - default: - return( MBEDTLS_MD_NONE ); - } -} - -/* - * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX - */ -unsigned char mbedtls_ssl_hash_from_md_alg( int md ) -{ - switch( md ) - { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - return( MBEDTLS_SSL_HASH_MD5 ); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - return( MBEDTLS_SSL_HASH_SHA1 ); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA224: - return( MBEDTLS_SSL_HASH_SHA224 ); - case MBEDTLS_MD_SHA256: - return( MBEDTLS_SSL_HASH_SHA256 ); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA384: - return( MBEDTLS_SSL_HASH_SHA384 ); - case MBEDTLS_MD_SHA512: - return( MBEDTLS_SSL_HASH_SHA512 ); -#endif - default: - return( MBEDTLS_SSL_HASH_NONE ); - } -} - -#if defined(MBEDTLS_ECP_C) -/* - * Check if a curve proposed by the peer is in our list. - * Return 0 if we're willing to use it, -1 otherwise. - */ -int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ) -{ - const mbedtls_ecp_group_id *gid; - - if( ssl->conf->curve_list == NULL ) - return( -1 ); - - for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) - if( *gid == grp_id ) - return( 0 ); - - return( -1 ); -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -/* - * Check if a hash proposed by the peer is in our list. - * Return 0 if we're willing to use it, -1 otherwise. - */ -int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, - mbedtls_md_type_t md ) -{ - const int *cur; - - if( ssl->conf->sig_hashes == NULL ) - return( -1 ); - - for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) - if( *cur == (int) md ) - return( 0 ); - - return( -1 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, - const mbedtls_ssl_ciphersuite_t *ciphersuite, - int cert_endpoint, - uint32_t *flags ) -{ - int ret = 0; -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - int usage = 0; -#endif -#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) - const char *ext_oid; - size_t ext_len; -#endif - -#if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) && \ - !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) - ((void) cert); - ((void) cert_endpoint); - ((void) flags); -#endif - -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - if( cert_endpoint == MBEDTLS_SSL_IS_SERVER ) - { - /* Server part of the key exchange */ - switch( ciphersuite->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT; - break; - - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; - break; - - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - usage = MBEDTLS_X509_KU_KEY_AGREEMENT; - break; - - /* Don't use default: we want warnings when adding new values */ - case MBEDTLS_KEY_EXCHANGE_NONE: - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - usage = 0; - } - } - else - { - /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */ - usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; - } - - if( mbedtls_x509_crt_check_key_usage( cert, usage ) != 0 ) - { - *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE; - ret = -1; - } -#else - ((void) ciphersuite); -#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */ - -#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) - if( cert_endpoint == MBEDTLS_SSL_IS_SERVER ) - { - ext_oid = MBEDTLS_OID_SERVER_AUTH; - ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH ); - } - else - { - ext_oid = MBEDTLS_OID_CLIENT_AUTH; - ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH ); - } - - if( mbedtls_x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 ) - { - *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE; - ret = -1; - } -#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ - - return( ret ); -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/* - * Convert version numbers to/from wire format - * and, for DTLS, to/from TLS equivalent. - * - * For TLS this is the identity. - * For DTLS, use 1's complement (v -> 255 - v, and then map as follows: - * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) - * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) - */ -void mbedtls_ssl_write_version( int major, int minor, int transport, - unsigned char ver[2] ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - if( minor == MBEDTLS_SSL_MINOR_VERSION_2 ) - --minor; /* DTLS 1.0 stored as TLS 1.1 internally */ - - ver[0] = (unsigned char)( 255 - ( major - 2 ) ); - ver[1] = (unsigned char)( 255 - ( minor - 1 ) ); - } - else -#else - ((void) transport); -#endif - { - ver[0] = (unsigned char) major; - ver[1] = (unsigned char) minor; - } -} - -void mbedtls_ssl_read_version( int *major, int *minor, int transport, - const unsigned char ver[2] ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - *major = 255 - ver[0] + 2; - *minor = 255 - ver[1] + 1; - - if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 ) - ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */ - } - else -#else - ((void) transport); -#endif - { - *major = ver[0]; - *minor = ver[1]; - } -} - -int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ) -{ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; - - switch( md ) - { -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_SSL_HASH_MD5: - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_SSL_HASH_SHA1: - ssl->handshake->calc_verify = ssl_calc_verify_tls; - break; -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_SSL_HASH_SHA384: - ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384; - break; -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_SSL_HASH_SHA256: - ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256; - break; -#endif - default: - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; - } - - return 0; -#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */ - (void) ssl; - (void) md; - - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, - unsigned char *output, - unsigned char *data, size_t data_len ) -{ - int ret = 0; - mbedtls_md5_context mbedtls_md5; - mbedtls_sha1_context mbedtls_sha1; - - mbedtls_md5_init( &mbedtls_md5 ); - mbedtls_sha1_init( &mbedtls_sha1 ); - - /* - * digitally-signed struct { - * opaque md5_hash[16]; - * opaque sha_hash[20]; - * }; - * - * md5_hash - * MD5(ClientHello.random + ServerHello.random - * + ServerParams); - * sha_hash - * SHA(ClientHello.random + ServerHello.random - * + ServerParams); - */ - if( ( ret = mbedtls_md5_starts_ret( &mbedtls_md5 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_starts_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, - ssl->handshake->randbytes, 64 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, data, data_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_md5_finish_ret( &mbedtls_md5, output ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_finish_ret", ret ); - goto exit; - } - - if( ( ret = mbedtls_sha1_starts_ret( &mbedtls_sha1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_starts_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, - ssl->handshake->randbytes, 64 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, data, - data_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_sha1_finish_ret( &mbedtls_sha1, - output + 16 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_finish_ret", ret ); - goto exit; - } - -exit: - mbedtls_md5_free( &mbedtls_md5 ); - mbedtls_sha1_free( &mbedtls_sha1 ); - - if( ret != 0 ) - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - - return( ret ); - -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) -int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg ) -{ - int ret = 0; - mbedtls_md_context_t ctx; - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); - *hashlen = mbedtls_md_get_size( md_info ); - - mbedtls_md_init( &ctx ); - - /* - * digitally-signed struct { - * opaque client_random[32]; - * opaque server_random[32]; - * ServerDHParams params; - * }; - */ - if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); - goto exit; - } - if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_starts", ret ); - goto exit; - } - if( ( ret = mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret ); - goto exit; - } - if( ( ret = mbedtls_md_update( &ctx, data, data_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret ); - goto exit; - } - if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret ); - goto exit; - } - -exit: - mbedtls_md_free( &ctx ); - - if( ret != 0 ) - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - - return( ret ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - -#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/mbedtls/threading.c b/mbedtls/threading.c deleted file mode 100644 index da5f55697..000000000 --- a/mbedtls/threading.c +++ /dev/null @@ -1,231 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Threading abstraction layer - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -/* - * Ensure gmtime_r is available even with -std=c99; must be defined before - * config.h, which pulls in glibc's features.h. Harmless on other platforms. - */ -#if !defined(_POSIX_C_SOURCE) -#define _POSIX_C_SOURCE 200112L -#endif - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_THREADING_C) - -#include "mbedtls/threading.h" - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) - -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__))) -#include -#endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__)) */ - -#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) -/* - * This is a convenience shorthand macro to avoid checking the long - * preprocessor conditions above. Ideally, we could expose this macro in - * platform_util.h and simply use it in platform_util.c, threading.c and - * threading.h. However, this macro is not part of the Mbed TLS public API, so - * we keep it private by only defining it in this file - */ - -#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) -#define THREADING_USE_GMTIME -#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ - -#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */ - -#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ - -#if defined(MBEDTLS_THREADING_PTHREAD) -static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL ) - return; - - /* A nonzero value of is_valid indicates a successfully initialized - * mutex. This is a workaround for not being able to return an error - * code for this function. The lock/unlock functions return an error - * if is_valid is nonzero. The Mbed TLS unit test code uses this field - * to distinguish more states of the mutex; see helpers.function for - * details. */ - mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0; -} - -static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL || !mutex->is_valid ) - return; - - (void) pthread_mutex_destroy( &mutex->mutex ); - mutex->is_valid = 0; -} - -static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL || ! mutex->is_valid ) - return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); - - if( pthread_mutex_lock( &mutex->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); - - return( 0 ); -} - -static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex ) -{ - if( mutex == NULL || ! mutex->is_valid ) - return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); - - if( pthread_mutex_unlock( &mutex->mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); - - return( 0 ); -} - -void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread; -void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread; -int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread; -int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread; - -/* - * With phtreads we can statically initialize mutexes - */ -#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 } - -#endif /* MBEDTLS_THREADING_PTHREAD */ - -#if defined(MBEDTLS_THREADING_ALT) -static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex ) -{ - ((void) mutex ); - return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); -} -static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex ) -{ - ((void) mutex ); - return; -} - -void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; -void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; -int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; -int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; - -/* - * Set functions pointers and initialize global mutexes - */ -void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), - void (*mutex_free)( mbedtls_threading_mutex_t * ), - int (*mutex_lock)( mbedtls_threading_mutex_t * ), - int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ) -{ - mbedtls_mutex_init = mutex_init; - mbedtls_mutex_free = mutex_free; - mbedtls_mutex_lock = mutex_lock; - mbedtls_mutex_unlock = mutex_unlock; - -#if defined(MBEDTLS_FS_IO) - mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); -#endif -#if defined(THREADING_USE_GMTIME) - mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); -#endif -} - -/* - * Free global mutexes - */ -void mbedtls_threading_free_alt( void ) -{ -#if defined(MBEDTLS_FS_IO) - mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); -#endif -#if defined(THREADING_USE_GMTIME) - mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); -#endif -} -#endif /* MBEDTLS_THREADING_ALT */ - -/* - * Define global mutexes - */ -#ifndef MUTEX_INIT -#define MUTEX_INIT -#endif -#if defined(MBEDTLS_FS_IO) -mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; -#endif -#if defined(THREADING_USE_GMTIME) -mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; -#endif - -#endif /* MBEDTLS_THREADING_C */ diff --git a/mbedtls/threading.h b/mbedtls/threading.h deleted file mode 100644 index 13683ad19..000000000 --- a/mbedtls/threading.h +++ /dev/null @@ -1,151 +0,0 @@ -#pragma GCC system_header -/** - * \file threading.h - * - * \brief Threading abstraction layer - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_THREADING_H -#define MBEDTLS_THREADING_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be - * used. */ -#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */ - -#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */ - -#if defined(MBEDTLS_THREADING_PTHREAD) -#include -typedef struct mbedtls_threading_mutex_t -{ - pthread_mutex_t mutex; - /* is_valid is 0 after a failed init or a free, and nonzero after a - * successful init. This field is not considered part of the public - * API of Mbed TLS and may change without notice. */ - char is_valid; -} mbedtls_threading_mutex_t; -#endif - -#if defined(MBEDTLS_THREADING_ALT) -/* You should define the mbedtls_threading_mutex_t type in your header */ -#include "threading_alt.h" - -/** - * \brief Set your alternate threading implementation function - * pointers and initialize global mutexes. If used, this - * function must be called once in the main thread before any - * other mbed TLS function is called, and - * mbedtls_threading_free_alt() must be called once in the main - * thread after all other mbed TLS functions. - * - * \note mutex_init() and mutex_free() don't return a status code. - * If mutex_init() fails, it should leave its argument (the - * mutex) in a state such that mutex_lock() will fail when - * called with this argument. - * - * \param mutex_init the init function implementation - * \param mutex_free the free function implementation - * \param mutex_lock the lock function implementation - * \param mutex_unlock the unlock function implementation - */ -void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), - void (*mutex_free)( mbedtls_threading_mutex_t * ), - int (*mutex_lock)( mbedtls_threading_mutex_t * ), - int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ); - -/** - * \brief Free global mutexes. - */ -void mbedtls_threading_free_alt( void ); -#endif /* MBEDTLS_THREADING_ALT */ - -#if defined(MBEDTLS_THREADING_C) -/* - * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock - * - * All these functions are expected to work or the result will be undefined. - */ -extern void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t *mutex ); -extern void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t *mutex ); -extern int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t *mutex ); -extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex ); - -/* - * Global mutexes - */ -#if defined(MBEDTLS_FS_IO) -extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; -#endif - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -/* This mutex may or may not be used in the default definition of - * mbedtls_platform_gmtime_r(), but in order to determine that, - * we need to check POSIX features, hence modify _POSIX_C_SOURCE. - * With the current approach, this declaration is orphaned, lacking - * an accompanying definition, in case mbedtls_platform_gmtime_r() - * doesn't need it, but that's not a problem. */ -extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; -#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ - -#endif /* MBEDTLS_THREADING_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* threading.h */ diff --git a/mbedtls/timing.c b/mbedtls/timing.c deleted file mode 100644 index bacb0c5c4..000000000 --- a/mbedtls/timing.c +++ /dev/null @@ -1,574 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Portable interface to the CPU cycle counter - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif - -#if defined(MBEDTLS_TIMING_C) - -#include "mbedtls/timing.h" - -#if !defined(MBEDTLS_TIMING_ALT) - -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) -#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h" -#endif - -#ifndef asm -#define asm __asm -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - -#include -#include - -struct _hr_time -{ - LARGE_INTEGER start; -}; - -#else - -#include -#include -#include -#include -#include - -struct _hr_time -{ - struct timeval start; -}; - -#endif /* _WIN32 && !EFIX64 && !EFI32 */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tsc; - __asm rdtsc - __asm mov [tsc], eax - return( tsc ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ - -/* some versions of mingw-64 have 32-bit longs even on x84_64 */ -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && ( defined(__i386__) || ( \ - ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) ) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long lo, hi; - asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); - return( lo ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __i386__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) ) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long lo, hi; - asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); - return( lo | ( hi << 32 ) ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && ( __amd64__ || __x86_64__ ) */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) ) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tbl, tbu0, tbu1; - - do - { - asm volatile( "mftbu %0" : "=r" (tbu0) ); - asm volatile( "mftb %0" : "=r" (tbl ) ); - asm volatile( "mftbu %0" : "=r" (tbu1) ); - } - while( tbu0 != tbu1 ); - - return( tbl ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && ( __powerpc__ || __ppc__ ) */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__sparc64__) - -#if defined(__OpenBSD__) -#warning OpenBSD does not allow access to tick register using software version instead -#else -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tick; - asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); - return( tick ); -} -#endif /* __OpenBSD__ */ -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __sparc64__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long tick; - asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); - asm volatile( "mov %%g1, %0" : "=r" (tick) ); - return( tick ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __sparc__ && !__sparc64__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__alpha__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long cc; - asm volatile( "rpcc %0" : "=r" (cc) ); - return( cc & 0xFFFFFFFF ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __alpha__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ - defined(__GNUC__) && defined(__ia64__) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - unsigned long itc; - asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); - return( itc ); -} -#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && - __GNUC__ && __ia64__ */ - -#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \ - !defined(EFIX64) && !defined(EFI32) - -#define HAVE_HARDCLOCK - -unsigned long mbedtls_timing_hardclock( void ) -{ - LARGE_INTEGER offset; - - QueryPerformanceCounter( &offset ); - - return( (unsigned long)( offset.QuadPart ) ); -} -#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ - -#if !defined(HAVE_HARDCLOCK) - -#define HAVE_HARDCLOCK - -static int hardclock_init = 0; -static struct timeval tv_init; - -unsigned long mbedtls_timing_hardclock( void ) -{ - struct timeval tv_cur; - - if( hardclock_init == 0 ) - { - gettimeofday( &tv_init, NULL ); - hardclock_init = 1; - } - - gettimeofday( &tv_cur, NULL ); - return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 - + ( tv_cur.tv_usec - tv_init.tv_usec ) ); -} -#endif /* !HAVE_HARDCLOCK */ - -volatile int mbedtls_timing_alarmed = 0; - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - -unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) -{ - struct _hr_time *t = (struct _hr_time *) val; - - if( reset ) - { - QueryPerformanceCounter( &t->start ); - return( 0 ); - } - else - { - unsigned long delta; - LARGE_INTEGER now, hfreq; - QueryPerformanceCounter( &now ); - QueryPerformanceFrequency( &hfreq ); - delta = (unsigned long)( ( now.QuadPart - t->start.QuadPart ) * 1000ul - / hfreq.QuadPart ); - return( delta ); - } -} - -/* It's OK to use a global because alarm() is supposed to be global anyway */ -static DWORD alarmMs; - -static void TimerProc( void *TimerContext ) -{ - (void) TimerContext; - Sleep( alarmMs ); - mbedtls_timing_alarmed = 1; - /* _endthread will be called implicitly on return - * That ensures execution of thread funcition's epilogue */ -} - -void mbedtls_set_alarm( int seconds ) -{ - if( seconds == 0 ) - { - /* No need to create a thread for this simple case. - * Also, this shorcut is more reliable at least on MinGW32 */ - mbedtls_timing_alarmed = 1; - return; - } - - mbedtls_timing_alarmed = 0; - alarmMs = seconds * 1000; - (void) _beginthread( TimerProc, 0, NULL ); -} - -#else /* _WIN32 && !EFIX64 && !EFI32 */ - -unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) -{ - struct _hr_time *t = (struct _hr_time *) val; - - if( reset ) - { - gettimeofday( &t->start, NULL ); - return( 0 ); - } - else - { - unsigned long delta; - struct timeval now; - gettimeofday( &now, NULL ); - delta = ( now.tv_sec - t->start.tv_sec ) * 1000ul - + ( now.tv_usec - t->start.tv_usec ) / 1000; - return( delta ); - } -} - -static void sighandler( int signum ) -{ - mbedtls_timing_alarmed = 1; - signal( signum, sighandler ); -} - -void mbedtls_set_alarm( int seconds ) -{ - mbedtls_timing_alarmed = 0; - signal( SIGALRM, sighandler ); - alarm( seconds ); - if( seconds == 0 ) - { - /* alarm(0) cancelled any previous pending alarm, but the - handler won't fire, so raise the flag straight away. */ - mbedtls_timing_alarmed = 1; - } -} - -#endif /* _WIN32 && !EFIX64 && !EFI32 */ - -/* - * Set delays to watch - */ -void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ) -{ - mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; - - ctx->int_ms = int_ms; - ctx->fin_ms = fin_ms; - - if( fin_ms != 0 ) - (void) mbedtls_timing_get_timer( &ctx->timer, 1 ); -} - -/* - * Get number of delays expired - */ -int mbedtls_timing_get_delay( void *data ) -{ - mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; - unsigned long elapsed_ms; - - if( ctx->fin_ms == 0 ) - return( -1 ); - - elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 ); - - if( elapsed_ms >= ctx->fin_ms ) - return( 2 ); - - if( elapsed_ms >= ctx->int_ms ) - return( 1 ); - - return( 0 ); -} - -#endif /* !MBEDTLS_TIMING_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Busy-waits for the given number of milliseconds. - * Used for testing mbedtls_timing_hardclock. - */ -static void busy_msleep( unsigned long msec ) -{ - struct mbedtls_timing_hr_time hires; - unsigned long i = 0; /* for busy-waiting */ - volatile unsigned long j; /* to prevent optimisation */ - - (void) mbedtls_timing_get_timer( &hires, 1 ); - - while( mbedtls_timing_get_timer( &hires, 0 ) < msec ) - i++; - - j = i; - (void) j; -} - -#define FAIL do \ - { \ - if( verbose != 0 ) \ - { \ - mbedtls_printf( "failed at line %d\n", __LINE__ ); \ - mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \ - cycles, ratio, millisecs, secs, hardfail, \ - (unsigned long) a, (unsigned long) b ); \ - mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=%lu status(ctx)=%d\n", \ - mbedtls_timing_get_timer( &hires, 0 ), \ - mbedtls_timing_get_timer( &ctx.timer, 0 ), \ - mbedtls_timing_get_delay( &ctx ) ); \ - } \ - return( 1 ); \ - } while( 0 ) - -/* - * Checkup routine - * - * Warning: this is work in progress, some tests may not be reliable enough - * yet! False positives may happen. - */ -int mbedtls_timing_self_test( int verbose ) -{ - unsigned long cycles = 0, ratio = 0; - unsigned long millisecs = 0, secs = 0; - int hardfail = 0; - struct mbedtls_timing_hr_time hires; - uint32_t a = 0, b = 0; - mbedtls_timing_delay_context ctx; - - if( verbose != 0 ) - mbedtls_printf( " TIMING tests note: will take some time!\n" ); - - if( verbose != 0 ) - mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " ); - - { - secs = 1; - - (void) mbedtls_timing_get_timer( &hires, 1 ); - - mbedtls_set_alarm( (int) secs ); - while( !mbedtls_timing_alarmed ) - ; - - millisecs = mbedtls_timing_get_timer( &hires, 0 ); - - /* For some reason on Windows it looks like alarm has an extra delay - * (maybe related to creating a new thread). Allow some room here. */ - if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 ) - FAIL; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " TIMING test #2 (set/get_delay ): " ); - - { - a = 800; - b = 400; - mbedtls_timing_set_delay( &ctx, a, a + b ); /* T = 0 */ - - busy_msleep( a - a / 4 ); /* T = a - a/4 */ - if( mbedtls_timing_get_delay( &ctx ) != 0 ) - FAIL; - - busy_msleep( a / 4 + b / 4 ); /* T = a + b/4 */ - if( mbedtls_timing_get_delay( &ctx ) != 1 ) - FAIL; - - busy_msleep( b ); /* T = a + b + b/4 */ - if( mbedtls_timing_get_delay( &ctx ) != 2 ) - FAIL; - } - - mbedtls_timing_set_delay( &ctx, 0, 0 ); - busy_msleep( 200 ); - if( mbedtls_timing_get_delay( &ctx ) != -1 ) - FAIL; - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - - if( verbose != 0 ) - mbedtls_printf( " TIMING test #3 (hardclock / get_timer): " ); - - /* - * Allow one failure for possible counter wrapping. - * On a 4Ghz 32-bit machine the cycle counter wraps about once per second; - * since the whole test is about 10ms, it shouldn't happen twice in a row. - */ - -hard_test: - if( hardfail > 1 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed (ignored)\n" ); - - goto hard_test_done; - } - - /* Get a reference ratio cycles/ms */ - millisecs = 1; - cycles = mbedtls_timing_hardclock(); - busy_msleep( millisecs ); - cycles = mbedtls_timing_hardclock() - cycles; - ratio = cycles / millisecs; - - /* Check that the ratio is mostly constant */ - for( millisecs = 2; millisecs <= 4; millisecs++ ) - { - cycles = mbedtls_timing_hardclock(); - busy_msleep( millisecs ); - cycles = mbedtls_timing_hardclock() - cycles; - - /* Allow variation up to 20% */ - if( cycles / millisecs < ratio - ratio / 5 || - cycles / millisecs > ratio + ratio / 5 ) - { - hardfail++; - goto hard_test; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - -hard_test_done: - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_TIMING_C */ diff --git a/mbedtls/timing.h b/mbedtls/timing.h deleted file mode 100644 index fed617b75..000000000 --- a/mbedtls/timing.h +++ /dev/null @@ -1,179 +0,0 @@ -#pragma GCC system_header -/** - * \file timing.h - * - * \brief Portable interface to timeouts and to the CPU cycle counter - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_TIMING_H -#define MBEDTLS_TIMING_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_TIMING_ALT) -// Regular implementation -// - -/** - * \brief timer structure - */ -struct mbedtls_timing_hr_time -{ - unsigned char opaque[32]; -}; - -/** - * \brief Context for mbedtls_timing_set/get_delay() - */ -typedef struct mbedtls_timing_delay_context -{ - struct mbedtls_timing_hr_time timer; - uint32_t int_ms; - uint32_t fin_ms; -} mbedtls_timing_delay_context; - -#else /* MBEDTLS_TIMING_ALT */ -#include "timing_alt.h" -#endif /* MBEDTLS_TIMING_ALT */ - -extern volatile int mbedtls_timing_alarmed; - -/** - * \brief Return the CPU cycle counter value - * - * \warning This is only a best effort! Do not rely on this! - * In particular, it is known to be unreliable on virtual - * machines. - * - * \note This value starts at an unspecified origin and - * may wrap around. - */ -unsigned long mbedtls_timing_hardclock( void ); - -/** - * \brief Return the elapsed time in milliseconds - * - * \param val points to a timer structure - * \param reset If 0, query the elapsed time. Otherwise (re)start the timer. - * - * \return Elapsed time since the previous reset in ms. When - * restarting, this is always 0. - * - * \note To initialize a timer, call this function with reset=1. - * - * Determining the elapsed time and resetting the timer is not - * atomic on all platforms, so after the sequence - * `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 = - * get_timer(0) }` the value time1+time2 is only approximately - * the delay since the first reset. - */ -unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ); - -/** - * \brief Setup an alarm clock - * - * \param seconds delay before the "mbedtls_timing_alarmed" flag is set - * (must be >=0) - * - * \warning Only one alarm at a time is supported. In a threaded - * context, this means one for the whole process, not one per - * thread. - */ -void mbedtls_set_alarm( int seconds ); - -/** - * \brief Set a pair of delays to watch - * (See \c mbedtls_timing_get_delay().) - * - * \param data Pointer to timing data. - * Must point to a valid \c mbedtls_timing_delay_context struct. - * \param int_ms First (intermediate) delay in milliseconds. - * The effect if int_ms > fin_ms is unspecified. - * \param fin_ms Second (final) delay in milliseconds. - * Pass 0 to cancel the current delay. - * - * \note To set a single delay, either use \c mbedtls_timing_set_timer - * directly or use this function with int_ms == fin_ms. - */ -void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ); - -/** - * \brief Get the status of delays - * (Memory helper: number of delays passed.) - * - * \param data Pointer to timing data - * Must point to a valid \c mbedtls_timing_delay_context struct. - * - * \return -1 if cancelled (fin_ms = 0), - * 0 if none of the delays are passed, - * 1 if only the intermediate delay is passed, - * 2 if the final delay is passed. - */ -int mbedtls_timing_get_delay( void *data ); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_timing_self_test( int verbose ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* timing.h */ diff --git a/mbedtls/version.c b/mbedtls/version.c deleted file mode 100644 index 6c531c8ee..000000000 --- a/mbedtls/version.c +++ /dev/null @@ -1,88 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Version information - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_VERSION_C) - -#include "mbedtls/version.h" -#include - -unsigned int mbedtls_version_get_number( void ) -{ - return( MBEDTLS_VERSION_NUMBER ); -} - -void mbedtls_version_get_string( char *string ) -{ - memcpy( string, MBEDTLS_VERSION_STRING, - sizeof( MBEDTLS_VERSION_STRING ) ); -} - -void mbedtls_version_get_string_full( char *string ) -{ - memcpy( string, MBEDTLS_VERSION_STRING_FULL, - sizeof( MBEDTLS_VERSION_STRING_FULL ) ); -} - -#endif /* MBEDTLS_VERSION_C */ diff --git a/mbedtls/version.h b/mbedtls/version.h deleted file mode 100644 index 890100362..000000000 --- a/mbedtls/version.h +++ /dev/null @@ -1,138 +0,0 @@ -#pragma GCC system_header -/** - * \file version.h - * - * \brief Run-time version information - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * This set of compile-time defines and run-time variables can be used to - * determine the version number of the mbed TLS library used. - */ -#ifndef MBEDTLS_VERSION_H -#define MBEDTLS_VERSION_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -/** - * The version number x.y.z is split into three parts. - * Major, Minor, Patchlevel - */ -#define MBEDTLS_VERSION_MAJOR 2 -#define MBEDTLS_VERSION_MINOR 16 -#define MBEDTLS_VERSION_PATCH 11 - -/** - * The single version number has the following structure: - * MMNNPP00 - * Major version | Minor version | Patch version - */ -#define MBEDTLS_VERSION_NUMBER 0x02100B00 -#define MBEDTLS_VERSION_STRING "2.16.11" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.11" - -#if defined(MBEDTLS_VERSION_C) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Get the version number. - * - * \return The constructed version number in the format - * MMNNPP00 (Major, Minor, Patch). - */ -unsigned int mbedtls_version_get_number( void ); - -/** - * Get the version string ("x.y.z"). - * - * \param string The string that will receive the value. - * (Should be at least 9 bytes in size) - */ -void mbedtls_version_get_string( char *string ); - -/** - * Get the full version string ("mbed TLS x.y.z"). - * - * \param string The string that will receive the value. The mbed TLS version - * string will use 18 bytes AT MOST including a terminating - * null byte. - * (So the buffer should be at least 18 bytes to receive this - * version string). - */ -void mbedtls_version_get_string_full( char *string ); - -/** - * \brief Check if support for a feature was compiled into this - * mbed TLS binary. This allows you to see at runtime if the - * library was for instance compiled with or without - * Multi-threading support. - * - * \note only checks against defines in the sections "System - * support", "mbed TLS modules" and "mbed TLS feature - * support" in config.h - * - * \param feature The string for the define to check (e.g. "MBEDTLS_AES_C") - * - * \return 0 if the feature is present, - * -1 if the feature is not present and - * -2 if support for feature checking as a whole was not - * compiled in. - */ -int mbedtls_version_check_feature( const char *feature ); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_VERSION_C */ - -#endif /* version.h */ diff --git a/mbedtls/version_features.c b/mbedtls/version_features.c deleted file mode 100644 index ddbe823d2..000000000 --- a/mbedtls/version_features.c +++ /dev/null @@ -1,835 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * Version feature information - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_VERSION_C) - -#include "mbedtls/version.h" - -#include - -static const char *features[] = { -#if defined(MBEDTLS_VERSION_FEATURES) -#if defined(MBEDTLS_HAVE_ASM) - "MBEDTLS_HAVE_ASM", -#endif /* MBEDTLS_HAVE_ASM */ -#if defined(MBEDTLS_NO_UDBL_DIVISION) - "MBEDTLS_NO_UDBL_DIVISION", -#endif /* MBEDTLS_NO_UDBL_DIVISION */ -#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION) - "MBEDTLS_NO_64BIT_MULTIPLICATION", -#endif /* MBEDTLS_NO_64BIT_MULTIPLICATION */ -#if defined(MBEDTLS_HAVE_SSE2) - "MBEDTLS_HAVE_SSE2", -#endif /* MBEDTLS_HAVE_SSE2 */ -#if defined(MBEDTLS_HAVE_TIME) - "MBEDTLS_HAVE_TIME", -#endif /* MBEDTLS_HAVE_TIME */ -#if defined(MBEDTLS_HAVE_TIME_DATE) - "MBEDTLS_HAVE_TIME_DATE", -#endif /* MBEDTLS_HAVE_TIME_DATE */ -#if defined(MBEDTLS_PLATFORM_MEMORY) - "MBEDTLS_PLATFORM_MEMORY", -#endif /* MBEDTLS_PLATFORM_MEMORY */ -#if defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) - "MBEDTLS_PLATFORM_NO_STD_FUNCTIONS", -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) - "MBEDTLS_PLATFORM_EXIT_ALT", -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ -#if defined(MBEDTLS_PLATFORM_TIME_ALT) - "MBEDTLS_PLATFORM_TIME_ALT", -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) - "MBEDTLS_PLATFORM_FPRINTF_ALT", -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) - "MBEDTLS_PLATFORM_PRINTF_ALT", -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) - "MBEDTLS_PLATFORM_SNPRINTF_ALT", -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) - "MBEDTLS_PLATFORM_NV_SEED_ALT", -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#if defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) - "MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT", -#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ -#if defined(MBEDTLS_DEPRECATED_WARNING) - "MBEDTLS_DEPRECATED_WARNING", -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#if defined(MBEDTLS_DEPRECATED_REMOVED) - "MBEDTLS_DEPRECATED_REMOVED", -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_CHECK_PARAMS) - "MBEDTLS_CHECK_PARAMS", -#endif /* MBEDTLS_CHECK_PARAMS */ -#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) - "MBEDTLS_CHECK_PARAMS_ASSERT", -#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ -#if defined(MBEDTLS_TIMING_ALT) - "MBEDTLS_TIMING_ALT", -#endif /* MBEDTLS_TIMING_ALT */ -#if defined(MBEDTLS_AES_ALT) - "MBEDTLS_AES_ALT", -#endif /* MBEDTLS_AES_ALT */ -#if defined(MBEDTLS_ARC4_ALT) - "MBEDTLS_ARC4_ALT", -#endif /* MBEDTLS_ARC4_ALT */ -#if defined(MBEDTLS_ARIA_ALT) - "MBEDTLS_ARIA_ALT", -#endif /* MBEDTLS_ARIA_ALT */ -#if defined(MBEDTLS_BLOWFISH_ALT) - "MBEDTLS_BLOWFISH_ALT", -#endif /* MBEDTLS_BLOWFISH_ALT */ -#if defined(MBEDTLS_CAMELLIA_ALT) - "MBEDTLS_CAMELLIA_ALT", -#endif /* MBEDTLS_CAMELLIA_ALT */ -#if defined(MBEDTLS_CCM_ALT) - "MBEDTLS_CCM_ALT", -#endif /* MBEDTLS_CCM_ALT */ -#if defined(MBEDTLS_CHACHA20_ALT) - "MBEDTLS_CHACHA20_ALT", -#endif /* MBEDTLS_CHACHA20_ALT */ -#if defined(MBEDTLS_CHACHAPOLY_ALT) - "MBEDTLS_CHACHAPOLY_ALT", -#endif /* MBEDTLS_CHACHAPOLY_ALT */ -#if defined(MBEDTLS_CMAC_ALT) - "MBEDTLS_CMAC_ALT", -#endif /* MBEDTLS_CMAC_ALT */ -#if defined(MBEDTLS_DES_ALT) - "MBEDTLS_DES_ALT", -#endif /* MBEDTLS_DES_ALT */ -#if defined(MBEDTLS_DHM_ALT) - "MBEDTLS_DHM_ALT", -#endif /* MBEDTLS_DHM_ALT */ -#if defined(MBEDTLS_ECJPAKE_ALT) - "MBEDTLS_ECJPAKE_ALT", -#endif /* MBEDTLS_ECJPAKE_ALT */ -#if defined(MBEDTLS_GCM_ALT) - "MBEDTLS_GCM_ALT", -#endif /* MBEDTLS_GCM_ALT */ -#if defined(MBEDTLS_NIST_KW_ALT) - "MBEDTLS_NIST_KW_ALT", -#endif /* MBEDTLS_NIST_KW_ALT */ -#if defined(MBEDTLS_MD2_ALT) - "MBEDTLS_MD2_ALT", -#endif /* MBEDTLS_MD2_ALT */ -#if defined(MBEDTLS_MD4_ALT) - "MBEDTLS_MD4_ALT", -#endif /* MBEDTLS_MD4_ALT */ -#if defined(MBEDTLS_MD5_ALT) - "MBEDTLS_MD5_ALT", -#endif /* MBEDTLS_MD5_ALT */ -#if defined(MBEDTLS_POLY1305_ALT) - "MBEDTLS_POLY1305_ALT", -#endif /* MBEDTLS_POLY1305_ALT */ -#if defined(MBEDTLS_RIPEMD160_ALT) - "MBEDTLS_RIPEMD160_ALT", -#endif /* MBEDTLS_RIPEMD160_ALT */ -#if defined(MBEDTLS_RSA_ALT) - "MBEDTLS_RSA_ALT", -#endif /* MBEDTLS_RSA_ALT */ -#if defined(MBEDTLS_SHA1_ALT) - "MBEDTLS_SHA1_ALT", -#endif /* MBEDTLS_SHA1_ALT */ -#if defined(MBEDTLS_SHA256_ALT) - "MBEDTLS_SHA256_ALT", -#endif /* MBEDTLS_SHA256_ALT */ -#if defined(MBEDTLS_SHA512_ALT) - "MBEDTLS_SHA512_ALT", -#endif /* MBEDTLS_SHA512_ALT */ -#if defined(MBEDTLS_XTEA_ALT) - "MBEDTLS_XTEA_ALT", -#endif /* MBEDTLS_XTEA_ALT */ -#if defined(MBEDTLS_ECP_ALT) - "MBEDTLS_ECP_ALT", -#endif /* MBEDTLS_ECP_ALT */ -#if defined(MBEDTLS_MD2_PROCESS_ALT) - "MBEDTLS_MD2_PROCESS_ALT", -#endif /* MBEDTLS_MD2_PROCESS_ALT */ -#if defined(MBEDTLS_MD4_PROCESS_ALT) - "MBEDTLS_MD4_PROCESS_ALT", -#endif /* MBEDTLS_MD4_PROCESS_ALT */ -#if defined(MBEDTLS_MD5_PROCESS_ALT) - "MBEDTLS_MD5_PROCESS_ALT", -#endif /* MBEDTLS_MD5_PROCESS_ALT */ -#if defined(MBEDTLS_RIPEMD160_PROCESS_ALT) - "MBEDTLS_RIPEMD160_PROCESS_ALT", -#endif /* MBEDTLS_RIPEMD160_PROCESS_ALT */ -#if defined(MBEDTLS_SHA1_PROCESS_ALT) - "MBEDTLS_SHA1_PROCESS_ALT", -#endif /* MBEDTLS_SHA1_PROCESS_ALT */ -#if defined(MBEDTLS_SHA256_PROCESS_ALT) - "MBEDTLS_SHA256_PROCESS_ALT", -#endif /* MBEDTLS_SHA256_PROCESS_ALT */ -#if defined(MBEDTLS_SHA512_PROCESS_ALT) - "MBEDTLS_SHA512_PROCESS_ALT", -#endif /* MBEDTLS_SHA512_PROCESS_ALT */ -#if defined(MBEDTLS_DES_SETKEY_ALT) - "MBEDTLS_DES_SETKEY_ALT", -#endif /* MBEDTLS_DES_SETKEY_ALT */ -#if defined(MBEDTLS_DES_CRYPT_ECB_ALT) - "MBEDTLS_DES_CRYPT_ECB_ALT", -#endif /* MBEDTLS_DES_CRYPT_ECB_ALT */ -#if defined(MBEDTLS_DES3_CRYPT_ECB_ALT) - "MBEDTLS_DES3_CRYPT_ECB_ALT", -#endif /* MBEDTLS_DES3_CRYPT_ECB_ALT */ -#if defined(MBEDTLS_AES_SETKEY_ENC_ALT) - "MBEDTLS_AES_SETKEY_ENC_ALT", -#endif /* MBEDTLS_AES_SETKEY_ENC_ALT */ -#if defined(MBEDTLS_AES_SETKEY_DEC_ALT) - "MBEDTLS_AES_SETKEY_DEC_ALT", -#endif /* MBEDTLS_AES_SETKEY_DEC_ALT */ -#if defined(MBEDTLS_AES_ENCRYPT_ALT) - "MBEDTLS_AES_ENCRYPT_ALT", -#endif /* MBEDTLS_AES_ENCRYPT_ALT */ -#if defined(MBEDTLS_AES_DECRYPT_ALT) - "MBEDTLS_AES_DECRYPT_ALT", -#endif /* MBEDTLS_AES_DECRYPT_ALT */ -#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) - "MBEDTLS_ECDH_GEN_PUBLIC_ALT", -#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */ -#if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) - "MBEDTLS_ECDH_COMPUTE_SHARED_ALT", -#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ -#if defined(MBEDTLS_ECDSA_VERIFY_ALT) - "MBEDTLS_ECDSA_VERIFY_ALT", -#endif /* MBEDTLS_ECDSA_VERIFY_ALT */ -#if defined(MBEDTLS_ECDSA_SIGN_ALT) - "MBEDTLS_ECDSA_SIGN_ALT", -#endif /* MBEDTLS_ECDSA_SIGN_ALT */ -#if defined(MBEDTLS_ECDSA_GENKEY_ALT) - "MBEDTLS_ECDSA_GENKEY_ALT", -#endif /* MBEDTLS_ECDSA_GENKEY_ALT */ -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - "MBEDTLS_ECP_INTERNAL_ALT", -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ -#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) - "MBEDTLS_ECP_RANDOMIZE_JAC_ALT", -#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ -#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) - "MBEDTLS_ECP_ADD_MIXED_ALT", -#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ -#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) - "MBEDTLS_ECP_DOUBLE_JAC_ALT", -#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) - "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT", -#endif /* MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT */ -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) - "MBEDTLS_ECP_NORMALIZE_JAC_ALT", -#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ -#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) - "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT", -#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ -#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) - "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT", -#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ -#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) - "MBEDTLS_ECP_NORMALIZE_MXZ_ALT", -#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ -#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) - "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN", -#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */ -#if defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND) - "MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND", -#endif /* MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */ -#if defined(MBEDTLS_TEST_NULL_ENTROPY) - "MBEDTLS_TEST_NULL_ENTROPY", -#endif /* MBEDTLS_TEST_NULL_ENTROPY */ -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - "MBEDTLS_ENTROPY_HARDWARE_ALT", -#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ -#if defined(MBEDTLS_AES_ROM_TABLES) - "MBEDTLS_AES_ROM_TABLES", -#endif /* MBEDTLS_AES_ROM_TABLES */ -#if defined(MBEDTLS_AES_FEWER_TABLES) - "MBEDTLS_AES_FEWER_TABLES", -#endif /* MBEDTLS_AES_FEWER_TABLES */ -#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) - "MBEDTLS_CAMELLIA_SMALL_MEMORY", -#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) - "MBEDTLS_CIPHER_MODE_CBC", -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CIPHER_MODE_CFB) - "MBEDTLS_CIPHER_MODE_CFB", -#endif /* MBEDTLS_CIPHER_MODE_CFB */ -#if defined(MBEDTLS_CIPHER_MODE_CTR) - "MBEDTLS_CIPHER_MODE_CTR", -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#if defined(MBEDTLS_CIPHER_MODE_OFB) - "MBEDTLS_CIPHER_MODE_OFB", -#endif /* MBEDTLS_CIPHER_MODE_OFB */ -#if defined(MBEDTLS_CIPHER_MODE_XTS) - "MBEDTLS_CIPHER_MODE_XTS", -#endif /* MBEDTLS_CIPHER_MODE_XTS */ -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) - "MBEDTLS_CIPHER_NULL_CIPHER", -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - "MBEDTLS_CIPHER_PADDING_PKCS7", -#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) - "MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS", -#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) - "MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN", -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) - "MBEDTLS_CIPHER_PADDING_ZEROS", -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ -#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) - "MBEDTLS_CTR_DRBG_USE_128_BIT_KEY", -#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ -#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) - "MBEDTLS_ENABLE_WEAK_CIPHERSUITES", -#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ -#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) - "MBEDTLS_REMOVE_ARC4_CIPHERSUITES", -#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ -#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES) - "MBEDTLS_REMOVE_3DES_CIPHERSUITES", -#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - "MBEDTLS_ECP_DP_SECP192R1_ENABLED", -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - "MBEDTLS_ECP_DP_SECP224R1_ENABLED", -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - "MBEDTLS_ECP_DP_SECP256R1_ENABLED", -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - "MBEDTLS_ECP_DP_SECP384R1_ENABLED", -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - "MBEDTLS_ECP_DP_SECP521R1_ENABLED", -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - "MBEDTLS_ECP_DP_SECP192K1_ENABLED", -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - "MBEDTLS_ECP_DP_SECP224K1_ENABLED", -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - "MBEDTLS_ECP_DP_SECP256K1_ENABLED", -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - "MBEDTLS_ECP_DP_BP256R1_ENABLED", -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - "MBEDTLS_ECP_DP_BP384R1_ENABLED", -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - "MBEDTLS_ECP_DP_BP512R1_ENABLED", -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - "MBEDTLS_ECP_DP_CURVE25519_ENABLED", -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - "MBEDTLS_ECP_DP_CURVE448_ENABLED", -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ -#if defined(MBEDTLS_ECP_NIST_OPTIM) - "MBEDTLS_ECP_NIST_OPTIM", -#endif /* MBEDTLS_ECP_NIST_OPTIM */ -#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) - "MBEDTLS_ECP_NO_INTERNAL_RNG", -#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - "MBEDTLS_ECP_RESTARTABLE", -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - "MBEDTLS_ECDSA_DETERMINISTIC", -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - "MBEDTLS_KEY_EXCHANGE_PSK_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) - "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) - "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED", -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) - "MBEDTLS_PK_PARSE_EC_EXTENDED", -#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ -#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) - "MBEDTLS_ERROR_STRERROR_DUMMY", -#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ -#if defined(MBEDTLS_GENPRIME) - "MBEDTLS_GENPRIME", -#endif /* MBEDTLS_GENPRIME */ -#if defined(MBEDTLS_FS_IO) - "MBEDTLS_FS_IO", -#endif /* MBEDTLS_FS_IO */ -#if defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) - "MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES", -#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ -#if defined(MBEDTLS_NO_PLATFORM_ENTROPY) - "MBEDTLS_NO_PLATFORM_ENTROPY", -#endif /* MBEDTLS_NO_PLATFORM_ENTROPY */ -#if defined(MBEDTLS_ENTROPY_FORCE_SHA256) - "MBEDTLS_ENTROPY_FORCE_SHA256", -#endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */ -#if defined(MBEDTLS_ENTROPY_NV_SEED) - "MBEDTLS_ENTROPY_NV_SEED", -#endif /* MBEDTLS_ENTROPY_NV_SEED */ -#if defined(MBEDTLS_MEMORY_DEBUG) - "MBEDTLS_MEMORY_DEBUG", -#endif /* MBEDTLS_MEMORY_DEBUG */ -#if defined(MBEDTLS_MEMORY_BACKTRACE) - "MBEDTLS_MEMORY_BACKTRACE", -#endif /* MBEDTLS_MEMORY_BACKTRACE */ -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) - "MBEDTLS_PK_RSA_ALT_SUPPORT", -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ -#if defined(MBEDTLS_PKCS1_V15) - "MBEDTLS_PKCS1_V15", -#endif /* MBEDTLS_PKCS1_V15 */ -#if defined(MBEDTLS_PKCS1_V21) - "MBEDTLS_PKCS1_V21", -#endif /* MBEDTLS_PKCS1_V21 */ -#if defined(MBEDTLS_RSA_NO_CRT) - "MBEDTLS_RSA_NO_CRT", -#endif /* MBEDTLS_RSA_NO_CRT */ -#if defined(MBEDTLS_SELF_TEST) - "MBEDTLS_SELF_TEST", -#endif /* MBEDTLS_SELF_TEST */ -#if defined(MBEDTLS_SHA256_SMALLER) - "MBEDTLS_SHA256_SMALLER", -#endif /* MBEDTLS_SHA256_SMALLER */ -#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) - "MBEDTLS_SSL_ALL_ALERT_MESSAGES", -#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - "MBEDTLS_SSL_ASYNC_PRIVATE", -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ -#if defined(MBEDTLS_SSL_DEBUG_ALL) - "MBEDTLS_SSL_DEBUG_ALL", -#endif /* MBEDTLS_SSL_DEBUG_ALL */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - "MBEDTLS_SSL_ENCRYPT_THEN_MAC", -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - "MBEDTLS_SSL_EXTENDED_MASTER_SECRET", -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) - "MBEDTLS_SSL_FALLBACK_SCSV", -#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - "MBEDTLS_SSL_HW_RECORD_ACCEL", -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - "MBEDTLS_SSL_CBC_RECORD_SPLITTING", -#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - "MBEDTLS_SSL_RENEGOTIATION", -#endif /* MBEDTLS_SSL_RENEGOTIATION */ -#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) - "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO", -#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ -#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) - "MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE", -#endif /* MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE */ -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH", -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) - "MBEDTLS_SSL_PROTO_SSL3", -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) - "MBEDTLS_SSL_PROTO_TLS1", -#endif /* MBEDTLS_SSL_PROTO_TLS1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) - "MBEDTLS_SSL_PROTO_TLS1_1", -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - "MBEDTLS_SSL_PROTO_TLS1_2", -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - "MBEDTLS_SSL_PROTO_DTLS", -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_ALPN) - "MBEDTLS_SSL_ALPN", -#endif /* MBEDTLS_SSL_ALPN */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - "MBEDTLS_SSL_DTLS_ANTI_REPLAY", -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - "MBEDTLS_SSL_DTLS_HELLO_VERIFY", -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) - "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - "MBEDTLS_SSL_DTLS_BADMAC_LIMIT", -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - "MBEDTLS_SSL_SESSION_TICKETS", -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ -#if defined(MBEDTLS_SSL_EXPORT_KEYS) - "MBEDTLS_SSL_EXPORT_KEYS", -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - "MBEDTLS_SSL_SERVER_NAME_INDICATION", -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - "MBEDTLS_SSL_TRUNCATED_HMAC", -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) - "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT", -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */ -#if defined(MBEDTLS_TEST_HOOKS) - "MBEDTLS_TEST_HOOKS", -#endif /* MBEDTLS_TEST_HOOKS */ -#if defined(MBEDTLS_THREADING_ALT) - "MBEDTLS_THREADING_ALT", -#endif /* MBEDTLS_THREADING_ALT */ -#if defined(MBEDTLS_THREADING_PTHREAD) - "MBEDTLS_THREADING_PTHREAD", -#endif /* MBEDTLS_THREADING_PTHREAD */ -#if defined(MBEDTLS_VERSION_FEATURES) - "MBEDTLS_VERSION_FEATURES", -#endif /* MBEDTLS_VERSION_FEATURES */ -#if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) - "MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3", -#endif /* MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 */ -#if defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) - "MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION", -#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */ -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - "MBEDTLS_X509_CHECK_KEY_USAGE", -#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */ -#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) - "MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE", -#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - "MBEDTLS_X509_RSASSA_PSS_SUPPORT", -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ -#if defined(MBEDTLS_ZLIB_SUPPORT) - "MBEDTLS_ZLIB_SUPPORT", -#endif /* MBEDTLS_ZLIB_SUPPORT */ -#if defined(MBEDTLS_AESNI_C) - "MBEDTLS_AESNI_C", -#endif /* MBEDTLS_AESNI_C */ -#if defined(MBEDTLS_AES_C) - "MBEDTLS_AES_C", -#endif /* MBEDTLS_AES_C */ -#if defined(MBEDTLS_ARC4_C) - "MBEDTLS_ARC4_C", -#endif /* MBEDTLS_ARC4_C */ -#if defined(MBEDTLS_ASN1_PARSE_C) - "MBEDTLS_ASN1_PARSE_C", -#endif /* MBEDTLS_ASN1_PARSE_C */ -#if defined(MBEDTLS_ASN1_WRITE_C) - "MBEDTLS_ASN1_WRITE_C", -#endif /* MBEDTLS_ASN1_WRITE_C */ -#if defined(MBEDTLS_BASE64_C) - "MBEDTLS_BASE64_C", -#endif /* MBEDTLS_BASE64_C */ -#if defined(MBEDTLS_BIGNUM_C) - "MBEDTLS_BIGNUM_C", -#endif /* MBEDTLS_BIGNUM_C */ -#if defined(MBEDTLS_BLOWFISH_C) - "MBEDTLS_BLOWFISH_C", -#endif /* MBEDTLS_BLOWFISH_C */ -#if defined(MBEDTLS_CAMELLIA_C) - "MBEDTLS_CAMELLIA_C", -#endif /* MBEDTLS_CAMELLIA_C */ -#if defined(MBEDTLS_ARIA_C) - "MBEDTLS_ARIA_C", -#endif /* MBEDTLS_ARIA_C */ -#if defined(MBEDTLS_CCM_C) - "MBEDTLS_CCM_C", -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CERTS_C) - "MBEDTLS_CERTS_C", -#endif /* MBEDTLS_CERTS_C */ -#if defined(MBEDTLS_CHACHA20_C) - "MBEDTLS_CHACHA20_C", -#endif /* MBEDTLS_CHACHA20_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - "MBEDTLS_CHACHAPOLY_C", -#endif /* MBEDTLS_CHACHAPOLY_C */ -#if defined(MBEDTLS_CIPHER_C) - "MBEDTLS_CIPHER_C", -#endif /* MBEDTLS_CIPHER_C */ -#if defined(MBEDTLS_CMAC_C) - "MBEDTLS_CMAC_C", -#endif /* MBEDTLS_CMAC_C */ -#if defined(MBEDTLS_CTR_DRBG_C) - "MBEDTLS_CTR_DRBG_C", -#endif /* MBEDTLS_CTR_DRBG_C */ -#if defined(MBEDTLS_DEBUG_C) - "MBEDTLS_DEBUG_C", -#endif /* MBEDTLS_DEBUG_C */ -#if defined(MBEDTLS_DES_C) - "MBEDTLS_DES_C", -#endif /* MBEDTLS_DES_C */ -#if defined(MBEDTLS_DHM_C) - "MBEDTLS_DHM_C", -#endif /* MBEDTLS_DHM_C */ -#if defined(MBEDTLS_ECDH_C) - "MBEDTLS_ECDH_C", -#endif /* MBEDTLS_ECDH_C */ -#if defined(MBEDTLS_ECDSA_C) - "MBEDTLS_ECDSA_C", -#endif /* MBEDTLS_ECDSA_C */ -#if defined(MBEDTLS_ECJPAKE_C) - "MBEDTLS_ECJPAKE_C", -#endif /* MBEDTLS_ECJPAKE_C */ -#if defined(MBEDTLS_ECP_C) - "MBEDTLS_ECP_C", -#endif /* MBEDTLS_ECP_C */ -#if defined(MBEDTLS_ENTROPY_C) - "MBEDTLS_ENTROPY_C", -#endif /* MBEDTLS_ENTROPY_C */ -#if defined(MBEDTLS_ERROR_C) - "MBEDTLS_ERROR_C", -#endif /* MBEDTLS_ERROR_C */ -#if defined(MBEDTLS_GCM_C) - "MBEDTLS_GCM_C", -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_HAVEGE_C) - "MBEDTLS_HAVEGE_C", -#endif /* MBEDTLS_HAVEGE_C */ -#if defined(MBEDTLS_HKDF_C) - "MBEDTLS_HKDF_C", -#endif /* MBEDTLS_HKDF_C */ -#if defined(MBEDTLS_HMAC_DRBG_C) - "MBEDTLS_HMAC_DRBG_C", -#endif /* MBEDTLS_HMAC_DRBG_C */ -#if defined(MBEDTLS_NIST_KW_C) - "MBEDTLS_NIST_KW_C", -#endif /* MBEDTLS_NIST_KW_C */ -#if defined(MBEDTLS_MD_C) - "MBEDTLS_MD_C", -#endif /* MBEDTLS_MD_C */ -#if defined(MBEDTLS_MD2_C) - "MBEDTLS_MD2_C", -#endif /* MBEDTLS_MD2_C */ -#if defined(MBEDTLS_MD4_C) - "MBEDTLS_MD4_C", -#endif /* MBEDTLS_MD4_C */ -#if defined(MBEDTLS_MD5_C) - "MBEDTLS_MD5_C", -#endif /* MBEDTLS_MD5_C */ -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) - "MBEDTLS_MEMORY_BUFFER_ALLOC_C", -#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ -#if defined(MBEDTLS_NET_C) - "MBEDTLS_NET_C", -#endif /* MBEDTLS_NET_C */ -#if defined(MBEDTLS_OID_C) - "MBEDTLS_OID_C", -#endif /* MBEDTLS_OID_C */ -#if defined(MBEDTLS_PADLOCK_C) - "MBEDTLS_PADLOCK_C", -#endif /* MBEDTLS_PADLOCK_C */ -#if defined(MBEDTLS_PEM_PARSE_C) - "MBEDTLS_PEM_PARSE_C", -#endif /* MBEDTLS_PEM_PARSE_C */ -#if defined(MBEDTLS_PEM_WRITE_C) - "MBEDTLS_PEM_WRITE_C", -#endif /* MBEDTLS_PEM_WRITE_C */ -#if defined(MBEDTLS_PK_C) - "MBEDTLS_PK_C", -#endif /* MBEDTLS_PK_C */ -#if defined(MBEDTLS_PK_PARSE_C) - "MBEDTLS_PK_PARSE_C", -#endif /* MBEDTLS_PK_PARSE_C */ -#if defined(MBEDTLS_PK_WRITE_C) - "MBEDTLS_PK_WRITE_C", -#endif /* MBEDTLS_PK_WRITE_C */ -#if defined(MBEDTLS_PKCS5_C) - "MBEDTLS_PKCS5_C", -#endif /* MBEDTLS_PKCS5_C */ -#if defined(MBEDTLS_PKCS11_C) - "MBEDTLS_PKCS11_C", -#endif /* MBEDTLS_PKCS11_C */ -#if defined(MBEDTLS_PKCS12_C) - "MBEDTLS_PKCS12_C", -#endif /* MBEDTLS_PKCS12_C */ -#if defined(MBEDTLS_PLATFORM_C) - "MBEDTLS_PLATFORM_C", -#endif /* MBEDTLS_PLATFORM_C */ -#if defined(MBEDTLS_POLY1305_C) - "MBEDTLS_POLY1305_C", -#endif /* MBEDTLS_POLY1305_C */ -#if defined(MBEDTLS_RIPEMD160_C) - "MBEDTLS_RIPEMD160_C", -#endif /* MBEDTLS_RIPEMD160_C */ -#if defined(MBEDTLS_RSA_C) - "MBEDTLS_RSA_C", -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_SHA1_C) - "MBEDTLS_SHA1_C", -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) - "MBEDTLS_SHA256_C", -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - "MBEDTLS_SHA512_C", -#endif /* MBEDTLS_SHA512_C */ -#if defined(MBEDTLS_SSL_CACHE_C) - "MBEDTLS_SSL_CACHE_C", -#endif /* MBEDTLS_SSL_CACHE_C */ -#if defined(MBEDTLS_SSL_COOKIE_C) - "MBEDTLS_SSL_COOKIE_C", -#endif /* MBEDTLS_SSL_COOKIE_C */ -#if defined(MBEDTLS_SSL_TICKET_C) - "MBEDTLS_SSL_TICKET_C", -#endif /* MBEDTLS_SSL_TICKET_C */ -#if defined(MBEDTLS_SSL_CLI_C) - "MBEDTLS_SSL_CLI_C", -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SRV_C) - "MBEDTLS_SSL_SRV_C", -#endif /* MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_TLS_C) - "MBEDTLS_SSL_TLS_C", -#endif /* MBEDTLS_SSL_TLS_C */ -#if defined(MBEDTLS_THREADING_C) - "MBEDTLS_THREADING_C", -#endif /* MBEDTLS_THREADING_C */ -#if defined(MBEDTLS_TIMING_C) - "MBEDTLS_TIMING_C", -#endif /* MBEDTLS_TIMING_C */ -#if defined(MBEDTLS_VERSION_C) - "MBEDTLS_VERSION_C", -#endif /* MBEDTLS_VERSION_C */ -#if defined(MBEDTLS_X509_USE_C) - "MBEDTLS_X509_USE_C", -#endif /* MBEDTLS_X509_USE_C */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) - "MBEDTLS_X509_CRT_PARSE_C", -#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_X509_CRL_PARSE_C) - "MBEDTLS_X509_CRL_PARSE_C", -#endif /* MBEDTLS_X509_CRL_PARSE_C */ -#if defined(MBEDTLS_X509_CSR_PARSE_C) - "MBEDTLS_X509_CSR_PARSE_C", -#endif /* MBEDTLS_X509_CSR_PARSE_C */ -#if defined(MBEDTLS_X509_CREATE_C) - "MBEDTLS_X509_CREATE_C", -#endif /* MBEDTLS_X509_CREATE_C */ -#if defined(MBEDTLS_X509_CRT_WRITE_C) - "MBEDTLS_X509_CRT_WRITE_C", -#endif /* MBEDTLS_X509_CRT_WRITE_C */ -#if defined(MBEDTLS_X509_CSR_WRITE_C) - "MBEDTLS_X509_CSR_WRITE_C", -#endif /* MBEDTLS_X509_CSR_WRITE_C */ -#if defined(MBEDTLS_XTEA_C) - "MBEDTLS_XTEA_C", -#endif /* MBEDTLS_XTEA_C */ -#endif /* MBEDTLS_VERSION_FEATURES */ - NULL -}; - -int mbedtls_version_check_feature( const char *feature ) -{ - const char **idx = features; - - if( *idx == NULL ) - return( -2 ); - - if( feature == NULL ) - return( -1 ); - - while( *idx != NULL ) - { - if( !strcmp( *idx, feature ) ) - return( 0 ); - idx++; - } - return( -1 ); -} - -#endif /* MBEDTLS_VERSION_C */ diff --git a/mbedtls/x509.c b/mbedtls/x509.c deleted file mode 100644 index 108b15caa..000000000 --- a/mbedtls/x509.c +++ /dev/null @@ -1,1110 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * X.509 common functions for parsing and verification - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The ITU-T X.509 standard defines a certificate format for PKI. - * - * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) - * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) - * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) - * - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_USE_C) - -#include "mbedtls/x509.h" -#include "mbedtls/asn1.h" -#include "mbedtls/oid.h" - -#include -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_printf printf -#define mbedtls_snprintf snprintf -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif -#if defined(MBEDTLS_HAVE_TIME_DATE) -#include "mbedtls/platform_util.h" -#include -#endif - -#define CHECK(code) if( ( ret = ( code ) ) != 0 ){ return( ret ); } -#define CHECK_RANGE(min, max, val) \ - do \ - { \ - if( ( val ) < ( min ) || ( val ) > ( max ) ) \ - { \ - return( ret ); \ - } \ - } while( 0 ) - -/* - * CertificateSerialNumber ::= INTEGER - */ -int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *serial ) -{ - int ret; - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_SERIAL + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) && - **p != MBEDTLS_ASN1_INTEGER ) - return( MBEDTLS_ERR_X509_INVALID_SERIAL + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - serial->tag = *(*p)++; - - if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret ); - - serial->p = *p; - *p += serial->len; - - return( 0 ); -} - -/* Get an algorithm identifier without parameters (eg for signatures) - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - */ -int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - return( 0 ); -} - -/* - * Parse an algorithm identifier with (optional) parameters - */ -int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg, mbedtls_x509_buf *params ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - return( 0 ); -} - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) -/* - * HashAlgorithm ::= AlgorithmIdentifier - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - * - * For HashAlgorithm, parameters MUST be NULL or absent. - */ -static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg ) -{ - int ret; - unsigned char *p; - const unsigned char *end; - mbedtls_x509_buf md_oid; - size_t len; - - /* Make sure we got a SEQUENCE and setup bounds */ - if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - p = (unsigned char *) alg->p; - end = p + alg->len; - - if( p >= end ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - /* Parse md_oid */ - md_oid.tag = *p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - md_oid.p = p; - p += md_oid.len; - - /* Get md_alg from md_oid */ - if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - /* Make sure params is absent of NULL */ - if( p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * RSASSA-PSS-params ::= SEQUENCE { - * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, - * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, - * saltLength [2] INTEGER DEFAULT 20, - * trailerField [3] INTEGER DEFAULT 1 } - * -- Note that the tags in this Sequence are explicit. - * - * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value - * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other - * option. Enfore this at parsing time. - */ -int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, - mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, - int *salt_len ) -{ - int ret; - unsigned char *p; - const unsigned char *end, *end2; - size_t len; - mbedtls_x509_buf alg_id, alg_params; - - /* First set everything to defaults */ - *md_alg = MBEDTLS_MD_SHA1; - *mgf_md = MBEDTLS_MD_SHA1; - *salt_len = 20; - - /* Make sure params is a SEQUENCE and setup bounds */ - if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - p = (unsigned char *) params->p; - end = p + params->len; - - if( p == end ) - return( 0 ); - - /* - * HashAlgorithm - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) - { - end2 = p + len; - - /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ - if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end2 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p == end ) - return( 0 ); - - /* - * MaskGenAlgorithm - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) - { - end2 = p + len; - - /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ - if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 ) - return( ret ); - - /* Only MFG1 is recognised for now */ - if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 ) - return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE + - MBEDTLS_ERR_OID_NOT_FOUND ); - - /* Parse HashAlgorithm */ - if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 ) - return( ret ); - - if( p != end2 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p == end ) - return( 0 ); - - /* - * salt_len - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 ) - { - end2 = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end2 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p == end ) - return( 0 ); - - /* - * trailer_field (if present, must be 1) - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 ) - { - int trailer_field; - - end2 = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end2 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - if( trailer_field != 1 ) - return( MBEDTLS_ERR_X509_INVALID_ALG ); - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - -/* - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - */ -static int x509_get_attr_type_value( unsigned char **p, - const unsigned char *end, - mbedtls_x509_name *cur ) -{ - int ret; - size_t len; - mbedtls_x509_buf *oid; - mbedtls_x509_buf *val; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - - end = *p + len; - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - oid = &cur->oid; - oid->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - - oid->p = *p; - *p += oid->len; - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING && - **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING && - **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING && - **p != MBEDTLS_ASN1_BIT_STRING ) - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - val = &cur->val; - val->tag = *(*p)++; - - if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - - val->p = *p; - *p += val->len; - - if( *p != end ) - { - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - cur->next = NULL; - - return( 0 ); -} - -/* - * Name ::= CHOICE { -- only one possibility for now -- - * rdnSequence RDNSequence } - * - * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - * - * RelativeDistinguishedName ::= - * SET OF AttributeTypeAndValue - * - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - * - * The data structure is optimized for the common case where each RDN has only - * one element, which is represented as a list of AttributeTypeAndValue. - * For the general case we still use a flat list, but we mark elements of the - * same set so that they are "merged" together in the functions that consume - * this list, eg mbedtls_x509_dn_gets(). - */ -int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, - mbedtls_x509_name *cur ) -{ - int ret; - size_t set_len; - const unsigned char *end_set; - - /* don't use recursion, we'd risk stack overflow if not optimized */ - while( 1 ) - { - /* - * parse SET - */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - - end_set = *p + set_len; - - while( 1 ) - { - if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) - return( ret ); - - if( *p == end_set ) - break; - - /* Mark this item as being no the only one in a set */ - cur->next_merged = 1; - - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - cur = cur->next; - } - - /* - * continue until end of SEQUENCE is reached - */ - if( *p == end ) - return( 0 ); - - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - cur = cur->next; - } -} - -static int x509_parse_int( unsigned char **p, size_t n, int *res ) -{ - *res = 0; - - for( ; n > 0; --n ) - { - if( ( **p < '0') || ( **p > '9' ) ) - return ( MBEDTLS_ERR_X509_INVALID_DATE ); - - *res *= 10; - *res += ( *(*p)++ - '0' ); - } - - return( 0 ); -} - -static int x509_date_is_valid(const mbedtls_x509_time *t ) -{ - int ret = MBEDTLS_ERR_X509_INVALID_DATE; - int month_len; - - CHECK_RANGE( 0, 9999, t->year ); - CHECK_RANGE( 0, 23, t->hour ); - CHECK_RANGE( 0, 59, t->min ); - CHECK_RANGE( 0, 59, t->sec ); - - switch( t->mon ) - { - case 1: case 3: case 5: case 7: case 8: case 10: case 12: - month_len = 31; - break; - case 4: case 6: case 9: case 11: - month_len = 30; - break; - case 2: - if( ( !( t->year % 4 ) && t->year % 100 ) || - !( t->year % 400 ) ) - month_len = 29; - else - month_len = 28; - break; - default: - return( ret ); - } - CHECK_RANGE( 1, month_len, t->day ); - - return( 0 ); -} - -/* - * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) - * field. - */ -static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, - mbedtls_x509_time *tm ) -{ - int ret; - - /* - * Minimum length is 10 or 12 depending on yearlen - */ - if ( len < yearlen + 8 ) - return ( MBEDTLS_ERR_X509_INVALID_DATE ); - len -= yearlen + 8; - - /* - * Parse year, month, day, hour, minute - */ - CHECK( x509_parse_int( p, yearlen, &tm->year ) ); - if ( 2 == yearlen ) - { - if ( tm->year < 50 ) - tm->year += 100; - - tm->year += 1900; - } - - CHECK( x509_parse_int( p, 2, &tm->mon ) ); - CHECK( x509_parse_int( p, 2, &tm->day ) ); - CHECK( x509_parse_int( p, 2, &tm->hour ) ); - CHECK( x509_parse_int( p, 2, &tm->min ) ); - - /* - * Parse seconds if present - */ - if ( len >= 2 ) - { - CHECK( x509_parse_int( p, 2, &tm->sec ) ); - len -= 2; - } - else - return ( MBEDTLS_ERR_X509_INVALID_DATE ); - - /* - * Parse trailing 'Z' if present - */ - if ( 1 == len && 'Z' == **p ) - { - (*p)++; - len--; - } - - /* - * We should have parsed all characters at this point - */ - if ( 0 != len ) - return ( MBEDTLS_ERR_X509_INVALID_DATE ); - - CHECK( x509_date_is_valid( tm ) ); - - return ( 0 ); -} - -/* - * Time ::= CHOICE { - * utcTime UTCTime, - * generalTime GeneralizedTime } - */ -int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, - mbedtls_x509_time *tm ) -{ - int ret; - size_t len, year_len; - unsigned char tag; - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_DATE + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - tag = **p; - - if( tag == MBEDTLS_ASN1_UTC_TIME ) - year_len = 2; - else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) - year_len = 4; - else - return( MBEDTLS_ERR_X509_INVALID_DATE + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - (*p)++; - ret = mbedtls_asn1_get_len( p, end, &len ); - - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); - - return x509_parse_time( p, len, year_len, tm ); -} - -int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) -{ - int ret; - size_t len; - int tag_type; - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - tag_type = **p; - - if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret ); - - sig->tag = tag_type; - sig->len = len; - sig->p = *p; - - *p += len; - - return( 0 ); -} - -/* - * Get signature algorithm from alg OID and optional parameters - */ -int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, - mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, - void **sig_opts ) -{ - int ret; - - if( *sig_opts != NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) - return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret ); - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - if( *pk_alg == MBEDTLS_PK_RSASSA_PSS ) - { - mbedtls_pk_rsassa_pss_options *pss_opts; - - pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) ); - if( pss_opts == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - ret = mbedtls_x509_get_rsassa_pss_params( sig_params, - md_alg, - &pss_opts->mgf1_hash_id, - &pss_opts->expected_salt_len ); - if( ret != 0 ) - { - mbedtls_free( pss_opts ); - return( ret ); - } - - *sig_opts = (void *) pss_opts; - } - else -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - { - /* Make sure parameters are absent or NULL */ - if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || - sig_params->len != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG ); - } - - return( 0 ); -} - -/* - * X.509 Extensions (No parsing of extensions, pointer should - * be either manually updated or extensions should be parsed!) - */ -int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag ) -{ - int ret; - size_t len; - - /* Extension structure use EXPLICIT tagging. That is, the actual - * `Extensions` structure is wrapped by a tag-length pair using - * the respective context-specific tag. */ - ret = mbedtls_asn1_get_tag( p, end, &ext->len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag; - ext->p = *p; - end = *p + ext->len; - - /* - * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( end != *p + len ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * Store the name in printable form into buf; no more - * than size characters will be written - */ -int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ) -{ - int ret; - size_t i, n; - unsigned char c, merge = 0; - const mbedtls_x509_name *name; - const char *short_name = NULL; - char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p; - - memset( s, 0, sizeof( s ) ); - - name = dn; - p = buf; - n = size; - - while( name != NULL ) - { - if( !name->oid.p ) - { - name = name->next; - continue; - } - - if( name != dn ) - { - ret = mbedtls_snprintf( p, n, merge ? " + " : ", " ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name ); - - if( ret == 0 ) - ret = mbedtls_snprintf( p, n, "%s=", short_name ); - else - ret = mbedtls_snprintf( p, n, "\?\?=" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - for( i = 0; i < name->val.len; i++ ) - { - if( i >= sizeof( s ) - 1 ) - break; - - c = name->val.p[i]; - if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) - s[i] = '?'; - else s[i] = c; - } - s[i] = '\0'; - ret = mbedtls_snprintf( p, n, "%s", s ); - MBEDTLS_X509_SAFE_SNPRINTF; - - merge = name->next_merged; - name = name->next; - } - - return( (int) ( size - n ) ); -} - -/* - * Store the serial in printable form into buf; no more - * than size characters will be written - */ -int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ) -{ - int ret; - size_t i, n, nr; - char *p; - - p = buf; - n = size; - - nr = ( serial->len <= 32 ) - ? serial->len : 28; - - for( i = 0; i < nr; i++ ) - { - if( i == 0 && nr > 1 && serial->p[i] == 0x0 ) - continue; - - ret = mbedtls_snprintf( p, n, "%02X%s", - serial->p[i], ( i < nr - 1 ) ? ":" : "" ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - if( nr != serial->len ) - { - ret = mbedtls_snprintf( p, n, "...." ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - return( (int) ( size - n ) ); -} - -/* - * Helper for writing signature algorithms - */ -int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts ) -{ - int ret; - char *p = buf; - size_t n = size; - const char *desc = NULL; - - ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); - if( ret != 0 ) - ret = mbedtls_snprintf( p, n, "???" ); - else - ret = mbedtls_snprintf( p, n, "%s", desc ); - MBEDTLS_X509_SAFE_SNPRINTF; - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) - { - const mbedtls_pk_rsassa_pss_options *pss_opts; - const mbedtls_md_info_t *md_info, *mgf_md_info; - - pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; - - md_info = mbedtls_md_info_from_type( md_alg ); - mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id ); - - ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", - md_info ? mbedtls_md_get_name( md_info ) : "???", - mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???", - pss_opts->expected_salt_len ); - MBEDTLS_X509_SAFE_SNPRINTF; - } -#else - ((void) pk_alg); - ((void) md_alg); - ((void) sig_opts); -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - - return( (int)( size - n ) ); -} - -/* - * Helper for writing "RSA key size", "EC key size", etc - */ -int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) -{ - char *p = buf; - size_t n = buf_size; - int ret; - - ret = mbedtls_snprintf( p, n, "%s key size", name ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( 0 ); -} - -#if defined(MBEDTLS_HAVE_TIME_DATE) -/* - * Set the time structure to the current time. - * Return 0 on success, non-zero on failure. - */ -static int x509_get_current_time( mbedtls_x509_time *now ) -{ - struct tm *lt, tm_buf; - mbedtls_time_t tt; - int ret = 0; - - tt = mbedtls_time( NULL ); - lt = mbedtls_platform_gmtime_r( &tt, &tm_buf ); - - if( lt == NULL ) - ret = -1; - else - { - now->year = lt->tm_year + 1900; - now->mon = lt->tm_mon + 1; - now->day = lt->tm_mday; - now->hour = lt->tm_hour; - now->min = lt->tm_min; - now->sec = lt->tm_sec; - } - - return( ret ); -} - -/* - * Return 0 if before <= after, 1 otherwise - */ -static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after ) -{ - if( before->year > after->year ) - return( 1 ); - - if( before->year == after->year && - before->mon > after->mon ) - return( 1 ); - - if( before->year == after->year && - before->mon == after->mon && - before->day > after->day ) - return( 1 ); - - if( before->year == after->year && - before->mon == after->mon && - before->day == after->day && - before->hour > after->hour ) - return( 1 ); - - if( before->year == after->year && - before->mon == after->mon && - before->day == after->day && - before->hour == after->hour && - before->min > after->min ) - return( 1 ); - - if( before->year == after->year && - before->mon == after->mon && - before->day == after->day && - before->hour == after->hour && - before->min == after->min && - before->sec > after->sec ) - return( 1 ); - - return( 0 ); -} - -int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) -{ - mbedtls_x509_time now; - - if( x509_get_current_time( &now ) != 0 ) - return( 1 ); - - return( x509_check_time( &now, to ) ); -} - -int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) -{ - mbedtls_x509_time now; - - if( x509_get_current_time( &now ) != 0 ) - return( 1 ); - - return( x509_check_time( from, &now ) ); -} - -#else /* MBEDTLS_HAVE_TIME_DATE */ - -int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) -{ - ((void) to); - return( 0 ); -} - -int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) -{ - ((void) from); - return( 0 ); -} -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#if defined(MBEDTLS_SELF_TEST) - -#include "mbedtls/x509_crt.h" -#include "mbedtls/certs.h" - -/* - * Checkup routine - */ -int mbedtls_x509_self_test( int verbose ) -{ - int ret = 0; -#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) - uint32_t flags; - mbedtls_x509_crt cacert; - mbedtls_x509_crt clicert; - - if( verbose != 0 ) - mbedtls_printf( " X.509 certificate load: " ); - - mbedtls_x509_crt_init( &cacert ); - mbedtls_x509_crt_init( &clicert ); - - ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, - mbedtls_test_cli_crt_len ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, - mbedtls_test_ca_crt_len ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n X.509 signature verify: "); - - ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n\n"); - -cleanup: - mbedtls_x509_crt_free( &cacert ); - mbedtls_x509_crt_free( &clicert ); -#else - ((void) verbose); -#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */ - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_X509_USE_C */ diff --git a/mbedtls/x509.h b/mbedtls/x509.h deleted file mode 100644 index e9ce2cf40..000000000 --- a/mbedtls/x509.h +++ /dev/null @@ -1,363 +0,0 @@ -#pragma GCC system_header -/** - * \file x509.h - * - * \brief X.509 generic defines and structures - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_X509_H -#define MBEDTLS_X509_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "asn1.h" -#include "pk.h" - -#if defined(MBEDTLS_RSA_C) -#include "rsa.h" -#endif - -/** - * \addtogroup x509_module - * \{ - */ - -#if !defined(MBEDTLS_X509_MAX_INTERMEDIATE_CA) -/** - * Maximum number of intermediate CAs in a verification chain. - * That is, maximum length of the chain, excluding the end-entity certificate - * and the trusted root certificate. - * - * Set this to a low value to prevent an adversary from making you waste - * resources verifying an overlong certificate chain. - */ -#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 -#endif - -/** - * \name X509 Error codes - * \{ - */ -#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE -0x2080 /**< Unavailable feature, e.g. RSA hashing/encryption combination. */ -#define MBEDTLS_ERR_X509_UNKNOWN_OID -0x2100 /**< Requested OID is unknown. */ -#define MBEDTLS_ERR_X509_INVALID_FORMAT -0x2180 /**< The CRT/CRL/CSR format is invalid, e.g. different type expected. */ -#define MBEDTLS_ERR_X509_INVALID_VERSION -0x2200 /**< The CRT/CRL/CSR version element is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_SERIAL -0x2280 /**< The serial tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_ALG -0x2300 /**< The algorithm tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_NAME -0x2380 /**< The name tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_DATE -0x2400 /**< The date tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_SIGNATURE -0x2480 /**< The signature tag or value invalid. */ -#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS -0x2500 /**< The extension tag or value is invalid. */ -#define MBEDTLS_ERR_X509_UNKNOWN_VERSION -0x2580 /**< CRT/CRL/CSR has an unsupported version number. */ -#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG -0x2600 /**< Signature algorithm (oid) is unsupported. */ -#define MBEDTLS_ERR_X509_SIG_MISMATCH -0x2680 /**< Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */ -#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED -0x2700 /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */ -#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT -0x2780 /**< Format not recognized as DER or PEM. */ -#define MBEDTLS_ERR_X509_BAD_INPUT_DATA -0x2800 /**< Input invalid. */ -#define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ -#define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ -#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */ -#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */ -/* \} name */ - -/** - * \name X509 Verify codes - * \{ - */ -/* Reminder: update x509_crt_verify_strings[] in library/x509_crt.c */ -#define MBEDTLS_X509_BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */ -#define MBEDTLS_X509_BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */ -#define MBEDTLS_X509_BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */ -#define MBEDTLS_X509_BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */ -#define MBEDTLS_X509_BADCRL_NOT_TRUSTED 0x10 /**< The CRL is not correctly signed by the trusted CA. */ -#define MBEDTLS_X509_BADCRL_EXPIRED 0x20 /**< The CRL is expired. */ -#define MBEDTLS_X509_BADCERT_MISSING 0x40 /**< Certificate was missing. */ -#define MBEDTLS_X509_BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */ -#define MBEDTLS_X509_BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */ -#define MBEDTLS_X509_BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */ -#define MBEDTLS_X509_BADCRL_FUTURE 0x0400 /**< The CRL is from the future */ -#define MBEDTLS_X509_BADCERT_KEY_USAGE 0x0800 /**< Usage does not match the keyUsage extension. */ -#define MBEDTLS_X509_BADCERT_EXT_KEY_USAGE 0x1000 /**< Usage does not match the extendedKeyUsage extension. */ -#define MBEDTLS_X509_BADCERT_NS_CERT_TYPE 0x2000 /**< Usage does not match the nsCertType extension. */ -#define MBEDTLS_X509_BADCERT_BAD_MD 0x4000 /**< The certificate is signed with an unacceptable hash. */ -#define MBEDTLS_X509_BADCERT_BAD_PK 0x8000 /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ -#define MBEDTLS_X509_BADCERT_BAD_KEY 0x010000 /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */ -#define MBEDTLS_X509_BADCRL_BAD_MD 0x020000 /**< The CRL is signed with an unacceptable hash. */ -#define MBEDTLS_X509_BADCRL_BAD_PK 0x040000 /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ -#define MBEDTLS_X509_BADCRL_BAD_KEY 0x080000 /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */ - -/* \} name */ -/* \} addtogroup x509_module */ - -/* - * X.509 v3 Key Usage Extension flags - * Reminder: update x509_info_key_usage() when adding new flags. - */ -#define MBEDTLS_X509_KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ -#define MBEDTLS_X509_KU_NON_REPUDIATION (0x40) /* bit 1 */ -#define MBEDTLS_X509_KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */ -#define MBEDTLS_X509_KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */ -#define MBEDTLS_X509_KU_KEY_AGREEMENT (0x08) /* bit 4 */ -#define MBEDTLS_X509_KU_KEY_CERT_SIGN (0x04) /* bit 5 */ -#define MBEDTLS_X509_KU_CRL_SIGN (0x02) /* bit 6 */ -#define MBEDTLS_X509_KU_ENCIPHER_ONLY (0x01) /* bit 7 */ -#define MBEDTLS_X509_KU_DECIPHER_ONLY (0x8000) /* bit 8 */ - -/* - * Netscape certificate types - * (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html) - */ - -#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */ -#define MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */ -#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */ -#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */ -#define MBEDTLS_X509_NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */ -#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */ -#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */ -#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */ - -/* - * X.509 extension types - * - * Comments refer to the status for using certificates. Status can be - * different for writing certificates or reading CRLs or CSRs. - */ -#define MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0) -#define MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER (1 << 1) -#define MBEDTLS_X509_EXT_KEY_USAGE (1 << 2) -#define MBEDTLS_X509_EXT_CERTIFICATE_POLICIES (1 << 3) -#define MBEDTLS_X509_EXT_POLICY_MAPPINGS (1 << 4) -#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME (1 << 5) /* Supported (DNS) */ -#define MBEDTLS_X509_EXT_ISSUER_ALT_NAME (1 << 6) -#define MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7) -#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS (1 << 8) /* Supported */ -#define MBEDTLS_X509_EXT_NAME_CONSTRAINTS (1 << 9) -#define MBEDTLS_X509_EXT_POLICY_CONSTRAINTS (1 << 10) -#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE (1 << 11) -#define MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS (1 << 12) -#define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13) -#define MBEDTLS_X509_EXT_FRESHEST_CRL (1 << 14) - -#define MBEDTLS_X509_EXT_NS_CERT_TYPE (1 << 16) - -/* - * Storage format identifiers - * Recognized formats: PEM and DER - */ -#define MBEDTLS_X509_FORMAT_DER 1 -#define MBEDTLS_X509_FORMAT_PEM 2 - -#define MBEDTLS_X509_MAX_DN_NAME_SIZE 256 /**< Maximum value size of a DN entry */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup x509_module - * \{ */ - -/** - * \name Structures for parsing X.509 certificates, CRLs and CSRs - * \{ - */ - -/** - * Type-length-value structure that allows for ASN1 using DER. - */ -typedef mbedtls_asn1_buf mbedtls_x509_buf; - -/** - * Container for ASN1 bit strings. - */ -typedef mbedtls_asn1_bitstring mbedtls_x509_bitstring; - -/** - * Container for ASN1 named information objects. - * It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.). - */ -typedef mbedtls_asn1_named_data mbedtls_x509_name; - -/** - * Container for a sequence of ASN.1 items - */ -typedef mbedtls_asn1_sequence mbedtls_x509_sequence; - -/** Container for date and time (precision in seconds). */ -typedef struct mbedtls_x509_time -{ - int year, mon, day; /**< Date. */ - int hour, min, sec; /**< Time. */ -} -mbedtls_x509_time; - -/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */ -/** \} addtogroup x509_module */ - -/** - * \brief Store the certificate DN in printable form into buf; - * no more than size characters will be written. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param dn The X509 name to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ); - -/** - * \brief Store the certificate serial in printable form into buf; - * no more than size characters will be written. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param serial The X509 serial to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ); - -/** - * \brief Check a given mbedtls_x509_time against the system time - * and tell if it's in the past. - * - * \note Intended usage is "if( is_past( valid_to ) ) ERROR". - * Hence the return value of 1 if on internal errors. - * - * \param to mbedtls_x509_time to check - * - * \return 1 if the given time is in the past or an error occurred, - * 0 otherwise. - */ -int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); - -/** - * \brief Check a given mbedtls_x509_time against the system time - * and tell if it's in the future. - * - * \note Intended usage is "if( is_future( valid_from ) ) ERROR". - * Hence the return value of 1 if on internal errors. - * - * \param from mbedtls_x509_time to check - * - * \return 1 if the given time is in the future or an error occurred, - * 0 otherwise. - */ -int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_x509_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -/* - * Internal module functions. You probably do not want to use these unless you - * know you do. - */ -int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, - mbedtls_x509_name *cur ); -int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg ); -int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg, mbedtls_x509_buf *params ); -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) -int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, - mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, - int *salt_len ); -#endif -int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ); -int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, - mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, - void **sig_opts ); -int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, - mbedtls_x509_time *t ); -int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *serial ); -int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag ); -int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts ); -int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ); -int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ); -int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, - int critical, const unsigned char *val, - size_t val_len ); -int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first ); -int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first ); -int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len, - unsigned char *sig, size_t size ); - -#define MBEDTLS_X509_SAFE_SNPRINTF \ - do { \ - if( ret < 0 || (size_t) ret >= n ) \ - return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); \ - \ - n -= (size_t) ret; \ - p += (size_t) ret; \ - } while( 0 ) - -#ifdef __cplusplus -} -#endif - -#endif /* x509.h */ diff --git a/mbedtls/x509_create.c b/mbedtls/x509_create.c deleted file mode 100644 index 2875d9532..000000000 --- a/mbedtls/x509_create.c +++ /dev/null @@ -1,417 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * X.509 base functions for creating certificates / CSRs - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CREATE_C) - -#include "mbedtls/x509.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/oid.h" - -#include - -/* Structure linking OIDs for X.509 DN AttributeTypes to their - * string representations and default string encodings used by Mbed TLS. */ -typedef struct { - const char *name; /* String representation of AttributeType, e.g. - * "CN" or "emailAddress". */ - size_t name_len; /* Length of 'name', without trailing 0 byte. */ - const char *oid; /* String representation of OID of AttributeType, - * as per RFC 5280, Appendix A.1. */ - int default_tag; /* The default character encoding used for the - * given attribute type, e.g. - * MBEDTLS_ASN1_UTF8_STRING for UTF-8. */ -} x509_attr_descriptor_t; - -#define ADD_STRLEN( s ) s, sizeof( s ) - 1 - -/* X.509 DN attributes from RFC 5280, Appendix A.1. */ -static const x509_attr_descriptor_t x509_attrs[] = -{ - { ADD_STRLEN( "CN" ), - MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "commonName" ), - MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "C" ), - MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "countryName" ), - MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "O" ), - MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "organizationName" ), - MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "L" ), - MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "locality" ), - MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "R" ), - MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, - { ADD_STRLEN( "OU" ), - MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "organizationalUnitName" ), - MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "ST" ), - MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "stateOrProvinceName" ), - MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "emailAddress" ), - MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, - { ADD_STRLEN( "serialNumber" ), - MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "postalAddress" ), - MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "postalCode" ), - MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "dnQualifier" ), - MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN( "title" ), - MBEDTLS_OID_AT_TITLE, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "surName" ), - MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "SN" ), - MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "givenName" ), - MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "GN" ), - MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "initials" ), - MBEDTLS_OID_AT_INITIALS, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "pseudonym" ), - MBEDTLS_OID_AT_PSEUDONYM, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "generationQualifier" ), - MBEDTLS_OID_AT_GENERATION_QUALIFIER, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN( "domainComponent" ), - MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, - { ADD_STRLEN( "DC" ), - MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, - { NULL, 0, NULL, MBEDTLS_ASN1_NULL } -}; - -static const x509_attr_descriptor_t *x509_attr_descr_from_name( const char *name, size_t name_len ) -{ - const x509_attr_descriptor_t *cur; - - for( cur = x509_attrs; cur->name != NULL; cur++ ) - if( cur->name_len == name_len && - strncmp( cur->name, name, name_len ) == 0 ) - break; - - if ( cur->name == NULL ) - return( NULL ); - - return( cur ); -} - -int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ) -{ - int ret = 0; - const char *s = name, *c = s; - const char *end = s + strlen( s ); - const char *oid = NULL; - const x509_attr_descriptor_t* attr_descr = NULL; - int in_tag = 1; - char data[MBEDTLS_X509_MAX_DN_NAME_SIZE]; - char *d = data; - - /* Clear existing chain if present */ - mbedtls_asn1_free_named_data_list( head ); - - while( c <= end ) - { - if( in_tag && *c == '=' ) - { - if( ( attr_descr = x509_attr_descr_from_name( s, c - s ) ) == NULL ) - { - ret = MBEDTLS_ERR_X509_UNKNOWN_OID; - goto exit; - } - - oid = attr_descr->oid; - s = c + 1; - in_tag = 0; - d = data; - } - - if( !in_tag && *c == '\\' && c != end ) - { - c++; - - /* Check for valid escaped characters */ - if( c == end || *c != ',' ) - { - ret = MBEDTLS_ERR_X509_INVALID_NAME; - goto exit; - } - } - else if( !in_tag && ( *c == ',' || c == end ) ) - { - mbedtls_asn1_named_data* cur = - mbedtls_asn1_store_named_data( head, oid, strlen( oid ), - (unsigned char *) data, - d - data ); - - if(cur == NULL ) - { - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - } - - // set tagType - cur->val.tag = attr_descr->default_tag; - - while( c < end && *(c + 1) == ' ' ) - c++; - - s = c + 1; - in_tag = 1; - } - - if( !in_tag && s != c + 1 ) - { - *(d++) = *c; - - if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE ) - { - ret = MBEDTLS_ERR_X509_INVALID_NAME; - goto exit; - } - } - - c++; - } - -exit: - - return( ret ); -} - -/* The first byte of the value in the mbedtls_asn1_named_data structure is reserved - * to store the critical boolean for us - */ -int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, - int critical, const unsigned char *val, size_t val_len ) -{ - mbedtls_asn1_named_data *cur; - - if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len, - NULL, val_len + 1 ) ) == NULL ) - { - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - } - - cur->val.p[0] = critical; - memcpy( cur->val.p + 1, val, val_len ); - - return( 0 ); -} - -/* - * RelativeDistinguishedName ::= - * SET OF AttributeTypeAndValue - * - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - */ -static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn1_named_data* cur_name) -{ - int ret; - size_t len = 0; - const char *oid = (const char*)cur_name->oid.p; - size_t oid_len = cur_name->oid.len; - const unsigned char *name = cur_name->val.p; - size_t name_len = cur_name->val.len; - - // Write correct string tag and value - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tagged_string( p, start, - cur_name->val.tag, - (const char *) name, - name_len ) ); - // Write OID - // - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, - oid_len ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SET ) ); - - return( (int) len ); -} - -int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first ) -{ - int ret; - size_t len = 0; - mbedtls_asn1_named_data *cur = first; - - while( cur != NULL ) - { - MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, cur ) ); - cur = cur->next; - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return( (int) len ); -} - -int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len, - unsigned char *sig, size_t size ) -{ - int ret; - size_t len = 0; - - if( *p < start || (size_t)( *p - start ) < size ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - len = size; - (*p) -= len; - memcpy( *p, sig, len ); - - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - *--(*p) = 0; - len += 1; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); - - // Write OID - // - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid, - oid_len, 0 ) ); - - return( (int) len ); -} - -static int x509_write_extension( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *ext ) -{ - int ret; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1, - ext->val.len - 1 ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); - - if( ext->val.p[0] != 0 ) - { - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) ); - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p, - ext->oid.len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return( (int) len ); -} - -/* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING - * -- contains the DER encoding of an ASN.1 value - * -- corresponding to the extension type identified - * -- by extnID - * } - */ -int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first ) -{ - int ret; - size_t len = 0; - mbedtls_asn1_named_data *cur_ext = first; - - while( cur_ext != NULL ) - { - MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) ); - cur_ext = cur_ext->next; - } - - return( (int) len ); -} - -#endif /* MBEDTLS_X509_CREATE_C */ diff --git a/mbedtls/x509_crl.c b/mbedtls/x509_crl.c deleted file mode 100644 index ae5be08d3..000000000 --- a/mbedtls/x509_crl.c +++ /dev/null @@ -1,811 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * X.509 Certidicate Revocation List (CRL) parsing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The ITU-T X.509 standard defines a certificate format for PKI. - * - * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) - * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) - * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) - * - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CRL_PARSE_C) - -#include "mbedtls/x509_crl.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_snprintf snprintf -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -#include -#else -#include -#endif - -#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) -#include -#endif - -/* - * Version ::= INTEGER { v1(0), v2(1) } - */ -static int x509_crl_get_version( unsigned char **p, - const unsigned char *end, - int *ver ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - *ver = 0; - return( 0 ); - } - - return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); - } - - return( 0 ); -} - -/* - * X.509 CRL v2 extensions - * - * We currently don't parse any extension's content, but we do check that the - * list of extensions is well-formed and abort on critical extensions (that - * are unsupported as we don't support any extension so far) - */ -static int x509_get_crl_ext( unsigned char **p, - const unsigned char *end, - mbedtls_x509_buf *ext ) -{ - int ret; - - if( *p == end ) - return( 0 ); - - /* - * crlExtensions [0] EXPLICIT Extensions OPTIONAL - * -- if present, version MUST be v2 - */ - if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0 ) ) != 0 ) - return( ret ); - - end = ext->p + ext->len; - - while( *p < end ) - { - /* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING } - */ - int is_critical = 0; - const unsigned char *end_ext_data; - size_t len; - - /* Get enclosing sequence tag */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - end_ext_data = *p + len; - - /* Get OID (currently ignored) */ - if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, - MBEDTLS_ASN1_OID ) ) != 0 ) - { - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - } - *p += len; - - /* Get optional critical */ - if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, - &is_critical ) ) != 0 && - ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) - { - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - } - - /* Data should be octet string type */ - if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, - MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - /* Ignore data so far and just check its length */ - *p += len; - if( *p != end_ext_data ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* Abort on (unsupported) critical extensions */ - if( is_critical ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * X.509 CRL v2 entry extensions (no extensions parsed yet.) - */ -static int x509_get_crl_entry_ext( unsigned char **p, - const unsigned char *end, - mbedtls_x509_buf *ext ) -{ - int ret; - size_t len = 0; - - /* OPTIONAL */ - if( end <= *p ) - return( 0 ); - - ext->tag = **p; - ext->p = *p; - - /* - * Get CRL-entry extension sequence header - * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2 - */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - ext->p = NULL; - return( 0 ); - } - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - } - - end = *p + ext->len; - - if( end != *p + ext->len ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - while( *p < end ) - { - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - *p += len; - } - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * X.509 CRL Entries - */ -static int x509_get_entries( unsigned char **p, - const unsigned char *end, - mbedtls_x509_crl_entry *entry ) -{ - int ret; - size_t entry_len; - mbedtls_x509_crl_entry *cur_entry = entry; - - if( *p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_tag( p, end, &entry_len, - MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( 0 ); - - return( ret ); - } - - end = *p + entry_len; - - while( *p < end ) - { - size_t len2; - const unsigned char *end2; - - cur_entry->raw.tag = **p; - if( ( ret = mbedtls_asn1_get_tag( p, end, &len2, - MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 ) - { - return( ret ); - } - - cur_entry->raw.p = *p; - cur_entry->raw.len = len2; - end2 = *p + len2; - - if( ( ret = mbedtls_x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_x509_get_time( p, end2, - &cur_entry->revocation_date ) ) != 0 ) - return( ret ); - - if( ( ret = x509_get_crl_entry_ext( p, end2, - &cur_entry->entry_ext ) ) != 0 ) - return( ret ); - - if( *p < end ) - { - cur_entry->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl_entry ) ); - - if( cur_entry->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - cur_entry = cur_entry->next; - } - } - - return( 0 ); -} - -/* - * Parse one CRLs in DER format and append it to the chained list - */ -int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, - const unsigned char *buf, size_t buflen ) -{ - int ret; - size_t len; - unsigned char *p = NULL, *end = NULL; - mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; - mbedtls_x509_crl *crl = chain; - - /* - * Check for valid input - */ - if( crl == NULL || buf == NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); - memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); - memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); - - /* - * Add new CRL on the end of the chain if needed. - */ - while( crl->version != 0 && crl->next != NULL ) - crl = crl->next; - - if( crl->version != 0 && crl->next == NULL ) - { - crl->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl ) ); - - if( crl->next == NULL ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - } - - mbedtls_x509_crl_init( crl->next ); - crl = crl->next; - } - - /* - * Copy raw DER-encoded CRL - */ - if( buflen == 0 ) - return( MBEDTLS_ERR_X509_INVALID_FORMAT ); - - p = mbedtls_calloc( 1, buflen ); - if( p == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - memcpy( p, buf, buflen ); - - crl->raw.p = p; - crl->raw.len = buflen; - - end = p + buflen; - - /* - * CertificateList ::= SEQUENCE { - * tbsCertList TBSCertList, - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT ); - } - - if( len != (size_t) ( end - p ) ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - /* - * TBSCertList ::= SEQUENCE { - */ - crl->tbs.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - end = p + len; - crl->tbs.len = end - crl->tbs.p; - - /* - * Version ::= INTEGER OPTIONAL { v1(0), v2(1) } - * -- if present, MUST be v2 - * - * signature AlgorithmIdentifier - */ - if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 || - ( ret = mbedtls_x509_get_alg( &p, end, &crl->sig_oid, &sig_params1 ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( ret ); - } - - if( crl->version < 0 || crl->version > 1 ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); - } - - crl->version++; - - if( ( ret = mbedtls_x509_get_sig_alg( &crl->sig_oid, &sig_params1, - &crl->sig_md, &crl->sig_pk, - &crl->sig_opts ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); - } - - /* - * issuer Name - */ - crl->issuer_raw.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( ret ); - } - - crl->issuer_raw.len = p - crl->issuer_raw.p; - - /* - * thisUpdate Time - * nextUpdate Time OPTIONAL - */ - if( ( ret = mbedtls_x509_get_time( &p, end, &crl->this_update ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( ret ); - } - - if( ( ret = mbedtls_x509_get_time( &p, end, &crl->next_update ) ) != 0 ) - { - if( ret != ( MBEDTLS_ERR_X509_INVALID_DATE + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) && - ret != ( MBEDTLS_ERR_X509_INVALID_DATE + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ) - { - mbedtls_x509_crl_free( crl ); - return( ret ); - } - } - - /* - * revokedCertificates SEQUENCE OF SEQUENCE { - * userCertificate CertificateSerialNumber, - * revocationDate Time, - * crlEntryExtensions Extensions OPTIONAL - * -- if present, MUST be v2 - * } OPTIONAL - */ - if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( ret ); - } - - /* - * crlExtensions EXPLICIT Extensions OPTIONAL - * -- if present, MUST be v2 - */ - if( crl->version == 2 ) - { - ret = x509_get_crl_ext( &p, end, &crl->crl_ext ); - - if( ret != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( ret ); - } - } - - if( p != end ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - end = crl->raw.p + crl->raw.len; - - /* - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING - */ - if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( ret ); - } - - if( crl->sig_oid.len != sig_oid2.len || - memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 || - sig_params1.len != sig_params2.len || - ( sig_params1.len != 0 && - memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_SIG_MISMATCH ); - } - - if( ( ret = mbedtls_x509_get_sig( &p, end, &crl->sig ) ) != 0 ) - { - mbedtls_x509_crl_free( crl ); - return( ret ); - } - - if( p != end ) - { - mbedtls_x509_crl_free( crl ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - return( 0 ); -} - -/* - * Parse one or more CRLs and add them to the chained list - */ -int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen ) -{ -#if defined(MBEDTLS_PEM_PARSE_C) - int ret; - size_t use_len = 0; - mbedtls_pem_context pem; - int is_pem = 0; - - if( chain == NULL || buf == NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - do - { - mbedtls_pem_init( &pem ); - - // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated - // string - if( buflen == 0 || buf[buflen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN X509 CRL-----", - "-----END X509 CRL-----", - buf, NULL, 0, &use_len ); - - if( ret == 0 ) - { - /* - * Was PEM encoded - */ - is_pem = 1; - - buflen -= use_len; - buf += use_len; - - if( ( ret = mbedtls_x509_crl_parse_der( chain, - pem.buf, pem.buflen ) ) != 0 ) - { - mbedtls_pem_free( &pem ); - return( ret ); - } - } - else if( is_pem ) - { - mbedtls_pem_free( &pem ); - return( ret ); - } - - mbedtls_pem_free( &pem ); - } - /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte. - * And a valid CRL cannot be less than 1 byte anyway. */ - while( is_pem && buflen > 1 ); - - if( is_pem ) - return( 0 ); - else -#endif /* MBEDTLS_PEM_PARSE_C */ - return( mbedtls_x509_crl_parse_der( chain, buf, buflen ) ); -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load one or more CRLs and add them to the chained list - */ -int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ) -{ - int ret; - size_t n; - unsigned char *buf; - - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - ret = mbedtls_x509_crl_parse( chain, buf, n ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -/* - * Return an informational string about the certificate. - */ -#define BEFORE_COLON 14 -#define BC "14" -/* - * Return an informational string about the CRL. - */ -int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crl *crl ) -{ - int ret; - size_t n; - char *p; - const mbedtls_x509_crl_entry *entry; - - p = buf; - n = size; - - ret = mbedtls_snprintf( p, n, "%sCRL version : %d", - prefix, crl->version ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &crl->issuer ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%sthis update : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crl->this_update.year, crl->this_update.mon, - crl->this_update.day, crl->this_update.hour, - crl->this_update.min, crl->this_update.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%snext update : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crl->next_update.year, crl->next_update.mon, - crl->next_update.day, crl->next_update.hour, - crl->next_update.min, crl->next_update.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; - - entry = &crl->entry; - - ret = mbedtls_snprintf( p, n, "\n%sRevoked certificates:", - prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - while( entry != NULL && entry->raw.len != 0 ) - { - ret = mbedtls_snprintf( p, n, "\n%sserial number: ", - prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_serial_gets( p, n, &entry->serial ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, " revocation date: " \ - "%04d-%02d-%02d %02d:%02d:%02d", - entry->revocation_date.year, entry->revocation_date.mon, - entry->revocation_date.day, entry->revocation_date.hour, - entry->revocation_date.min, entry->revocation_date.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; - - entry = entry->next; - } - - ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md, - crl->sig_opts ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( (int) ( size - n ) ); -} - -/* - * Initialize a CRL chain - */ -void mbedtls_x509_crl_init( mbedtls_x509_crl *crl ) -{ - memset( crl, 0, sizeof(mbedtls_x509_crl) ); -} - -/* - * Unallocate all CRL data - */ -void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ) -{ - mbedtls_x509_crl *crl_cur = crl; - mbedtls_x509_crl *crl_prv; - mbedtls_x509_name *name_cur; - mbedtls_x509_name *name_prv; - mbedtls_x509_crl_entry *entry_cur; - mbedtls_x509_crl_entry *entry_prv; - - if( crl == NULL ) - return; - - do - { -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free( crl_cur->sig_opts ); -#endif - - name_cur = crl_cur->issuer.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - entry_cur = crl_cur->entry.next; - while( entry_cur != NULL ) - { - entry_prv = entry_cur; - entry_cur = entry_cur->next; - mbedtls_platform_zeroize( entry_prv, - sizeof( mbedtls_x509_crl_entry ) ); - mbedtls_free( entry_prv ); - } - - if( crl_cur->raw.p != NULL ) - { - mbedtls_platform_zeroize( crl_cur->raw.p, crl_cur->raw.len ); - mbedtls_free( crl_cur->raw.p ); - } - - crl_cur = crl_cur->next; - } - while( crl_cur != NULL ); - - crl_cur = crl; - do - { - crl_prv = crl_cur; - crl_cur = crl_cur->next; - - mbedtls_platform_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) ); - if( crl_prv != crl ) - mbedtls_free( crl_prv ); - } - while( crl_cur != NULL ); -} - -#endif /* MBEDTLS_X509_CRL_PARSE_C */ diff --git a/mbedtls/x509_crl.h b/mbedtls/x509_crl.h deleted file mode 100644 index efa5eb1bb..000000000 --- a/mbedtls/x509_crl.h +++ /dev/null @@ -1,200 +0,0 @@ -#pragma GCC system_header -/** - * \file x509_crl.h - * - * \brief X.509 certificate revocation list parsing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_X509_CRL_H -#define MBEDTLS_X509_CRL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "x509.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup x509_module - * \{ */ - -/** - * \name Structures and functions for parsing CRLs - * \{ - */ - -/** - * Certificate revocation list entry. - * Contains the CA-specific serial numbers and revocation dates. - */ -typedef struct mbedtls_x509_crl_entry -{ - mbedtls_x509_buf raw; - - mbedtls_x509_buf serial; - - mbedtls_x509_time revocation_date; - - mbedtls_x509_buf entry_ext; - - struct mbedtls_x509_crl_entry *next; -} -mbedtls_x509_crl_entry; - -/** - * Certificate revocation list structure. - * Every CRL may have multiple entries. - */ -typedef struct mbedtls_x509_crl -{ - mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ - mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ - - int version; /**< CRL version (1=v1, 2=v2) */ - mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */ - - mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */ - - mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ - - mbedtls_x509_time this_update; - mbedtls_x509_time next_update; - - mbedtls_x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */ - - mbedtls_x509_buf crl_ext; - - mbedtls_x509_buf sig_oid2; - mbedtls_x509_buf sig; - mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ - - struct mbedtls_x509_crl *next; -} -mbedtls_x509_crl; - -/** - * \brief Parse a DER-encoded CRL and append it to the chained list - * - * \param chain points to the start of the chain - * \param buf buffer holding the CRL data in DER format - * \param buflen size of the buffer - * (including the terminating null byte for PEM data) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, - const unsigned char *buf, size_t buflen ); -/** - * \brief Parse one or more CRLs and append them to the chained list - * - * \note Multiple CRLs are accepted only if using PEM format - * - * \param chain points to the start of the chain - * \param buf buffer holding the CRL data in PEM or DER format - * \param buflen size of the buffer - * (including the terminating null byte for PEM data) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen ); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Load one or more CRLs and append them to the chained list - * - * \note Multiple CRLs are accepted only if using PEM format - * - * \param chain points to the start of the chain - * \param path filename to read the CRLs from (in PEM or DER encoding) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief Returns an informational string about the CRL. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param crl The X509 CRL to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crl *crl ); - -/** - * \brief Initialize a CRL (chain) - * - * \param crl CRL chain to initialize - */ -void mbedtls_x509_crl_init( mbedtls_x509_crl *crl ); - -/** - * \brief Unallocate all CRL data - * - * \param crl CRL chain to free - */ -void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ); - -/* \} name */ -/* \} addtogroup x509_module */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_x509_crl.h */ diff --git a/mbedtls/x509_crt.c b/mbedtls/x509_crt.c deleted file mode 100644 index 7e8b04156..000000000 --- a/mbedtls/x509_crt.c +++ /dev/null @@ -1,2773 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * X.509 certificate parsing and verification - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The ITU-T X.509 standard defines a certificate format for PKI. - * - * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) - * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) - * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) - * - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - * - * [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - -#include "mbedtls/x509_crt.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_snprintf snprintf -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -#include -#else -#include -#endif - -#if defined(MBEDTLS_FS_IO) -#include -#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32) -#include -#include -#include -#endif /* !_WIN32 || EFIX64 || EFI32 */ -#endif - -/* - * Item in a verification chain: cert and flags for it - */ -typedef struct { - mbedtls_x509_crt *crt; - uint32_t flags; -} x509_crt_verify_chain_item; - -/* - * Max size of verification chain: end-entity + intermediates + trusted root - */ -#define X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) - -/* Default profile. Do not remove items unless there are serious security - * concerns. */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = -{ -#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES) - /* Allow SHA-1 (weak, but still safe in controlled environments) */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | -#endif - /* Only SHA-2 hashes */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), - 0xFFFFFFF, /* Any PK alg */ - 0xFFFFFFF, /* Any curve */ - 2048, -}; - -/* - * Next-default profile - */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = -{ - /* Hashes from SHA-256 and above */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), - 0xFFFFFFF, /* Any PK alg */ -#if defined(MBEDTLS_ECP_C) - /* Curves at or above 128-bit security level */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ), -#else - 0, -#endif - 2048, -}; - -/* - * NSA Suite B Profile - */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = -{ - /* Only SHA-256 and 384 */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), - /* Only ECDSA */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), -#if defined(MBEDTLS_ECP_C) - /* Only NIST P-256 and P-384 */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), -#else - 0, -#endif - 0, -}; - -/* - * Check md_alg against profile - * Return 0 if md_alg is acceptable for this profile, -1 otherwise - */ -static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile, - mbedtls_md_type_t md_alg ) -{ - if( md_alg == MBEDTLS_MD_NONE ) - return( -1 ); - - if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 ) - return( 0 ); - - return( -1 ); -} - -/* - * Check pk_alg against profile - * Return 0 if pk_alg is acceptable for this profile, -1 otherwise - */ -static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile, - mbedtls_pk_type_t pk_alg ) -{ - if( pk_alg == MBEDTLS_PK_NONE ) - return( -1 ); - - if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 ) - return( 0 ); - - return( -1 ); -} - -/* - * Check key against profile - * Return 0 if pk is acceptable for this profile, -1 otherwise - */ -static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, - const mbedtls_pk_context *pk ) -{ - const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type( pk ); - -#if defined(MBEDTLS_RSA_C) - if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS ) - { - if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen ) - return( 0 ); - - return( -1 ); - } -#endif - -#if defined(MBEDTLS_ECP_C) - if( pk_alg == MBEDTLS_PK_ECDSA || - pk_alg == MBEDTLS_PK_ECKEY || - pk_alg == MBEDTLS_PK_ECKEY_DH ) - { - const mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id; - - if( gid == MBEDTLS_ECP_DP_NONE ) - return( -1 ); - - if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 ) - return( 0 ); - - return( -1 ); - } -#endif - - return( -1 ); -} - -/* - * Like memcmp, but case-insensitive and always returns -1 if different - */ -static int x509_memcasecmp( const void *s1, const void *s2, size_t len ) -{ - size_t i; - unsigned char diff; - const unsigned char *n1 = s1, *n2 = s2; - - for( i = 0; i < len; i++ ) - { - diff = n1[i] ^ n2[i]; - - if( diff == 0 ) - continue; - - if( diff == 32 && - ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || - ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) - { - continue; - } - - return( -1 ); - } - - return( 0 ); -} - -/* - * Return 0 if name matches wildcard, -1 otherwise - */ -static int x509_check_wildcard( const char *cn, const mbedtls_x509_buf *name ) -{ - size_t i; - size_t cn_idx = 0, cn_len = strlen( cn ); - - /* We can't have a match if there is no wildcard to match */ - if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) - return( -1 ); - - for( i = 0; i < cn_len; ++i ) - { - if( cn[i] == '.' ) - { - cn_idx = i; - break; - } - } - - if( cn_idx == 0 ) - return( -1 ); - - if( cn_len - cn_idx == name->len - 1 && - x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) - { - return( 0 ); - } - - return( -1 ); -} - -/* - * Compare two X.509 strings, case-insensitive, and allowing for some encoding - * variations (but not all). - * - * Return 0 if equal, -1 otherwise. - */ -static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b ) -{ - if( a->tag == b->tag && - a->len == b->len && - memcmp( a->p, b->p, b->len ) == 0 ) - { - return( 0 ); - } - - if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && - ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && - a->len == b->len && - x509_memcasecmp( a->p, b->p, b->len ) == 0 ) - { - return( 0 ); - } - - return( -1 ); -} - -/* - * Compare two X.509 Names (aka rdnSequence). - * - * See RFC 5280 section 7.1, though we don't implement the whole algorithm: - * we sometimes return unequal when the full algorithm would return equal, - * but never the other way. (In particular, we don't do Unicode normalisation - * or space folding.) - * - * Return 0 if equal, -1 otherwise. - */ -static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b ) -{ - /* Avoid recursion, it might not be optimised by the compiler */ - while( a != NULL || b != NULL ) - { - if( a == NULL || b == NULL ) - return( -1 ); - - /* type */ - if( a->oid.tag != b->oid.tag || - a->oid.len != b->oid.len || - memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 ) - { - return( -1 ); - } - - /* value */ - if( x509_string_cmp( &a->val, &b->val ) != 0 ) - return( -1 ); - - /* structure of the list of sets */ - if( a->next_merged != b->next_merged ) - return( -1 ); - - a = a->next; - b = b->next; - } - - /* a == NULL == b */ - return( 0 ); -} - -/* - * Reset (init or clear) a verify_chain - */ -static void x509_crt_verify_chain_reset( - mbedtls_x509_crt_verify_chain *ver_chain ) -{ - size_t i; - - for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ ) - { - ver_chain->items[i].crt = NULL; - ver_chain->items[i].flags = (uint32_t) -1; - } - - ver_chain->len = 0; -} - -/* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ -static int x509_get_version( unsigned char **p, - const unsigned char *end, - int *ver ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - *ver = 0; - return( 0 ); - } - - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - end = *p + len; - - if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_VERSION + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - */ -static int x509_get_dates( unsigned char **p, - const unsigned char *end, - mbedtls_x509_time *from, - mbedtls_x509_time *to ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); - - end = *p + len; - - if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 ) - return( ret ); - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_DATE + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * X.509 v2/v3 unique identifier (not parsed) - */ -static int x509_get_uid( unsigned char **p, - const unsigned char *end, - mbedtls_x509_buf *uid, int n ) -{ - int ret; - - if( *p == end ) - return( 0 ); - - uid->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( 0 ); - - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - uid->p = *p; - *p += uid->len; - - return( 0 ); -} - -static int x509_get_basic_constraints( unsigned char **p, - const unsigned char *end, - int *ca_istrue, - int *max_pathlen ) -{ - int ret; - size_t len; - - /* - * BasicConstraints ::= SEQUENCE { - * cA BOOLEAN DEFAULT FALSE, - * pathLenConstraint INTEGER (0..MAX) OPTIONAL } - */ - *ca_istrue = 0; /* DEFAULT FALSE */ - *max_pathlen = 0; /* endless */ - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( *p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - ret = mbedtls_asn1_get_int( p, end, ca_istrue ); - - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( *ca_istrue != 0 ) - *ca_istrue = 1; - } - - if( *p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer - * overflow, which is an undefined behavior. */ - if( *max_pathlen == INT_MAX ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - (*max_pathlen)++; - - return( 0 ); -} - -static int x509_get_ns_cert_type( unsigned char **p, - const unsigned char *end, - unsigned char *ns_cert_type) -{ - int ret; - mbedtls_x509_bitstring bs = { 0, 0, NULL }; - - if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( bs.len != 1 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - /* Get actual bitstring */ - *ns_cert_type = *bs.p; - return( 0 ); -} - -static int x509_get_key_usage( unsigned char **p, - const unsigned char *end, - unsigned int *key_usage) -{ - int ret; - size_t i; - mbedtls_x509_bitstring bs = { 0, 0, NULL }; - - if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( bs.len < 1 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - /* Get actual bitstring */ - *key_usage = 0; - for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ ) - { - *key_usage |= (unsigned int) bs.p[i] << (8*i); - } - - return( 0 ); -} - -/* - * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId - * - * KeyPurposeId ::= OBJECT IDENTIFIER - */ -static int x509_get_ext_key_usage( unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *ext_key_usage) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - /* Sequence length must be >= 1 */ - if( ext_key_usage->buf.p == NULL ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - return( 0 ); -} - -/* - * SubjectAltName ::= GeneralNames - * - * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - * - * GeneralName ::= CHOICE { - * otherName [0] OtherName, - * rfc822Name [1] IA5String, - * dNSName [2] IA5String, - * x400Address [3] ORAddress, - * directoryName [4] Name, - * ediPartyName [5] EDIPartyName, - * uniformResourceIdentifier [6] IA5String, - * iPAddress [7] OCTET STRING, - * registeredID [8] OBJECT IDENTIFIER } - * - * OtherName ::= SEQUENCE { - * type-id OBJECT IDENTIFIER, - * value [0] EXPLICIT ANY DEFINED BY type-id } - * - * EDIPartyName ::= SEQUENCE { - * nameAssigner [0] DirectoryString OPTIONAL, - * partyName [1] DirectoryString } - * - * NOTE: we only parse and use dNSName at this point. - */ -static int x509_get_subject_alt_name( unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *subject_alt_name ) -{ - int ret; - size_t len, tag_len; - mbedtls_asn1_buf *buf; - unsigned char tag; - mbedtls_asn1_sequence *cur = subject_alt_name; - - /* Get main sequence tag */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - while( *p < end ) - { - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - tag = **p; - (*p)++; - if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) != - MBEDTLS_ASN1_CONTEXT_SPECIFIC ) - { - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } - - /* Skip everything but DNS name */ - if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) ) - { - *p += tag_len; - continue; - } - - /* Allocate and assign next pointer */ - if( cur->buf.p != NULL ) - { - if( cur->next != NULL ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); - - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_ALLOC_FAILED ); - - cur = cur->next; - } - - buf = &(cur->buf); - buf->tag = tag; - buf->p = *p; - buf->len = tag_len; - *p += buf->len; - } - - /* Set final sequence entry's next pointer to NULL */ - cur->next = NULL; - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * X.509 v3 extensions - * - */ -static int x509_get_crt_ext( unsigned char **p, - const unsigned char *end, - mbedtls_x509_crt *crt ) -{ - int ret; - size_t len; - unsigned char *end_ext_data, *end_ext_octet; - - if( *p == end ) - return( 0 ); - - if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) - return( ret ); - - end = crt->v3_ext.p + crt->v3_ext.len; - while( *p < end ) - { - /* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING } - */ - mbedtls_x509_buf extn_oid = {0, 0, NULL}; - int is_critical = 0; /* DEFAULT FALSE */ - int ext_type = 0; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - end_ext_data = *p + len; - - /* Get extension ID */ - if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len, - MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - extn_oid.tag = MBEDTLS_ASN1_OID; - extn_oid.p = *p; - *p += extn_oid.len; - - /* Get optional critical */ - if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 && - ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - /* Data should be octet string type */ - if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, - MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - end_ext_octet = *p + len; - - if( end_ext_octet != end_ext_data ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* - * Detect supported extensions - */ - ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type ); - - if( ret != 0 ) - { - /* No parser found, skip extension */ - *p = end_ext_octet; - -#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) - if( is_critical ) - { - /* Data is marked as critical: fail */ - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } -#endif - continue; - } - - /* Forbid repeated extensions */ - if( ( crt->ext_types & ext_type ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); - - crt->ext_types |= ext_type; - - switch( ext_type ) - { - case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS: - /* Parse basic constraints */ - if( ( ret = x509_get_basic_constraints( p, end_ext_octet, - &crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) - return( ret ); - break; - - case MBEDTLS_X509_EXT_KEY_USAGE: - /* Parse key usage */ - if( ( ret = x509_get_key_usage( p, end_ext_octet, - &crt->key_usage ) ) != 0 ) - return( ret ); - break; - - case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE: - /* Parse extended key usage */ - if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, - &crt->ext_key_usage ) ) != 0 ) - return( ret ); - break; - - case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: - /* Parse subject alt name */ - if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, - &crt->subject_alt_names ) ) != 0 ) - return( ret ); - break; - - case MBEDTLS_X509_EXT_NS_CERT_TYPE: - /* Parse netscape certificate type */ - if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, - &crt->ns_cert_type ) ) != 0 ) - return( ret ); - break; - - default: - return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); - } - } - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * Parse and fill a single X.509 certificate in DER format - */ -static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf, - size_t buflen ) -{ - int ret; - size_t len; - unsigned char *p, *end, *crt_end; - mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; - - memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); - memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); - memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); - - /* - * Check for valid input - */ - if( crt == NULL || buf == NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - // Use the original buffer until we figure out actual length - p = (unsigned char*) buf; - len = buflen; - end = p + len; - - /* - * Certificate ::= SEQUENCE { - * tbsCertificate TBSCertificate, - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT ); - } - - if( len > (size_t) ( end - p ) ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - crt_end = p + len; - - // Create and populate a new buffer for the raw field - crt->raw.len = crt_end - buf; - crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len ); - if( p == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - memcpy( p, buf, crt->raw.len ); - - // Direct pointers to the new buffer - p += crt->raw.len - len; - end = crt_end = p + len; - - /* - * TBSCertificate ::= SEQUENCE { - */ - crt->tbs.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - end = p + len; - crt->tbs.len = end - crt->tbs.p; - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - * - * CertificateSerialNumber ::= INTEGER - * - * signature AlgorithmIdentifier - */ - if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || - ( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 || - ( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid, - &sig_params1 ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - if( crt->version < 0 || crt->version > 2 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); - } - - crt->version++; - - if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1, - &crt->sig_md, &crt->sig_pk, - &crt->sig_opts ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - /* - * issuer Name - */ - crt->issuer_raw.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - crt->issuer_raw.len = p - crt->issuer_raw.p; - - /* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - * - */ - if( ( ret = x509_get_dates( &p, end, &crt->valid_from, - &crt->valid_to ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - /* - * subject Name - */ - crt->subject_raw.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - crt->subject_raw.len = p - crt->subject_raw.p; - - /* - * SubjectPublicKeyInfo - */ - if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - /* - * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * extensions [3] EXPLICIT Extensions OPTIONAL - * -- If present, version shall be v3 - */ - if( crt->version == 2 || crt->version == 3 ) - { - ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); - if( ret != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - } - - if( crt->version == 2 || crt->version == 3 ) - { - ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); - if( ret != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - } - -#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) - if( crt->version == 3 ) -#endif - { - ret = x509_get_crt_ext( &p, end, crt ); - if( ret != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - } - - if( p != end ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - end = crt_end; - - /* - * } - * -- end of TBSCertificate - * - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING - */ - if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - if( crt->sig_oid.len != sig_oid2.len || - memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 || - sig_params1.tag != sig_params2.tag || - sig_params1.len != sig_params2.len || - ( sig_params1.len != 0 && - memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_SIG_MISMATCH ); - } - - if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - if( p != end ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - return( 0 ); -} - -/* - * Parse one X.509 certificate in DER format from a buffer and add them to a - * chained list - */ -int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, - size_t buflen ) -{ - int ret; - mbedtls_x509_crt *crt = chain, *prev = NULL; - - /* - * Check for valid input - */ - if( crt == NULL || buf == NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - while( crt->version != 0 && crt->next != NULL ) - { - prev = crt; - crt = crt->next; - } - - /* - * Add new certificate on the end of the chain if needed. - */ - if( crt->version != 0 && crt->next == NULL ) - { - crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); - - if( crt->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - prev = crt; - mbedtls_x509_crt_init( crt->next ); - crt = crt->next; - } - - if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 ) - { - if( prev ) - prev->next = NULL; - - if( crt != chain ) - mbedtls_free( crt ); - - return( ret ); - } - - return( 0 ); -} - -/* - * Parse one or more PEM certificates from a buffer and add them to the chained - * list - */ -int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ) -{ -#if defined(MBEDTLS_PEM_PARSE_C) - int success = 0, first_error = 0, total_failed = 0; - int buf_format = MBEDTLS_X509_FORMAT_DER; -#endif - - /* - * Check for valid input - */ - if( chain == NULL || buf == NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - /* - * Determine buffer content. Buffer contains either one DER certificate or - * one or more PEM certificates. - */ -#if defined(MBEDTLS_PEM_PARSE_C) - if( buflen != 0 && buf[buflen - 1] == '\0' && - strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL ) - { - buf_format = MBEDTLS_X509_FORMAT_PEM; - } - - if( buf_format == MBEDTLS_X509_FORMAT_DER ) - return mbedtls_x509_crt_parse_der( chain, buf, buflen ); -#else - return mbedtls_x509_crt_parse_der( chain, buf, buflen ); -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) - if( buf_format == MBEDTLS_X509_FORMAT_PEM ) - { - int ret; - mbedtls_pem_context pem; - - /* 1 rather than 0 since the terminating NULL byte is counted in */ - while( buflen > 1 ) - { - size_t use_len; - mbedtls_pem_init( &pem ); - - /* If we get there, we know the string is null-terminated */ - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN CERTIFICATE-----", - "-----END CERTIFICATE-----", - buf, NULL, 0, &use_len ); - - if( ret == 0 ) - { - /* - * Was PEM encoded - */ - buflen -= use_len; - buf += use_len; - } - else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA ) - { - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - mbedtls_pem_free( &pem ); - - /* - * PEM header and footer were found - */ - buflen -= use_len; - buf += use_len; - - if( first_error == 0 ) - first_error = ret; - - total_failed++; - continue; - } - else - break; - - ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen ); - - mbedtls_pem_free( &pem ); - - if( ret != 0 ) - { - /* - * Quit parsing on a memory error - */ - if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED ) - return( ret ); - - if( first_error == 0 ) - first_error = ret; - - total_failed++; - continue; - } - - success = 1; - } - } - - if( success ) - return( total_failed ); - else if( first_error ) - return( first_error ); - else - return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT ); -#endif /* MBEDTLS_PEM_PARSE_C */ -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load one or more certificates and add them to the chained list - */ -int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ) -{ - int ret; - size_t n; - unsigned char *buf; - - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - ret = mbedtls_x509_crt_parse( chain, buf, n ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} - -int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) -{ - int ret = 0; -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - int w_ret; - WCHAR szDir[MAX_PATH]; - char filename[MAX_PATH]; - char *p; - size_t len = strlen( path ); - - WIN32_FIND_DATAW file_data; - HANDLE hFind; - - if( len > MAX_PATH - 3 ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - memset( szDir, 0, sizeof(szDir) ); - memset( filename, 0, MAX_PATH ); - memcpy( filename, path, len ); - filename[len++] = '\\'; - p = filename + len; - filename[len++] = '*'; - - w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, - MAX_PATH - 3 ); - if( w_ret == 0 ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - hFind = FindFirstFileW( szDir, &file_data ); - if( hFind == INVALID_HANDLE_VALUE ) - return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); - - len = MAX_PATH - len; - do - { - memset( p, 0, len ); - - if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) - continue; - - w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, - lstrlenW( file_data.cFileName ), - p, (int) len - 1, - NULL, NULL ); - if( w_ret == 0 ) - { - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - goto cleanup; - } - - w_ret = mbedtls_x509_crt_parse_file( chain, filename ); - if( w_ret < 0 ) - ret++; - else - ret += w_ret; - } - while( FindNextFileW( hFind, &file_data ) != 0 ); - - if( GetLastError() != ERROR_NO_MORE_FILES ) - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - -cleanup: - FindClose( hFind ); -#else /* _WIN32 */ - int t_ret; - int snp_ret; - struct stat sb; - struct dirent *entry; - char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN]; - DIR *dir = opendir( path ); - - if( dir == NULL ) - return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 ) - { - closedir( dir ); - return( ret ); - } -#endif /* MBEDTLS_THREADING_C */ - - while( ( entry = readdir( dir ) ) != NULL ) - { - snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name, - "%s/%s", path, entry->d_name ); - - if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name ) - { - ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - goto cleanup; - } - else if( stat( entry_name, &sb ) == -1 ) - { - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - goto cleanup; - } - - if( !S_ISREG( sb.st_mode ) ) - continue; - - // Ignore parse errors - // - t_ret = mbedtls_x509_crt_parse_file( chain, entry_name ); - if( t_ret < 0 ) - ret++; - else - ret += t_ret; - } - -cleanup: - closedir( dir ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 ) - ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; -#endif /* MBEDTLS_THREADING_C */ - -#endif /* _WIN32 */ - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -static int x509_info_subject_alt_name( char **buf, size_t *size, - const mbedtls_x509_sequence *subject_alt_name ) -{ - size_t i; - size_t n = *size; - char *p = *buf; - const mbedtls_x509_sequence *cur = subject_alt_name; - const char *sep = ""; - size_t sep_len = 0; - - while( cur != NULL ) - { - if( cur->buf.len + sep_len >= n ) - { - *p = '\0'; - return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); - } - - n -= cur->buf.len + sep_len; - for( i = 0; i < sep_len; i++ ) - *p++ = sep[i]; - for( i = 0; i < cur->buf.len; i++ ) - *p++ = cur->buf.p[i]; - - sep = ", "; - sep_len = 2; - - cur = cur->next; - } - - *p = '\0'; - - *size = n; - *buf = p; - - return( 0 ); -} - -#define PRINT_ITEM(i) \ - { \ - ret = mbedtls_snprintf( p, n, "%s" i, sep ); \ - MBEDTLS_X509_SAFE_SNPRINTF; \ - sep = ", "; \ - } - -#define CERT_TYPE(type,name) \ - if( ns_cert_type & (type) ) \ - PRINT_ITEM( name ); - -static int x509_info_cert_type( char **buf, size_t *size, - unsigned char ns_cert_type ) -{ - int ret; - size_t n = *size; - char *p = *buf; - const char *sep = ""; - - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" ); - - *size = n; - *buf = p; - - return( 0 ); -} - -#define KEY_USAGE(code,name) \ - if( key_usage & (code) ) \ - PRINT_ITEM( name ); - -static int x509_info_key_usage( char **buf, size_t *size, - unsigned int key_usage ) -{ - int ret; - size_t n = *size; - char *p = *buf; - const char *sep = ""; - - KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature" ); - KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation" ); - KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment" ); - KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment" ); - KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement" ); - KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign" ); - KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign" ); - KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only" ); - KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only" ); - - *size = n; - *buf = p; - - return( 0 ); -} - -static int x509_info_ext_key_usage( char **buf, size_t *size, - const mbedtls_x509_sequence *extended_key_usage ) -{ - int ret; - const char *desc; - size_t n = *size; - char *p = *buf; - const mbedtls_x509_sequence *cur = extended_key_usage; - const char *sep = ""; - - while( cur != NULL ) - { - if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 ) - desc = "???"; - - ret = mbedtls_snprintf( p, n, "%s%s", sep, desc ); - MBEDTLS_X509_SAFE_SNPRINTF; - - sep = ", "; - - cur = cur->next; - } - - *size = n; - *buf = p; - - return( 0 ); -} - -/* - * Return an informational string about the certificate. - */ -#define BEFORE_COLON 18 -#define BC "18" -int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crt *crt ) -{ - int ret; - size_t n; - char *p; - char key_size_str[BEFORE_COLON]; - - p = buf; - n = size; - - if( NULL == crt ) - { - ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( (int) ( size - n ) ); - } - - ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", - prefix, crt->version ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_snprintf( p, n, "%sserial number : ", - prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_serial_gets( p, n, &crt->serial ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &crt->issuer ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &crt->subject ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%sissued on : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crt->valid_from.year, crt->valid_from.mon, - crt->valid_from.day, crt->valid_from.hour, - crt->valid_from.min, crt->valid_from.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crt->valid_to.year, crt->valid_to.mon, - crt->valid_to.day, crt->valid_to.hour, - crt->valid_to.min, crt->valid_to.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk, - crt->sig_md, crt->sig_opts ); - MBEDTLS_X509_SAFE_SNPRINTF; - - /* Key size */ - if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, - mbedtls_pk_get_name( &crt->pk ) ) ) != 0 ) - { - return( ret ); - } - - ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen( &crt->pk ) ); - MBEDTLS_X509_SAFE_SNPRINTF; - - /* - * Optional extensions - */ - - if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS ) - { - ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, - crt->ca_istrue ? "true" : "false" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( crt->max_pathlen > 0 ) - { - ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - } - - if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) - { - ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = x509_info_subject_alt_name( &p, &n, - &crt->subject_alt_names ) ) != 0 ) - return( ret ); - } - - if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) - { - ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) - return( ret ); - } - - if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) - { - ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) - return( ret ); - } - - if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) - { - ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = x509_info_ext_key_usage( &p, &n, - &crt->ext_key_usage ) ) != 0 ) - return( ret ); - } - - ret = mbedtls_snprintf( p, n, "\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( (int) ( size - n ) ); -} - -struct x509_crt_verify_string { - int code; - const char *string; -}; - -static const struct x509_crt_verify_string x509_crt_verify_strings[] = { - { MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" }, - { MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" }, - { MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" }, - { MBEDTLS_X509_BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" }, - { MBEDTLS_X509_BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" }, - { MBEDTLS_X509_BADCRL_EXPIRED, "The CRL is expired" }, - { MBEDTLS_X509_BADCERT_MISSING, "Certificate was missing" }, - { MBEDTLS_X509_BADCERT_SKIP_VERIFY, "Certificate verification was skipped" }, - { MBEDTLS_X509_BADCERT_OTHER, "Other reason (can be used by verify callback)" }, - { MBEDTLS_X509_BADCERT_FUTURE, "The certificate validity starts in the future" }, - { MBEDTLS_X509_BADCRL_FUTURE, "The CRL is from the future" }, - { MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" }, - { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" }, - { MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" }, - { MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." }, - { MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, - { MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." }, - { MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." }, - { MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, - { MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." }, - { 0, NULL } -}; - -int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, - uint32_t flags ) -{ - int ret; - const struct x509_crt_verify_string *cur; - char *p = buf; - size_t n = size; - - for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ ) - { - if( ( flags & cur->code ) == 0 ) - continue; - - ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string ); - MBEDTLS_X509_SAFE_SNPRINTF; - flags ^= cur->code; - } - - if( flags != 0 ) - { - ret = mbedtls_snprintf( p, n, "%sUnknown reason " - "(this should not happen)\n", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - return( (int) ( size - n ) ); -} - -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) -int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, - unsigned int usage ) -{ - unsigned int usage_must, usage_may; - unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY - | MBEDTLS_X509_KU_DECIPHER_ONLY; - - if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 ) - return( 0 ); - - usage_must = usage & ~may_mask; - - if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - usage_may = usage & may_mask; - - if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - return( 0 ); -} -#endif - -#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) -int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, - const char *usage_oid, - size_t usage_len ) -{ - const mbedtls_x509_sequence *cur; - - /* Extension is not mandatory, absent means no restriction */ - if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 ) - return( 0 ); - - /* - * Look for the requested usage (or wildcard ANY) in our list - */ - for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) - { - const mbedtls_x509_buf *cur_oid = &cur->buf; - - if( cur_oid->len == usage_len && - memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) - { - return( 0 ); - } - - if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 ) - return( 0 ); - } - - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); -} -#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ - -#if defined(MBEDTLS_X509_CRL_PARSE_C) -/* - * Return 1 if the certificate is revoked, or 0 otherwise. - */ -int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ) -{ - const mbedtls_x509_crl_entry *cur = &crl->entry; - - while( cur != NULL && cur->serial.len != 0 ) - { - if( crt->serial.len == cur->serial.len && - memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) - { - return( 1 ); - } - - cur = cur->next; - } - - return( 0 ); -} - -/* - * Check that the given certificate is not revoked according to the CRL. - * Skip validation if no CRL for the given CA is present. - */ -static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, - mbedtls_x509_crl *crl_list, - const mbedtls_x509_crt_profile *profile ) -{ - int flags = 0; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - const mbedtls_md_info_t *md_info; - - if( ca == NULL ) - return( flags ); - - while( crl_list != NULL ) - { - if( crl_list->version == 0 || - x509_name_cmp( &crl_list->issuer, &ca->subject ) != 0 ) - { - crl_list = crl_list->next; - continue; - } - - /* - * Check if the CA is configured to sign CRLs - */ -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - if( mbedtls_x509_crt_check_key_usage( ca, - MBEDTLS_X509_KU_CRL_SIGN ) != 0 ) - { - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } -#endif - - /* - * Check if CRL is correctly signed by the trusted CA - */ - if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 ) - flags |= MBEDTLS_X509_BADCRL_BAD_MD; - - if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 ) - flags |= MBEDTLS_X509_BADCRL_BAD_PK; - - md_info = mbedtls_md_info_from_type( crl_list->sig_md ); - if( mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ) != 0 ) - { - /* Note: this can't happen except after an internal error */ - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } - - if( x509_profile_check_key( profile, &ca->pk ) != 0 ) - flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - - if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, - crl_list->sig_md, hash, mbedtls_md_get_size( md_info ), - crl_list->sig.p, crl_list->sig.len ) != 0 ) - { - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } - - /* - * Check for validity of CRL (Do not drop out) - */ - if( mbedtls_x509_time_is_past( &crl_list->next_update ) ) - flags |= MBEDTLS_X509_BADCRL_EXPIRED; - - if( mbedtls_x509_time_is_future( &crl_list->this_update ) ) - flags |= MBEDTLS_X509_BADCRL_FUTURE; - - /* - * Check if certificate is revoked - */ - if( mbedtls_x509_crt_is_revoked( crt, crl_list ) ) - { - flags |= MBEDTLS_X509_BADCERT_REVOKED; - break; - } - - crl_list = crl_list->next; - } - - return( flags ); -} -#endif /* MBEDTLS_X509_CRL_PARSE_C */ - -/* - * Check the signature of a certificate by its parent - */ -static int x509_crt_check_signature( const mbedtls_x509_crt *child, - mbedtls_x509_crt *parent, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - const mbedtls_md_info_t *md_info; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - - md_info = mbedtls_md_info_from_type( child->sig_md ); - if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 ) - { - /* Note: this can't happen except after an internal error */ - return( -1 ); - } - - /* Skip expensive computation on obvious mismatch */ - if( ! mbedtls_pk_can_do( &parent->pk, child->sig_pk ) ) - return( -1 ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA ) - { - return( mbedtls_pk_verify_restartable( &parent->pk, - child->sig_md, hash, mbedtls_md_get_size( md_info ), - child->sig.p, child->sig.len, &rs_ctx->pk ) ); - } -#else - (void) rs_ctx; -#endif - - return( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, - child->sig_md, hash, mbedtls_md_get_size( md_info ), - child->sig.p, child->sig.len ) ); -} - -/* - * Check if 'parent' is a suitable parent (signing CA) for 'child'. - * Return 0 if yes, -1 if not. - * - * top means parent is a locally-trusted certificate - */ -static int x509_crt_check_parent( const mbedtls_x509_crt *child, - const mbedtls_x509_crt *parent, - int top ) -{ - int need_ca_bit; - - /* Parent must be the issuer */ - if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 ) - return( -1 ); - - /* Parent must have the basicConstraints CA bit set as a general rule */ - need_ca_bit = 1; - - /* Exception: v1/v2 certificates that are locally trusted. */ - if( top && parent->version < 3 ) - need_ca_bit = 0; - - if( need_ca_bit && ! parent->ca_istrue ) - return( -1 ); - -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - if( need_ca_bit && - mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 ) - { - return( -1 ); - } -#endif - - return( 0 ); -} - -/* - * Find a suitable parent for child in candidates, or return NULL. - * - * Here suitable is defined as: - * 1. subject name matches child's issuer - * 2. if necessary, the CA bit is set and key usage allows signing certs - * 3. for trusted roots, the signature is correct - * (for intermediates, the signature is checked and the result reported) - * 4. pathlen constraints are satisfied - * - * If there's a suitable candidate which is also time-valid, return the first - * such. Otherwise, return the first suitable candidate (or NULL if there is - * none). - * - * The rationale for this rule is that someone could have a list of trusted - * roots with two versions on the same root with different validity periods. - * (At least one user reported having such a list and wanted it to just work.) - * The reason we don't just require time-validity is that generally there is - * only one version, and if it's expired we want the flags to state that - * rather than NOT_TRUSTED, as would be the case if we required it here. - * - * The rationale for rule 3 (signature for trusted roots) is that users might - * have two versions of the same CA with different keys in their list, and the - * way we select the correct one is by checking the signature (as we don't - * rely on key identifier extensions). (This is one way users might choose to - * handle key rollover, another relies on self-issued certs, see [SIRO].) - * - * Arguments: - * - [in] child: certificate for which we're looking for a parent - * - [in] candidates: chained list of potential parents - * - [out] r_parent: parent found (or NULL) - * - [out] r_signature_is_good: 1 if child signature by parent is valid, or 0 - * - [in] top: 1 if candidates consists of trusted roots, ie we're at the top - * of the chain, 0 otherwise - * - [in] path_cnt: number of intermediates seen so far - * - [in] self_cnt: number of self-signed intermediates seen so far - * (will never be greater than path_cnt) - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - 0 on success - * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise - */ -static int x509_crt_find_parent_in( - mbedtls_x509_crt *child, - mbedtls_x509_crt *candidates, - mbedtls_x509_crt **r_parent, - int *r_signature_is_good, - int top, - unsigned path_cnt, - unsigned self_cnt, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_x509_crt *parent, *fallback_parent; - int signature_is_good, fallback_signature_is_good; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* did we have something in progress? */ - if( rs_ctx != NULL && rs_ctx->parent != NULL ) - { - /* restore saved state */ - parent = rs_ctx->parent; - fallback_parent = rs_ctx->fallback_parent; - fallback_signature_is_good = rs_ctx->fallback_signature_is_good; - - /* clear saved state */ - rs_ctx->parent = NULL; - rs_ctx->fallback_parent = NULL; - rs_ctx->fallback_signature_is_good = 0; - - /* resume where we left */ - goto check_signature; - } -#endif - - fallback_parent = NULL; - fallback_signature_is_good = 0; - - for( parent = candidates; parent != NULL; parent = parent->next ) - { - /* basic parenting skills (name, CA bit, key usage) */ - if( x509_crt_check_parent( child, parent, top ) != 0 ) - continue; - - /* +1 because stored max_pathlen is 1 higher that the actual value */ - if( parent->max_pathlen > 0 && - (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt ) - { - continue; - } - - /* Signature */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -check_signature: -#endif - ret = x509_crt_check_signature( child, parent, rs_ctx ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - /* save state */ - rs_ctx->parent = parent; - rs_ctx->fallback_parent = fallback_parent; - rs_ctx->fallback_signature_is_good = fallback_signature_is_good; - - return( ret ); - } -#else - (void) ret; -#endif - - signature_is_good = ret == 0; - if( top && ! signature_is_good ) - continue; - - /* optional time check */ - if( mbedtls_x509_time_is_past( &parent->valid_to ) || - mbedtls_x509_time_is_future( &parent->valid_from ) ) - { - if( fallback_parent == NULL ) - { - fallback_parent = parent; - fallback_signature_is_good = signature_is_good; - } - - continue; - } - - *r_parent = parent; - *r_signature_is_good = signature_is_good; - - break; - } - - if( parent == NULL ) - { - *r_parent = fallback_parent; - *r_signature_is_good = fallback_signature_is_good; - } - - return( 0 ); -} - -/* - * Find a parent in trusted CAs or the provided chain, or return NULL. - * - * Searches in trusted CAs first, and return the first suitable parent found - * (see find_parent_in() for definition of suitable). - * - * Arguments: - * - [in] child: certificate for which we're looking for a parent, followed - * by a chain of possible intermediates - * - [in] trust_ca: list of locally trusted certificates - * - [out] parent: parent found (or NULL) - * - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0 - * - [out] signature_is_good: 1 if child signature by parent is valid, or 0 - * - [in] path_cnt: number of links in the chain so far (EE -> ... -> child) - * - [in] self_cnt: number of self-signed certs in the chain so far - * (will always be no greater than path_cnt) - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - 0 on success - * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise - */ -static int x509_crt_find_parent( - mbedtls_x509_crt *child, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crt **parent, - int *parent_is_trusted, - int *signature_is_good, - unsigned path_cnt, - unsigned self_cnt, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_x509_crt *search_list; - - *parent_is_trusted = 1; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* restore then clear saved state if we have some stored */ - if( rs_ctx != NULL && rs_ctx->parent_is_trusted != -1 ) - { - *parent_is_trusted = rs_ctx->parent_is_trusted; - rs_ctx->parent_is_trusted = -1; - } -#endif - - while( 1 ) { - search_list = *parent_is_trusted ? trust_ca : child->next; - - ret = x509_crt_find_parent_in( child, search_list, - parent, signature_is_good, - *parent_is_trusted, - path_cnt, self_cnt, rs_ctx ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - /* save state */ - rs_ctx->parent_is_trusted = *parent_is_trusted; - return( ret ); - } -#else - (void) ret; -#endif - - /* stop here if found or already in second iteration */ - if( *parent != NULL || *parent_is_trusted == 0 ) - break; - - /* prepare second iteration */ - *parent_is_trusted = 0; - } - - /* extra precaution against mistakes in the caller */ - if( *parent == NULL ) - { - *parent_is_trusted = 0; - *signature_is_good = 0; - } - - return( 0 ); -} - -/* - * Check if an end-entity certificate is locally trusted - * - * Currently we require such certificates to be self-signed (actually only - * check for self-issued as self-signatures are not checked) - */ -static int x509_crt_check_ee_locally_trusted( - mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca ) -{ - mbedtls_x509_crt *cur; - - /* must be self-issued */ - if( x509_name_cmp( &crt->issuer, &crt->subject ) != 0 ) - return( -1 ); - - /* look for an exact match with trusted cert */ - for( cur = trust_ca; cur != NULL; cur = cur->next ) - { - if( crt->raw.len == cur->raw.len && - memcmp( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 ) - { - return( 0 ); - } - } - - /* too bad */ - return( -1 ); -} - -/* - * Build and verify a certificate chain - * - * Given a peer-provided list of certificates EE, C1, ..., Cn and - * a list of trusted certs R1, ... Rp, try to build and verify a chain - * EE, Ci1, ... Ciq [, Rj] - * such that every cert in the chain is a child of the next one, - * jumping to a trusted root as early as possible. - * - * Verify that chain and return it with flags for all issues found. - * - * Special cases: - * - EE == Rj -> return a one-element list containing it - * - EE, Ci1, ..., Ciq cannot be continued with a trusted root - * -> return that chain with NOT_TRUSTED set on Ciq - * - * Tests for (aspects of) this function should include at least: - * - trusted EE - * - EE -> trusted root - * - EE -> intermediate CA -> trusted root - * - if relevant: EE untrusted - * - if relevant: EE -> intermediate, untrusted - * with the aspect under test checked at each relevant level (EE, int, root). - * For some aspects longer chains are required, but usually length 2 is - * enough (but length 1 is not in general). - * - * Arguments: - * - [in] crt: the cert list EE, C1, ..., Cn - * - [in] trust_ca: the trusted list R1, ..., Rp - * - [in] ca_crl, profile: as in verify_with_profile() - * - [out] ver_chain: the built and verified chain - * Only valid when return value is 0, may contain garbage otherwise! - * Restart note: need not be the same when calling again to resume. - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - non-zero if the chain could not be fully built and examined - * - 0 is the chain was successfully built and examined, - * even if it was found to be invalid - */ -static int x509_crt_verify_chain( - mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - mbedtls_x509_crt_verify_chain *ver_chain, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - /* Don't initialize any of those variables here, so that the compiler can - * catch potential issues with jumping ahead when restarting */ - int ret; - uint32_t *flags; - mbedtls_x509_crt_verify_chain_item *cur; - mbedtls_x509_crt *child; - mbedtls_x509_crt *parent; - int parent_is_trusted; - int child_is_trusted; - int signature_is_good; - unsigned self_cnt; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* resume if we had an operation in progress */ - if( rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent ) - { - /* restore saved state */ - *ver_chain = rs_ctx->ver_chain; /* struct copy */ - self_cnt = rs_ctx->self_cnt; - - /* restore derived state */ - cur = &ver_chain->items[ver_chain->len - 1]; - child = cur->crt; - flags = &cur->flags; - - goto find_parent; - } -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - child = crt; - self_cnt = 0; - parent_is_trusted = 0; - child_is_trusted = 0; - - while( 1 ) { - /* Add certificate to the verification chain */ - cur = &ver_chain->items[ver_chain->len]; - cur->crt = child; - cur->flags = 0; - ver_chain->len++; - flags = &cur->flags; - - /* Check time-validity (all certificates) */ - if( mbedtls_x509_time_is_past( &child->valid_to ) ) - *flags |= MBEDTLS_X509_BADCERT_EXPIRED; - - if( mbedtls_x509_time_is_future( &child->valid_from ) ) - *flags |= MBEDTLS_X509_BADCERT_FUTURE; - - /* Stop here for trusted roots (but not for trusted EE certs) */ - if( child_is_trusted ) - return( 0 ); - - /* Check signature algorithm: MD & PK algs */ - if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_MD; - - if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_PK; - - /* Special case: EE certs that are locally trusted */ - if( ver_chain->len == 1 && - x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 ) - { - return( 0 ); - } - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -find_parent: -#endif - /* Look for a parent in trusted CAs or up the chain */ - ret = x509_crt_find_parent( child, trust_ca, &parent, - &parent_is_trusted, &signature_is_good, - ver_chain->len - 1, self_cnt, rs_ctx ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - /* save state */ - rs_ctx->in_progress = x509_crt_rs_find_parent; - rs_ctx->self_cnt = self_cnt; - rs_ctx->ver_chain = *ver_chain; /* struct copy */ - - return( ret ); - } -#else - (void) ret; -#endif - - /* No parent? We're done here */ - if( parent == NULL ) - { - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; - return( 0 ); - } - - /* Count intermediate self-issued (not necessarily self-signed) certs. - * These can occur with some strategies for key rollover, see [SIRO], - * and should be excluded from max_pathlen checks. */ - if( ver_chain->len != 1 && - x509_name_cmp( &child->issuer, &child->subject ) == 0 ) - { - self_cnt++; - } - - /* path_cnt is 0 for the first intermediate CA, - * and if parent is trusted it's not an intermediate CA */ - if( ! parent_is_trusted && - ver_chain->len > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) - { - /* return immediately to avoid overflow the chain array */ - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - } - - /* signature was checked while searching parent */ - if( ! signature_is_good ) - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; - - /* check size of signing key */ - if( x509_profile_check_key( profile, &parent->pk ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - -#if defined(MBEDTLS_X509_CRL_PARSE_C) - /* Check trusted CA's CRL for the given crt */ - *flags |= x509_crt_verifycrl( child, parent, ca_crl, profile ); -#else - (void) ca_crl; -#endif - - /* prepare for next iteration */ - child = parent; - parent = NULL; - child_is_trusted = parent_is_trusted; - signature_is_good = 0; - } -} - -/* - * Check for CN match - */ -static int x509_crt_check_cn( const mbedtls_x509_buf *name, - const char *cn, size_t cn_len ) -{ - /* try exact match */ - if( name->len == cn_len && - x509_memcasecmp( cn, name->p, cn_len ) == 0 ) - { - return( 0 ); - } - - /* try wildcard match */ - if( x509_check_wildcard( cn, name ) == 0 ) - { - return( 0 ); - } - - return( -1 ); -} - -/* - * Verify the requested CN - only call this if cn is not NULL! - */ -static void x509_crt_verify_name( const mbedtls_x509_crt *crt, - const char *cn, - uint32_t *flags ) -{ - const mbedtls_x509_name *name; - const mbedtls_x509_sequence *cur; - size_t cn_len = strlen( cn ); - - if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) - { - for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next ) - { - if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 ) - break; - } - - if( cur == NULL ) - *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; - } - else - { - for( name = &crt->subject; name != NULL; name = name->next ) - { - if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 && - x509_crt_check_cn( &name->val, cn, cn_len ) == 0 ) - { - break; - } - } - - if( name == NULL ) - *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; - } -} - -/* - * Merge the flags for all certs in the chain, after calling callback - */ -static int x509_crt_merge_flags_with_cb( - uint32_t *flags, - const mbedtls_x509_crt_verify_chain *ver_chain, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - int ret; - unsigned i; - uint32_t cur_flags; - const mbedtls_x509_crt_verify_chain_item *cur; - - for( i = ver_chain->len; i != 0; --i ) - { - cur = &ver_chain->items[i-1]; - cur_flags = cur->flags; - - if( NULL != f_vrfy ) - if( ( ret = f_vrfy( p_vrfy, cur->crt, (int) i-1, &cur_flags ) ) != 0 ) - return( ret ); - - *flags |= cur_flags; - } - - return( 0 ); -} - -/* - * Verify the certificate validity (default profile, not restartable) - */ -int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl, - &mbedtls_x509_crt_profile_default, cn, flags, - f_vrfy, p_vrfy, NULL ) ); -} - -/* - * Verify the certificate validity (user-chosen profile, not restartable) - */ -int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl, - profile, cn, flags, f_vrfy, p_vrfy, NULL ) ); -} - -/* - * Verify the certificate validity, with profile, restartable version - * - * This function: - * - checks the requested CN (if any) - * - checks the type and size of the EE cert's key, - * as that isn't done as part of chain building/verification currently - * - builds and verifies the chain - * - then calls the callback and merges the flags - */ -int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_pk_type_t pk_type; - mbedtls_x509_crt_verify_chain ver_chain; - uint32_t ee_flags; - - *flags = 0; - ee_flags = 0; - x509_crt_verify_chain_reset( &ver_chain ); - - if( profile == NULL ) - { - ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; - goto exit; - } - - /* check name if requested */ - if( cn != NULL ) - x509_crt_verify_name( crt, cn, &ee_flags ); - - /* Check the type and size of the key */ - pk_type = mbedtls_pk_get_type( &crt->pk ); - - if( x509_profile_check_pk_alg( profile, pk_type ) != 0 ) - ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK; - - if( x509_profile_check_key( profile, &crt->pk ) != 0 ) - ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - - /* Check the chain */ - ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile, - &ver_chain, rs_ctx ); - - if( ret != 0 ) - goto exit; - - /* Merge end-entity flags */ - ver_chain.items[0].flags |= ee_flags; - - /* Build final flags, calling callback on the way if any */ - ret = x509_crt_merge_flags_with_cb( flags, &ver_chain, f_vrfy, p_vrfy ); - -exit: -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) - mbedtls_x509_crt_restart_free( rs_ctx ); -#endif - - /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by - * the SSL module for authmode optional, but non-zero return from the - * callback means a fatal error so it shouldn't be ignored */ - if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ) - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - - if( ret != 0 ) - { - *flags = (uint32_t) -1; - return( ret ); - } - - if( *flags != 0 ) - return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); - - return( 0 ); -} - -/* - * Initialize a certificate chain - */ -void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ) -{ - memset( crt, 0, sizeof(mbedtls_x509_crt) ); -} - -/* - * Unallocate all certificate data - */ -void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ) -{ - mbedtls_x509_crt *cert_cur = crt; - mbedtls_x509_crt *cert_prv; - mbedtls_x509_name *name_cur; - mbedtls_x509_name *name_prv; - mbedtls_x509_sequence *seq_cur; - mbedtls_x509_sequence *seq_prv; - - if( crt == NULL ) - return; - - do - { - mbedtls_pk_free( &cert_cur->pk ); - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free( cert_cur->sig_opts ); -#endif - - name_cur = cert_cur->issuer.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - name_cur = cert_cur->subject.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - seq_cur = cert_cur->ext_key_usage.next; - while( seq_cur != NULL ) - { - seq_prv = seq_cur; - seq_cur = seq_cur->next; - mbedtls_platform_zeroize( seq_prv, - sizeof( mbedtls_x509_sequence ) ); - mbedtls_free( seq_prv ); - } - - seq_cur = cert_cur->subject_alt_names.next; - while( seq_cur != NULL ) - { - seq_prv = seq_cur; - seq_cur = seq_cur->next; - mbedtls_platform_zeroize( seq_prv, - sizeof( mbedtls_x509_sequence ) ); - mbedtls_free( seq_prv ); - } - - if( cert_cur->raw.p != NULL ) - { - mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len ); - mbedtls_free( cert_cur->raw.p ); - } - - cert_cur = cert_cur->next; - } - while( cert_cur != NULL ); - - cert_cur = crt; - do - { - cert_prv = cert_cur; - cert_cur = cert_cur->next; - - mbedtls_platform_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) ); - if( cert_prv != crt ) - mbedtls_free( cert_prv ); - } - while( cert_cur != NULL ); -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ) -{ - mbedtls_pk_restart_init( &ctx->pk ); - - ctx->parent = NULL; - ctx->fallback_parent = NULL; - ctx->fallback_signature_is_good = 0; - - ctx->parent_is_trusted = -1; - - ctx->in_progress = x509_crt_rs_none; - ctx->self_cnt = 0; - x509_crt_verify_chain_reset( &ctx->ver_chain ); -} - -/* - * Free the components of a restart context - */ -void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_pk_restart_free( &ctx->pk ); - mbedtls_x509_crt_restart_init( ctx ); -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -#endif /* MBEDTLS_X509_CRT_PARSE_C */ diff --git a/mbedtls/x509_crt.h b/mbedtls/x509_crt.h deleted file mode 100644 index 04e45f26b..000000000 --- a/mbedtls/x509_crt.h +++ /dev/null @@ -1,820 +0,0 @@ -#pragma GCC system_header -/** - * \file x509_crt.h - * - * \brief X.509 certificate parsing and writing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_X509_CRT_H -#define MBEDTLS_X509_CRT_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "x509.h" -#include "x509_crl.h" - -/** - * \addtogroup x509_module - * \{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name Structures and functions for parsing and writing X.509 certificates - * \{ - */ - -/** - * Container for an X.509 certificate. The certificate may be chained. - */ -typedef struct mbedtls_x509_crt -{ - mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ - mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ - - int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ - mbedtls_x509_buf serial; /**< Unique id for certificate issued by a specific CA. */ - mbedtls_x509_buf sig_oid; /**< Signature algorithm, e.g. sha1RSA */ - - mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */ - mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */ - - mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ - mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ - - mbedtls_x509_time valid_from; /**< Start time of certificate validity. */ - mbedtls_x509_time valid_to; /**< End time of certificate validity. */ - - mbedtls_pk_context pk; /**< Container for the public key context. */ - - mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ - mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ - mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */ - mbedtls_x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */ - - int ext_types; /**< Bit string containing detected and parsed extensions */ - int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */ - int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */ - - unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */ - - mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ - - unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ - - mbedtls_x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */ - mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ - - struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */ -} -mbedtls_x509_crt; - -/** - * Build flag from an algorithm/curve identifier (pk, md, ecp) - * Since 0 is always XXX_NONE, ignore it. - */ -#define MBEDTLS_X509_ID_FLAG( id ) ( 1 << ( (id) - 1 ) ) - -/** - * Security profile for certificate verification. - * - * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG(). - */ -typedef struct mbedtls_x509_crt_profile -{ - uint32_t allowed_mds; /**< MDs for signatures */ - uint32_t allowed_pks; /**< PK algs for signatures */ - uint32_t allowed_curves; /**< Elliptic curves for ECDSA */ - uint32_t rsa_min_bitlen; /**< Minimum size for RSA keys */ -} -mbedtls_x509_crt_profile; - -#define MBEDTLS_X509_CRT_VERSION_1 0 -#define MBEDTLS_X509_CRT_VERSION_2 1 -#define MBEDTLS_X509_CRT_VERSION_3 2 - -#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32 -#define MBEDTLS_X509_RFC5280_UTC_TIME_LEN 15 - -#if !defined( MBEDTLS_X509_MAX_FILE_PATH_LEN ) -#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 -#endif - -/** - * Container for writing a certificate (CRT) - */ -typedef struct mbedtls_x509write_cert -{ - int version; - mbedtls_mpi serial; - mbedtls_pk_context *subject_key; - mbedtls_pk_context *issuer_key; - mbedtls_asn1_named_data *subject; - mbedtls_asn1_named_data *issuer; - mbedtls_md_type_t md_alg; - char not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; - char not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; - mbedtls_asn1_named_data *extensions; -} -mbedtls_x509write_cert; - -/** - * Item in a verification chain: cert and flags for it - */ -typedef struct { - mbedtls_x509_crt *crt; - uint32_t flags; -} mbedtls_x509_crt_verify_chain_item; - -/** - * Max size of verification chain: end-entity + intermediates + trusted root - */ -#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) - -/** - * Verification chain as built by \c mbedtls_crt_verify_chain() - */ -typedef struct -{ - mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE]; - unsigned len; -} mbedtls_x509_crt_verify_chain; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Context for resuming X.509 verify operations - */ -typedef struct -{ - /* for check_signature() */ - mbedtls_pk_restart_ctx pk; - - /* for find_parent_in() */ - mbedtls_x509_crt *parent; /* non-null iff parent_in in progress */ - mbedtls_x509_crt *fallback_parent; - int fallback_signature_is_good; - - /* for find_parent() */ - int parent_is_trusted; /* -1 if find_parent is not in progress */ - - /* for verify_chain() */ - enum { - x509_crt_rs_none, - x509_crt_rs_find_parent, - } in_progress; /* none if no operation is in progress */ - int self_cnt; - mbedtls_x509_crt_verify_chain ver_chain; - -} mbedtls_x509_crt_restart_ctx; - -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_x509_crt_restart_ctx; - -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * Default security profile. Should provide a good balance between security - * and compatibility with current deployments. - * - * This profile permits: - * - SHA2 hashes. - * - All supported elliptic curves. - * - RSA with 2048 bits and above. - * - * New minor versions of Mbed TLS may extend this profile, for example if - * new curves are added to the library. New minor versions of Mbed TLS will - * not reduce this profile unless serious security concerns require it. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default; - -/** - * Expected next default profile. Recommended for new deployments. - * Currently targets a 128-bit security level, except for allowing RSA-2048. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next; - -/** - * NSA Suite B profile. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb; - -/** - * \brief Parse a single DER formatted certificate and add it - * to the chained list. - * - * \param chain points to the start of the chain - * \param buf buffer holding the certificate DER data - * \param buflen size of the buffer - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, - size_t buflen ); - -/** - * \brief Parse one DER-encoded or one or more concatenated PEM-encoded - * certificates and add them to the chained list. - * - * For CRTs in PEM encoding, the function parses permissively: - * if at least one certificate can be parsed, the function - * returns the number of certificates for which parsing failed - * (hence \c 0 if all certificates were parsed successfully). - * If no certificate could be parsed, the function returns - * the first (negative) error encountered during parsing. - * - * PEM encoded certificates may be interleaved by other data - * such as human readable descriptions of their content, as - * long as the certificates are enclosed in the PEM specific - * '-----{BEGIN/END} CERTIFICATE-----' delimiters. - * - * \param chain The chain to which to add the parsed certificates. - * \param buf The buffer holding the certificate data in PEM or DER format. - * For certificates in PEM encoding, this may be a concatenation - * of multiple certificates; for DER encoding, the buffer must - * comprise exactly one certificate. - * \param buflen The size of \p buf, including the terminating \c NULL byte - * in case of PEM encoded data. - * - * \return \c 0 if all certificates were parsed successfully. - * \return The (positive) number of certificates that couldn't - * be parsed if parsing was partly successful (see above). - * \return A negative X509 or PEM error code otherwise. - * - */ -int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Load one or more certificates and add them - * to the chained list. Parses permissively. If some - * certificates can be parsed, the result is the number - * of failed certificates it encountered. If none complete - * correctly, the first error is returned. - * - * \param chain points to the start of the chain - * \param path filename to read the certificates from - * - * \return 0 if all certificates parsed successfully, a positive number - * if partly successful or a specific X509 or PEM error code - */ -int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ); - -/** - * \brief Load one or more certificate files from a path and add them - * to the chained list. Parses permissively. If some - * certificates can be parsed, the result is the number - * of failed certificates it encountered. If none complete - * correctly, the first error is returned. - * - * \param chain points to the start of the chain - * \param path directory / folder to read the certificate files from - * - * \return 0 if all certificates parsed successfully, a positive number - * if partly successful or a specific X509 or PEM error code - */ -int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief Returns an informational string about the - * certificate. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param crt The X509 certificate to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crt *crt ); - -/** - * \brief Returns an informational string about the - * verification status of a certificate. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param flags Verification flags created by mbedtls_x509_crt_verify() - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, - uint32_t flags ); - -/** - * \brief Verify the certificate signature - * - * The verify callback is a user-supplied callback that - * can clear / modify / add flags for a certificate. If set, - * the verification callback is called for each - * certificate in the chain (from the trust-ca down to the - * presented crt). The parameters for the callback are: - * (void *parameter, mbedtls_x509_crt *crt, int certificate_depth, - * int *flags). With the flags representing current flags for - * that specific certificate and the certificate depth from - * the bottom (Peer cert depth = 0). - * - * All flags left after returning from the callback - * are also returned to the application. The function should - * return 0 for anything (including invalid certificates) - * other than fatal error, as a non-zero return code - * immediately aborts the verification process. For fatal - * errors, a specific error code should be used (different - * from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not - * be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR - * can be used if no better code is available. - * - * \note In case verification failed, the results can be displayed - * using \c mbedtls_x509_crt_verify_info() - * - * \note Same as \c mbedtls_x509_crt_verify_with_profile() with the - * default security profile. - * - * \note It is your responsibility to provide up-to-date CRLs for - * all trusted CAs. If no CRL is provided for the CA that was - * used to sign the certificate, CRL verification is skipped - * silently, that is *without* setting any flag. - * - * \note The \c trust_ca list can contain two types of certificates: - * (1) those of trusted root CAs, so that certificates - * chaining up to those CAs will be trusted, and (2) - * self-signed end-entity certificates to be trusted (for - * specific peers you know) - in that case, the self-signed - * certificate doesn't need to have the CA bit set. - * - * \param crt a certificate (chain) to be verified - * \param trust_ca the list of trusted CAs (see note above) - * \param ca_crl the list of CRLs for trusted CAs (see note above) - * \param cn expected Common Name (can be set to - * NULL if the CN must not be verified) - * \param flags result of the verification - * \param f_vrfy verification function - * \param p_vrfy verification parameter - * - * \return 0 (and flags set to 0) if the chain was verified and valid, - * MBEDTLS_ERR_X509_CERT_VERIFY_FAILED if the chain was verified - * but found to be invalid, in which case *flags will have one - * or more MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX - * flags set, or another error (and flags set to 0xffffffff) - * in case of a fatal error encountered during the - * verification process. - */ -int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ); - -/** - * \brief Verify the certificate signature according to profile - * - * \note Same as \c mbedtls_x509_crt_verify(), but with explicit - * security profile. - * - * \note The restrictions on keys (RSA minimum size, allowed curves - * for ECDSA) apply to all certificates: trusted root, - * intermediate CAs if any, and end entity certificate. - * - * \param crt a certificate (chain) to be verified - * \param trust_ca the list of trusted CAs - * \param ca_crl the list of CRLs for trusted CAs - * \param profile security profile for verification - * \param cn expected Common Name (can be set to - * NULL if the CN must not be verified) - * \param flags result of the verification - * \param f_vrfy verification function - * \param p_vrfy verification parameter - * - * \return 0 if successful or MBEDTLS_ERR_X509_CERT_VERIFY_FAILED - * in which case *flags will have one or more - * MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX flags - * set, - * or another error in case of a fatal error encountered - * during the verification process. - */ -int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ); - -/** - * \brief Restartable version of \c mbedtls_crt_verify_with_profile() - * - * \note Performs the same job as \c mbedtls_crt_verify_with_profile() - * but can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param crt a certificate (chain) to be verified - * \param trust_ca the list of trusted CAs - * \param ca_crl the list of CRLs for trusted CAs - * \param profile security profile for verification - * \param cn expected Common Name (can be set to - * NULL if the CN must not be verified) - * \param flags result of the verification - * \param f_vrfy verification function - * \param p_vrfy verification parameter - * \param rs_ctx restart context (NULL to disable restart) - * - * \return See \c mbedtls_crt_verify_with_profile(), or - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy, - mbedtls_x509_crt_restart_ctx *rs_ctx ); - -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) -/** - * \brief Check usage of certificate against keyUsage extension. - * - * \param crt Leaf certificate used. - * \param usage Intended usage(s) (eg MBEDTLS_X509_KU_KEY_ENCIPHERMENT - * before using the certificate to perform an RSA key - * exchange). - * - * \note Except for decipherOnly and encipherOnly, a bit set in the - * usage argument means this bit MUST be set in the - * certificate. For decipherOnly and encipherOnly, it means - * that bit MAY be set. - * - * \return 0 is these uses of the certificate are allowed, - * MBEDTLS_ERR_X509_BAD_INPUT_DATA if the keyUsage extension - * is present but does not match the usage argument. - * - * \note You should only call this function on leaf certificates, on - * (intermediate) CAs the keyUsage extension is automatically - * checked by \c mbedtls_x509_crt_verify(). - */ -int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, - unsigned int usage ); -#endif /* MBEDTLS_X509_CHECK_KEY_USAGE) */ - -#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) -/** - * \brief Check usage of certificate against extendedKeyUsage. - * - * \param crt Leaf certificate used. - * \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or - * MBEDTLS_OID_CLIENT_AUTH). - * \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()). - * - * \return 0 if this use of the certificate is allowed, - * MBEDTLS_ERR_X509_BAD_INPUT_DATA if not. - * - * \note Usually only makes sense on leaf certificates. - */ -int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, - const char *usage_oid, - size_t usage_len ); -#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ - -#if defined(MBEDTLS_X509_CRL_PARSE_C) -/** - * \brief Verify the certificate revocation status - * - * \param crt a certificate to be verified - * \param crl the CRL to verify against - * - * \return 1 if the certificate is revoked, 0 otherwise - * - */ -int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ); -#endif /* MBEDTLS_X509_CRL_PARSE_C */ - -/** - * \brief Initialize a certificate (chain) - * - * \param crt Certificate chain to initialize - */ -void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ); - -/** - * \brief Unallocate all certificate data - * - * \param crt Certificate chain to free - */ -void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context - */ -void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ); - -/** - * \brief Free the components of a restart context - */ -void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/* \} name */ -/* \} addtogroup x509_module */ - -#if defined(MBEDTLS_X509_CRT_WRITE_C) -/** - * \brief Initialize a CRT writing context - * - * \param ctx CRT context to initialize - */ -void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ); - -/** - * \brief Set the verion for a Certificate - * Default: MBEDTLS_X509_CRT_VERSION_3 - * - * \param ctx CRT context to use - * \param version version to set (MBEDTLS_X509_CRT_VERSION_1, MBEDTLS_X509_CRT_VERSION_2 or - * MBEDTLS_X509_CRT_VERSION_3) - */ -void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version ); - -/** - * \brief Set the serial number for a Certificate. - * - * \param ctx CRT context to use - * \param serial serial number to set - * - * \return 0 if successful - */ -int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial ); - -/** - * \brief Set the validity period for a Certificate - * Timestamps should be in string format for UTC timezone - * i.e. "YYYYMMDDhhmmss" - * e.g. "20131231235959" for December 31st 2013 - * at 23:59:59 - * - * \param ctx CRT context to use - * \param not_before not_before timestamp - * \param not_after not_after timestamp - * - * \return 0 if timestamp was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before, - const char *not_after ); - -/** - * \brief Set the issuer name for a Certificate - * Issuer names should contain a comma-separated list - * of OID types and values: - * e.g. "C=UK,O=ARM,CN=mbed TLS CA" - * - * \param ctx CRT context to use - * \param issuer_name issuer name to set - * - * \return 0 if issuer name was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, - const char *issuer_name ); - -/** - * \brief Set the subject name for a Certificate - * Subject names should contain a comma-separated list - * of OID types and values: - * e.g. "C=UK,O=ARM,CN=mbed TLS Server 1" - * - * \param ctx CRT context to use - * \param subject_name subject name to set - * - * \return 0 if subject name was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, - const char *subject_name ); - -/** - * \brief Set the subject public key for the certificate - * - * \param ctx CRT context to use - * \param key public key to include - */ -void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ); - -/** - * \brief Set the issuer key used for signing the certificate - * - * \param ctx CRT context to use - * \param key private key to sign with - */ -void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ); - -/** - * \brief Set the MD algorithm to use for the signature - * (e.g. MBEDTLS_MD_SHA1) - * - * \param ctx CRT context to use - * \param md_alg MD algorithm to use - */ -void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg ); - -/** - * \brief Generic function to add to or replace an extension in the - * CRT - * - * \param ctx CRT context to use - * \param oid OID of the extension - * \param oid_len length of the OID - * \param critical if the extension is critical (per the RFC's definition) - * \param val value of the extension OCTET STRING - * \param val_len length of the value data - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx, - const char *oid, size_t oid_len, - int critical, - const unsigned char *val, size_t val_len ); - -/** - * \brief Set the basicConstraints extension for a CRT - * - * \param ctx CRT context to use - * \param is_ca is this a CA certificate - * \param max_pathlen maximum length of certificate chains below this - * certificate (only for CA certificates, -1 is - * inlimited) - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, - int is_ca, int max_pathlen ); - -#if defined(MBEDTLS_SHA1_C) -/** - * \brief Set the subjectKeyIdentifier extension for a CRT - * Requires that mbedtls_x509write_crt_set_subject_key() has been - * called before - * - * \param ctx CRT context to use - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ); - -/** - * \brief Set the authorityKeyIdentifier extension for a CRT - * Requires that mbedtls_x509write_crt_set_issuer_key() has been - * called before - * - * \param ctx CRT context to use - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ); -#endif /* MBEDTLS_SHA1_C */ - -/** - * \brief Set the Key Usage Extension flags - * (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN) - * - * \param ctx CRT context to use - * \param key_usage key usage flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, - unsigned int key_usage ); - -/** - * \brief Set the Netscape Cert Type flags - * (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL) - * - * \param ctx CRT context to use - * \param ns_cert_type Netscape Cert Type flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, - unsigned char ns_cert_type ); - -/** - * \brief Free the contents of a CRT write context - * - * \param ctx CRT context to free - */ -void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ); - -/** - * \brief Write a built up certificate to a X509 DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx certificate to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function (for signature, see note) - * \param p_rng RNG parameter - * - * \return length of data written if successful, or a specific - * error code - * - * \note f_rng may be NULL if RSA is used for signature and the - * signature is made offline (otherwise f_rng is desirable - * for countermeasures against timing attacks). - * ECDSA signatures always require a non-NULL f_rng. - */ -int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a built up certificate to a X509 PEM string - * - * \param ctx certificate to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function (for signature, see note) - * \param p_rng RNG parameter - * - * \return 0 if successful, or a specific error code - * - * \note f_rng may be NULL if RSA is used for signature and the - * signature is made offline (otherwise f_rng is desirable - * for countermeasures against timing attacks). - * ECDSA signatures always require a non-NULL f_rng. - */ -int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_X509_CRT_WRITE_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_x509_crt.h */ diff --git a/mbedtls/x509_csr.c b/mbedtls/x509_csr.c deleted file mode 100644 index 8ecc7c50d..000000000 --- a/mbedtls/x509_csr.c +++ /dev/null @@ -1,457 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * X.509 Certificate Signing Request (CSR) parsing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * The ITU-T X.509 standard defines a certificate format for PKI. - * - * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) - * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) - * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) - * - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CSR_PARSE_C) - -#include "mbedtls/x509_csr.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_snprintf snprintf -#endif - -#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) -#include -#endif - -/* - * Version ::= INTEGER { v1(0) } - */ -static int x509_csr_get_version( unsigned char **p, - const unsigned char *end, - int *ver ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - *ver = 0; - return( 0 ); - } - - return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); - } - - return( 0 ); -} - -/* - * Parse a CSR in DER format - */ -int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, - const unsigned char *buf, size_t buflen ) -{ - int ret; - size_t len; - unsigned char *p, *end; - mbedtls_x509_buf sig_params; - - memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) ); - - /* - * Check for valid input - */ - if( csr == NULL || buf == NULL || buflen == 0 ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - mbedtls_x509_csr_init( csr ); - - /* - * first copy the raw DER data - */ - p = mbedtls_calloc( 1, len = buflen ); - - if( p == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - memcpy( p, buf, buflen ); - - csr->raw.p = p; - csr->raw.len = len; - end = p + len; - - /* - * CertificationRequest ::= SEQUENCE { - * certificationRequestInfo CertificationRequestInfo, - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING - * } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT ); - } - - if( len != (size_t) ( end - p ) ) - { - mbedtls_x509_csr_free( csr ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - /* - * CertificationRequestInfo ::= SEQUENCE { - */ - csr->cri.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - end = p + len; - csr->cri.len = end - csr->cri.p; - - /* - * Version ::= INTEGER { v1(0) } - */ - if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( ret ); - } - - if( csr->version != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); - } - - csr->version++; - - /* - * subject Name - */ - csr->subject_raw.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( ret ); - } - - csr->subject_raw.len = p - csr->subject_raw.p; - - /* - * subjectPKInfo SubjectPublicKeyInfo - */ - if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( ret ); - } - - /* - * attributes [0] Attributes - * - * The list of possible attributes is open-ended, though RFC 2985 - * (PKCS#9) defines a few in section 5.4. We currently don't support any, - * so we just ignore them. This is a safe thing to do as the worst thing - * that could happen is that we issue a certificate that does not match - * the requester's expectations - this cannot cause a violation of our - * signature policies. - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - p += len; - - end = csr->raw.p + csr->raw.len; - - /* - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING - */ - if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( ret ); - } - - if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params, - &csr->sig_md, &csr->sig_pk, - &csr->sig_opts ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); - } - - if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 ) - { - mbedtls_x509_csr_free( csr ); - return( ret ); - } - - if( p != end ) - { - mbedtls_x509_csr_free( csr ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - return( 0 ); -} - -/* - * Parse a CSR, allowing for PEM or raw DER encoding - */ -int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ) -{ -#if defined(MBEDTLS_PEM_PARSE_C) - int ret; - size_t use_len; - mbedtls_pem_context pem; -#endif - - /* - * Check for valid input - */ - if( csr == NULL || buf == NULL || buflen == 0 ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_PEM_PARSE_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( buf[buflen - 1] == '\0' ) - { - mbedtls_pem_init( &pem ); - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN CERTIFICATE REQUEST-----", - "-----END CERTIFICATE REQUEST-----", - buf, NULL, 0, &use_len ); - if( ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN NEW CERTIFICATE REQUEST-----", - "-----END NEW CERTIFICATE REQUEST-----", - buf, NULL, 0, &use_len ); - } - - if( ret == 0 ) - { - /* - * Was PEM encoded, parse the result - */ - ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ); - } - - mbedtls_pem_free( &pem ); - if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); - } -#endif /* MBEDTLS_PEM_PARSE_C */ - return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) ); -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load a CSR into the structure - */ -int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ) -{ - int ret; - size_t n; - unsigned char *buf; - - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - ret = mbedtls_x509_csr_parse( csr, buf, n ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -#define BEFORE_COLON 14 -#define BC "14" -/* - * Return an informational string about the CSR. - */ -int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_csr *csr ) -{ - int ret; - size_t n; - char *p; - char key_size_str[BEFORE_COLON]; - - p = buf; - n = size; - - ret = mbedtls_snprintf( p, n, "%sCSR version : %d", - prefix, csr->version ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &csr->subject ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, - csr->sig_opts ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, - mbedtls_pk_get_name( &csr->pk ) ) ) != 0 ) - { - return( ret ); - } - - ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen( &csr->pk ) ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( (int) ( size - n ) ); -} - -/* - * Initialize a CSR - */ -void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ) -{ - memset( csr, 0, sizeof(mbedtls_x509_csr) ); -} - -/* - * Unallocate all CSR data - */ -void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ) -{ - mbedtls_x509_name *name_cur; - mbedtls_x509_name *name_prv; - - if( csr == NULL ) - return; - - mbedtls_pk_free( &csr->pk ); - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free( csr->sig_opts ); -#endif - - name_cur = csr->subject.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - if( csr->raw.p != NULL ) - { - mbedtls_platform_zeroize( csr->raw.p, csr->raw.len ); - mbedtls_free( csr->raw.p ); - } - - mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) ); -} - -#endif /* MBEDTLS_X509_CSR_PARSE_C */ diff --git a/mbedtls/x509_csr.h b/mbedtls/x509_csr.h deleted file mode 100644 index 898207496..000000000 --- a/mbedtls/x509_csr.h +++ /dev/null @@ -1,333 +0,0 @@ -#pragma GCC system_header -/** - * \file x509_csr.h - * - * \brief X.509 certificate signing request parsing and writing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_X509_CSR_H -#define MBEDTLS_X509_CSR_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "x509.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup x509_module - * \{ */ - -/** - * \name Structures and functions for X.509 Certificate Signing Requests (CSR) - * \{ - */ - -/** - * Certificate Signing Request (CSR) structure. - */ -typedef struct mbedtls_x509_csr -{ - mbedtls_x509_buf raw; /**< The raw CSR data (DER). */ - mbedtls_x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */ - - int version; /**< CSR version (1=v1). */ - - mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). */ - mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ - - mbedtls_pk_context pk; /**< Container for the public key context. */ - - mbedtls_x509_buf sig_oid; - mbedtls_x509_buf sig; - mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ -} -mbedtls_x509_csr; - -/** - * Container for writing a CSR - */ -typedef struct mbedtls_x509write_csr -{ - mbedtls_pk_context *key; - mbedtls_asn1_named_data *subject; - mbedtls_md_type_t md_alg; - mbedtls_asn1_named_data *extensions; -} -mbedtls_x509write_csr; - -#if defined(MBEDTLS_X509_CSR_PARSE_C) -/** - * \brief Load a Certificate Signing Request (CSR) in DER format - * - * \note CSR attributes (if any) are currently silently ignored. - * - * \param csr CSR context to fill - * \param buf buffer holding the CRL data - * \param buflen size of the buffer - * - * \return 0 if successful, or a specific X509 error code - */ -int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, - const unsigned char *buf, size_t buflen ); - -/** - * \brief Load a Certificate Signing Request (CSR), DER or PEM format - * - * \note See notes for \c mbedtls_x509_csr_parse_der() - * - * \param csr CSR context to fill - * \param buf buffer holding the CRL data - * \param buflen size of the buffer - * (including the terminating null byte for PEM data) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Load a Certificate Signing Request (CSR) - * - * \note See notes for \c mbedtls_x509_csr_parse() - * - * \param csr CSR context to fill - * \param path filename to read the CSR from - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief Returns an informational string about the - * CSR. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param csr The X509 CSR to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_csr *csr ); - -/** - * \brief Initialize a CSR - * - * \param csr CSR to initialize - */ -void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ); - -/** - * \brief Unallocate all CSR data - * - * \param csr CSR to free - */ -void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ); -#endif /* MBEDTLS_X509_CSR_PARSE_C */ - -/* \} name */ -/* \} addtogroup x509_module */ - -#if defined(MBEDTLS_X509_CSR_WRITE_C) -/** - * \brief Initialize a CSR context - * - * \param ctx CSR context to initialize - */ -void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ); - -/** - * \brief Set the subject name for a CSR - * Subject names should contain a comma-separated list - * of OID types and values: - * e.g. "C=UK,O=ARM,CN=mbed TLS Server 1" - * - * \param ctx CSR context to use - * \param subject_name subject name to set - * - * \return 0 if subject name was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx, - const char *subject_name ); - -/** - * \brief Set the key for a CSR (public key will be included, - * private key used to sign the CSR when writing it) - * - * \param ctx CSR context to use - * \param key Asymetric key to include - */ -void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key ); - -/** - * \brief Set the MD algorithm to use for the signature - * (e.g. MBEDTLS_MD_SHA1) - * - * \param ctx CSR context to use - * \param md_alg MD algorithm to use - */ -void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg ); - -/** - * \brief Set the Key Usage Extension flags - * (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN) - * - * \param ctx CSR context to use - * \param key_usage key usage flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - * - * \note The decipherOnly flag from the Key Usage - * extension is represented by bit 8 (i.e. - * 0x8000), which cannot typically be represented - * in an unsigned char. Therefore, the flag - * decipherOnly (i.e. - * #MBEDTLS_X509_KU_DECIPHER_ONLY) cannot be set using this - * function. - */ -int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ); - -/** - * \brief Set the Netscape Cert Type flags - * (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL) - * - * \param ctx CSR context to use - * \param ns_cert_type Netscape Cert Type flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, - unsigned char ns_cert_type ); - -/** - * \brief Generic function to add to or replace an extension in the - * CSR - * - * \param ctx CSR context to use - * \param oid OID of the extension - * \param oid_len length of the OID - * \param val value of the extension OCTET STRING - * \param val_len length of the value data - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx, - const char *oid, size_t oid_len, - const unsigned char *val, size_t val_len ); - -/** - * \brief Free the contents of a CSR context - * - * \param ctx CSR context to free - */ -void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ); - -/** - * \brief Write a CSR (Certificate Signing Request) to a - * DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx CSR to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function (for signature, see note) - * \param p_rng RNG parameter - * - * \return length of data written if successful, or a specific - * error code - * - * \note f_rng may be NULL if RSA is used for signature and the - * signature is made offline (otherwise f_rng is desirable - * for countermeasures against timing attacks). - * ECDSA signatures always require a non-NULL f_rng. - */ -int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a CSR (Certificate Signing Request) to a - * PEM string - * - * \param ctx CSR to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function (for signature, see note) - * \param p_rng RNG parameter - * - * \return 0 if successful, or a specific error code - * - * \note f_rng may be NULL if RSA is used for signature and the - * signature is made offline (otherwise f_rng is desirable - * for countermeasures against timing attacks). - * ECDSA signatures always require a non-NULL f_rng. - */ -int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_X509_CSR_WRITE_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_x509_csr.h */ diff --git a/mbedtls/x509write_crt.c b/mbedtls/x509write_crt.c deleted file mode 100644 index abeea0b07..000000000 --- a/mbedtls/x509write_crt.c +++ /dev/null @@ -1,614 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * X.509 certificate writing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * References: - * - certificates: RFC 5280, updated by RFC 6818 - * - CSRs: PKCS#10 v1.7 aka RFC 2986 - * - attributes: PKCS#9 v2.0 aka RFC 2985 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CRT_WRITE_C) - -#include "mbedtls/x509_crt.h" -#include "mbedtls/oid.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/sha1.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif /* MBEDTLS_PEM_WRITE_C */ - -/* - * For the currently used signature algorithms the buffer to store any signature - * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) - */ -#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE -#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN -#else -#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE -#endif - -void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_x509write_cert ) ); - - mbedtls_mpi_init( &ctx->serial ); - ctx->version = MBEDTLS_X509_CRT_VERSION_3; -} - -void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ) -{ - mbedtls_mpi_free( &ctx->serial ); - - mbedtls_asn1_free_named_data_list( &ctx->subject ); - mbedtls_asn1_free_named_data_list( &ctx->issuer ); - mbedtls_asn1_free_named_data_list( &ctx->extensions ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_cert ) ); -} - -void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, - int version ) -{ - ctx->version = version; -} - -void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, - mbedtls_md_type_t md_alg ) -{ - ctx->md_alg = md_alg; -} - -void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, - mbedtls_pk_context *key ) -{ - ctx->subject_key = key; -} - -void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, - mbedtls_pk_context *key ) -{ - ctx->issuer_key = key; -} - -int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, - const char *subject_name ) -{ - return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); -} - -int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, - const char *issuer_name ) -{ - return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name ); -} - -int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, - const mbedtls_mpi *serial ) -{ - int ret; - - if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, - const char *not_before, - const char *not_after ) -{ - if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 || - strlen( not_after ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ) - { - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - } - strncpy( ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); - strncpy( ctx->not_after , not_after , MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); - ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; - ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; - - return( 0 ); -} - -int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx, - const char *oid, size_t oid_len, - int critical, - const unsigned char *val, size_t val_len ) -{ - return( mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, - critical, val, val_len ) ); -} - -int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, - int is_ca, int max_pathlen ) -{ - int ret; - unsigned char buf[9]; - unsigned char *c = buf + sizeof(buf); - size_t len = 0; - - memset( buf, 0, sizeof(buf) ); - - if( is_ca && max_pathlen > 127 ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - if( is_ca ) - { - if( max_pathlen >= 0 ) - { - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, - max_pathlen ) ); - } - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) ); - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return( - mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, - MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ), - 0, buf + sizeof(buf) - len, len ) ); -} - -#if defined(MBEDTLS_SHA1_C) -int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ) -{ - int ret; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ - unsigned char *c = buf + sizeof(buf); - size_t len = 0; - - memset( buf, 0, sizeof(buf) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); - - ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, - buf + sizeof( buf ) - 20 ); - if( ret != 0 ) - return( ret ); - c = buf + sizeof( buf ) - 20; - len = 20; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) ); - - return mbedtls_x509write_crt_set_extension( ctx, - MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, - MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ), - 0, buf + sizeof(buf) - len, len ); -} - -int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ) -{ - int ret; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ - unsigned char *c = buf + sizeof( buf ); - size_t len = 0; - - memset( buf, 0, sizeof(buf) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); - - ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, - buf + sizeof( buf ) - 20 ); - if( ret != 0 ) - return( ret ); - c = buf + sizeof( buf ) - 20; - len = 20; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return mbedtls_x509write_crt_set_extension( - ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, - MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), - 0, buf + sizeof( buf ) - len, len ); -} -#endif /* MBEDTLS_SHA1_C */ - -static size_t crt_get_unused_bits_for_named_bitstring( unsigned char bitstring, - size_t bit_offset ) -{ - size_t unused_bits; - - /* Count the unused bits removing trailing 0s */ - for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ ) - if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 ) - break; - - return( unused_bits ); -} - -int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, - unsigned int key_usage ) -{ - unsigned char buf[4], ku; - unsigned char *c; - int ret; - size_t unused_bits; - const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE | - MBEDTLS_X509_KU_NON_REPUDIATION | - MBEDTLS_X509_KU_KEY_ENCIPHERMENT | - MBEDTLS_X509_KU_DATA_ENCIPHERMENT | - MBEDTLS_X509_KU_KEY_AGREEMENT | - MBEDTLS_X509_KU_KEY_CERT_SIGN | - MBEDTLS_X509_KU_CRL_SIGN; - - /* Check that nothing other than the allowed flags is set */ - if( ( key_usage & ~allowed_bits ) != 0 ) - return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); - - c = buf + 4; - ku = (unsigned char)key_usage; - unused_bits = crt_get_unused_bits_for_named_bitstring( ku, 1 ); - ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 8 - unused_bits ); - - if( ret < 0 ) - return( ret ); - else if( ret < 3 || ret > 4 ) - return( MBEDTLS_ERR_X509_INVALID_FORMAT ); - - ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, - MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), - 1, c, (size_t)ret ); - if( ret != 0 ) - return( ret ); - - return( 0 ); -} - -int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, - unsigned char ns_cert_type ) -{ - unsigned char buf[4]; - unsigned char *c; - size_t unused_bits; - int ret; - - c = buf + 4; - - unused_bits = crt_get_unused_bits_for_named_bitstring( ns_cert_type, 0 ); - ret = mbedtls_asn1_write_bitstring( &c, - buf, - &ns_cert_type, - 8 - unused_bits ); - if( ret < 3 || ret > 4 ) - return( ret ); - - ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, - MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), - 0, c, (size_t)ret ); - if( ret != 0 ) - return( ret ); - - return( 0 ); -} - -static int x509_write_time( unsigned char **p, unsigned char *start, - const char *t, size_t size ) -{ - int ret; - size_t len = 0; - - /* - * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) - */ - if( t[0] == '2' && t[1] == '0' && t[2] < '5' ) - { - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, - (const unsigned char *) t + 2, - size - 2 ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, - MBEDTLS_ASN1_UTC_TIME ) ); - } - else - { - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, - (const unsigned char *) t, - size ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, - MBEDTLS_ASN1_GENERALIZED_TIME ) ); - } - - return( (int) len ); -} - -int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, - unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - const char *sig_oid; - size_t sig_oid_len = 0; - unsigned char *c, *c2; - unsigned char hash[64]; - unsigned char sig[SIGNATURE_MAX_SIZE]; - size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; - size_t len = 0; - mbedtls_pk_type_t pk_alg; - - /* - * Prepare data to be signed at the end of the target buffer - */ - c = buf + size; - - /* Signature algorithm needed in TBS, and later for actual signature */ - - /* There's no direct way of extracting a signature algorithm - * (represented as an element of mbedtls_pk_type_t) from a PK instance. */ - if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_RSA ) ) - pk_alg = MBEDTLS_PK_RSA; - else if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_ECDSA ) ) - pk_alg = MBEDTLS_PK_ECDSA; - else - return( MBEDTLS_ERR_X509_INVALID_ALG ); - - if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, - &sig_oid, &sig_oid_len ) ) != 0 ) - { - return( ret ); - } - - /* - * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - */ - - /* Only for v3 */ - if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 ) - { - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_x509_write_extensions( &c, - buf, ctx->extensions ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); - } - - /* - * SubjectPublicKeyInfo - */ - MBEDTLS_ASN1_CHK_ADD( pub_len, - mbedtls_pk_write_pubkey_der( ctx->subject_key, - buf, c - buf ) ); - c -= pub_len; - len += pub_len; - - /* - * Subject ::= Name - */ - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_x509_write_names( &c, buf, - ctx->subject ) ); - - /* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - */ - sub_len = 0; - - MBEDTLS_ASN1_CHK_ADD( sub_len, - x509_write_time( &c, buf, ctx->not_after, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); - - MBEDTLS_ASN1_CHK_ADD( sub_len, - x509_write_time( &c, buf, ctx->not_before, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); - - len += sub_len; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, sub_len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - /* - * Issuer ::= Name - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf, - ctx->issuer ) ); - - /* - * Signature ::= AlgorithmIdentifier - */ - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_algorithm_identifier( &c, buf, - sig_oid, strlen( sig_oid ), 0 ) ); - - /* - * Serial ::= INTEGER - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, - &ctx->serial ) ); - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ - - /* Can be omitted for v1 */ - if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 ) - { - sub_len = 0; - MBEDTLS_ASN1_CHK_ADD( sub_len, - mbedtls_asn1_write_int( &c, buf, ctx->version ) ); - len += sub_len; - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_len( &c, buf, sub_len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - /* - * Make signature - */ - - /* Compute hash of CRT. */ - if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, - len, hash ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, - hash, 0, sig, &sig_len, - f_rng, p_rng ) ) != 0 ) - { - return( ret ); - } - - /* Move CRT to the front of the buffer to have space - * for the signature. */ - memmove( buf, c, len ); - c = buf + len; - - /* Add signature at the end of the buffer, - * making sure that it doesn't underflow - * into the CRT buffer. */ - c2 = buf + size; - MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, c, - sig_oid, sig_oid_len, sig, sig_len ) ); - - /* - * Memory layout after this step: - * - * buf c=buf+len c2 buf+size - * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm] - */ - - /* Move raw CRT to just before the signature. */ - c = c2 - len; - memmove( c, buf, len ); - - len += sig_and_oid_len; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return( (int) len ); -} - -#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" -#define PEM_END_CRT "-----END CERTIFICATE-----\n" - -#if defined(MBEDTLS_PEM_WRITE_C) -int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, - unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - size_t olen; - - if( ( ret = mbedtls_x509write_crt_der( crt, buf, size, - f_rng, p_rng ) ) < 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, - buf + size - ret, ret, - buf, size, &olen ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_PEM_WRITE_C */ - -#endif /* MBEDTLS_X509_CRT_WRITE_C */ diff --git a/mbedtls/x509write_csr.c b/mbedtls/x509write_csr.c deleted file mode 100644 index 6f6687405..000000000 --- a/mbedtls/x509write_csr.c +++ /dev/null @@ -1,398 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * X.509 Certificate Signing Request writing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -/* - * References: - * - CSRs: PKCS#10 v1.7 aka RFC 2986 - * - attributes: PKCS#9 v2.0 aka RFC 2985 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CSR_WRITE_C) - -#include "mbedtls/x509_csr.h" -#include "mbedtls/oid.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif - -/* - * For the currently used signature algorithms the buffer to store any signature - * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) - */ -#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE -#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN -#else -#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_x509write_csr ) ); -} - -void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ) -{ - mbedtls_asn1_free_named_data_list( &ctx->subject ); - mbedtls_asn1_free_named_data_list( &ctx->extensions ); - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_csr ) ); -} - -void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg ) -{ - ctx->md_alg = md_alg; -} - -void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key ) -{ - ctx->key = key; -} - -int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx, - const char *subject_name ) -{ - return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); -} - -int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx, - const char *oid, size_t oid_len, - const unsigned char *val, size_t val_len ) -{ - return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, - 0, val, val_len ); -} - -static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring, - size_t bit_offset ) -{ - size_t unused_bits; - - /* Count the unused bits removing trailing 0s */ - for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ ) - if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 ) - break; - - return( unused_bits ); -} - -int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ) -{ - unsigned char buf[4]; - unsigned char *c; - size_t unused_bits; - int ret; - - c = buf + 4; - - unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 ); - ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits ); - - if( ret < 0 ) - return( ret ); - else if( ret < 3 || ret > 4 ) - return( MBEDTLS_ERR_X509_INVALID_FORMAT ); - - ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, - MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), - c, (size_t)ret ); - if( ret != 0 ) - return( ret ); - - return( 0 ); -} - -int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, - unsigned char ns_cert_type ) -{ - unsigned char buf[4]; - unsigned char *c; - size_t unused_bits; - int ret; - - c = buf + 4; - - unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 ); - ret = mbedtls_asn1_write_bitstring( &c, - buf, - &ns_cert_type, - 8 - unused_bits ); - - if( ret < 0 ) - return( ret ); - else if( ret < 3 || ret > 4 ) - return( ret ); - - ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, - MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), - c, (size_t)ret ); - if( ret != 0 ) - return( ret ); - - return( 0 ); -} - -static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx, - unsigned char *buf, - size_t size, - unsigned char *sig, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - const char *sig_oid; - size_t sig_oid_len = 0; - unsigned char *c, *c2; - unsigned char hash[64]; - size_t pub_len = 0, sig_and_oid_len = 0, sig_len; - size_t len = 0; - mbedtls_pk_type_t pk_alg; - - /* Write the CSR backwards starting from the end of buf */ - c = buf + size; - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, buf, - ctx->extensions ) ); - - if( len ) - { - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ); - - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_oid( - &c, buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ, - MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ); - - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key, - buf, c - buf ) ); - c -= pub_len; - len += pub_len; - - /* - * Subject ::= Name - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf, - ctx->subject ) ); - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - - /* - * Sign the written CSR data into the sig buffer - * Note: hash errors can happen only after an internal error - */ - ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); - if( ret != 0 ) - return( ret ); - - if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, - f_rng, p_rng ) ) != 0 ) - { - return( ret ); - } - - if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) ) - pk_alg = MBEDTLS_PK_RSA; - else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) ) - pk_alg = MBEDTLS_PK_ECDSA; - else - return( MBEDTLS_ERR_X509_INVALID_ALG ); - - if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, - &sig_oid, &sig_oid_len ) ) != 0 ) - { - return( ret ); - } - - /* - * Move the written CSR data to the start of buf to create space for - * writing the signature into buf. - */ - memmove( buf, c, len ); - - /* - * Write sig and its OID into buf backwards from the end of buf. - * Note: mbedtls_x509_write_sig will check for c2 - ( buf + len ) < sig_len - * and return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if needed. - */ - c2 = buf + size; - MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, - mbedtls_x509_write_sig( &c2, buf + len, sig_oid, sig_oid_len, - sig, sig_len ) ); - - /* - * Compact the space between the CSR data and signature by moving the - * CSR data to the start of the signature. - */ - c2 -= len; - memmove( c2, buf, len ); - - /* ASN encode the total size and tag the CSR data with it. */ - len += sig_and_oid_len; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, - mbedtls_asn1_write_tag( - &c2, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - - /* Zero the unused bytes at the start of buf */ - memset( buf, 0, c2 - buf); - - return( (int) len ); -} - -int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, - size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - unsigned char *sig; - - if( ( sig = mbedtls_calloc( 1, SIGNATURE_MAX_SIZE ) ) == NULL ) - { - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - } - - ret = x509write_csr_der_internal( ctx, buf, size, sig, f_rng, p_rng ); - - mbedtls_free( sig ); - - return( ret ); -} - -#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" -#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" - -#if defined(MBEDTLS_PEM_WRITE_C) -int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - unsigned char output_buf[4096]; - size_t olen = 0; - - if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf), - f_rng, p_rng ) ) < 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR, - output_buf + sizeof(output_buf) - ret, - ret, buf, size, &olen ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_PEM_WRITE_C */ - -#endif /* MBEDTLS_X509_CSR_WRITE_C */ diff --git a/mbedtls/xtea.c b/mbedtls/xtea.c deleted file mode 100644 index b50a670b9..000000000 --- a/mbedtls/xtea.c +++ /dev/null @@ -1,315 +0,0 @@ -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -/* - * An 32-bit implementation of the XTEA algorithm - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_XTEA_C) - -#include "mbedtls/xtea.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_XTEA_ALT) - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -void mbedtls_xtea_init( mbedtls_xtea_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_xtea_context ) ); -} - -void mbedtls_xtea_free( mbedtls_xtea_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_xtea_context ) ); -} - -/* - * XTEA key schedule - */ -void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] ) -{ - int i; - - memset( ctx, 0, sizeof(mbedtls_xtea_context) ); - - for( i = 0; i < 4; i++ ) - { - GET_UINT32_BE( ctx->k[i], key, i << 2 ); - } -} - -/* - * XTEA encrypt function - */ -int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode, - const unsigned char input[8], unsigned char output[8]) -{ - uint32_t *k, v0, v1, i; - - k = ctx->k; - - GET_UINT32_BE( v0, input, 0 ); - GET_UINT32_BE( v1, input, 4 ); - - if( mode == MBEDTLS_XTEA_ENCRYPT ) - { - uint32_t sum = 0, delta = 0x9E3779B9; - - for( i = 0; i < 32; i++ ) - { - v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); - sum += delta; - v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); - } - } - else /* MBEDTLS_XTEA_DECRYPT */ - { - uint32_t delta = 0x9E3779B9, sum = delta * 32; - - for( i = 0; i < 32; i++ ) - { - v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); - sum -= delta; - v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); - } - } - - PUT_UINT32_BE( v0, output, 0 ); - PUT_UINT32_BE( v1, output, 4 ); - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * XTEA-CBC buffer encryption/decryption - */ -int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length, - unsigned char iv[8], const unsigned char *input, - unsigned char *output) -{ - int i; - unsigned char temp[8]; - - if( length % 8 ) - return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH ); - - if( mode == MBEDTLS_XTEA_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, 8 ); - mbedtls_xtea_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_xtea_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* !MBEDTLS_XTEA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * XTEA tests vectors (non-official) - */ - -static const unsigned char xtea_test_key[6][16] = -{ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 } -}; - -static const unsigned char xtea_test_pt[6][8] = -{ - { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, - { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, - { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, - { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, - { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, - { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } -}; - -static const unsigned char xtea_test_ct[6][8] = -{ - { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, - { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, - { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, - { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, - { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, - { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } -}; - -/* - * Checkup routine - */ -int mbedtls_xtea_self_test( int verbose ) -{ - int i, ret = 0; - unsigned char buf[8]; - mbedtls_xtea_context ctx; - - mbedtls_xtea_init( &ctx ); - for( i = 0; i < 6; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " XTEA test #%d: ", i + 1 ); - - memcpy( buf, xtea_test_pt[i], 8 ); - - mbedtls_xtea_setup( &ctx, xtea_test_key[i] ); - mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf ); - - if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -exit: - mbedtls_xtea_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_XTEA_C */ diff --git a/mbedtls/xtea.h b/mbedtls/xtea.h deleted file mode 100644 index d6e321c55..000000000 --- a/mbedtls/xtea.h +++ /dev/null @@ -1,165 +0,0 @@ -#pragma GCC system_header -/** - * \file xtea.h - * - * \brief XTEA block cipher (32-bit) - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** - */ -#ifndef MBEDTLS_XTEA_H -#define MBEDTLS_XTEA_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#define MBEDTLS_XTEA_ENCRYPT 1 -#define MBEDTLS_XTEA_DECRYPT 0 - -#define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH -0x0028 /**< The data input has an invalid length. */ - -/* MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED is deprecated and should not be used. */ -#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED -0x0029 /**< XTEA hardware accelerator failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_XTEA_ALT) -// Regular implementation -// - -/** - * \brief XTEA context structure - */ -typedef struct mbedtls_xtea_context -{ - uint32_t k[4]; /*!< key */ -} -mbedtls_xtea_context; - -#else /* MBEDTLS_XTEA_ALT */ -#include "xtea_alt.h" -#endif /* MBEDTLS_XTEA_ALT */ - -/** - * \brief Initialize XTEA context - * - * \param ctx XTEA context to be initialized - */ -void mbedtls_xtea_init( mbedtls_xtea_context *ctx ); - -/** - * \brief Clear XTEA context - * - * \param ctx XTEA context to be cleared - */ -void mbedtls_xtea_free( mbedtls_xtea_context *ctx ); - -/** - * \brief XTEA key schedule - * - * \param ctx XTEA context to be initialized - * \param key the secret key - */ -void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] ); - -/** - * \brief XTEA cipher function - * - * \param ctx XTEA context - * \param mode MBEDTLS_XTEA_ENCRYPT or MBEDTLS_XTEA_DECRYPT - * \param input 8-byte input block - * \param output 8-byte output block - * - * \return 0 if successful - */ -int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, - int mode, - const unsigned char input[8], - unsigned char output[8] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief XTEA CBC cipher function - * - * \param ctx XTEA context - * \param mode MBEDTLS_XTEA_ENCRYPT or MBEDTLS_XTEA_DECRYPT - * \param length the length of input, multiple of 8 - * \param iv initialization vector for CBC mode - * \param input input block - * \param output output block - * - * \return 0 if successful, - * MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH if the length % 8 != 0 - */ -int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_xtea_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* xtea.h */ diff --git a/menu/index.cpp b/menu/index.cpp deleted file mode 100644 index 8ae358b42..000000000 --- a/menu/index.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include - - -std::string menu_index_url () -{ - return "menu/index"; -} - - -bool menu_index_acl (Webserver_Request& webserver_request) -{ - return Filter_Roles::access_control (webserver_request, Filter_Roles::guest ()); -} - - -std::string menu_index (Webserver_Request& webserver_request) -{ - std::string item = webserver_request.query ["item"]; - item = menu_logic_click (item); - redirect_browser (webserver_request, item); - return std::string(); -} diff --git a/menu/index.h b/menu/index.h deleted file mode 100644 index c585ec87f..000000000 --- a/menu/index.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#pragma once - -#include - -class Webserver_Request; - -std::string menu_index_url (); -bool menu_index_acl (Webserver_Request& webserver_request); -std::string menu_index (Webserver_Request& webserver_request); diff --git a/menu/logic.cpp b/menu/logic.cpp deleted file mode 100644 index 0633a1c1f..000000000 --- a/menu/logic.cpp +++ /dev/null @@ -1,1292 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wuseless-cast" -#include -#pragma GCC diagnostic pop -#include -#include -#include -#include -#include -using namespace std; - - -string menu_logic_href (string href) -{ - href = filter::strings::replace ("?", "__q__", href); - href = filter::strings::replace ("&", "__a__", href); - href = filter::strings::replace ("=", "__i__", href); - return href; -} - - -string menu_logic_click (string item) -{ - item = filter::strings::replace ("__q__", "?", item); - item = filter::strings::replace ("__a__", "&", item); - item = filter::strings::replace ("__i__", "=", item); - Database_Config_General::setLastMenuClick (item); - return item; -} - - -string menu_logic_create_item (string href, string text, bool history, string title, string colour) -{ - string item; - item.append (R"()" + text + ""); - item.append (""); - return item; -} - - -string menu_logic_translate_menu () -{ - return "translate"; -} - - -string menu_logic_search_menu () -{ - return "search"; -} - - -string menu_logic_tools_menu () -{ - return "tools"; -} - - -string menu_logic_settings_menu () -{ - return "settings"; -} - - -string menu_logic_settings_resources_menu () -{ - return "settings-resources"; -} - - -// Returns the html for the main menu categories. -// Also fills the $tooltip with an appropriate value for this main menu. -// This function is called for the main page, that is, the home page. -string menu_logic_main_categories (Webserver_Request& webserver_request, string & tooltip) -{ - // The sets of html that is going to form the menu. - vector html; - - // The sets of tooltips for the main menu item. - vector tooltipbits; - - // Deal with a situation the user has access to the workspaces. - if (workspace_index_acl (webserver_request)) { - if (config::logic::default_bibledit_configuration ()) { - string label = translate ("Workspace"); - string tooltip2; - menu_logic_workspace_category (webserver_request, &tooltip2); - html.push_back (menu_logic_create_item (workspace_index_url (), label, true, tooltip2, "")); - tooltipbits.push_back (label); - } - } - - string menutooltip; - int current_theme_index = webserver_request.database_config_user ()->getCurrentTheme (); - string filename = current_theme_filebased_cache_filename (webserver_request.session_identifier); - string color = Filter_Css::theme_picker (current_theme_index, 1); - - if (!menu_logic_translate_category (webserver_request, &menutooltip).empty ()) { - if (config::logic::default_bibledit_configuration ()) { - html.push_back (menu_logic_create_item (menu_logic_translate_menu (), menu_logic_translate_text (), false, menutooltip, color)); - tooltipbits.push_back (menu_logic_translate_text ()); - } - } - - if (!menu_logic_search_category (webserver_request, &menutooltip).empty ()) { - if (config::logic::default_bibledit_configuration ()) { - html.push_back (menu_logic_create_item (menu_logic_search_menu (), menu_logic_search_text (), false, menutooltip, color)); - tooltipbits.push_back (menu_logic_search_text ()); - } - } - - if (!menu_logic_tools_category (webserver_request, &menutooltip).empty ()) { - if (config::logic::default_bibledit_configuration ()) { - html.push_back (menu_logic_create_item (menu_logic_tools_menu (), menu_logic_tools_text (), false, menutooltip, color)); - tooltipbits.push_back (menu_logic_tools_text ()); - } - } - - if (!menu_logic_settings_category (webserver_request, &menutooltip).empty ()) { - if (config::logic::default_bibledit_configuration ()) { - html.push_back (menu_logic_create_item (menu_logic_settings_menu (), menu_logic_settings_text (), false, menutooltip, color)); - tooltipbits.push_back (menu_logic_settings_text ()); - } - } - - if (!menu_logic_help_category (webserver_request).empty ()) { - if (config::logic::default_bibledit_configuration ()) { - html.push_back (menu_logic_create_item ("help/index", menu_logic_help_text (), true, menu_logic_help_text (), color)); - tooltipbits.push_back (menu_logic_help_text ()); - } - } - -#ifdef HAVE_CLOUD - // When a user is not logged in, or if a guest is logged in, - // put the public feedback into the main menu, rather than in a sub menu. - if (menu_logic_public_or_guest (webserver_request)) { - if (!public_logic_bibles (webserver_request).empty ()) { - html.push_back (menu_logic_create_item (public_index_url (), menu_logic_public_feedback_text (), true, "", "")); - tooltipbits.push_back (menu_logic_public_feedback_text ()); - } - } -#endif - - // When a user is logged in, and is a guest, put the Logout into the main menu, rather than in a sub menu. - if (webserver_request.session_logic ()->loggedIn ()) { - if (webserver_request.session_logic ()->currentLevel () == Filter_Roles::guest ()) { - if (session_logout_acl (webserver_request)) { - html.push_back (menu_logic_create_item (session_logout_url (), menu_logic_logout_text (), true, "", "")); - tooltipbits.push_back (menu_logic_logout_text ()); - } - } - } - - - // When not logged in, display Login menu item. - if (webserver_request.session_logic ()->currentUser ().empty ()) { - string label = translate ("Login"); - html.push_back (menu_logic_create_item (session_login_url (), label, true, "", "")); - tooltipbits.push_back (label); - } - - // Create one string of tool tips for this menu item, separated by a vertical bar. - tooltip = filter::strings::implode (tooltipbits, " | "); - - // Create one string of html that is going to form the menu. - return filter::strings::implode (html, "\n"); -} - - -/* - Some of the functions below generate a start menu. - - It goes through all possible menu entries. - It reads the access levels of those entries. - It takes the menu entries the currently logged-in user has access to. - - It originally self-organized the entries such that the ones used clicked often came earlier in the menu. - But menu entries moving around creates confusion. - Therefore it was removed again. - */ - - -string menu_logic_basic_categories (Webserver_Request& webserver_request) -{ - vector html; - - int current_theme_index = webserver_request.database_config_user ()->getCurrentTheme (); - string filename = current_theme_filebased_cache_filename (webserver_request.session_identifier); - string color = Filter_Css::theme_picker (current_theme_index, 1); - - if (read_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (read_index_url (), translate ("Read"), true, "", color)); - } - - if (resource_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_index_url (), menu_logic_resources_text (), true, "", color)); - } - - if (editone2_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (editone2_index_url (), menu_logic_translate_text (), true, "", color)); - } - - if (changes_changes_acl (webserver_request)) { - if (webserver_request.database_config_user ()->getMenuChangesInBasicMode ()) { - html.push_back (menu_logic_create_item (changes_changes_url (), menu_logic_changes_text (), true, "", color)); - } - } - - if (notes_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (notes_index_url (), menu_logic_consultation_notes_text (), true, "", color)); - } - - if (personalize_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (personalize_index_url (), "⋮", true, "", color)); - } - -#ifdef HAVE_CLOUD - // When a user is not logged in, or a guest, - // put the public feedback into the main menu, rather than in a sub menu. - // This is the default configuration. - bool public_feedback_possible { true }; - if (public_feedback_possible) { - if (menu_logic_public_or_guest (webserver_request)) { - if (!public_logic_bibles (webserver_request).empty ()) { - html.push_back (menu_logic_create_item (public_index_url (), menu_logic_public_feedback_text (), true, "", "")); - } - } - } -#endif - - // When not logged in, display Login menu item. - if (webserver_request.session_logic ()->currentUser ().empty ()) { - html.push_back (menu_logic_create_item (session_login_url (), translate ("Login"), true, "", "")); - } - - // When a user is logged in, and is a guest, - // put the Logout into the main menu, - // rather than in a sub menu. -#ifdef HAVE_CLOUD - if (webserver_request.session_logic ()->loggedIn ()) { - if (webserver_request.session_logic ()->currentLevel () == Filter_Roles::guest ()) { - if (session_logout_acl (webserver_request)) { - html.push_back (menu_logic_create_item (session_logout_url (), menu_logic_logout_text (), true, "", "")); - } - } - } -#endif - - return filter::strings::implode (html, "\n"); -} - - -// Generates html for the workspace main menu. -// Plus the tooltip for it. -string menu_logic_workspace_category (Webserver_Request& webserver_request, string * tooltip) -{ - vector html; - vector labels; - - // Add the available configured workspaces to the menu. - // The user's role should be sufficiently high. - if (workspace_organize_acl (webserver_request)) { - string activeWorkspace = webserver_request.database_config_user()->getActiveWorkspace (); - - vector workspaces = workspace_get_names (webserver_request); - for (size_t i = 0; i < workspaces.size(); i++) { - string item = menu_logic_create_item (workspace_index_url () + "?bench=" + filter::strings::convert_to_string (i), workspaces[i], true, "", ""); - // Adds an active class if it is the current workspace. - if (workspaces[i] == activeWorkspace) { - size_t startIndex = item.find(R"(">assign (filter::strings::implode (labels, " | ")); - return filter::strings::implode (html, "\n"); -} - - -string menu_logic_translate_category (Webserver_Request& webserver_request, string * tooltip) -{ - vector html; - vector labels; - - // Visual chapter editor. - if (edit_index_acl (webserver_request)) { - string label = menu_logic_editor_menu_text (true, true); - html.push_back (menu_logic_create_item (edit_index_url (), label, true, "", "")); - labels.push_back (label); - } - - // Visual verse editor. - if (editone2_index_acl (webserver_request)) { - string label = menu_logic_editor_menu_text (true, false); - html.push_back (menu_logic_create_item (editone2_index_url (), label, true, "", "")); - labels.push_back (label); - } - - // USFM (chapter) editor. - if (editusfm_index_acl (webserver_request)) { - string label = menu_logic_editor_menu_text (false, true); - html.push_back (menu_logic_create_item (editusfm_index_url (), label, true, "", "")); - labels.push_back (label); - } - - if (notes_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (notes_index_url (), menu_logic_consultation_notes_text (), true, "", "")); - labels.push_back (menu_logic_consultation_notes_text ()); - } - - if (resource_index_acl (webserver_request)) { - string label = menu_logic_resources_text (); - html.push_back (menu_logic_create_item (resource_index_url (), label, true, "", "")); - labels.push_back (label); - } - - if (resource_user9view_acl (webserver_request)) { - // Only display user-defined resources if they are there. - if (!Database_UserResources::names ().empty ()) { - string label = translate ("User resources"); - html.push_back (menu_logic_create_item (resource_user9view_url (), label, true, "", "")); - labels.push_back (label); - } - } - - if (changes_changes_acl (webserver_request)) { - html.push_back (menu_logic_create_item (changes_changes_url (), menu_logic_changes_text (), true, "", "")); - labels.push_back (menu_logic_changes_text ()); - } - - // When a user is logged in, but not a guest, - // put the public feedback into this sub menu, rather than in the main menu. -#ifndef HAVE_CLIENT - if (!webserver_request.session_logic ()->currentUser ().empty ()) { - if (!menu_logic_public_or_guest (webserver_request)) { - if (!public_logic_bibles (webserver_request).empty ()) { - html.push_back (menu_logic_create_item (public_index_url (), menu_logic_public_feedback_text (), true, "", "")); - labels.push_back (menu_logic_public_feedback_text ()); - } - } - } -#endif - - if (!html.empty ()) { - html.insert (html.begin (), menu_logic_translate_text () + ": "); - } - - if (tooltip) tooltip->assign (filter::strings::implode (labels, " | ")); - return filter::strings::implode (html, "\n"); -} - - -string menu_logic_search_category (Webserver_Request& webserver_request, string * tooltip) -{ - vector html; - vector labels; - - if (search_index_acl (webserver_request)) { - string label = translate ("Search"); - html.push_back (menu_logic_create_item (search_index_url (), label, true, "", "")); - labels.push_back (label); - } - - if (search_replace_acl (webserver_request)) { - string label = translate ("Replace"); - html.push_back (menu_logic_create_item (search_replace_url (), label, true, "", "")); - labels.push_back (label); - } - - if (search_search2_acl (webserver_request)) { - string label = translate ("Advanced search"); - html.push_back (menu_logic_create_item (search_search2_url (), translate ("Advanced search"), true, "", "")); - labels.push_back (label); - } - - if (search_replace2_acl (webserver_request)) { - string label = translate ("Advanced replace"); - html.push_back (menu_logic_create_item (search_replace2_url (), label, true, "", "")); - labels.push_back (label); - } - - if (search_all_acl (webserver_request)) { - string label = translate ("Search all Bibles and notes"); - html.push_back (menu_logic_create_item (search_all_url (), label, true, "", "")); - labels.push_back (label); - } - - if (search_similar_acl (webserver_request)) { - string label = translate ("Search Bible for similar verses"); - html.push_back (menu_logic_create_item (search_similar_url (), label, true, "", "")); - labels.push_back (label); - } - - if (search_strongs_acl (webserver_request)) { - string label = translate ("Search Bible for similar Strong's numbers"); - html.push_back (menu_logic_create_item (search_strongs_url (), label, true, "", "")); - labels.push_back (label); - } - - if (search_strong_acl (webserver_request)) { - string label = translate ("Search Bible for Strong's number"); - html.push_back (menu_logic_create_item (search_strong_url (), label, true, "", "")); - labels.push_back (label); - } - - if (search_originals_acl (webserver_request)) { - string label = translate ("Search Bible for similar Hebrew or Greek words"); - html.push_back (menu_logic_create_item (search_originals_url (), label, true, "", "")); - labels.push_back (label); - } - - if (!html.empty ()) { - html.insert (html.begin (), menu_logic_search_text () + ": "); - } - - if (tooltip) tooltip->assign (filter::strings::implode (labels, " | ")); - return filter::strings::implode (html, "\n"); -} - - -string menu_logic_tools_category (Webserver_Request& webserver_request, string * tooltip) -{ - // The labels that may end up in the menu. - string checks = translate ("Checks"); - string consistency = translate ("Consistency"); - string print = translate ("Print"); - string changes = menu_logic_changes_text (); - string planning = translate ("Planning"); - string send_receive = translate ("Send/receive"); - string hyphenation = translate ("Hyphenate"); - string develop = translate ("Develop"); - string exporting = translate ("Export"); - string journal = translate ("Journal"); - vector labels = { - checks, - consistency, - print, - changes, - planning, - send_receive, - hyphenation, - develop, - exporting, - journal - }; - - // Sort the labels in alphabetical order for the menu. - // Using the localized labels means that the sorted order of the menu depends on the localization. - sort (labels.begin (), labels.end ()); - - vector html; - vector tiplabels; - - for (auto & label : labels) { - - if (label == checks) { - if (checks_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (checks_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - if (label == consistency) { - if (consistency_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (consistency_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - if (label == print) { -#ifndef HAVE_CLIENT - if (resource_print_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_print_url (), label, true, "", "")); - tiplabels.push_back (label); - } -#endif - } - - if (label == changes) { - // Downloading revisions only on server, not on client. -#ifndef HAVE_CLIENT - if (index_listing_acl (webserver_request, "revisions")) { - html.push_back (menu_logic_create_item (index_listing_url ("revisions"), menu_logic_changes_text (), true, "", "")); - tiplabels.push_back (menu_logic_changes_text ()); - } -#endif - } - - if (label == planning) { -#ifndef HAVE_CLIENT - if (sprint_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (sprint_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } -#endif - } - - if (label == send_receive) { - if (sendreceive_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (sendreceive_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - if (label == hyphenation) { - if (manage_hyphenation_acl (webserver_request)) { - html.push_back (menu_logic_create_item (manage_hyphenation_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - if (label == develop) { - if (developer_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (developer_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - if (label == exporting) { - if (manage_exports_acl (webserver_request)) { - html.push_back (menu_logic_create_item (manage_exports_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - if (label == journal) { - if (journal_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (journal_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - } - - if (!html.empty ()) { - html.insert (html.begin (), menu_logic_tools_text () + ": "); - } - - if (tooltip) tooltip->assign (filter::strings::implode (tiplabels, " | ")); - return filter::strings::implode (html, "\n"); -} - - -string menu_logic_settings_category (Webserver_Request& webserver_request, string * tooltip) -{ - [[maybe_unused]] bool demo = config::logic::demo_enabled (); - - // The labels that may end up in the menu. - string bibles = menu_logic_bible_manage_text (); - string workspaces = menu_logic_workspace_organize_text (); - string checks = menu_logic_checks_settings_text (); - string resources = menu_logic_resources_text (); - string changes = menu_logic_changes_text (); - string preferences = translate ("Preferences"); - string users = menu_logic_manage_users_text (); - string mail = translate ("Mail"); - string styles = menu_logic_styles_text (); - string versifications = menu_logic_versification_index_text (); - string mappings = menu_logic_mapping_index_text (); - string repository = translate ("Repository"); - string cloud = translate ("Cloud"); - string paratext = translate ("Paratext"); - string notifications = translate ("Notifications"); - string account = translate ("Account"); - string basic_mode = translate ("Basic mode"); - string system = translate ("System"); - string images = menu_logic_images_index_text(); - vector labels = { - bibles, - workspaces, - checks, - resources, - changes, - preferences, - users, - mail, - styles, - versifications, - mappings, - repository, - cloud, - paratext, - menu_logic_logout_text (), - notifications, - account, - basic_mode, - system, - images - }; - - // Sort the labels in alphabetical order for the menu. - // Using the localized labels means that the sorted order of the menu depends on the localization. - sort (labels.begin (), labels.end ()); - - vector html; - vector tiplabels; - - for (auto & label : labels) { - - if (label == bibles) { - if (bible_manage_acl (webserver_request)) { - html.push_back (menu_logic_create_item (bible_manage_url (), menu_logic_bible_manage_text (), true, "", "")); - tiplabels.push_back (menu_logic_bible_manage_text ()); - } - } - - if (label == workspaces) { - if (workspace_organize_acl (webserver_request)) { - html.push_back (menu_logic_create_item (workspace_organize_url (), menu_logic_workspace_organize_text (), true, "", "")); - tiplabels.push_back (menu_logic_workspace_organize_text ()); - } - } - - if (label == checks) { - if (checks_settings_acl (webserver_request)) { - html.push_back (menu_logic_create_item (checks_settings_url (), menu_logic_checks_settings_text (), true, "", "")); - tiplabels.push_back (menu_logic_checks_settings_text ()); - } - } - - if (label == resources) { - if (!menu_logic_settings_resources_category (webserver_request).empty ()) { - html.push_back (menu_logic_create_item (menu_logic_settings_resources_menu (), menu_logic_resources_text (), false, "", "")); - tiplabels.push_back (menu_logic_resources_text ()); - } -#ifdef HAVE_CLIENT - // Only client can cache resources. - // The Cloud is always online, with a fast connection, and can easily fetch a resource from the web. - // Many Cloud instances may run on one server, and if the Cloud were to cache resources, - // it would be going to use a huge amount of disk space. - if (resource_cache_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_cache_url (), menu_logic_resources_text (), true, "", "")); - tiplabels.push_back (menu_logic_resources_text ()); - } -#endif - } - - if (label == changes) { -#ifndef HAVE_CLIENT - // Managing change notifications only on server, not on client. - if (changes_manage_acl (webserver_request)) { - html.push_back (menu_logic_create_item (changes_manage_url (), menu_logic_changes_text (), true, "", "")); - tiplabels.push_back (menu_logic_changes_text ()); - } -#endif - } - - if (label == preferences) { - if (personalize_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (personalize_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - if (label == users) { -#ifndef HAVE_CLIENT - if (manage_users_acl (webserver_request)) { - html.push_back (menu_logic_create_item (manage_users_url (), menu_logic_manage_users_text (), true, "", "")); - tiplabels.push_back (menu_logic_manage_users_text ()); - } -#endif - } - - if (label == mail) { -#ifndef HAVE_CLIENT - if (email_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (email_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } -#endif - } - - if (label == styles) { - if (styles_indexm_acl (webserver_request)) { - html.push_back (menu_logic_create_item (styles_indexm_url (), menu_logic_styles_text (), true, "", "")); - tiplabels.push_back (menu_logic_styles_text ()); - } - } - - if (label == versifications) { - if (versification_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (versification_index_url (), menu_logic_versification_index_text (), true, "", "")); - tiplabels.push_back (menu_logic_versification_index_text ()); - } - } - - if (label == mappings) { - if (mapping_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (mapping_index_url (), menu_logic_mapping_index_text (), true, "", "")); - tiplabels.push_back (menu_logic_mapping_index_text ()); - } - } - -#ifndef HAVE_CLIENT - if (label == repository) { - if (collaboration_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (collaboration_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } -#endif - - if (label == cloud) { - // If the installation is not prepared for Client mode, disable the Cloud menu item. - // But keep the menu item in an open installation. - bool cloud_menu = client_index_acl (webserver_request); -#ifndef HAVE_CLIENT - cloud_menu = false; -#endif - if (config::logic::demo_enabled ()) cloud_menu = true; - if (cloud_menu) { - if (client_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (client_index_url (), label, true, "", "")); - tiplabels.push_back (client_index_url ()); - } - } - } - -#ifdef HAVE_PARATEXT - if (label == paratext) { - if (paratext_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (paratext_index_url (), label, true, "", "")); - tiplabels.push_back (paratext_index_url ()); - } - } -#endif - -#ifdef HAVE_CLOUD - // Logout menu entry only in the Cloud, never on the client. - if (label == menu_logic_logout_text ()) { - // Cannot logout in the demo. - if (!demo) { - // If logged in, but not as guest, put the Logout menu here. - if (webserver_request.session_logic ()->loggedIn ()) { - if (webserver_request.session_logic ()->currentLevel () != Filter_Roles::guest ()) { - if (session_logout_acl (webserver_request)) { - html.push_back (menu_logic_create_item (session_logout_url (), menu_logic_logout_text (), true, "", "")); - tiplabels.push_back (menu_logic_logout_text ()); - } - } - } - } - } -#endif - - if (label == notifications) { - if (user_notifications_acl (webserver_request)) { - html.push_back (menu_logic_create_item (user_notifications_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - -#ifdef HAVE_CLOUD - if (label == account) { - if (!demo) { - if (!ldap_logic_is_on ()) { - if (user_account_acl (webserver_request)) { - html.push_back (menu_logic_create_item (user_account_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - } - } -#endif - - if (label == basic_mode) { - if (webserver_request.session_logic ()->currentLevel () > Filter_Roles::guest ()) { - html.push_back (menu_logic_create_item (index_index_url () + filter::strings::convert_to_string ("?mode=basic"), label, true, "", "")); - tiplabels.push_back (label); - } - } - - if (label == system) { - if (system_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (system_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - if (label == images) { - if (images_index_acl (webserver_request)) { - html.push_back (menu_logic_create_item (images_index_url (), label, true, "", "")); - tiplabels.push_back (label); - } - } - - } - - if (!html.empty ()) { - string user = webserver_request.session_logic ()->currentUser (); - html.insert (html.begin (), menu_logic_settings_text () + " (" + user + "): "); - } - - if (tooltip) tooltip->assign (filter::strings::implode (tiplabels, " | ")); - return filter::strings::implode (html, "\n"); -} - - -string menu_logic_settings_resources_category ([[maybe_unused]] Webserver_Request& webserver_request) -{ - vector html; - -#ifdef HAVE_CLOUD - if (resource_manage_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_manage_url (), translate ("USFM"), true, "", "")); - } -#endif - -#ifdef HAVE_CLOUD - if (resource_images_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_images_url (), translate ("Images"), true, "", "")); - } -#endif - -#ifdef HAVE_CLOUD - if (!config_globals_hide_bible_resources) { - if (resource_sword_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_sword_url (), translate ("SWORD"), true, "", "")); - } - } -#endif - -#ifdef HAVE_CLOUD - if (resource_user9edit_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_user9edit_url (), translate ("User-defined"), true, "", "")); - } -#endif - -#ifdef HAVE_CLOUD - if (!config_globals_hide_bible_resources) { - if (resource_biblegateway_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_biblegateway_url (), "BibleGateway", true, "", "")); - } - } -#endif - -#ifdef HAVE_CLOUD - if (!config_globals_hide_bible_resources) { - if (resource_studylight_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_studylight_url (), "StudyLight", true, "", "")); - } - } -#endif - -#ifdef HAVE_CLOUD - if (resource_comparative9edit_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_comparative9edit_url (), translate ("Comparative"), true, "", "")); - } -#endif - -#ifdef HAVE_CLOUD - if (resource_translated9edit_acl (webserver_request)) { - html.push_back (menu_logic_create_item (resource_translated9edit_url (), translate ("Translated"), true, "", "")); - } -#endif - - if (!html.empty ()) { - html.insert (html.begin (), menu_logic_resources_text () + ": "); - } - - return filter::strings::implode (html, "\n"); -} - - -string menu_logic_help_category (Webserver_Request& webserver_request) -{ - vector html; - - if (!webserver_request.session_logic ()->currentUser ().empty ()) { - html.push_back (menu_logic_create_item ("help/index", translate ("Help and About"), true, "", "")); - } - - if (!html.empty ()) { - html.insert (html.begin (), menu_logic_help_text () + ": "); - } - - return filter::strings::implode (html, "\n"); -} - - -// Returns true in case the user is a public user, that is, not logged-in, -// or when the user has the role of Guest. -bool menu_logic_public_or_guest (Webserver_Request& webserver_request) -{ - if (webserver_request.session_logic ()->currentUser ().empty ()) return true; - if (webserver_request.session_logic ()->currentLevel () == Filter_Roles::guest ()) return true; - return false; -} - - -// Returns the text that belongs to a certain menu item. -string menu_logic_menu_text (string menu_item) -{ - if (menu_item == menu_logic_translate_menu ()) { - return menu_logic_translate_text (); - } - if (menu_item == notes_index_url ()) { - return menu_logic_consultation_notes_text (); - } - if (menu_item == menu_logic_search_menu ()) { - return menu_logic_search_text (); - } - if (menu_item == menu_logic_tools_menu ()) { - return menu_logic_tools_text (); - } - if (menu_item == menu_logic_settings_menu ()) { - return menu_logic_settings_text (); - } - return menu_logic_menu_text (); -} - - -// Returns the URL that belongs to $menu_item. -string menu_logic_menu_url (string menu_item) -{ - if ( - (menu_item == menu_logic_translate_menu ()) - || - (menu_item == menu_logic_search_menu ()) - || - (menu_item == menu_logic_tools_menu ()) - || - (menu_item == menu_logic_settings_menu ()) - ) { - return filter_url_build_http_query (index_index_url (), "item", menu_item); - } - - return menu_item; -} - - -string menu_logic_translate_text () -{ - return translate ("Translate"); -} - - -string menu_logic_search_text () -{ - return translate ("Search"); -} - - -string menu_logic_tools_text () -{ - return translate ("Tools"); -} - - -string menu_logic_settings_text () -{ - return translate ("Settings"); -} - - -string menu_logic_help_text () -{ - return translate ("Help"); -} - - -string menu_logic_public_feedback_text () -{ - return translate ("Feedback"); -} - - -string menu_logic_logout_text () -{ - return translate ("Logout"); -} - - -string menu_logic_consultation_notes_text () -{ - return translate ("Notes"); -} - - -string menu_logic_bible_manage_text () -{ - return translate ("Bibles"); -} - - -string menu_logic_workspace_organize_text () -{ - return translate ("Workspaces"); -} - - -string menu_logic_checks_settings_text () -{ - return translate ("Checks"); -} - - -string menu_logic_resources_text () -{ - return translate ("Resources"); -} - - -string menu_logic_resource_images_text () -{ - return translate ("Image resources"); -} - - -string menu_logic_manage_users_text () -{ - return translate ("Users"); -} - - -string menu_logic_versification_index_text () -{ - return translate ("Versifications"); -} - - -string menu_logic_mapping_index_text () -{ - return translate ("Verse mappings"); -} - - -string menu_logic_styles_indext_text () -{ - return translate ("Select stylesheet"); -} - - -string menu_logic_styles_indexm_text () -{ - return translate ("Edit stylesheet"); -} - - -string menu_logic_changes_text () -{ - return translate ("Changes"); -} - - -string menu_logic_styles_text () -{ - return translate ("Styles"); -} - - -string menu_logic_menu_text () -{ - return translate ("Menu"); -} - - -string menu_logic_images_index_text () -{ - return translate ("Images"); -} - - -string menu_logic_editor_settings_text (bool visual, int selection) -{ - if (visual) { - if (selection == 0) return translate ("Both the visual chapter and visual verse editors"); - if (selection == 1) return translate ("Only the visual chapter editor"); - if (selection == 2) return translate ("Only the visual verse editor"); - } else { - if (selection <= 0) return translate ("Hide"); - if (selection >= 1) return translate ("Show"); - } - return ""; -} - - -bool menu_logic_editor_enabled (Webserver_Request& webserver_request, bool visual, bool chapter) -{ - // Get the user's preference for the visual or USFM editors. - int selection = 0; - if (visual) selection = webserver_request.database_config_user ()->getFastSwitchVisualEditors (); - else selection = webserver_request.database_config_user ()->getFastSwitchUsfmEditors (); - - if (visual) { - // Check whether the visual chapter or verse editor is active. - if (selection == 0) return true; - if ((selection == 1) && chapter) return true; - if ((selection == 2) && !chapter) return true; - } else { - // Check whether the USFM chapter editor is active. - if (selection >= 1) return true; - } - - // The requested editor is inactive. - return false; -} - - -string menu_logic_editor_menu_text (bool visual, bool chapter) -{ - // Get the correct menu text. - if (visual && chapter) return translate ("Chapter editor"); - if (visual && !chapter) return translate ("Verse editor"); - if (!visual) return translate ("USFM editor"); - // Fallback. - return translate ("Bible"); -} - - -// Whether the device can do tabbed mode. -bool menu_logic_can_do_tabbed_mode () -{ -#ifdef HAVE_ANDROID - return true; -#endif -#ifdef HAVE_IOS - return true; -#endif - return false; -} - - -// For internal repatitive use. -jsonxx::Object menu_logic_tabbed_mode_add_tab (string url, string label) -{ - jsonxx::Object object; - object << "url" << url; - object << "label" << label; - return object; -} - - -// This looks at the settings, and then generates JSON, and stores that in the general configuration. -void menu_logic_tabbed_mode_save_json (Webserver_Request& webserver_request) -{ - string json; - - // Whether the device can do tabbed mode. - if (menu_logic_can_do_tabbed_mode ()) { - - // If the setting is on, generate the JSON. - bool generate_json = Database_Config_General::getMenuInTabbedViewOn (); - - // Tabbed view not possible in advanced mode. - if (!webserver_request.database_config_user ()->getBasicInterfaceMode ()) { - generate_json = false; - } - - if (generate_json) { - // Storage for the tabbed view. - jsonxx::Array json_array; - // Adding tabs in the order an average translator uses them most of the time: - // Add the Bible editor tab. - json_array << menu_logic_tabbed_mode_add_tab (editone2_index_url (), menu_logic_translate_text ()); - // Add the resources tab. - json_array << menu_logic_tabbed_mode_add_tab (resource_index_url (), menu_logic_resources_text ()); - // Add the consultation notes tab. - json_array << menu_logic_tabbed_mode_add_tab (notes_index_url (), menu_logic_consultation_notes_text ()); - // Add the change notifications, if enabled. - if (webserver_request.database_config_user ()->getMenuChangesInBasicMode ()) { - json_array << menu_logic_tabbed_mode_add_tab (changes_changes_url (), menu_logic_changes_text ()); - } - // Add the preferences tab. - json_array << menu_logic_tabbed_mode_add_tab (personalize_index_url (), menu_logic_settings_text ()); - // JSON representation of the URLs. - json = json_array.json (); - } - } - - Database_Config_General::setMenuInTabbedViewJSON (json); -} - - -string menu_logic_verse_separator (string separator) -{ - if (separator == ".") { - return translate ("dot") + " ( . )"; - } - if (separator == ":") { - return translate ("colon") + " ( : )"; - } - return " ( " + separator + " ) "; -} diff --git a/menu/logic.h b/menu/logic.h deleted file mode 100644 index e11060212..000000000 --- a/menu/logic.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string menu_logic_href (std::string href); -std::string menu_logic_click (std::string item); - -std::string menu_logic_create_item (std::string href, std::string text, bool history, std::string title, std::string colour); - -std::string menu_logic_translate_menu (); -std::string menu_logic_search_menu (); -std::string menu_logic_tools_menu (); -std::string menu_logic_settings_menu (); -std::string menu_logic_settings_resources_menu (); - -std::string menu_logic_main_categories (Webserver_Request& webserver_request, std::string & tooltip); -std::string menu_logic_basic_categories (Webserver_Request& webserver_request); - -std::string menu_logic_workspace_category (Webserver_Request& webserver_request, std::string * tooltip = nullptr); -std::string menu_logic_translate_category (Webserver_Request& webserver_request, std::string * tooltip = nullptr); -std::string menu_logic_search_category (Webserver_Request& webserver_request, std::string * tooltip = nullptr); -std::string menu_logic_tools_category (Webserver_Request& webserver_request, std::string * tooltip = nullptr); -std::string menu_logic_settings_category (Webserver_Request& webserver_request, std::string * tooltip = nullptr); -std::string menu_logic_settings_resources_category (Webserver_Request& webserver_request); -std::string menu_logic_help_category (Webserver_Request& webserver_request); - -bool menu_logic_public_or_guest (Webserver_Request& webserver_request); - -std::string menu_logic_menu_text (std::string menu_item); -std::string menu_logic_menu_url (std::string menu_item); - -std::string menu_logic_translate_text (); -std::string menu_logic_search_text (); -std::string menu_logic_tools_text (); -std::string menu_logic_settings_text (); -std::string menu_logic_help_text (); -std::string menu_logic_public_feedback_text (); -std::string menu_logic_logout_text (); -std::string menu_logic_consultation_notes_text (); -std::string menu_logic_bible_manage_text (); -std::string menu_logic_workspace_organize_text (); -std::string menu_logic_checks_settings_text (); -std::string menu_logic_resources_text (); -std::string menu_logic_resource_images_text (); -std::string menu_logic_manage_users_text (); -std::string menu_logic_versification_index_text (); -std::string menu_logic_mapping_index_text (); -std::string menu_logic_styles_indext_text (); -std::string menu_logic_styles_indexm_text (); -std::string menu_logic_changes_text (); -std::string menu_logic_styles_text (); -std::string menu_logic_menu_text (); -std::string menu_logic_images_index_text (); - -std::string menu_logic_editor_settings_text (bool visual, int selection); -bool menu_logic_editor_enabled (Webserver_Request& webserver_request, bool visual, bool chapter); -std::string menu_logic_editor_menu_text (bool visual, bool chapter); - -bool menu_logic_can_do_tabbed_mode (); -void menu_logic_tabbed_mode_save_json (Webserver_Request& webserver_request); - -std::string menu_logic_verse_separator (std::string separator); diff --git a/microtar/microtar.c b/microtar/microtar.c deleted file mode 100644 index aadf0a6d7..000000000 --- a/microtar/microtar.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (c) 2017 rxi - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include - -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" - -#include "microtar.h" - -typedef struct { - char name[100]; - char mode[8]; - char owner[8]; - char group[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char type; - char linkname[100]; - char _padding[255]; -} mtar_raw_header_t; - - -static unsigned round_up(unsigned n, unsigned incr) { - return n + (incr - n % incr) % incr; -} - - -static unsigned checksum(const mtar_raw_header_t* rh) { - unsigned i; - unsigned char *p = (unsigned char*) rh; - unsigned res = 256; - for (i = 0; i < offsetof(mtar_raw_header_t, checksum); i++) { - res += p[i]; - } - for (i = offsetof(mtar_raw_header_t, type); i < sizeof(*rh); i++) { - res += p[i]; - } - return res; -} - - -static int tread(mtar_t *tar, void *data, unsigned size) { - int err = tar->read(tar, data, size); - tar->pos += size; - return err; -} - - -static int twrite(mtar_t *tar, const void *data, unsigned size) { - int err = tar->write(tar, data, size); - tar->pos += size; - return err; -} - - -static int write_null_bytes(mtar_t *tar, int n) { - int i, err; - char nul = '\0'; - for (i = 0; i < n; i++) { - err = twrite(tar, &nul, 1); - if (err) { - return err; - } - } - return MTAR_ESUCCESS; -} - - -static int raw_to_header(mtar_header_t *h, const mtar_raw_header_t *rh) { - unsigned chksum1, chksum2; - - /* If the checksum starts with a null byte we assume the record is NULL */ - if (*rh->checksum == '\0') { - return MTAR_ENULLRECORD; - } - - /* Build and compare checksum */ - chksum1 = checksum(rh); - sscanf(rh->checksum, "%o", &chksum2); - if (chksum1 != chksum2) { - return MTAR_EBADCHKSUM; - } - - /* Load raw header into header */ - sscanf(rh->mode, "%o", &h->mode); - sscanf(rh->owner, "%o", &h->owner); - sscanf(rh->size, "%o", &h->size); - sscanf(rh->mtime, "%o", &h->mtime); - h->type = rh->type; - strcpy(h->name, rh->name); - strcpy(h->linkname, rh->linkname); - - return MTAR_ESUCCESS; -} - - -static int header_to_raw(mtar_raw_header_t *rh, const mtar_header_t *h) { - unsigned chksum; - - /* Load header into raw header */ - memset(rh, 0, sizeof(*rh)); - sprintf(rh->mode, "%o", h->mode); - sprintf(rh->owner, "%o", h->owner); - sprintf(rh->size, "%o", h->size); - sprintf(rh->mtime, "%o", h->mtime); - rh->type = h->type ? h->type : MTAR_TREG; - strcpy(rh->name, h->name); - strcpy(rh->linkname, h->linkname); - - /* Calculate and write checksum */ - chksum = checksum(rh); - sprintf(rh->checksum, "%06o", chksum); - rh->checksum[7] = ' '; - - return MTAR_ESUCCESS; -} - - -const char* mtar_strerror(int err) { - switch (err) { - case MTAR_ESUCCESS : return "success"; - case MTAR_EFAILURE : return "failure"; - case MTAR_EOPENFAIL : return "could not open"; - case MTAR_EREADFAIL : return "could not read"; - case MTAR_EWRITEFAIL : return "could not write"; - case MTAR_ESEEKFAIL : return "could not seek"; - case MTAR_EBADCHKSUM : return "bad checksum"; - case MTAR_ENULLRECORD : return "null record"; - case MTAR_ENOTFOUND : return "file not found"; - } - return "unknown error"; -} - - -static int file_write(mtar_t *tar, const void *data, unsigned size) { - unsigned long res = fwrite(data, 1, size, tar->stream); - return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL; -} - -static int file_read(mtar_t *tar, void *data, unsigned size) { - unsigned long res = fread(data, 1, size, tar->stream); - return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL; -} - -static int file_seek(mtar_t *tar, unsigned offset) { - int res = fseek(tar->stream, offset, SEEK_SET); - return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL; -} - -static int file_close(mtar_t *tar) { - fclose(tar->stream); - return MTAR_ESUCCESS; -} - - -int mtar_open(mtar_t *tar, const char *filename, const char *mode) { - int err; - mtar_header_t h; - - /* Init tar struct and functions */ - memset(tar, 0, sizeof(*tar)); - tar->write = file_write; - tar->read = file_read; - tar->seek = file_seek; - tar->close = file_close; - - /* Assure mode is always binary */ - if ( strchr(mode, 'r') ) mode = "rb"; - if ( strchr(mode, 'w') ) mode = "wb"; - if ( strchr(mode, 'a') ) mode = "ab"; - /* Open file */ - tar->stream = fopen(filename, mode); - if (!tar->stream) { - return MTAR_EOPENFAIL; - } - /* Read first header to check it is valid if mode is `r` */ - if (*mode == 'r') { - err = mtar_read_header(tar, &h); - if (err != MTAR_ESUCCESS) { - mtar_close(tar); - return err; - } - } - - /* Return ok */ - return MTAR_ESUCCESS; -} - - -int mtar_close(mtar_t *tar) { - return tar->close(tar); -} - - -int mtar_seek(mtar_t *tar, unsigned pos) { - int err = tar->seek(tar, pos); - tar->pos = pos; - return err; -} - - -int mtar_rewind(mtar_t *tar) { - tar->remaining_data = 0; - tar->last_header = 0; - return mtar_seek(tar, 0); -} - - -int mtar_next(mtar_t *tar) { - int err, n; - mtar_header_t h; - /* Load header */ - err = mtar_read_header(tar, &h); - if (err) { - return err; - } - /* Seek to next record */ - n = round_up(h.size, 512) + sizeof(mtar_raw_header_t); - return mtar_seek(tar, tar->pos + n); -} - - -int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h) { - int err; - mtar_header_t header; - /* Start at beginning */ - err = mtar_rewind(tar); - if (err) { - return err; - } - /* Iterate all files until we hit an error or find the file */ - while ( (err = mtar_read_header(tar, &header)) == MTAR_ESUCCESS ) { - if ( !strcmp(header.name, name) ) { - if (h) { - *h = header; - } - return MTAR_ESUCCESS; - } - mtar_next(tar); - } - /* Return error */ - if (err == MTAR_ENULLRECORD) { - err = MTAR_ENOTFOUND; - } - return err; -} - - -int mtar_read_header(mtar_t *tar, mtar_header_t *h) { - int err; - mtar_raw_header_t rh; - /* Save header position */ - tar->last_header = tar->pos; - /* Read raw header */ - err = tread(tar, &rh, sizeof(rh)); - if (err) { - return err; - } - /* Seek back to start of header */ - err = mtar_seek(tar, tar->last_header); - if (err) { - return err; - } - /* Load raw header into header struct and return */ - return raw_to_header(h, &rh); -} - - -int mtar_read_data(mtar_t *tar, void *ptr, unsigned size) { - int err; - /* If we have no remaining data then this is the first read, we get the size, - * set the remaining data and seek to the beginning of the data */ - if (tar->remaining_data == 0) { - mtar_header_t h; - /* Read header */ - err = mtar_read_header(tar, &h); - if (err) { - return err; - } - /* Seek past header and init remaining data */ - err = mtar_seek(tar, tar->pos + sizeof(mtar_raw_header_t)); - if (err) { - return err; - } - tar->remaining_data = h.size; - } - /* Read data */ - err = tread(tar, ptr, size); - if (err) { - return err; - } - tar->remaining_data -= size; - /* If there is no remaining data we've finished reading and seek back to the - * header */ - if (tar->remaining_data == 0) { - return mtar_seek(tar, tar->last_header); - } - return MTAR_ESUCCESS; -} - - -int mtar_write_header(mtar_t *tar, const mtar_header_t *h) { - mtar_raw_header_t rh; - /* Build raw header and write */ - header_to_raw(&rh, h); - tar->remaining_data = h->size; - return twrite(tar, &rh, sizeof(rh)); -} - - -int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size) { - mtar_header_t h; - /* Build header */ - memset(&h, 0, sizeof(h)); - strcpy(h.name, name); - h.size = size; - h.type = MTAR_TREG; - h.mode = 0664; - /* Write header */ - return mtar_write_header(tar, &h); -} - - -int mtar_write_dir_header(mtar_t *tar, const char *name) { - mtar_header_t h; - /* Build header */ - memset(&h, 0, sizeof(h)); - strcpy(h.name, name); - h.type = MTAR_TDIR; - h.mode = 0775; - /* Write header */ - return mtar_write_header(tar, &h); -} - - -int mtar_write_data(mtar_t *tar, const void *data, unsigned size) { - int err; - /* Write data */ - err = twrite(tar, data, size); - if (err) { - return err; - } - tar->remaining_data -= size; - /* Write padding if we've written all the data for this file */ - if (tar->remaining_data == 0) { - return write_null_bytes(tar, round_up(tar->pos, 512) - tar->pos); - } - return MTAR_ESUCCESS; -} - - -int mtar_finalize(mtar_t *tar) { - /* Write two NULL records */ - return write_null_bytes(tar, sizeof(mtar_raw_header_t) * 2); -} diff --git a/microtar/microtar.h b/microtar/microtar.h deleted file mode 100644 index 89623b7f6..000000000 --- a/microtar/microtar.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2017 rxi - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef MICROTAR_H -#define MICROTAR_H - -#include -#include - -#define MTAR_VERSION "0.1.0" - -enum { - MTAR_ESUCCESS = 0, - MTAR_EFAILURE = -1, - MTAR_EOPENFAIL = -2, - MTAR_EREADFAIL = -3, - MTAR_EWRITEFAIL = -4, - MTAR_ESEEKFAIL = -5, - MTAR_EBADCHKSUM = -6, - MTAR_ENULLRECORD = -7, - MTAR_ENOTFOUND = -8 -}; - -enum { - MTAR_TREG = '0', - MTAR_TLNK = '1', - MTAR_TSYM = '2', - MTAR_TCHR = '3', - MTAR_TBLK = '4', - MTAR_TDIR = '5', - MTAR_TFIFO = '6' -}; - -typedef struct { - unsigned mode; - unsigned owner; - unsigned size; - unsigned mtime; - unsigned type; - char name[100]; - char linkname[100]; -} mtar_header_t; - - -typedef struct mtar_t mtar_t; - -struct mtar_t { - int (*read)(mtar_t *tar, void *data, unsigned size); - int (*write)(mtar_t *tar, const void *data, unsigned size); - int (*seek)(mtar_t *tar, unsigned pos); - int (*close)(mtar_t *tar); - void *stream; - unsigned pos; - unsigned remaining_data; - unsigned last_header; -}; - - -#ifdef __cplusplus -extern "C" { -#endif - -const char* mtar_strerror(int err); - -int mtar_open(mtar_t *tar, const char *filename, const char *mode); -int mtar_close(mtar_t *tar); - -int mtar_seek(mtar_t *tar, unsigned pos); -int mtar_rewind(mtar_t *tar); -int mtar_next(mtar_t *tar); -int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h); -int mtar_read_header(mtar_t *tar, mtar_header_t *h); -int mtar_read_data(mtar_t *tar, void *ptr, unsigned size); - -int mtar_write_header(mtar_t *tar, const mtar_header_t *h); -int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size); -int mtar_write_dir_header(mtar_t *tar, const char *name); -int mtar_write_data(mtar_t *tar, const void *data, unsigned size); -int mtar_finalize(mtar_t *tar); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/mimetic098/body.cxx b/mimetic098/body.cxx deleted file mode 100644 index 18805d98b..000000000 --- a/mimetic098/body.cxx +++ /dev/null @@ -1,166 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: body.cxx,v 1.3 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ - -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#include -#include -#include - -namespace mimetic -{ -using std::string; - -Body::Body() -: m_owner(0) -{ -} - -void Body::set(const std::string& text) -{ - this->assign(text); -} - -void Body::owner(MimeEntity* owner) -{ - m_owner = owner; -} - -MimeEntity* Body::owner() -{ - return m_owner; -} - -const MimeEntity* Body::owner() const -{ - return m_owner; -} - -bool Body::load(const string& fqn) -{ - File in(fqn); - if(!in) - return false; - this->clear(); - File::iterator beg = in.begin(), end = in.end(); - std::copy(beg, end, back_inserter(*this) ); - return true; -} - -MimeEntityList& Body::parts() -{ - return m_parts; -} - -const MimeEntityList& Body::parts() const -{ - return m_parts; -} - -void Body::preamble(const string& v) -{ - m_preamble = v; -} - -const string& Body::preamble() const -{ - return m_preamble; -} - -string& Body::preamble() -{ - return m_preamble; -} - -void Body::epilogue(const string& v) -{ - m_epilogue = v; -} - -const string& Body::epilogue() const -{ - return m_epilogue; -} - -string& Body::epilogue() -{ - return m_epilogue; -} - -} - diff --git a/mimetic098/body.h b/mimetic098/body.h deleted file mode 100644 index b3b5c0260..000000000 --- a/mimetic098/body.h +++ /dev/null @@ -1,141 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: body.h,v 1.16 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_BODY_H_ -#define _MIMETIC_BODY_H_ -#include -#include -#include -#include -#include -#include - - -namespace mimetic -{ - -/// MIME message body -class Body: public Rfc822Body -{ -public: - friend class MimeEntity; - Body(); - - /** - set body content - */ - void set(const std::string&); - - /** - load file as is, no encoding is performed - */ - bool load(const std::string&); - - /** - load file and code it using \p Codec - */ - template - bool load(const std::string&, const Codec&); - - /** - en/decode body content - */ - template - bool code(const Codec&); - - /** - set body \e preamble - - \sa RFC822 - */ - void preamble(const std::string&); - /** - get body \e preamble - - \sa RFC822 - */ - const std::string& preamble() const; - std::string& preamble(); - - /** - set body \e epilogue - - \sa RFC822 - */ - void epilogue(const std::string&); - /** - get body \e epilogue - - \sa RFC822 - */ - const std::string& epilogue() const; - std::string& epilogue(); - - /** - get body's parts list - */ - MimeEntityList& parts(); - const MimeEntityList& parts() const; - - /** - get body's MimeEntity owner - */ - MimeEntity* owner(); - const MimeEntity* owner() const; - -protected: - void owner(MimeEntity*); -protected: - MimeEntity* m_owner; - MimeEntityList m_parts; - std::string m_preamble, m_epilogue; -}; - -template -bool Body::load(const std::string& fqn, const Codec& cc) -{ - File in(fqn); - if(!in) - return false; - - File::iterator beg = in.begin(), end = in.end(); - Codec codec(cc); - - if(codec.codeSizeMultiplier() > 1.0) - { - /* increase body string size */ - struct stat st; - if(::stat(fqn.c_str(), &st)) - return false; - reserve((size_type)(::ceil(st.st_size * codec.codeSizeMultiplier()))); - } - - this->clear(); - mimetic::code(beg, end, codec, back_inserter(*this) ); - return true; -} - - -template -bool Body::code(const Codec& cc) -{ - // OPTIMIZE - std::string coded; - Codec codec(cc); - - if(codec.codeSizeMultiplier() > 1.0) - coded.reserve((size_type)::ceil(size() * codec.codeSizeMultiplier())); - - mimetic::code(begin(), end(), codec, back_inserter(coded) ); - this->assign(coded); - return true; -} - -} - -#endif diff --git a/mimetic098/circular_buffer.h b/mimetic098/circular_buffer.h deleted file mode 100644 index 2dfa9ff9e..000000000 --- a/mimetic098/circular_buffer.h +++ /dev/null @@ -1,141 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: circular_buffer.h,v 1.8 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CODEC_CIRCULAR_BUFFER_H_ -#define _MIMETIC_CODEC_CIRCULAR_BUFFER_H_ -#include -#include - -namespace mimetic -{ - -template -struct circular_buffer -{ - typedef circular_buffer self_type; - typedef T value_type; - typedef unsigned int size_type; - circular_buffer(unsigned int sz = 4) - : m_sz(sz), m_count(0), m_first(0), m_last(0) - { - m_pItem = new value_type[sz]; - } - ~circular_buffer() - { - delete[] m_pItem; - } - circular_buffer(const circular_buffer& r) - : m_sz(r.m_sz), m_count(r.m_count), - m_first(r.m_first) ,m_last(r.m_last) - { - m_pItem = new value_type[m_sz]; - for(size_type i =0; i < m_sz; i++) - m_pItem[i] = r.m_pItem[i]; - } - circular_buffer& operator=(const circular_buffer& r) - { - m_sz = r.m_sz; - m_count = r.m_count; - m_first = r.m_first; - m_last = r.m_last; - - if(m_pItem) - delete[] m_pItem; - m_pItem = new value_type[m_sz]; - for(size_type i =0; i < m_sz; i++) - m_pItem[i] = r.m_pItem[i]; - return *this; - } - inline void push_back(const value_type& c) - { - m_pItem[m_last] = c; - m_last = ++m_last % m_sz; - m_count += (m_count == m_sz ? 0 : 1); - } - inline void push_front(const value_type& c) - { - m_first = (--m_first + m_sz) % m_sz; - m_pItem[m_first] = c; - m_count += (m_count == m_sz ? 0 : 1); - } - inline void pop_front() - { - m_first = ++m_first % m_sz; - m_count--; - } - inline void pop_back() - { - m_last = (--m_last + m_sz) % m_sz; - m_count--; - } - inline const value_type& front() const - { - return m_pItem[m_first]; - } - inline const value_type& back() const - { - int last = (m_last -1 + m_sz) % m_sz; - return m_pItem[last]; - } - inline bool operator==(const std::string& r) const - { - if(m_count < r.length()) - return false; - const self_type& me = *this; - for(size_type i = 0; i < m_count; i++) - if(me[i] != r[i]) - return false; - return true; - } - inline bool operator!=(const std::string& r) const - { - return !operator==(r); - } - bool compare(size_type off, size_type n0, const std::string& r) const - { - const self_type& me = *this; - for(size_type i = 0; i < n0; i++) - if(me[off+i] != r[i]) - return false; - return true; - } - inline value_type& operator[](unsigned int i) const - { - unsigned int idx = (m_first + i) % m_sz; - return m_pItem[idx]; - } - inline bool empty() const - { - return m_count == 0; - } - std::string str() const - { - std::string result; - const self_type& me = *this; - for(size_type i = 0; i < m_count; i++) - result += me[i]; - return result; - } - inline size_type count() const - { - return m_count; - } - inline size_type max_size() const - { - return m_sz; - } -private: - size_type m_sz, m_count; - int m_first, m_last; - value_type* m_pItem; -}; - -} - -#endif - diff --git a/mimetic098/codec/base64.cxx b/mimetic098/codec/base64.cxx deleted file mode 100644 index 9f01d524a..000000000 --- a/mimetic098/codec/base64.cxx +++ /dev/null @@ -1,106 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: base64.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ - -#pragma GCC diagnostic ignored "-Wsign-conversion" - -#include - -using namespace mimetic; - -const char Base64::sEncTable[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/="; - -const char Base64::sDecTable[] = { - static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1), - static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1), - static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1), - static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1), - static_cast(-1),static_cast(-1),static_cast(-1),62,static_cast(-1),static_cast(-1),static_cast(-1),63,52,53, - 54,55,56,57,58,59,60,61,static_cast(-1),static_cast(-1), - static_cast(-1), eq_sign, static_cast(-1),static_cast(-1),static_cast(-1), 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9,10,11,12,13,14, - 15,16,17,18,19,20,21,22,23,24, - 25,static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),static_cast(-1),26,27,28, - 29,30,31,32,33,34,35,36,37,38, - 39,40,41,42,43,44,45,46,47,48, - 49,50,51,static_cast(-1) -}; - -const int Base64::sDecTableSz = sizeof(Base64::sDecTable) / sizeof(char); - diff --git a/mimetic098/codec/base64.h b/mimetic098/codec/base64.h deleted file mode 100644 index 279b5fc43..000000000 --- a/mimetic098/codec/base64.h +++ /dev/null @@ -1,246 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: base64.h,v 1.15 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CODEC_BASE64_H_ -#define _MIMETIC_CODEC_BASE64_H_ - -#include -#include -#include - -namespace mimetic -{ - - -class Base64 -{ - enum { LF = 0xA, CR = 0xD, NL = '\n' }; - enum { default_maxlen = 76 }; - enum { eq_sign = 100 }; - static const char sEncTable[]; - static const char sDecTable[]; - static const int sDecTableSz; -public: - class Encoder; class Decoder; - typedef Encoder encoder_type; - typedef Decoder decoder_type; - - -/// Base64 encoder -/*! - - \sa encode decode - */ -class Encoder: public buffered_codec, public chainable_codec -{ - enum { pad_idx = 64 }; - char_type m_ch[3]; - int m_cidx; - int m_pos, m_maxlen; - - template - inline void writeBuf(OutIt& out) - { - int pad_count = 3 - m_cidx; - m_cidx = 0; - int idx[4]; - idx[0] = m_ch[0] >> 2; - switch(pad_count) - { - case 0: - idx[1] = (((m_ch[0] & 3) << 4) | (m_ch[1] >> 4)); - idx[2] = ((m_ch[1] & 0xf) << 2) | (m_ch[2] >> 6); - idx[3] = m_ch[2] & 0x3f; - break; - case 1: - idx[1] = (((m_ch[0] & 3) << 4) | (m_ch[1] >> 4)); - idx[2] = (m_ch[1] & 0xf) << 2 ; - idx[3] = pad_idx; - break; - case 2: - idx[1] = (m_ch[0] & 3) << 4; - idx[2] = idx[3] = pad_idx; - break; - } - for(int i = 0; i < 4; ++i) - { - *out = sEncTable[ idx[i] ]; ++out; - if(m_maxlen && ++m_pos > m_maxlen) - { - *out = NL; ++out; - m_pos = 1; - } - } - } -public: - /*! return the multiplier of the required (max) size of the output buffer - * when encoding */ - double codeSizeMultiplier() const - { - return 1.5; - } - /*! Constructor, maxlen is the maximum length of every encoded line */ - Encoder(int maxlen = default_maxlen) - : m_cidx(0), m_pos(1), m_maxlen(maxlen) - { - } - /*! Returns the name of the codec ("Base64") */ - const char* name() const { return "Base64"; } - /*! - Encodes [\p bit,\p eit) and write any encoded char to \p out. - */ - template - void process(InIt bit, InIt eit, OutIt out) - { - for(; bit != eit; ++bit) - { - m_ch[m_cidx++] = (char_type)*bit; - if(m_cidx < 3) - continue; - writeBuf(out); - } - if(m_cidx > 0) - writeBuf(out); - } - /*! - Encodes \p c and write any encoded output char to \p out. - \warning You must call flush() when all chars have been - processed by the encode funcion. - \n - \code - while( (c = getchar()) != EOF ) - b64.encode(c, out); - b64.flush(); - \endcode - \n - \sa flush() - */ - template - void process(char_type c, OutIt& out) - { - m_ch[m_cidx++] = c; - if(m_cidx < 3) - return; - writeBuf(out); - } - /*! - Write to \p out any buffered encoded char. - */ - template - void flush(OutIt& out) - { - if(m_cidx > 0) - writeBuf(out); - } -}; - -/// Base64 decoder -/*! - - \sa encode decode - */ -class Decoder: public buffered_codec, public chainable_codec -{ - int m_cidx; - char_type m_ch[4]; - - template - inline void writeBuf(OutIt& out) - { - if(m_cidx < 4) - { // malformed, missing chars will be cosidered pad - switch(m_cidx) - { - case 0: - case 1: - return; // ignore; - case 2: - m_ch[2] = m_ch[3] = eq_sign; - break; - case 3: - m_ch[3] = eq_sign; - break; - } - } - m_cidx = 0; - *out = (m_ch[0] << 2 | ((m_ch[1] >> 4) & 0x3) ); ++out; - if(m_ch[2] == eq_sign) return; - *out = (m_ch[1] << 4 | ((m_ch[2] >> 2) & 0xF) ); ++out; - if(m_ch[3] == eq_sign) return; - *out = (m_ch[2] << 6 | m_ch[3]); ++out; - } -public: - /*! Constructor */ - Decoder() - : m_cidx(0) - { - } - /*! Returns the name of the codec ("Base64") */ - const char* name() const { return "Base64"; } - - /*! - Decodes [\p bit,\p eit) and write any decoded char to \p out. - */ - template - inline void process(InIt bit, InIt eit, OutIt out) - { - char_type c; - - for(; bit != eit; ++bit) - { - c = *bit; - if(c > sDecTableSz || sDecTable[c] == -1) - continue; // malformed or newline - m_ch[m_cidx++] = sDecTable[c]; - if(m_cidx < 4) - continue; - writeBuf(out); - } - if(m_cidx > 0) - writeBuf(out); - } - /*! - Decodes \p c and write any decoded output char to \p out. - - \warning You must call flush() when all chars have been - processed by the decode funcion. - \n - \code - while( (c = getchar()) != EOF ) - b64.decode(c, out); - b64.flush(); - \endcode - \n - \sa flush() - */ - template - void process(char_type c, OutIt& out) - { - if(c > sDecTableSz || sDecTable[c] == -1) - return; // malformed or newline - m_ch[m_cidx++] = sDecTable[c]; - if(m_cidx < 4) - return; - writeBuf(out); - } - /*! - Write to \p out any buffered decoded char. - */ - template - void flush(OutIt& out) - { - if(m_cidx > 0) - writeBuf(out); - } -}; - -}; // Base64 - -} -#endif - diff --git a/mimetic098/codec/code.h b/mimetic098/codec/code.h deleted file mode 100644 index 54638c8fb..000000000 --- a/mimetic098/codec/code.h +++ /dev/null @@ -1,120 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: code.h,v 1.5 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CODEC_CODE_H_ -#define _MIMETIC_CODEC_CODE_H_ -#include -#include -#include -#include - -namespace mimetic -{ - - - -template -void code(InIt beg, InIt end, Codec& cc, OutIt out) -{ - typedef typename Codec::codec_type codec_type; - code(beg, end, cc, out, codec_type()); -} - -// code func for buffered codecs -template -void code(InIt beg, InIt end, Codec& cc, OutIt out,const buffered_codec_type_tag&) -{ - for(; beg != end; ++beg) - cc.process(*beg, out); - cc.flush(out); -} - -// code func for unbuffered codecs -template -void code(InIt beg, InIt end,Codec& codec,OutIt out,const unbuffered_codec_type_tag&) -{ - for(; beg != end; ++beg) - codec.process(*beg, out); -} - -// code func for chained codecs -template -void code(InIt beg, InIt end, const codec_chain& cc, OutIt out) -{ - typedef codec_chain Node1; - typedef codec_chain< oiterator_wrapper > - TailNode; - typedef typename push_back_node::node_type - codec_chain_type; - - oiterator_wrapper oiw(out); - codec_chain_type chain = build_push_back_node(cc,TailNode(oiw)); - - for(; beg != end; ++beg) - chain.process(*beg); - chain.flush(); -} - -/// Encodes (beg, end] using \p cc codec -/*! - Encodes (beg, end] using \p cc codec and write any - output characters to the output iterator \p out. - - \p cc can be a simple codec: - \code - Base64::Encoder b64; - code(beg, end, b64, out); - \endcode - or a chain of codecs: - \code - Base64::Encoder b64; - ToUpperCase tuc; - code(beg, end, tuc | b64, out); - \endcode - */ -template -void encode(InIt beg, InIt end, Codec& cc, OutIt out) -{ - code(beg, end, cc, out); -} - -/// decodes (beg, end] using \e cc codec and write any -/*! - decodes (beg, end] using \e cc codec and write any - output characters to the output iterator \e out - */ -template -void decode(InIt beg, InIt end, Codec& cc, OutIt out) -{ - code(beg, end, cc, out); -} - - -template -void encode(InIt beg, InIt end, const codec_chain& cc, OutIt out) -{ - code(beg,end,cc,out); -} - -template -void decode(InIt beg, InIt end, const codec_chain& cc, OutIt out) -{ - code(beg,end,cc,out); -} - -} - - - -#endif - - - - - - diff --git a/mimetic098/codec/codec.h b/mimetic098/codec/codec.h deleted file mode 100644 index 97ee71415..000000000 --- a/mimetic098/codec/codec.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: codec.h,v 1.7 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CODEC_CODEC_H_ -#define _MIMETIC_CODEC_CODEC_H_ -#include -#include -#include -#include -#include -#include -#endif diff --git a/mimetic098/codec/codec_base.h b/mimetic098/codec/codec_base.h deleted file mode 100644 index f4b3bb584..000000000 --- a/mimetic098/codec/codec_base.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: codec_base.h,v 1.13 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CODEC_CODECBASE_H_ -#define _MIMETIC_CODEC_CODECBASE_H_ -namespace mimetic -{ - - -struct buffered_codec_type_tag -{ -}; - -struct unbuffered_codec_type_tag -{ -}; - - -/// Codecs base class -struct codec -{ - typedef unsigned char char_type; - virtual ~codec() {} - virtual const char* name() const = 0; - - /*! return the multiplier of the required (max) size of the output buffer - * when encoding */ - virtual double codeSizeMultiplier() const { return 1.0; } -}; - - - -/// Base class for unbuffered codecs -struct unbuffered_codec: public codec -{ - typedef unbuffered_codec_type_tag codec_type; - template - void flush(OutIt&) - { - } -}; - -/// Base class for buffered codecs -struct buffered_codec: public codec -{ - typedef buffered_codec_type_tag codec_type; -}; - - -} - -#endif - diff --git a/mimetic098/codec/codec_chain.h b/mimetic098/codec/codec_chain.h deleted file mode 100644 index 43bd1b82c..000000000 --- a/mimetic098/codec/codec_chain.h +++ /dev/null @@ -1,432 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: codec_chain.h,v 1.13 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CODEC_CODEC_CHAIN_ -#define _MIMETIC_CODEC_CODEC_CHAIN_ -#include -#include -#include - - -namespace mimetic -{ - -struct null_node; - -template -struct codec_chain; - - -/* - * push_back_node - */ -template -struct push_back_node -{ - typedef - codec_chain< - typename Node::content_type, - typename - push_back_node< - typename Node::next_node_type, - LastNode - >::node_type - > node_type; -}; - -template -struct push_back_node -{ - typedef LastNode node_type; -}; - - -/* - * returns item[idx] of the Node passed to the ctor - */ -template -struct item -{ - typedef typename Node::next_node_type next_node_type; - typedef typename item::node_type node_type; - item(const Node& node) - : m_node(node) - {} - const node_type& node() const - { - return item(m_node.m_next).node(); - } - const typename node_type::content_type& content() const - { - return node().m_c; - } - -private: - const Node& m_node; -}; - -template -struct item -{ - typedef Node node_type; - item(const Node& node) - :m_node(node) - {} - const node_type& node() const - { - return m_node; - } - const typename node_type::content_type& content() const - { - return m_node.m_c; - } -private: - const Node& m_node; -}; - - -/* - * build push_back_node -struct build_push_back_node -{ - typedef typename item::node_type nth_node_type; - typedef typename nth_node_type::content_type nth_content_type; - typedef codec_chain - next_tail_node_type; - typedef typename - build_push_back_node::result_node_type - result_node_type; - /* - result_node_type is equal to push_back_node::node_type - */ - build_push_back_node(const Node& initn, const TailNode& tailn) - : m_initn(initn), m_tailn(tailn) - { - } - operator const result_node_type() const - { - return get(); - } - const result_node_type get() const - { - const nth_content_type& nth_c=item(m_initn).content(); - next_tail_node_type next_tail(nth_c, m_tailn); - return build_push_back_node(m_initn,next_tail).get(); - } -private: - const Node& m_initn; - const TailNode& m_tailn; -}; - - -template -struct build_push_back_node -{ - typedef typename item::node_type nth_node_type; - typedef typename nth_node_type::content_type nth_content_type; - typedef codec_chain next_tail_node_type; - typedef next_tail_node_type result_node_type; - - build_push_back_node(const Node& initn, const TailNode& tailn) - : m_initn(initn), m_tailn(tailn) - { - } - operator const result_node_type() const - { - return get(); - } - const result_node_type get() const - { - const nth_content_type& nth_c=item(m_initn).content(); - next_tail_node_type next_tail(nth_c, m_tailn); - return next_tail; - } -private: - const Node& m_initn; - const TailNode& m_tailn; -}; - -/// Defines a chain of codecs -/*! - Chain of codecs. Don't use it directly use | operator instead. - - \code - // converts test string to upper case, replaces LF chars with - // CRLF and encodes it using quoted-printable codec - ToUpperCase tuc; - Lf2CrLf l2c; - QP::Encoder qp; - char buf[MAXLEN]; - - string test("....some text here...."); - code(test.begin(), test.end(), tuc | l2c | qp, buf); - \endcode - - \warning Chainable codecs must derive from chainable_codec<> - \sa encode decode - */ - - -template -struct codec_chain -{ - typedef codec_chain self_type; - typedef C content_type; - typedef N next_node_type; - enum { count = 1 + next_node_type::count }; - codec_chain() - { - setName(); - } - codec_chain(const content_type& c) - : m_c(c) - { - setName(); - } - codec_chain(const content_type& c, const next_node_type& node) - : m_c(c), m_next(node) - { - setName(); - } - codec_chain(const codec_chain& node) - : m_c(node.m_c), m_next(node.m_next) - { - setName(); - } - codec_chain(const null_node&) - { - setName(); - } - const char* name() const - { - return m_name.c_str(); - } - void process(char c) - { - m_c.process(c, m_next); - } - void flush() - { - m_c.flush(m_next); - m_next.flush(); - } - template - const Cn& get_c(int idx) const - { - return get_c(--idx); - } - const content_type& get_c(int idx) const - { - if(idx == 0) - return m_c; - else - return get_c(--idx); - } - template - const C1& operator[](int idx) const - { - if(idx == 0) - return m_c; - else - return m_next[--idx]; - } - self_type& operator*() - { return *this; } - self_type& operator=(char c) - { - m_c.process(c, m_next); - return *this; - } - self_type& operator++() - { return *this; } - self_type& operator++(int) - { return *this; } - template - typename - push_back_node >::node_type - operator|(const TailC& l) - { - typedef codec_chain tail_node; - tail_node tail = l; - build_push_back_node bpbn(*this,tail); - return bpbn.get(); - } - //protected: - content_type m_c; - next_node_type m_next; - std::string m_name; -private: - void setName() - { - m_name = std::string() + m_c.name() + "|" + m_next.name(); - } -}; - - -struct null_node -{ - enum { idx = 1 }; - enum { count = 0 }; - struct null_content - {}; - typedef null_node self_type; - typedef null_content content_type; - null_node() - { - } - template - null_node(const codec_chain& node) - { - (void) node; - } - const char* name() const - { - return "null_node"; - } - self_type& operator*() - { - return *this; - } - self_type& operator=(char c) - { - (void) c; - return *this; - } - self_type& operator++() - { - return *this; - } - self_type& operator++(int) - { - return *this; - } - void flush() - { - } - null_content m_c; -}; - - -/* - * helper classes useful to build codec chains - * i.e. node_traits::node_type - * i.e. node_traits::node_type - */ -template -struct node_traits -{ -}; - -// class specializations... - -template -struct node_traits -{ - typedef codec_chain > > > > > node_type; -}; - -template -struct node_traits -{ - typedef codec_chain > > > > node_type; -}; - -template -struct node_traits -{ - typedef codec_chain > > > node_type; -}; - -template -struct node_traits -{ - typedef codec_chain > > node_type; -}; - - -template -struct node_traits -{ - typedef codec_chain > node_type; -}; - -template -struct node_traits -{ - typedef codec_chain node_type; -}; - - -/* - * must be the base of all chainable codecs - */ -template -struct chainable_codec -{ - template - typename node_traits::node_type - operator|(const B& b) - { - typedef codec_chain node_b; - const A& a = static_cast(*this); - return typename node_traits::node_type(a, node_b(b)); - } -}; - - -/* - * operator|-creates temporary nodes to initialize chain contents - */ - - -#if 0 -template -typename node_traits::node_type -operator|(const A& a, const B& b) -{ - - typedef codec_chain node_b; - return typename node_traits::node_type(a, node_b(b)); -} - -template -typename -push_back_node, codec_chain >::node_type -operator|(const codec_chain& node, const Last& l) -{ - typedef codec_chain InitNode; - typedef codec_chain TailNode; - TailNode tailnode = l; - build_push_back_node bpbn(node,tailnode); - - return bpbn.get(); -} - -#endif -} // namespace mimetic - -#endif - diff --git a/mimetic098/codec/other_codecs.h b/mimetic098/codec/other_codecs.h deleted file mode 100644 index 1a5502c0b..000000000 --- a/mimetic098/codec/other_codecs.h +++ /dev/null @@ -1,171 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: other_codecs.h,v 1.13 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CODEC_OTHER_CODECS_H_ -#define _MIMETIC_CODEC_OTHER_CODECS_H_ -#include - -namespace mimetic -{ - -/// Pass through codec. Copies input to output -/*! - - \sa encode decode - */ -struct NullCodec: public unbuffered_codec, public chainable_codec -{ - template - void process(char c, OutIt& out) - { - *out = c; ++out; - } - const char* name() const - { - return "NullCodec"; - } -}; - -/// Converts input chars to upper case -/*! - - \sa encode decode - */ -struct ToUpperCase: public unbuffered_codec, public chainable_codec -{ - template - void process(char c, OutIt& out) - { - enum { offset = 'A' - 'a' }; - if(c >= 'a' && c <= 'z') - c += offset; - *out = c; - ++out; - } - const char* name() const - { - return "ToUpperCase"; - } -}; - -/// Converts input chars to lower case -/*! - - \sa encode decode - */ -struct ToLowerCase: public unbuffered_codec, public chainable_codec -{ - template - void process(char c, OutIt& out) - { - enum { offset = 'a' - 'A' }; - if(c >= 'A' && c <= 'Z') - c += offset; - *out = c; - ++out; - } - const char* name() const - { - return "ToLowerCase"; - } -}; - - -/// Converts any LF (\\n) to CRLF (\\r\\n) -/*! - - \sa encode decode - */ -struct Lf2CrLf: public unbuffered_codec, public chainable_codec -{ - template - void process(char c, OutIt& out) - { - enum { LF = 0xA, CR = 0xD }; - if(c == LF) - { - *out = CR; - ++out; - *out = LF; - ++out; - } else { - *out = c; - ++out; - } - } - const char* name() const - { - return "Lf2CrLf"; - } -}; - -/// Inserts a new line if the input line is too long -/*! - - \sa encode decode - */ -struct MaxLineLen: public unbuffered_codec, public chainable_codec -{ - MaxLineLen() - : m_max(0), m_written(0) - { - } - MaxLineLen(uint m) - : m_max(m), m_written(0) - { - } - template - void process(char c, OutIt& out) - { - enum { cr = 0xD, lf = 0xA }; - if(m_max && m_written++ == m_max) - { - *out = cr; ++out; - *out = lf; ++out; - m_written = 1; - } - *out = c; - ++out; - } - const char* name() const - { - return "MaxLineLen"; - } -private: - unsigned int m_max, m_written; -}; - -// internal -template -struct oiterator_wrapper: - public unbuffered_codec, - public chainable_codec > -{ - oiterator_wrapper(): m_pOut(0) - { - } - oiterator_wrapper(OutIt& out): m_pOut(&out) - { - } - template - void process(char c, OutIt2& out) - { - **m_pOut = c; ++(*m_pOut); - *out = c; ++out; - } - const char* name() const - { - return "oiterator_wrapper"; - } -private: - OutIt* m_pOut; -}; - - -} -#endif diff --git a/mimetic098/codec/qp.cxx b/mimetic098/codec/qp.cxx deleted file mode 100644 index 00e360762..000000000 --- a/mimetic098/codec/qp.cxx +++ /dev/null @@ -1,129 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: qp.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include - -using namespace mimetic; - - -char QP::sTb[] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, - 3, 4, 4, 3, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - -// %, &, ', - 4, 4, 2, 5, 5, 5, 5, 0, 0, 0, - -// (, ), *, +, ,, -, ., /, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -// 2, 3, 4, 5, 6, 7, 8, 9, :, ;, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -// <, >, ?, A, B, C, D, E, - 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, - -// F, G, H, I, J, K, L, M, N, O, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -// P, Q, R, S, T, U, V, W, X, Y, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -// Z, _, a, b, c, - 0, 5, 5, 5, 5, 0, 5, 0, 0, 0, - -// d, e, f, g, h, i, j, k, l, m, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -// n, o, p, q, r, s, t, u, v, w, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -// x, y, z, - 0, 0, 0, 5, 5, 5, 5, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, -}; - diff --git a/mimetic098/codec/qp.h b/mimetic098/codec/qp.h deleted file mode 100644 index ee7cb4671..000000000 --- a/mimetic098/codec/qp.h +++ /dev/null @@ -1,499 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: qp.h,v 1.20 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CODEC_QP_H_ -#define _MIMETIC_CODEC_QP_H_ -#include -#include -#include -#include - -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wshorten-64-to-32" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" - - - -#include -#include -#include -#include -#include - -namespace mimetic -{ - -class QP -{ - friend class test_qp; - enum { LF = 0xA, CR = 0xD, NL = LF, TAB = 9, SP = 32 }; - enum { default_maxlen = 76 }; - enum { - printable, /* print as-is */ - tab, /* print if !isBinary */ - sp, /* ' ' */ - newline, /* cr or lf; encode if isBinary*/ - binary, /* rest of the ascii map */ - unsafe /* "!\"#$@[]\\^`{}|~" */ - }; - static char sTb[256]; - -public: - -/// quoted-printable encoder -/*! - - \sa encode decode - */ -class Encoder: public buffered_codec, public chainable_codec -{ - enum { laBufSz = 5 }; // look-ahead buffer - size_t m_pos, m_maxlen; - bool m_binary; - circular_buffer m_cbuf; - - template - void hardLineBrk(OutIt& out) - { - *out = NL; ++out; - m_pos = 1; - } - template - void softLineBrk(OutIt& out) - { - *out = '='; ++out; - hardLineBrk(out); - } - template - void write(char_type ch, OutIt& out) - { - bool is_last_ch = m_cbuf.empty(); - if(!is_last_ch && m_pos == m_maxlen) - softLineBrk(out); - *out = ch; ++out; - m_pos++; - } - template - void writeHex(char_type ch, OutIt& out) - { - static char_type hexc[] = - { - '0', '1', '2', '3', '4', '5' ,'6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F' - }; - bool is_last_ch = m_cbuf.empty(); - if(m_pos + (is_last_ch ? 1 : 2) >= m_maxlen) - softLineBrk(out); - // write out =HH - *out = '='; ++out; - *out = hexc[ch >> 4]; ++out; - *out = hexc[ch & 0xf]; ++out; - m_pos += 3; - } - template - void encodeChar(char_type c, OutIt& out) - { - int cnt = m_cbuf.count(); - switch(sTb[c]) - { - case printable: - if(m_pos == 1) - { - switch(c) - { - case 'F': // hex enc on "^From .*" - if(cnt>=4 && m_cbuf.compare(0,4,"rom ")) - { - writeHex(c,out); - return; - } - break; - case '.': // hex encode if "^.[\r\n]" or on eof - if(!cnt || sTb[ m_cbuf[0] ] == newline) - { - writeHex(c,out); - return; - } - break; - } - } - write(c,out); - break; - case tab: - case sp: - // on binary encoding, or last input ch or newline - if(m_binary || !cnt || sTb[ m_cbuf[0] ] == newline) - writeHex(c,out); - else - write(c,out); - break; - case newline: - if(m_binary) - writeHex(c, out); - else { - if(cnt && m_cbuf[0] == (c == CR ? LF : CR)) - m_cbuf.pop_front(); // eat it - hardLineBrk(out); - } - break; - case binary: - if(!m_binary) m_binary = 1; // switch to binary mode - writeHex(c, out); - break; - case unsafe: - writeHex(c, out); - break; - } - } -public: - /*! return the multiplier of the required (max) size of the output buffer - * when encoding */ - double codeSizeMultiplier() const - { - // worse case is *3 but we'll use the (euristic) average value of 1.5. - // this may decrease performance when encoding messages with many - // non-ASCII (> 127) characters - return 1.5; - } - /*! - Constructor - \param isBinary if true all space and newline characters will be - treated like binary chars and will be hex encoded (useful if you - want to encode a binary file). - */ - Encoder(bool isBinary = false) - : m_pos(1), m_maxlen(default_maxlen), - m_binary(isBinary), m_cbuf(laBufSz) - { - } - /*! Returns the name of the codec ("Quoted-Printable") */ - const char* name() const { return "Quoted-Printable"; } - /*! Returns the max line length */ - size_t maxlen() - { - return m_maxlen; - } - /*! - Set the max line length. No more then \p i chars will be - printed on one line. - */ - void maxlen(size_t i) - { - m_maxlen = i; - } - /*! - Encodes [\p bit,\p eit) and write any encoded char to \p out. - */ - template - void process(InIt bit, InIt eit, OutIt out) - { - for(; bit != eit; ++bit) - process(*bit, out); - flush(out); - } - /*! - Encodes \p ic and write any encoded output char to \p out. - \warning You must call flush() when all chars have been - processed by the encode funcion. - \n - \code - while( (c = getchar()) != EOF ) - qp.process(c, out); - qp.flush(); - \endcode - \n - \sa flush() - */ - template - void process(char_type ic, OutIt& out) - { - m_cbuf.push_back(ic); - if(m_cbuf.count() < laBufSz) - return; - char_type c = m_cbuf.front(); - m_cbuf.pop_front(); - encodeChar(c, out); - } - /*! - Write to \p out any buffered encoded char. - */ - template - void flush(OutIt& out) - { - char_type c; - while(!m_cbuf.empty()) - { - c = m_cbuf.front(); - m_cbuf.pop_front(); - encodeChar(c, out); - } - } -}; - -/// quoted-printable decoder -/*! - - \sa encode decode - */ -class Decoder: public buffered_codec, public chainable_codec -{ - enum { laBufSz = 80 }; // look-ahead buffer - enum { - sWaitingChar, - sAfterEq, - sWaitingFirstHex, - sWaitingSecondHex, - sBlank, - sNewline, - sOtherChar - }; - //size_t m_pos; - size_t m_maxlen; - - int m_state, m_nl; - std::string m_prev; - - template - void hardLineBrk(OutIt& out) const - { - *out = NL; ++out; - } - template - void write(char_type ch, OutIt& out) const - { - *out = ch; ++out; - } - bool isnl(char_type c) const - { - return (c == CR || c == LF); - } - template - void flushPrev(OutIt& out) - { - copy(m_prev.begin(), m_prev.end(), out); - m_prev.clear(); - } - int hex_to_int(char_type c) const - { - if( c >= '0' && c <='9') return c - '0'; - else if( c >= 'A' && c <='F') return c - 'A' + 10; - else if( c >= 'a' && c <='f') return c - 'a' + 10; - else return 0; - } - bool ishex(char_type c) const - { - return (c >= '0' && c <= '9') || - (c >= 'A' && c <= 'F') || - (c >= 'a' && c <= 'f'); - } - template - void decodeChar(char_type c, OutIt& out) - { - for(;;) - { - switch(m_state) - { - case sBlank: - if(isblank(c)) - m_prev.append(1,c); - else if(isnl(c)) { - // soft linebrk & ignore trailing blanks - m_prev.clear(); - m_state = sWaitingChar; - } else { - flushPrev(out); - m_state = sWaitingChar; - continue; - } - return; - case sAfterEq: - if(isblank(c)) - m_prev.append(1,c); - else if(isnl(c)) { - // soft linebrk - m_state = sNewline; - continue; - } else { - if(m_prev.length() > 1) - { - // there're blanks after = - flushPrev(out); - m_state = sWaitingChar; - } else - m_state = sWaitingFirstHex; - continue; - } - return; - case sWaitingFirstHex: - if(!ishex(c)) - { - // malformed: =[not-hexch] - flushPrev(out); - write(c, out); - m_state = sWaitingChar; - return; - } else { - m_prev.append(1,c); - m_state = sWaitingSecondHex; - } - return; - case sWaitingSecondHex: - if(!ishex(c)) - { // malformed (=[hexch][not-hexch]) - flushPrev(out); - write(c, out); - } else { - char_type oc, last; - assert(m_prev.length()); - last = m_prev[m_prev.length()-1]; - oc = hex_to_int(last) << 4 | - hex_to_int(c) ; - write(oc,out); - m_prev.clear(); - } - m_state = sWaitingChar; - return; - case sNewline: - if(m_nl == 0) - { - m_nl = c; - return; - } else { - int len = (int)m_prev.length(); - if(!len || m_prev[0] != '=') - hardLineBrk(out); - m_prev.clear(); - m_state = sWaitingChar; - bool is2Ch; - is2Ch = (c == (m_nl == CR ? LF : CR)); - m_nl = 0; - if(is2Ch) - return; - continue; - } - case sWaitingChar: - if(isblank(c)) - { - m_state = sBlank; - continue; - } else if(isnl(c)) { - m_state = sNewline; - continue; - } else if(c == '=') { - m_state = sAfterEq; - m_prev.append(1, c); - return; - } else { - // WARNING: NOT ignoring chars > 126 - // as suggested in rfc2045 6.7 note 4 - if(c < 32 && c != TAB) - { - // malformed, CTRL ch found - // ignore (rfc2045 6.7 note 4) - return; - } - write(c,out); - } - return; - } - } - } -public: - /*! Constructor */ - Decoder() - : m_state(sWaitingChar), m_nl(0) - { - } - /*! Returns the name of the codec ("Quoted-Printable") */ - const char* name() const { return "Quoted-Printable"; } - /*! Returns the max line length */ - size_t maxlen() - { - return m_maxlen; - } - /*! - Set the max line length. No more then \p i chars will be - printed on one line. - */ - void maxlen(size_t i) - { - m_maxlen = i; - } - /*! - Decodes [\p bit,\p eit) and write any decoded char to \p out. - */ - template - void process(InIt bit, InIt eit, OutIt out) - { - for(;bit != eit; ++bit) - decodeChar(*bit, out); - flush(out); - } - /*! - Decodes \p ic and write any decoded output char to \p out. - - \warning You must call flush() when all chars have been - processed by the code(...) funcion. - \n - \code - while( (c = getchar()) != EOF ) - qp.process(c, out); - qp.flush(); - \endcode - \n - \sa flush() - */ - template - void process(char_type ic, OutIt& out) - { - decodeChar(ic, out); - } - /*! - Write to \p out any buffered decoded char. - */ - template - void flush(OutIt& out) - { - /* m_prev can be (regex): - empty: - ok - '=' : - malformed, '=' is last stream char, print as is - (rfc2045 6.7 note 3) - '=[a-zA-Z]' - malformed, print as is - (rfc2045 6.7 note 2) - '= +' - malformed, just print '=' and ignore trailing - blanks (rfc2045 6.7 (3) ) - */ - int len = (int)m_prev.length(); - if(len) - { - if(len == 1) - { - /* malformed if m_prev[0] == '=' */ - write('=', out); - } else { - write('=', out); - if(m_prev[1] != ' ') - write(m_prev[1], out); - } - } else if(m_nl != 0) // stream ends with newline - hardLineBrk(out); - - } -}; - -}; - - -} // namespace - -#endif - diff --git a/mimetic098/config_win32.h b/mimetic098/config_win32.h deleted file mode 100644 index 6e6dcda6b..000000000 --- a/mimetic098/config_win32.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma GCC system_header - -/* mimetic/config_win32.h */ - -#undef HAVE_DIRENT_H -#undef HAVE_GETPAGESIZE -#undef HAVE_MMAP -#undef HAVE_UNISTD_H -#undef HAVE_SYS_TIME_H - -#undef STDC_HEADERS -#undef HAVE_SYS_STAT_H -#undef HAVE_SYS_TYPES_H - -#define STDC_HEADERS 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TYPES_H 1 - -#define PACKAGE "mimetic" -#define VERSION "0.9.8" - - -typedef __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; - diff --git a/mimetic098/contentdescription.cxx b/mimetic098/contentdescription.cxx deleted file mode 100644 index 92a213e67..000000000 --- a/mimetic098/contentdescription.cxx +++ /dev/null @@ -1,116 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contentdescription.cxx,v 1.3 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#include - -namespace mimetic -{ -using namespace std; - -const char ContentDescription::label[] = "Content-Description"; - -ContentDescription::ContentDescription() -{ -} - -ContentDescription::ContentDescription(const char* cstr) -{ - set(cstr); -} - -ContentDescription::ContentDescription(const string& val) -{ - set(val); -} - - -void ContentDescription::set(const string& val) -{ - m_value = val; -} - -string ContentDescription::str() const -{ - return m_value; -} - - -FieldValue* ContentDescription::clone() const -{ - return new ContentDescription(*this); -} - -} diff --git a/mimetic098/contentdescription.h b/mimetic098/contentdescription.h deleted file mode 100644 index 4bc48ae48..000000000 --- a/mimetic098/contentdescription.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contentdescription.h,v 1.12 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CONTENT_DESCRIPTION_H_ -#define _MIMETIC_CONTENT_DESCRIPTION_H_ -#include -#include - -namespace mimetic -{ - -/// Content-Description field value -struct ContentDescription: public FieldValue -{ - static const char label[]; - ContentDescription(); - ContentDescription(const char*); - ContentDescription(const std::string&); - void set(const std::string&); - std::string str() const; -protected: - FieldValue* clone() const; -private: - std::string m_value; -}; - -} - -#endif - diff --git a/mimetic098/contentdisposition.cxx b/mimetic098/contentdisposition.cxx deleted file mode 100644 index 4747e7876..000000000 --- a/mimetic098/contentdisposition.cxx +++ /dev/null @@ -1,198 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contentdisposition.cxx,v 1.4 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#include -#include -#include - -namespace mimetic -{ -using namespace std; - -const char ContentDisposition::label[] = "Content-Disposition"; - -ContentDisposition::ContentDisposition() -{ -} - - -ContentDisposition::ContentDisposition(const char* cstr) -{ - set(cstr); -} - -ContentDisposition::ContentDisposition(const string& val) -{ - set(val); -} - -void ContentDisposition::type(const string& stype) -{ - m_type.assign(stype); -} - -const istring& ContentDisposition::type() const -{ - return m_type; -} - -const ContentDisposition::ParamList& ContentDisposition::paramList() const -{ - return m_paramList; -} - -ContentDisposition::ParamList& ContentDisposition::paramList() -{ - return m_paramList; -} - -const string& ContentDisposition::param(const string& field) const -{ - ParamList::const_iterator bit = m_paramList.begin(), eit = m_paramList.end(); - for(; bit != eit; ++bit) - { - if(bit->name() == field) - return bit->value(); - } - return nullstring; -} - -void ContentDisposition::param(const std::string& name, const std::string& val) -{ - ParamList::iterator bit = m_paramList.begin(), eit = m_paramList.end(); - for(; bit != eit; ++bit) - { - if(bit->name() == name) - { - bit->value(val); - return; - } - } - m_paramList.push_back(Param(name, val)); -} - -void ContentDisposition::set(const string& val) -{ - string type; - StringTokenizer stok(&val, ";"); - if(!stok.next(type)) - return; - m_type.assign(type); - - string sparam; - while(stok.next(sparam)) - { - Param p(sparam); - m_paramList.push_back(p); - } -} - -string ContentDisposition::str() const -{ - string ostr = m_type; - ParamList::const_iterator bit, eit; - bit = m_paramList.begin(); - eit = m_paramList.end(); - for(; bit != eit; ++bit) - ostr += "; " + bit->name() + "=\"" - + bit->value() + "\""; - return ostr; -} - -ostream& ContentDisposition::write(ostream& os, int fold) const -{ - os << "Content-Disposition: " << m_type; - ParamList::const_iterator bit, eit; - bit = m_paramList.begin(); - eit = m_paramList.end(); - for(; bit != eit; ++bit) - if(fold) - os << ";" << crlf << "\t" << bit->name() - << "=\"" << bit->value() << "\""; - else - os << "; " << bit->name() << "=\"" - << bit->value() << "\""; - - os << crlf; - return os; -} - - -FieldValue* ContentDisposition::clone() const -{ - return new ContentDisposition(*this); -} - -} diff --git a/mimetic098/contentdisposition.h b/mimetic098/contentdisposition.h deleted file mode 100644 index 74563d965..000000000 --- a/mimetic098/contentdisposition.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contentdisposition.h,v 1.12 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CONTENT_DISPOSITION_H_ -#define _MIMETIC_CONTENT_DISPOSITION_H_ -#include -#include -#include -#include - -namespace mimetic -{ - - - -/// Content-Disposition field value -struct ContentDisposition: public FieldValue -{ - typedef FieldParam Param; - typedef FieldParamList ParamList; -public: - static const char label[]; - ContentDisposition(); - ContentDisposition(const char*); - ContentDisposition(const std::string&); - - void type(const std::string&); - const istring& type() const; - - const ParamList& paramList() const; - ParamList& paramList(); - - const std::string& param(const std::string&) const; - void param(const std::string&, const std::string&); - - void set(const std::string&); - std::string str() const; - - std::ostream& write(std::ostream& os, int fold = 0) const; -protected: - FieldValue* clone() const; -private: - istring m_type; - ParamList m_paramList; -}; - -} - -#endif - diff --git a/mimetic098/contentid.cxx b/mimetic098/contentid.cxx deleted file mode 100644 index 9c7843353..000000000 --- a/mimetic098/contentid.cxx +++ /dev/null @@ -1,123 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contentid.cxx,v 1.3 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ - -#pragma GCC diagnostic ignored "-Wsign-conversion" - -#include -#include - -namespace mimetic -{ -unsigned int ContentId::ms_sequence_number = 0; - -const char ContentId::label[] = "Content-ID"; - -ContentId::ContentId() -{ - std::string host = gethostname(); - if(!host.length()) - host = "unknown"; - m_cid = "c" + utils::int2str((int)time(0)) + "." + utils::int2str(getpid()) + - "." + utils::int2str(++ms_sequence_number) + "@" + host; -} - -ContentId::ContentId(const char* cstr) -:m_cid(cstr) -{ -} - - -ContentId::ContentId(const std::string& value) -:m_cid(value) -{ -} - -void ContentId::set(const std::string& value) -{ - m_cid = value; -} - -std::string ContentId::str() const -{ - return m_cid; -} - -FieldValue* ContentId::clone() const -{ - return new ContentId(*this); -} - -} diff --git a/mimetic098/contentid.h b/mimetic098/contentid.h deleted file mode 100644 index 0e8e3ada4..000000000 --- a/mimetic098/contentid.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contentid.h,v 1.11 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CONTENTID_H_ -#define _MIMETIC_CONTENTID_H_ -#include -#include -#include -#include - -namespace mimetic -{ - -/// Content-ID field value -struct ContentId: public FieldValue -{ - // format: yyyymmgg.pid.seq@hostname - static const char label[]; - ContentId(); - ContentId(const char*); - ContentId(const std::string&); - void set(const std::string&); - std::string str() const; -protected: - FieldValue* clone() const; -private: - static unsigned int ms_sequence_number; - std::string m_cid; -}; - -} - -#endif diff --git a/mimetic098/contenttransferencoding.cxx b/mimetic098/contenttransferencoding.cxx deleted file mode 100644 index 169450e51..000000000 --- a/mimetic098/contenttransferencoding.cxx +++ /dev/null @@ -1,131 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contenttransferencoding.cxx,v 1.3 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#include - -namespace mimetic -{ -using namespace std; - -const char ContentTransferEncoding::label[] = "Content-Transfer-Encoding"; -const char ContentTransferEncoding::base64[] = "base64"; -const char ContentTransferEncoding::quoted_printable[] = "quoted-printable"; -const char ContentTransferEncoding::binary[] = "binary"; -const char ContentTransferEncoding::sevenbit[] = "7bit"; -const char ContentTransferEncoding::eightbit[] = "8bit"; - -ContentTransferEncoding::ContentTransferEncoding() -{ -} - -ContentTransferEncoding::ContentTransferEncoding(const char* cstr) -: m_mechanism(cstr) -{ -} - - -ContentTransferEncoding::ContentTransferEncoding(const string& mechanism) -: m_mechanism(mechanism) -{ -} - -const istring& ContentTransferEncoding::mechanism() const -{ - return m_mechanism; -} - -void ContentTransferEncoding::mechanism(const string& mechanism) -{ - m_mechanism.assign (mechanism); -} - -void ContentTransferEncoding::set(const string& val) -{ - mechanism(val); -} - -string ContentTransferEncoding::str() const -{ - return mechanism(); -} - -FieldValue* ContentTransferEncoding::clone() const -{ - return new ContentTransferEncoding(*this); -} - -} - diff --git a/mimetic098/contenttransferencoding.h b/mimetic098/contenttransferencoding.h deleted file mode 100644 index e3d9358d6..000000000 --- a/mimetic098/contenttransferencoding.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contenttransferencoding.h,v 1.12 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CONTENT_TRANSFER_ENCODING_H_ -#define _MIMETIC_CONTENT_TRANSFER_ENCODING_H_ -#include -#include -#include - -namespace mimetic -{ - - -/// Content-Transfer-Encoding field value -struct ContentTransferEncoding: public FieldValue -{ - static const char label[]; - static const char base64[]; - static const char quoted_printable[]; - static const char binary[]; - static const char sevenbit[]; - static const char eightbit[]; - - ContentTransferEncoding(); - ContentTransferEncoding(const char*); - ContentTransferEncoding(const std::string&); - const istring& mechanism() const; - void mechanism(const std::string&); - - void set(const std::string&); - std::string str() const; -protected: - FieldValue* clone() const; -private: - istring m_mechanism; -}; - -} - -#endif - diff --git a/mimetic098/contenttype.cxx b/mimetic098/contenttype.cxx deleted file mode 100644 index 49ded3d16..000000000 --- a/mimetic098/contenttype.cxx +++ /dev/null @@ -1,258 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contenttype.cxx,v 1.3 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#include -#include -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wsign-conversion" - -#include -#include -#include - -namespace mimetic -{ -using namespace std; - -const char ContentType::label[] = "Content-Type"; - -int ContentType::Boundary::ms_i = 0; -string ContentType::Boundary::ms_common_boundary = string(); - - -ContentType::Boundary::Boundary() -{ - if(ms_i++ == 0) - { // initialize static boundary string - const char tb[] = "0123456789" - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "-_."; // "=+,()/" - stringstream ss; - srand((unsigned int)time(0)); - short tbSize = sizeof(tb)-1; - for(uint i=0; i < 48; ++i) - { - unsigned int r = rand(); - ss << tb[r % tbSize]; - } - ms_common_boundary = "----" + ss.str(); - } - m_boundary = ms_common_boundary + "=_" + utils::int2hex(ms_i) + "_"; -} - -ContentType::Boundary::operator const string&() const -{ - return m_boundary; -} - -ContentType::ContentType() -{ -// m_paramList.push_back(Param("charset", "us-ascii")); -} - -ContentType::ContentType(const char* cstr) -{ - set(cstr); -} - -ContentType::ContentType(const string& value) -{ - set(value); -} - -ContentType::ContentType(const string& stype, const string& ssubtype) -{ - set(stype, ssubtype); -} - -void ContentType::set(const string& stype, const string& ssubtype) -{ - type(stype); - subtype(ssubtype); -} - -bool ContentType::isMultipart() const -{ - return m_type == "multipart"; -} - -void ContentType::param(const string& name, const string& value) -{ - ParamList::iterator bit = m_paramList.begin(), eit = m_paramList.end(); - for(; bit != eit; ++bit) - { - if(bit->name() == name) - { - bit->value(value); - return; - } - } - m_paramList.push_back(Param(name, value)); -} - -const string& ContentType::param(const string& field) const -{ - ParamList::const_iterator bit = m_paramList.begin(), eit = m_paramList.end(); - for(; bit != eit; ++bit) - { - if(bit->name() == field) - return bit->value(); - } - return nullstring; -} - -void ContentType::type(const string& v) -{ - m_type.assign(v); -// if(isMultipart()) -// m_paramList.push_back(ContentType::Param("boundary", Boundary())); -} - -void ContentType::subtype(const string& v) -{ - m_subtype.assign(v); -} - -const istring& ContentType::type() const -{ - return m_type; -} - -const istring& ContentType::subtype() const -{ - return m_subtype; -} - -const ContentType::ParamList& ContentType::paramList() const -{ - return m_paramList; -} - -ContentType::ParamList& ContentType::paramList() -{ - return m_paramList; -} - - -void ContentType::set(const string& val) -{ - StringTokenizer stok(&val, ";"); - string ct; - if(!stok.next(ct)) - return; - - // parse type/subtype - string stype, ssubtype; - stok.setDelimList("/"); - stok.setSource(&ct); - stok.next(stype); - stok.next(ssubtype); - set(stype, ssubtype); - - // parse field params - string params(val, min(val.length(), ct.length() + 1)); - if(!params.length()) - return; - string paramValue; - stok.setDelimList(";"); - stok.setSource(¶ms); - while(stok.next(paramValue)) - { - ContentType::Param p(paramValue); - m_paramList.push_back(p); - } -} - -string ContentType::str() const -{ - string ostr = m_type + "/" + m_subtype; - ParamList::const_iterator bit = m_paramList.begin(), - eit = m_paramList.end(); - for(; bit != eit; ++bit) - ostr += "; " + bit->name() + "=\"" + bit->value() + "\""; - return ostr; -} - - -FieldValue* ContentType::clone() const -{ - return new ContentType(*this); -} - -} - diff --git a/mimetic098/contenttype.h b/mimetic098/contenttype.h deleted file mode 100644 index 1c9ede801..000000000 --- a/mimetic098/contenttype.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: contenttype.h,v 1.13 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_CONTENT_TYPE_H_ -#define _MIMETIC_CONTENT_TYPE_H_ -#include -#include -#include -#include - -namespace mimetic -{ - -/// Content-Type field value -class ContentType: public FieldValue -{ -public: - static const char label[]; - struct Boundary - { - Boundary(); - operator const std::string&() const; - private: - std::string m_boundary; - static std::string ms_common_boundary; - static int ms_i; - }; - typedef FieldParam Param; - typedef FieldParamList ParamList; -public: - ContentType(); - ContentType(const char*); - ContentType(const std::string&); - ContentType(const std::string&, const std::string&); - - void set(const std::string&); - void set(const std::string&, const std::string&); - - bool isMultipart() const; - - const istring& type() const; - void type(const std::string&); - - void subtype(const std::string&); - const istring& subtype() const; - - const ParamList& paramList() const; - ParamList& paramList(); - - const std::string& param(const std::string&) const; - void param(const std::string&, const std::string&); - - std::string str() const; -protected: - FieldValue* clone() const; -private: - istring m_type, m_subtype; - ParamList m_paramList; -}; - -} - -#endif diff --git a/mimetic098/fieldparam.cxx b/mimetic098/fieldparam.cxx deleted file mode 100644 index c0a852e0d..000000000 --- a/mimetic098/fieldparam.cxx +++ /dev/null @@ -1,139 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: fieldparam.cxx,v 1.3 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#include -#include - -namespace mimetic -{ - -using namespace std; - -FieldParam::FieldParam() -{ -} - -FieldParam::FieldParam(const string& lpv) -{ - string::const_iterator bit = lpv.begin(), eit = lpv.end(); - for( ; bit != eit; ++bit) - { - if(*bit == '=') - { - string n(lpv.begin(), bit), v(++bit, eit); - m_name.assign (remove_external_blanks(n)); - m_value = remove_dquote(remove_external_blanks(v)); - break; - } - } -} - -FieldParam::FieldParam(const string& n, const string& v) -{ - name(n); - value(v); -} - -const istring& FieldParam::name() const -{ - return m_name; -} - -const string& FieldParam::value() const -{ - return m_value; -} - -void FieldParam::name(const string& n) -{ - m_name.assign(n); -} - -void FieldParam::value(const string& v) -{ - m_value = v; -} - -ostream& operator<<(ostream& os, const FieldParam& p) -{ - os << p.name() << "="; - const string& val = p.value(); - if(val.find_first_of("()\\<>\"@,;:/[]?=") != std::string::npos) - return os << "\"" << val << "\""; - else - return os << val; -} - -} diff --git a/mimetic098/fieldparam.h b/mimetic098/fieldparam.h deleted file mode 100644 index b2324ffa1..000000000 --- a/mimetic098/fieldparam.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: fieldparam.h,v 1.7 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_FIELD_PARAM_H_ -#define _MIMETIC_FIELD_PARAM_H_ -#include -#include -#include -#include - -namespace mimetic -{ - -/// Field param -struct FieldParam -{ - FieldParam(); - FieldParam(const std::string&); - FieldParam(const std::string&, const std::string&); - const istring& name() const; - const std::string& value() const; - void name(const std::string&); - void value(const std::string&); - friend std::ostream& operator<<(std::ostream&, const FieldParam&); -private: - istring m_name; - std::string m_value; -}; - -typedef std::list FieldParamList; -} - -#endif diff --git a/mimetic098/header.cxx b/mimetic098/header.cxx deleted file mode 100644 index 997dd1f55..000000000 --- a/mimetic098/header.cxx +++ /dev/null @@ -1,177 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: header.cxx,v 1.3 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#include - -namespace mimetic -{ -using namespace std; - -// MIME-Version: -const MimeVersion& Header::mimeVersion() const -{ - return getField(MimeVersion::label); -} - -MimeVersion& Header::mimeVersion() -{ - return getField(MimeVersion::label); -} - -void Header::mimeVersion(const MimeVersion& val) -{ - setField(MimeVersion::label, val); -} - -// Content-Type -const ContentType& Header::contentType() const -{ - return getField(ContentType::label); -} - -ContentType& Header::contentType() -{ - return getField(ContentType::label); -} - -void Header::contentType(const ContentType& val) -{ - setField(ContentType::label, val); -} - -// Content-Transfer-Encoding -const ContentTransferEncoding& Header::contentTransferEncoding() const -{ - return getField(ContentTransferEncoding::label); -} - -ContentTransferEncoding& Header::contentTransferEncoding() -{ - return getField(ContentTransferEncoding::label); -} - -void Header::contentTransferEncoding(const ContentTransferEncoding& val) -{ - setField(ContentTransferEncoding::label, val); -} - -// Content-Disposition -const ContentDisposition& Header::contentDisposition() const -{ - return getField(ContentDisposition::label); -} - -ContentDisposition& Header::contentDisposition() -{ - return getField(ContentDisposition::label); -} - -void Header::contentDisposition(const ContentDisposition& val) -{ - setField(ContentDisposition::label, val); -} - -// Content-Description -const ContentDescription& Header::contentDescription() const -{ - return getField(ContentDescription::label); -} - -ContentDescription& Header::contentDescription() -{ - return getField(ContentDescription::label); -} - -void Header::contentDescription(const ContentDescription& val) -{ - setField(ContentDescription::label, val); -} - -// Content-Id -const ContentId& Header::contentId() const -{ - return getField(ContentId::label); -} - -ContentId& Header::contentId() -{ - return getField(ContentId::label); -} - -void Header::contentId(const ContentId& val) -{ - setField(ContentId::label, val); -} - -} - diff --git a/mimetic098/header.h b/mimetic098/header.h deleted file mode 100644 index 60af970ec..000000000 --- a/mimetic098/header.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: header.h,v 1.12 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_HEADER_H_ -#define _MIMETIC_HEADER_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mimetic -{ - -/// MIME message header class -struct Header: public Rfc822Header -{ - const MimeVersion& mimeVersion() const; - MimeVersion& mimeVersion(); - void mimeVersion(const MimeVersion&); - - const ContentType& contentType() const; - ContentType& contentType(); - void contentType(const ContentType&); - - const ContentTransferEncoding& contentTransferEncoding() const; - ContentTransferEncoding& contentTransferEncoding(); - void contentTransferEncoding(const ContentTransferEncoding&); - - const ContentDisposition& contentDisposition() const; - ContentDisposition& contentDisposition(); - void contentDisposition(const ContentDisposition&); - - const ContentDescription& contentDescription() const; - ContentDescription& contentDescription(); - void contentDescription(const ContentDescription&); - - const ContentId& contentId() const; - ContentId& contentId(); - void contentId(const ContentId&); -}; - -} - -#endif diff --git a/mimetic098/libconfig.h b/mimetic098/libconfig.h deleted file mode 100644 index 714b6f947..000000000 --- a/mimetic098/libconfig.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) by 2002-2004 Stefano Barbato - email : stefano@codesink.org - - $Id: libconfig.h,v 1.10 2009-02-16 18:08:59 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_LIB_CONFIG_H_ -#define _MIMETIC_LIB_CONFIG_H_ -#if defined(__unix__) || defined(__linux__) || defined(__unix) || defined(_AIX) -#ifdef HAVE_MIMETIC_CONFIG -#include "config.h" -#endif -#define CONFIG_UNIX -#endif - -/* Mac OS X */ -#if defined(__APPLE__) && defined(__MACH__) -typedef unsigned int uint; -#ifdef HAVE_MIMETIC_CONFIG -#include "config.h" -#endif -#define CONFIG_UNIX -#endif - -/* Windows */ -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) -#include -#include -#include -#include -#include -typedef unsigned int uint; -#define CONFIG_WIN32 -#endif - -#if !defined(CONFIG_WIN32) && !defined(CONFIG_UNIX) -#error "I'm unable to guess platform type. please define CONFIG_WIN32 or CONFIG_UNIX" -#endif -#if defined(CONFIG_WIN32) && defined(CONFIG_UNIX) -#error "I'm unable to guess platform type. please define CONFIG_UNIX or CONFIG_WIN32" -#endif - -#ifdef CONFIG_UNIX -#include -#define PATH_SEPARATOR '/' -typedef unsigned int uint32; -struct newline_traits -{ - enum { lf = 0xA, cr = 0xD }; - enum { size = 1 }; - enum { ch0 = lf, ch1 = 0 }; -}; -#endif - -#ifdef CONFIG_WIN32 -#define PATH_SEPARATOR '\\' -typedef unsigned int uint32; -struct newline_traits -{ - enum { lf = 0xA, cr = 0xD }; - enum { size = 2 }; - enum { ch0 = cr, ch1 = lf }; -}; -#endif - -#endif diff --git a/mimetic098/message.cxx b/mimetic098/message.cxx deleted file mode 100644 index 07199845f..000000000 --- a/mimetic098/message.cxx +++ /dev/null @@ -1,223 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: message.cxx,v 1.4 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#include -#include -#include -#include -#include - -namespace mimetic -{ - -using namespace std; -Attachment::Attachment(const std::string& fqn) -{ - set(fqn, ContentType("application","octet-stream"),Base64::Encoder()); -} - -Attachment::Attachment(const std::string& fqn, const ContentType& ct) -{ - set(fqn, ct, Base64::Encoder()); -} - - -TextEntity::TextEntity() -{ - header().contentType("text/unknown"); -} - -TextEntity::TextEntity(const string& text) -{ - m_header.contentType("text/unknown"); - m_body.assign(text); -} - -TextEntity::TextEntity(const string& text, const string& charset) -{ - ContentType ct("text", "unknown"); - ct.paramList().push_back(ContentType::Param("charset", charset)); - m_header.contentType(ct); - m_body.assign(text); -} - -TextPlain::TextPlain(const string& text) -: TextEntity(text) -{ - m_header.contentType("text/plain"); -} - -TextPlain::TextPlain(const string& text, const string& charset) -: TextEntity(text,charset) -{ - m_header.contentType("text/plain"); -} - - -TextEnriched::TextEnriched(const string& text) -: TextEntity(text) -{ - m_header.contentType("text/enriched"); -} -TextEnriched::TextEnriched(const string& text, const string& charset) -: TextEntity(text,charset) -{ - m_header.contentType("text/enriched"); -} - - -MultipartEntity::MultipartEntity() -{ - ContentType::Boundary boundary; - ContentType ct("multipart", "unknown"); - ct.paramList().push_back(ContentType::Param("boundary", boundary)); - m_header.contentType(ct); -} - -MultipartMixed::MultipartMixed() -{ - ContentType::Boundary boundary; - ContentType ct("multipart", "mixed"); - ct.paramList().push_back(ContentType::Param("boundary", boundary)); - m_header.contentType(ct); -} - -MultipartParallel::MultipartParallel() -{ - ContentType::Boundary boundary; - ContentType ct("multipart", "parallel"); - ct.paramList().push_back(ContentType::Param("boundary", boundary)); - m_header.contentType(ct); -} - -MultipartAlternative::MultipartAlternative() -{ - ContentType::Boundary boundary; - ContentType ct("multipart", "alternative"); - ct.paramList().push_back(ContentType::Param("boundary", boundary)); - m_header.contentType(ct); -} - -MultipartDigest::MultipartDigest() -{ - ContentType::Boundary boundary; - ContentType ct("multipart", "digest"); - ct.paramList().push_back(ContentType::Param("boundary", boundary)); - m_header.contentType(ct); -} - -ApplicationOctStream::ApplicationOctStream() -{ - m_header.contentType("application/octet-stream"); -} - -MessageRfc822::MessageRfc822(const MimeEntity& me) -: m_me(me) -{ - m_header.contentType("message/rfc822"); -} - -ostream& MessageRfc822::write(ostream& os,const char* eol) const -{ - MimeEntity::write(os); - return os << m_me; -} - -string ApplicationOctStream::type() const -{ - return m_header.contentType().param("type"); -} - -void ApplicationOctStream::type(const string& type) -{ - ContentType ct = m_header.contentType(); - ct.param("type",type); - m_header.contentType(ct); -} - -uint ApplicationOctStream::padding() const -{ - return utils::str2int(m_header.contentType().param("padding")); -} - -void ApplicationOctStream::padding(unsigned int n) -{ - ContentType ct = m_header.contentType(); - ct.param("padding", utils::int2str(n)); - m_header.contentType(ct); -} - - -} diff --git a/mimetic098/message.h b/mimetic098/message.h deleted file mode 100644 index 5446909cd..000000000 --- a/mimetic098/message.h +++ /dev/null @@ -1,246 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: message.h,v 1.13 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_MESSAGE_H_ -#define _MIMETIC_MESSAGE_H_ -#include -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -namespace mimetic -{ - -class ContentType; - -/// Base class for text/* MIME entities. -struct TextEntity: public MimeEntity -{ - /** - * Sets its content-type to "text/unknown" - */ - TextEntity(); - TextEntity(const std::string& text); - /** - * Sets its content-type to "text/unknown", - * sets its body with the "text" variable and adds - * "charset=us-ascii" content-type parameter - */ - TextEntity(const std::string& text, const std::string& charset); -}; - -/// text/plain entity class -/*! - TextPlain is a MimeEntity that defaults its ContentType to "text/plain" - and its charset to "us-ascii". - */ -struct TextPlain: public TextEntity -{ - TextPlain(const std::string& text); - /** - * constructs a TextPlain object, assigns text to its body and adds - * a ContentType::Param("charset", charset) to ContentType parameter list - */ - TextPlain(const std::string& text, const std::string& charset); -}; - - -/// text/enriched entity class -struct TextEnriched: public TextEntity -{ - TextEnriched(const std::string& text); - /** - * constructs a TextPlain object, assigns text to its body and adds - * a ContentType::Param("charset", charset) to ContentType parameter list - */ - TextEnriched(const std::string& text, const std::string& charset); -}; - -/// Base multipart/* class -/** - Base multipart/ * class. Its constructor sets the content-type - to "multipart/unknown" and adds and fills a "boundary" parameter - */ -struct MultipartEntity: public MimeEntity -{ - MultipartEntity(); -}; - -/// multipart/mixed entity class -struct MultipartMixed: public MultipartEntity -{ - MultipartMixed(); -}; - -/// multipart/parallel entity class -struct MultipartParallel: public MultipartEntity -{ - MultipartParallel(); -}; - -/// multipart/alternative entity class -struct MultipartAlternative: public MultipartEntity -{ - MultipartAlternative(); -}; - -/// multipart/digest entity class -struct MultipartDigest: public MultipartEntity -{ - MultipartDigest(); -}; - - -/// application/octet-stream entity class -struct ApplicationOctStream: public MimeEntity -{ - ApplicationOctStream(); - template - ApplicationOctStream(const std::string&, const Codec& c=Base64::Encoder()); - std::string type() const; - void type(const std::string&); - uint padding() const; - void padding(unsigned int); - bool operator()() const { return isValid(); } - bool isValid() const { return m_status; } -protected: - std::string m_fqn; - bool m_status; -}; - -/// Helper class to embed file attachments -struct Attachment: public MimeEntity -{ - /** - * defaults to application/octet-stream - */ - Attachment(const std::string&); - Attachment(const std::string&, const ContentType&); - template - Attachment(const std::string&, const Codec& c ); - template - Attachment(const std::string&, const ContentType&, const Codec& c); - bool operator()() const { return isValid(); } - bool isValid() const { return m_status; } -private: - template - void set(const std::string&, const ContentType&, const Codec& c); - std::string m_fqn; - bool m_status; -}; - -/// image/jpeg attachment -struct ImageJpeg: public Attachment -{ - ImageJpeg(const std::string& fqn) - : Attachment(fqn, ContentType("image","jpeg")) - { - } - template - ImageJpeg(const std::string& fqn, const Codec& c) - : Attachment(fqn, ContentType("image","jpeg"), c) - { - } -}; - -/// audio/basic attachment -struct AudioBasic: public Attachment -{ - AudioBasic(const std::string& fqn) - : Attachment(fqn, ContentType("audio","basic")) - { - } - template - AudioBasic(const std::string& fqn, const Codec& c) - : Attachment(fqn, ContentType("audio","basic"), c) - { - } -}; - - - -/// message/rfc822 entity type -struct MessageRfc822: public MimeEntity -{ - MessageRfc822(const MimeEntity&); -protected: - std::ostream& write(std::ostream&,const char*) const; -private: - const MimeEntity& m_me; -}; - - - -/** - * defaults to application/octet-stream - */ -template -Attachment::Attachment(const std::string& fqn, const Codec& codec) -{ - set(fqn, ContentType("application","octet-stream"), codec); -} - -template -Attachment::Attachment(const std::string& fqn, const ContentType& ctype, const Codec& codec) -{ - set(fqn, ctype, codec); -} - -template -void Attachment::set(const std::string& fqn, const ContentType& ctype, const Codec& codec) -{ - Header& h = header(); - m_fqn = fqn; - m_status = false; - std::string filename = utils::extractFilename(m_fqn); - // Content-Type - h.contentType(ctype); - h.contentType().paramList().push_back(ContentType::Param("name", filename)); - - // Content-Transfer-Encoding - h.contentTransferEncoding().mechanism(codec.name()); - - // Content-Disposition - h.contentDisposition().type("attachment"); - h.contentDisposition().paramList().push_back(ContentDisposition::Param("filename", filename)); - - m_status = body().load(m_fqn, codec); -} - - -template -ApplicationOctStream::ApplicationOctStream(const std::string& fqn, const Codec& codec) -{ - Header& h = header(); - m_fqn = fqn; - m_status = false; - std::string filename = utils::extractFilename(m_fqn); - // Content-Type - h.contentType(ContentType("application", "octet-stream")); - h.contentType().paramList().push_back(ContentType::Param("name", filename)); - - // Content-Transfer-Encoding - h.contentTransferEncoding().mechanism(codec.name()); - - // Content-Disposition - h.contentDisposition().type("attachment"); - h.contentDisposition().paramList().push_back(ContentDisposition::Param("filename", filename)); - - m_status = body().load(m_fqn, codec); -} - -} - - -#endif - diff --git a/mimetic098/mimeentity.cxx b/mimetic098/mimeentity.cxx deleted file mode 100644 index 1dcad2fc3..000000000 --- a/mimetic098/mimeentity.cxx +++ /dev/null @@ -1,231 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mimeentity.cxx,v 1.5 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#include -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wshadow" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mimetic -{ - -using namespace std; - -void MimeEntity::load(istream& is, int mask) -{ - typedef istreambuf_iterator it_type; - typedef it_type::iterator_category it_cat; - IteratorParser prs(*this); - prs.iMask(mask); - prs.run( it_type(is), it_type()); -} - -bool MimeEntity::hasField(const string& name) const -{ - return m_header.hasField(name); -} - -ostream& MimeEntity::write(ostream& os, const char* eol) const -{ - enum { max_line_len = 76 }; - if(eol != 0) - { - // TODO - //build nl2localnl filter streambuf - } - // header field - Header::const_iterator hbit = header().begin(), heit = header().end(); - for(; hbit != heit; ++hbit) - hbit->write(os, max_line_len) << crlf; - const ContentType& ct = m_header.contentType(); - // body - if(ct.isMultipart()) - { - string boundary = "--" + ct.param("boundary"); - if(body().preamble().length()) - os << crlf << body().preamble(); - // opening boundary - if(body().parts().size() == 0) - os << crlf << boundary << crlf; - MimeEntityList::const_iterator bit, eit; - bit = body().parts().begin(); - eit = body().parts().end(); - for(; bit != eit; ++bit) - { - os << crlf << boundary << crlf; - MimeEntity* pMe = *bit; - os << *pMe; - } - // closing boundary - os << crlf << boundary + "--" << crlf; - if(body().epilogue().length()) - os << body().epilogue(); - } else if(ct.type() == "message" && ct.subtype() == "rfc822") { - MimeEntityList::const_iterator bit, eit; - bit = body().parts().begin(); - eit = body().parts().end(); - for(; bit != eit; ++bit) - { - os << crlf; - MimeEntity* pMe = *bit; - os << *pMe; - } - } else { - os << crlf << body(); - } - os.flush(); - return os; -} - -ostream& operator<<(ostream& os, const MimeEntity& m) -{ - return m.write(os); -} - - -// called by all constructors() -void MimeEntity::commonInit() -{ - m_body.owner(this); -} - - -MimeEntity::MimeEntity() -{ - commonInit(); -} - - -MimeEntity::MimeEntity(std::istream& is) -{ - commonInit(); - load(is); -} - -MimeEntity::~MimeEntity() -{ - MimeEntityList::iterator bit = m_body.parts().begin(), - eit = m_body.parts().end(); - for(; bit != eit; ++bit) - if(*bit) - delete *bit; - m_body.clear(); -} - -Header& MimeEntity::header() -{ - return m_header; -} - -const Header& MimeEntity::header() const -{ - return m_header; -} - -Body& MimeEntity::body() -{ - return m_body; -} - -const Body& MimeEntity::body() const -{ - return m_body; -} - -MimeEntity::size_type MimeEntity::size() const -{ - count_streambuf csb; - ostream os(&csb); - os << *this; - return csb.size(); -} - - - - -} diff --git a/mimetic098/mimeentity.h b/mimetic098/mimeentity.h deleted file mode 100644 index 033b19104..000000000 --- a/mimetic098/mimeentity.h +++ /dev/null @@ -1,142 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mimeentity.h,v 1.29 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_MIMEENTITY_H_ -#define _MIMETIC_MIMEENTITY_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace mimetic -{ - -class MimeEntity; - - -/// Represent a MIME entity -class MimeEntity -{ - friend class Body; - friend class MimeEntityLoader; - typedef std::list BoundaryList; - typedef unsigned long int size_type; -public: - /** - * Blank MIME entity - */ - MimeEntity(); - /** - * Parse [beg, end] and build entity based on content - */ - template - MimeEntity(Iterator beg, Iterator end, int mask = imNone); - /** - * Parse istream and build entity based on content - */ - MimeEntity(std::istream&); - - virtual ~MimeEntity(); - - /** - * copy text rapresentation of the MimeEntity to the output iterator - */ - template - size_type copy(OutputIt out); - - Header& header(); - const Header& header() const; - - Body& body(); - const Body& body() const; - - /** - * single step load functions: parse the input provided and build the - * entity - * - * use load(..., mask) to ignore some part of the message when it's - * not needed saving memory space and execution time - */ - template - void load(Iterator, Iterator, int mask = imNone); - void load(std::istream&, int mask = imNone); - - /** - * helper functions: return header().hasField(str) - */ - bool hasField(const std::string&) const; - - /** - * returns entity size - * Note: this function is slow, use it if you really need - */ - size_type size() const; - friend std::ostream& operator<<(std::ostream&, const MimeEntity&); -protected: - void commonInit(); - - virtual std::ostream& write(std::ostream&, const char* eol = 0) const; - -protected: - Header m_header; - Body m_body; - size_type m_lines; - size_type m_size; - -private: - //MimeEntity(const MimeEntity&); - //MimeEntity& operator=(const MimeEntity&); -}; - - - -template -MimeEntity::MimeEntity(Iterator bit, Iterator eit, int mask) -{ - commonInit(); - load(bit, eit, mask); -} - - -template -void MimeEntity::load(Iterator bit, Iterator eit, int mask) -{ - IteratorParser::iterator_category> prs(*this); - prs.iMask(mask); - prs.run(bit, eit); -} - -template -MimeEntity::size_type MimeEntity::copy(OutputIt out) -{ - passthrough_streambuf psb(out); - std::ostream os(&psb); - os << *this; - return psb.size(); -} - -} - -#endif diff --git a/mimetic098/mimeentitylist.h b/mimetic098/mimeentitylist.h deleted file mode 100644 index cc92ed52e..000000000 --- a/mimetic098/mimeentitylist.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mimeentitylist.h,v 1.8 2008-10-07 11:06:25 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_MIME_ENTITY_LIST_ -#define _MIMETIC_MIME_ENTITY_LIST_ -#include -#include - -namespace mimetic -{ - -class MimeEntity; - -/// List of MimeEntity classes -typedef std::list MimeEntityList; - - -} - -#endif diff --git a/mimetic098/mimetic.h b/mimetic098/mimetic.h deleted file mode 100644 index 4bae7cbb1..000000000 --- a/mimetic098/mimetic.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mimetic.h,v 1.18 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_MIMETIC_H_ -#define _MIMETIC_MIMETIC_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif diff --git a/mimetic098/mimeversion.cxx b/mimetic098/mimeversion.cxx deleted file mode 100644 index 5c055dac8..000000000 --- a/mimetic098/mimeversion.cxx +++ /dev/null @@ -1,117 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mimeversion.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -#include -#include - -namespace mimetic -{ -using namespace std; - -const char MimeVersion::label[] = "Mime-Version"; - - -MimeVersion::MimeVersion() -: Version() -{ -} - -MimeVersion::MimeVersion(const string& s) -: Version(s) -{ -} - -MimeVersion::MimeVersion(ver_type maj, ver_type min) -: Version(maj, min) -{ -} - -string MimeVersion::str() const -{ - return Version::str(); -} - -void MimeVersion::set(const string& s) -{ - Version::set(s); -} - -FieldValue* MimeVersion::clone() const -{ - return new MimeVersion(*this); -} - -} diff --git a/mimetic098/mimeversion.h b/mimetic098/mimeversion.h deleted file mode 100644 index d3c85ffb9..000000000 --- a/mimetic098/mimeversion.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mimeversion.h,v 1.12 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_MIMEVERSION_H_ -#define _MIMETIC_MIMEVERSION_H_ -#include -#include -#include -#include -namespace mimetic -{ - -// major & minor are macro defined in /usr/include/sys/sysmacros.h (linux) -// so we'll better use maj & min instead - -/// Mime-Version field value -struct MimeVersion: public Version, public FieldValue -{ - static const char label[]; - - MimeVersion(); - MimeVersion(const std::string&); - MimeVersion(ver_type, ver_type); - - void set(const std::string&); - std::string str() const; -protected: - FieldValue* clone() const; -}; - -} -#endif diff --git a/mimetic098/os/directory.h b/mimetic098/os/directory.h deleted file mode 100644 index bb7f671aa..000000000 --- a/mimetic098/os/directory.h +++ /dev/null @@ -1,169 +0,0 @@ -#pragma GCC system_header - -#ifndef _MIMETIC_OS_DIRECTORY_H_ -#define _MIMETIC_OS_DIRECTORY_H_ -#include -#include -#include -#ifdef HAVE_DIRENT_H -#include -#endif -#include -#include - -namespace mimetic -{ - -class Directory -{ -public: - struct DirEntry - { - enum Type { Unknown, RegularFile, Directory, Link }; - DirEntry(): type(Unknown) {} - std::string name; - Type type; - }; - friend class iterator; - struct iterator: public std::iterator - { - iterator() // end() it - : m_dirp(0), m_dirh(0), m_eoi(true) - { - } - iterator(Directory* dirp) // begin() it - : m_dirp(dirp), m_eoi(false) - { - m_dirh = opendir(m_dirp->m_path.c_str()); - if(m_dirh) - { - m_dirent = readdir(m_dirh); - setDirent(m_dirent); - } else { - // opendir error, set equal to end() - m_dirp = 0; - m_dirh = 0; - m_eoi = true; - } - } - ~iterator() - { - if(m_dirh) - closedir(m_dirh); - } - const DirEntry& operator*() const - { - return m_de; - } - const DirEntry* operator->() const - { - return &m_de; - } - iterator& operator++() - { - if((m_dirent = readdir(m_dirh)) == NULL) - { - m_eoi = true; - return *this; - } - setDirent(m_dirent); - return *this; - } - iterator operator++(int) // postfix - { - iterator it = *this; - ++*this; - return it; - } - bool operator==(const iterator& right) - { - if(m_eoi && right.m_eoi) - return true; - - return - m_eoi == right.m_eoi && - m_dirp->m_path == right.m_dirp->m_path && - m_dirent && right.m_dirent && - #ifdef _DIRENT_HAVE_D_TYPE - m_dirent->d_type == right.m_dirent->d_type && - #endif - std::string(m_dirent->d_name) == right.m_dirent->d_name; - } - bool operator!=(const iterator& right) - { - return !operator==(right); - } - private: - void setDirent(struct dirent* dent) - { - m_de.name = dent->d_name; - m_de.type = DirEntry::Unknown; - #ifdef _DIRENT_HAVE_D_TYPE - switch(dent->d_type) - { - case DT_DIR: - m_de.type = DirEntry::Directory; - break; - case DT_REG: - m_de.type = DirEntry::RegularFile; - break; - case DT_LNK: - m_de.type = DirEntry::Link; - break; - } - #endif - } - Directory* m_dirp; - DIR* m_dirh; - bool m_eoi; - DirEntry m_de; - struct dirent* m_dirent; - }; - - Directory(const std::string& dir) - : m_path(dir) - { - } - ~Directory() - { - } - iterator begin() - { return iterator(this); } - iterator end() - { return iterator(); }; - bool exists() const - { - struct stat st; - return stat(m_path.c_str(), &st) == 0 && S_ISDIR(st.st_mode); - } - static bool exists(const std::string& dname) - { - struct stat st; - return stat(dname.c_str(), &st) == 0 && S_ISDIR(st.st_mode); - } - static bool create(const std::string& dname) - { - if(!exists(dname)) - return mkdir(dname.c_str(), 0755) == 0; - else - return 0; - } - static bool remove(const std::string& dname) - { - if(!exists(dname)) - return 0; - else - return rmdir(dname.c_str()) == 0; - } - const std::string& path() const - { - return m_path; - } -private: - std::string m_path; -}; - -} - -#endif - diff --git a/mimetic098/os/file.h b/mimetic098/os/file.h deleted file mode 100644 index e5426f14e..000000000 --- a/mimetic098/os/file.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: file.h,v 1.8 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_OS_FILE_H -#define _MIMETIC_OS_FILE_H -#define HAVE_MMAP 1 -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_MMAP -#include -#endif - -namespace mimetic -{ - -#if HAVE_MMAP == 1 -typedef MMFile File; -#else -typedef StdFile File; -#endif - -} - - - -#endif - diff --git a/mimetic098/os/file_iterator.cxx b/mimetic098/os/file_iterator.cxx deleted file mode 100644 index 1641c4862..000000000 --- a/mimetic098/os/file_iterator.cxx +++ /dev/null @@ -1,196 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: file_iterator.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic ignored "-Wsign-conversion" -#include -#include -#include -#include -#ifdef HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif - -namespace mimetic -{ - -using namespace std; - -ifile_iterator::ifile_iterator() -: m_eof(1), m_buf(0), m_ptr(0), m_count(0), m_pFile(0), m_read(0) -{ - setBufsz(); -} - - -ifile_iterator::ifile_iterator(StdFile* pFile) -: m_eof(0), m_buf(0), m_ptr(0), m_count(0), m_pFile(pFile), m_read(0) -{ - setBufsz(); - if(m_pFile == 0) - { - m_eof = 1; - return; - } - m_ptr = m_buf = new value_type[m_bufsz]; - underflow(); -} - -void ifile_iterator::setBufsz() -{ - #ifdef HAVE_GETPAGESIZE - m_bufsz = getpagesize(); - #else - m_bufsz = defBufsz; - #endif -} - -void ifile_iterator::cp(const ifile_iterator& r) -{ - if(m_buf) - delete[] m_buf; - m_eof = 1; - m_buf = m_ptr = 0; - m_count = m_read = 0; - m_pFile = 0; - if(r.m_eof || r.m_pFile == 0) - return; - m_eof = r.m_eof; - m_count = r.m_count; - m_pFile = r.m_pFile; - m_read = r.m_read; - m_bufsz = r.m_bufsz; - - m_ptr = m_buf = new value_type[m_bufsz]; - for(int i = 0; i < m_count; ++i) - m_ptr[i] = r.m_ptr[i]; - return; -} - -ifile_iterator& ifile_iterator::operator=(const ifile_iterator& r) -{ - cp(r); - return *this; -} - -ifile_iterator::ifile_iterator(const ifile_iterator& r) -: m_buf(0) -{ - cp(r); -} - - -ifile_iterator::~ifile_iterator() -{ - if(m_buf) - delete[] m_buf; - if(m_pFile == 0) - return; - m_eof = 1; - m_pFile = 0; -} - - -void ifile_iterator::underflow() -{ - if(m_eof) - return; - m_count = m_pFile->read(m_buf, m_bufsz); - if(m_count > 0) - { - m_ptr = m_buf; - m_read += m_count; - } else { - m_count = 0; - m_eof = 1; - } -} - -} - diff --git a/mimetic098/os/file_iterator.h b/mimetic098/os/file_iterator.h deleted file mode 100644 index 81f8124b4..000000000 --- a/mimetic098/os/file_iterator.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: file_iterator.h,v 1.11 2008-10-27 18:30:42 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_OS_FILE_ITERATOR_H_ -#define _MIMETIC_OS_FILE_ITERATOR_H_ -#include -#include - -namespace mimetic -{ -struct StdFile; - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -struct ifile_iterator: public std::iterator -#pragma clang diagnostic pop -{ - ifile_iterator(); - ifile_iterator(StdFile* f); - ifile_iterator(const ifile_iterator&); - ifile_iterator& operator=(const ifile_iterator&); - ~ifile_iterator(); - inline ifile_iterator& operator++(); - inline ifile_iterator operator++(int); - inline reference operator*(); - inline bool operator!=(const ifile_iterator& right) const; - inline bool operator==(const ifile_iterator& right) const; -private: - void cp(const ifile_iterator&); - void setBufsz(); - enum { defBufsz = 4096 }; // default buffer size(4 missing getpagesize) - void underflow(); - bool m_eof; - value_type* m_buf; - value_type* m_ptr; - int m_count; - StdFile* m_pFile; - unsigned int m_read; //bytes read so far - unsigned int m_bufsz; -}; - -inline -ifile_iterator ifile_iterator::operator++(int) // postfix -{ - ifile_iterator cp = *this; - operator++(); - return cp; -} - - -inline -ifile_iterator& ifile_iterator::operator++() // prefix -{ - if(--m_count > 0) - ++m_ptr; - else - underflow(); - return *this; -} - - -inline -ifile_iterator::reference ifile_iterator::operator*() -{ - return *m_ptr; -} - -inline -bool ifile_iterator::operator!=(const ifile_iterator& right) const -{ - // always different except when both are EOF - return !operator==(right); -} - - -inline -bool ifile_iterator::operator==(const ifile_iterator& right) const -{ - // are equal if both are EOF - return (m_eof && right.m_eof); -} - -} - -#endif diff --git a/mimetic098/os/fileop.cxx b/mimetic098/os/fileop.cxx deleted file mode 100644 index f9113b840..000000000 --- a/mimetic098/os/fileop.cxx +++ /dev/null @@ -1,164 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: fileop.cxx,v 1.5 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif - -using namespace std; - -namespace mimetic -{ - -//static -bool FileOp::remove(const string& fqn) -{ - return unlink(fqn.c_str()) == 0; -} - -//static -bool FileOp::move(const string& oldf, const string& newf) -{ -#if defined(CONFIG_UNIX) - if(link(oldf.c_str(), newf.c_str()) == 0) - { - unlink(oldf.c_str()); - return true; - } - return false; -#elif defined(CONFIG_WIN32) - return(rename(oldf.c_str(), newf.c_str()) == 0); -#else -#error sys not supported -#endif -} -//static -bool FileOp::exists(const string& fqn) -{ - struct stat st; - return ::stat(fqn.c_str(), &st) == 0; -} - -//static -uint FileOp::size(const string& fqn) -{ - struct stat st; - if(::stat(fqn.c_str(), &st) == 0) - return st.st_size; - else - return 0; -} - -//static -uint FileOp::ctime(const string& fqn) -{ - struct stat st; - if(::stat(fqn.c_str(), &st) == 0) - return st.st_ctime; - else - return 0; -} - -//static -uint FileOp::atime(const string& fqn) -{ - struct stat st; - if(::stat(fqn.c_str(), &st) == 0) - return st.st_atime; - else - return 0; -} - -//static -uint FileOp::mtime(const string& fqn) -{ - struct stat st; - if(::stat(fqn.c_str(), &st) == 0) - return st.st_mtime; - else - return 0; -} - -} - - diff --git a/mimetic098/os/fileop.h b/mimetic098/os/fileop.h deleted file mode 100644 index ba31e45ca..000000000 --- a/mimetic098/os/fileop.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: fileop.h,v 1.7 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_OS_FILEOP_H -#define _MIMETIC_OS_FILEOP_H -#include - -namespace mimetic -{ - -/// Defines some file utility functions -struct FileOp -{ - typedef unsigned int uint; - /* static funtions */ - static bool remove(const std::string&); - static bool move(const std::string&, const std::string&); - static bool exists(const std::string&); - - static uint size(const std::string&); - static uint ctime(const std::string&); // creation time - static uint atime(const std::string&); // last time accessed(r/w) - static uint mtime(const std::string&); // last time written -}; - -} - - -#endif - diff --git a/mimetic098/os/mmfile.cxx b/mimetic098/os/mmfile.cxx deleted file mode 100644 index 7e0eeb9f1..000000000 --- a/mimetic098/os/mmfile.cxx +++ /dev/null @@ -1,199 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wundef" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mmfile.cxx,v 1.6 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic ignored "-Wsign-conversion" -#include -#include -#include - -using namespace std; - -namespace mimetic -{ - -MMFile::MMFile() -: m_stated(false), m_fd(-1), m_beg(0), m_end(0) -{ -} - -MMFile::MMFile(const string& fqn, int mode) -: m_fqn(fqn), m_stated(false), m_fd(-1), m_beg(0), m_end(0) -{ - memset(&m_st, 0, sizeof(m_st)); - if(!stat()) - return; - open(mode); -} - -bool MMFile::open(const std::string& fqn, int mode /*= O_RDONLY*/) -{ - m_fqn = fqn; - if(!stat() || !S_ISREG(m_st.st_mode)) - return false; - return open(mode); -} - -bool MMFile::open(int mode) -{ - if(!stat() || !S_ISREG(m_st.st_mode)) - return false; - m_fd = ::open(m_fqn.c_str(), mode); - if(m_fd > 0) - return map(); - else - return false; -} - -bool MMFile::map() -{ - m_beg = (char*) mmap(0, m_st.st_size, PROT_READ, MAP_SHARED,m_fd,0); - if(m_beg > (char *)0) - { - m_end = m_beg + m_st.st_size; - //#ifdef HAVE_MADVISE - //madvise(m_beg, m_st.st_size, MADV_SEQUENTIAL); - //#endif - return true; - } - return false; -} - -MMFile::~MMFile() -{ - if(m_beg) - munmap(m_beg, m_st.st_size); - if(m_fd) - close(); -} - -MMFile::iterator MMFile::begin() -{ - return m_beg; -} - -MMFile::iterator MMFile::end() -{ - return m_end; -} - -MMFile::const_iterator MMFile::begin() const -{ - return m_beg; -} - - -MMFile::const_iterator MMFile::end() const -{ - return m_end; -} - -uint MMFile::read(char* buf, int bufsz) -{ - long r; - do - { - r = ::read(m_fd, buf, bufsz); - } while(r < 0 && errno == EINTR); - return (uint)r; -} - -MMFile::operator bool() const -{ - return m_fd > 0; -} - -bool MMFile::stat() -{ - return m_stated || (m_stated = (::stat(m_fqn.c_str(), &m_st) == 0)); -} - -void MMFile::close() -{ - while(::close(m_fd) < 0 && errno == EINTR) - ; - m_fd = -1; -} - -} - diff --git a/mimetic098/os/mmfile.h b/mimetic098/os/mmfile.h deleted file mode 100644 index 8554c0b1d..000000000 --- a/mimetic098/os/mmfile.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mmfile.h,v 1.12 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_OS_MMFILE_H -#define _MIMETIC_OS_MMFILE_H -#include -#include -#include -#include -#include -#include -#include - -namespace mimetic -{ - -/// Memory mapped file -struct MMFile: public FileOp -{ - typedef char* iterator; - typedef const char* const_iterator; - MMFile(); - MMFile(const std::string&, int mode = O_RDONLY); - ~MMFile(); - operator bool() const; - bool open(const std::string&, int mode = O_RDONLY); - void close(); - uint read(char*, int); - - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - -protected: - bool map(); - bool open(int flags); - bool stat(); - - std::string m_fqn; - bool m_stated; - struct stat m_st; - int m_fd; - - char *m_beg, *m_end; -}; - -} - - -#endif - diff --git a/mimetic098/os/os.h b/mimetic098/os/os.h deleted file mode 100644 index 1e31fd7f2..000000000 --- a/mimetic098/os/os.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: os.h,v 1.6 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_OS_OS_H_ -#define _MIMETIC_OS_OS_H_ -#include -#include -#endif diff --git a/mimetic098/os/stdfile.cxx b/mimetic098/os/stdfile.cxx deleted file mode 100644 index 7e175647d..000000000 --- a/mimetic098/os/stdfile.cxx +++ /dev/null @@ -1,171 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: stdfile.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - - -using namespace std; - - -namespace mimetic -{ - - -StdFile::StdFile() -: m_stated(false), m_fd(-1) -{ -} - -StdFile::StdFile(const string& fqn, int mode) -: m_fqn(fqn), m_stated(false), m_fd(-1) -{ - memset(&m_st,0, sizeof(m_st)); - if(!stat()) - return; - open(mode); -} - -void StdFile::open(const std::string& fqn, int mode /*= O_RDONLY*/) -{ - m_fqn = fqn; - open(mode); -} - -void StdFile::open(int mode) -{ - m_fd = ::open(m_fqn.c_str(), mode); -} - -StdFile::~StdFile() -{ - if(m_fd) - close(); -} - -StdFile::iterator StdFile::begin() -{ - return iterator(this); -} - -StdFile::iterator StdFile::end() -{ - return iterator(); -} - -uint StdFile::read(char* buf, int bufsz) -{ - int r; - do - { - r = ::read(m_fd, buf, bufsz); - } while(r < 0 && errno == EINTR); - return r; -} - -StdFile::operator bool() const -{ - return m_fd > 0; -} - -bool StdFile::stat() -{ - return m_stated || (m_stated = (::stat(m_fqn.c_str(), &m_st) == 0)); -} - -void StdFile::close() -{ - while(::close(m_fd) < 0 && errno == EINTR) - ; - m_fd = -1; -} - - -} - diff --git a/mimetic098/os/stdfile.h b/mimetic098/os/stdfile.h deleted file mode 100644 index 6c69faa9e..000000000 --- a/mimetic098/os/stdfile.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: stdfile.h,v 1.9 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_OS_STDFILE_H -#define _MIMETIC_OS_STDFILE_H -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mimetic -{ - -// File class -struct StdFile: public FileOp -{ - typedef ifile_iterator iterator; - StdFile(); - StdFile(const std::string&, int mode = O_RDONLY); - ~StdFile(); - operator bool() const; - void open(const std::string&, int mode = O_RDONLY); - void close(); - uint read(char*, int); - - iterator begin(); - iterator end(); -protected: - void open(int flags); - bool stat(); - - std::string m_fqn; - bool m_stated; - struct stat m_st; - int m_fd; -}; - -} - - -#endif - diff --git a/mimetic098/os/utils.cxx b/mimetic098/os/utils.cxx deleted file mode 100644 index 1a79e4363..000000000 --- a/mimetic098/os/utils.cxx +++ /dev/null @@ -1,106 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: utils.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -#include -#include -//#ifdef HAVE_UNISTD_H -#include -//#endif - -namespace mimetic -{ - -std::string gethostname() -{ -#ifdef CONFIG_WIN32 - /* WSAStartup(...) must be called before any Winsock func */ - return std::string(); -#else - char buf[64]; - if(::gethostname(buf, 64) < 0) - return std::string(); - else - return std::string(buf); -#endif -} - -int getpid() -{ - return ::getpid(); -} - -} - diff --git a/mimetic098/os/utils.h b/mimetic098/os/utils.h deleted file mode 100644 index 8b275d44c..000000000 --- a/mimetic098/os/utils.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: utils.h,v 1.9 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_OS_UTILS_H_ -#define _MIMETIC_OS_UTILS_H_ -#include - -namespace mimetic -{ -/// Returns host name -std::string gethostname(); - -/// Returns the ID of the calling process -int getpid(); - -} - -#endif diff --git a/mimetic098/parser/itparser.h b/mimetic098/parser/itparser.h deleted file mode 100644 index 200895f0f..000000000 --- a/mimetic098/parser/itparser.h +++ /dev/null @@ -1,766 +0,0 @@ -#pragma GCC system_header - -#ifndef _MIMETIC_PARSER_ITPARSER_H_ -#define _MIMETIC_PARSER_ITPARSER_H_ -#include -#include -#include -#include -#include -#include -#include - - -// FIXME: handle HigherLevelClosingBoundary - -namespace mimetic -{ - -/// Parse the input reading from an iterator -template::iterator_category> -struct IteratorParser -{ -}; - -/* - * Input Iterator - */ -template -struct IteratorParser -{ - - IteratorParser(MimeEntity& me) - : m_me(me), m_iMask(imNone), m_lastBoundary(NoBoundary) - { - m_entityStack.push(&m_me); - } - virtual ~IteratorParser() - { - } - /** - * set the Ignore Mask to \p mask - */ - void iMask(size_t mask) { m_iMask = mask; } - /** - * get the Ignore Mask - */ - size_t iMask() const { return m_iMask; } - /** - * start parsing - */ - void run(Iterator bit, Iterator eit) - { - m_bit = bit; - m_eit = eit; - doLoad(); - } -protected: - typedef std::list BoundaryList; - enum { - CR = 0xD, - LF = 0xA, - NL = '\n' - }; - enum /* ParsingElem */ { - peIgnore, - pePreamble, - peBody, - peEpilogue - }; - enum BoundaryType { - NoBoundary = 0, - Boundary, - ClosingBoundary, - HigherLevelBoundary - //, HigherLevelClosingBoundary - }; - enum EntityType { - etRfc822, - etMsgRfc822, - etMultipart - }; - // vars - MimeEntity& m_me; - Iterator m_bit, m_eit; - size_t m_iMask; // ignore mask - BoundaryList m_boundaryList; - BoundaryType m_lastBoundary; - std::stack m_entityStack; - -protected: - void appendPreambleBlock(const char* buf, int sz) - { - MimeEntity* pMe = m_entityStack.top(); - pMe->body().preamble().append(buf,sz); - } - - void appendEpilogueBlock(const char* buf, int sz) - { - MimeEntity* pMe = m_entityStack.top(); - pMe->body().epilogue().append(buf,sz); - } - - void appendBodyBlock(const char* buf, int sz) - { - MimeEntity* pMe = m_entityStack.top(); - pMe->body().append(buf, sz); - } - - std::string getBoundary() - { - const MimeEntity* pMe = m_entityStack.top(); - const ContentType& ct = pMe->header().contentType(); - return std::string("--") + ct.param("boundary"); - } - - void popChild() - { - m_entityStack.pop(); - } - - void pushNewChild() - { - MimeEntity* pMe = m_entityStack.top(); - MimeEntity* pChild = new MimeEntity; - pMe->body().parts().push_back(pChild); - m_entityStack.push(pChild); - } - - EntityType getType() - { - MimeEntity* pMe = m_entityStack.top(); - const Header& h = pMe->header(); - // will NOT be automatically created if it doesn't exists; - // null ContentType will be returned - const ContentType& ct = h.contentType(); - if(ct.isMultipart()) - return etMultipart; - else if (ct.type() == "message" && ct.subtype() == "rfc822") - return etMsgRfc822; - else - return etRfc822; - } - - void addField(const std::string& name, const std::string& value) - { - MimeEntity* pMe = m_entityStack.top(); - Header& h = pMe->header(); - Header::iterator it = h.insert(h.end(), Field()); - it->name(name); - it->value(value); - } - - BoundaryType isBoundary(const std::string& line) - { - if(line.length() == 0 || line[0] != '-') - return m_lastBoundary = NoBoundary; - - int level = 0; // multipart nesting level - size_t lineLen = line.length(); - BoundaryList::const_iterator bit, eit; - bit = m_boundaryList.begin(), eit = m_boundaryList.end(); - for(;bit != eit; ++bit, ++level) - { - const std::string& b = *bit; - size_t bLen = b.length(); - if(line.compare(0, bLen, b) == 0) - { - // not the expected boundary, malformed msg - if(level > 0) - return m_lastBoundary=HigherLevelBoundary; - // plain boundary or closing boundary? - if(lineLen > bLen && line.compare(bLen,2,"--") == 0) - return m_lastBoundary = ClosingBoundary; - else - return m_lastBoundary = Boundary; - } - } - return m_lastBoundary = NoBoundary; - } - // is new line - inline bool isnl(char c) const - { - return (c == CR || c == LF); - } - // is a two char newline - inline bool isnl(char a, char b) const - { - if(a == CR || a == LF) - if(b == (a == CR ? LF : CR)) - return true; - return false; - } - void doLoad() - { - loadHeader(); - loadBody(); - } - bool valid() const - { - return m_bit != m_eit; - } - void append(char*& buf, size_t& bufsz, char c, size_t& pos) - { - enum { alloc_block = 128}; - if(pos == bufsz) - { - // allocate and init buffer - char* tmp = buf; - size_t oldBufsz = bufsz; - while(pos >= bufsz) - bufsz = bufsz + alloc_block; - buf = new char[bufsz+1]; - if(tmp != 0) - { - assert(oldBufsz > 0); - memset(buf, 0, bufsz); - memcpy(buf, tmp, oldBufsz); - delete[] tmp; - } - } - buf[pos++] = c; - } - // parses the header and calls addField and pushChild - // to add fields and nested entities - void loadHeader() - { - enum { - sInit, - sIgnoreLine, - sNewline, - sWaitingName, - sWaitingValue, - sWaitingFoldedValue, - sName, - sValue, - sIgnoreHeader - }; - int status; - int pos; - char *name, *value; - size_t nBufSz, vBufSz, nPos, vPos; - char prev, c = 0; - - name = value = 0; - pos = nBufSz = vBufSz = nPos = vPos = 0; - status = (m_iMask & imHeader ? sIgnoreHeader : sInit); - //status = sInit; - while(m_bit != m_eit) - { - c = *m_bit; - switch(status) - { - case sInit: - if(isnl(c)) - status = sNewline; - else - status = sName; - continue; - case sIgnoreLine: - if(!isnl(c)) - break; - status = sNewline; - continue; - case sNewline: - status = sWaitingName; - if(pos > 0) - { - pos = 0; - prev = c; - if(++m_bit == m_eit) goto out; //eof - c = *m_bit; - if(c == (prev == CR ? LF : CR)) - { - --pos; - break; - } else - continue; - } else { - // empty line, end of header - prev = c; - if(++m_bit == m_eit) goto out; //eof - c = *m_bit; - if(c == (prev == CR ? LF : CR)) - ++m_bit; - goto out; - } - case sWaitingName: - if(isblank(c)) - { - // folded value - status = sWaitingFoldedValue; - continue; - } - // not blank, new field or empty line - if(nPos) - { - name[nPos] = 0; - // is not an empty field (name: \n) - if(vPos) - { - value[vPos] = 0; - addField(name,value); - } else - addField(name,""); - nPos = vPos = 0; - } - status = (isnl(c) ? sNewline : sName); - continue; - case sWaitingValue: - if(isblank(c)) - break; // eat leading blanks - status = sValue; - continue; - case sWaitingFoldedValue: - if(isblank(c)) - break; // eat leading blanks - append(value, vBufSz, ' ', vPos); - status = sValue; - continue; - case sName: - if(c > 32 && c < 127 && c != ':') { - if(nPos > 0 && isblank(name[nPos-1])) - { - /* "FIELDNAME BLANK+ c" found, consider that the first - body line */ - onBlock(name, (int)nPos, peBody); - goto out; - } - append(name, nBufSz, c, nPos); - } else if(c == ':') { - if(nPos == 0) - { - /* header line starting with ':', ignore the line */ - status = sIgnoreLine; - continue; - } - - /* malformed fix: remove any trailing blanks of the field - name */ - while(nPos > 0 && isblank(name[nPos-1])) - nPos--; - - status = sWaitingValue; - } else if(isblank(c)) { - /* blank after the field name -> malformed; it may be a - malformed field with trailing blank or - the start of the body; save the char so we can try to - recover later trimming the field name or push the - whole line to the body part with onBlock() */ - append(name, nBufSz, c, nPos); - } else { - /* bad header line or blank line between header and body is - missing; consider we're in the first line of the body */ - onBlock(name, (int)nPos, peBody); - goto out; - } - break; - case sValue: - if(isnl(c)) - { - status = sNewline; - continue; - } - append(value, vBufSz, c, vPos); - break; - case sIgnoreHeader: - if(isnl(c)) - { - prev = c; - if(++m_bit == m_eit) goto out; //eof - c = *m_bit; - if(c == (prev == CR ? LF : CR)) - ++m_bit; - if(pos == 0) - goto out; //empty line, eoh - pos = 0; - continue; - } - break; - } - ++m_bit; ++pos; - } - out: - if(name) - delete[] name; - if(value) - delete[] value; - return; - } - void loadBody() - { - switch(getType()) - { - case etRfc822: - if(m_iMask & imBody) - jump_to_next_boundary(); - else - copy_until_boundary(peBody); - break; - case etMultipart: - loadMultipart(); - break; - case etMsgRfc822: - if(m_iMask & imChildParts) - jump_to_next_boundary(); - else { - pushNewChild(); - doLoad(); // load child entities - popChild(); - } - break; - } - } - void loadMultipart() - { - std::string boundary = getBoundary(); - m_boundaryList.push_front(boundary); - ParsingElem pe; - // preamble - pe = (m_iMask & imPreamble ? peIgnore : pePreamble ); - copy_until_boundary(pe); - while(m_bit != m_eit) - { - switch(m_lastBoundary) - { - case NoBoundary: - return; // eof - case Boundary: - if(m_iMask & imChildParts) - jump_to_next_boundary(); - else { - pushNewChild(); - doLoad(); - popChild(); - } - break; - case ClosingBoundary: - m_boundaryList.erase(m_boundaryList.begin()); - // epilogue - pe=(m_iMask & imEpilogue? peIgnore: peEpilogue); - copy_until_boundary(pe); - return; - case HigherLevelBoundary: - m_boundaryList.erase(m_boundaryList.begin()); - return; - } - } - } - inline void onBlock(const char* block, int sz, ParsingElem pe) - { - switch(pe) - { - case peIgnore: - return; - case pePreamble: - appendPreambleBlock(block, sz); - break; - case peEpilogue: - appendEpilogueBlock(block, sz); - break; - case peBody: - appendBodyBlock(block, sz); - break; - } - } - void jump_to_next_boundary() - { - copy_until_boundary(peIgnore); - } - // this is where most of execution time is spent when parsing - // large messages; I'm using a plain char[] buffer instead of - // std::string because I want to be as fast as possible here - virtual void copy_until_boundary(ParsingElem pe) - { - size_t pos, lines, eomsz = 0; - char c; - enum { nlsz = 1 }; - const char *eom = 0; - - enum { blksz = 4096 }; - char block[blksz]; - size_t blkpos = 0; - size_t sl_off = 0; // start of line offset into *block - - pos = lines = 0; - while(m_bit != m_eit) - { - // if buffer is full - if(blkpos >= blksz - 2 - nlsz) - { - if(sl_off == 0) - { - // very long line found, assume it - // can't be a boundary and flush the buf - // with the partial line - block[blkpos] = 0; - onBlock(block, (int)blkpos, pe); - blkpos = sl_off = 0; - } else { - // flush the buffer except the last - // (probably incomplete) line - size_t llen = blkpos - sl_off; - onBlock(block, (int)sl_off, pe); - memmove(block, block + sl_off, llen); - sl_off = 0; - blkpos = llen; - } - } - c = *m_bit; - if(isnl(c)) - { - char nlbuf[3] = { 0, 0, 0 }; - - nlbuf[0] = c; // save the current NL char in nlbuf - - // save the second char of the NL sequence (if any) in nlbuf - if(++m_bit != m_eit) - { - char next = *m_bit; - if(next == (c == CR ? LF : CR)) - { - nlbuf[1] = next; // save the next char in the NL seq - ++m_bit; - } - } - - if(pos) - { - // not an empty row, is this a boundary? - block[blkpos] = 0; - if(block[sl_off] == '-' && sl_off < blkpos && - block[sl_off+1] == '-') - { - std::string Line(block+sl_off, blkpos-sl_off); - if(isBoundary(Line)) - { - // trim last newline - if (sl_off>=2) - { - size_t i = sl_off; - char a = block[--i]; - char b = block[--i]; - - if(isnl(a,b)) - sl_off -= 2; - else if(isnl(a)) - sl_off--; - - } else if (sl_off==1 && isnl(block[0])) { - sl_off--; - } - onBlock(block, (int)sl_off, pe); - return; - } - } - // exit if this is the end of message - // marker - if(eom && pos >= eomsz) - { - char *line = block + sl_off; - size_t i = 0; - for(; i < eomsz; i++) - if(eom[i] != line[i]) - break; - if(i==eomsz) // if eom found - { - onBlock(block, (int)sl_off, pe); - return; - } - } - } - // append the saved NL sequence - for(int i = 0; nlbuf[i] != 0; i++) - block[blkpos++] = nlbuf[i]; - block[blkpos] = 0; - sl_off = blkpos; - pos = 0; - } else { - pos++; // line pos - block[blkpos++] = c; - ++m_bit; - } - } - // eof - block[blkpos] = 0; - onBlock(block, (int)blkpos, pe); - } -}; - - -/* - * Forward Iterator - */ -template -struct IteratorParser: - public IteratorParser -{ - /* input_iterator ops - * *it = xxx - * X& op++ - * X& op++(int) - */ - typedef IteratorParser base_type; - IteratorParser(MimeEntity& me) - : base_type(me) - { - } -}; - -/* - * Bidirectional Iterator - */ -template -struct IteratorParser: - public IteratorParser -{ - typedef IteratorParser base_type; - IteratorParser(MimeEntity& me) - : base_type(me) - { - } -}; - -/* - * Random Access Iterator - */ -template -struct IteratorParser: - public IteratorParser -{ - typedef IteratorParser base_type; - IteratorParser(MimeEntity& me) - : base_type(me) - { - } -private: - using base_type::peIgnore; - using base_type::pePreamble; - using base_type::peBody; - using base_type::peEpilogue; - - using base_type::NoBoundary; - using base_type::Boundary; - using base_type::ClosingBoundary; - using base_type::HigherLevelBoundary; - - using base_type::m_boundaryList; - using base_type::m_lastBoundary; - using base_type::m_entityStack; - using base_type::m_me; - using base_type::m_iMask; - using base_type::m_bit; - using base_type::m_eit; - using base_type::isnl; - - typedef TreeNode BoundaryTree; - inline void onBlock(Iterator bit, int size, ParsingElem pe) - { - if(pe == peIgnore) - return; - Iterator eit = bit + size; - MimeEntity* pMe = m_entityStack.top(); - switch(pe) - { - case pePreamble: - pMe->body().preamble().append(bit, eit); - break; - case peEpilogue: - pMe->body().epilogue().append(bit, eit); - break; - case peBody: - pMe->body().append(bit, eit); - break; - } - } - void copy_until_boundary(ParsingElem pe) - { - // if we don't have any boundary copy until m_eit and return - if(m_boundaryList.empty()) - { - onBlock(m_bit, m_eit-m_bit, pe); - m_bit = m_eit; - return; - } - // search for current boundary; if not found (i.e. malformed - // message) repeat the search for higher level boundary - // (slow just for malformed msg, very fast otherwise) - typename base_type::BoundaryList::const_iterator - bBit = m_boundaryList.begin(), bEit = m_boundaryList.end(); - m_lastBoundary = NoBoundary; - int depth = 0; - for( ;bBit != bEit; ++bBit, ++depth) - { - const std::string& boundary = *bBit; - Iterator off; - if( (off=utils::find_bm(m_bit,m_eit,boundary)) != m_eit) - { - Iterator base = m_bit; - size_t block_sz = off - base; - m_lastBoundary = - (depth ? HigherLevelBoundary: Boundary); - off += boundary.length(); - m_bit = off; - if(offbegin(); - const char *w = bit->c_str(); - do - { - it = find_if(pChilds->begin(), pChilds->end(), - FindNodePred(*w)); - if( it == pChilds->end() ) - it = pChilds->insert(pChilds->end(),*w); - pChilds = &it->childList(); - depth++; - } while(*(++w)); - } - } - -}; - -} - -#endif diff --git a/mimetic098/parser/itparserdecl.h b/mimetic098/parser/itparserdecl.h deleted file mode 100644 index 2e51f17b6..000000000 --- a/mimetic098/parser/itparserdecl.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma GCC system_header - -#ifndef _MIMETIC_ITPARSER_DECL_H_ -#define _MIMETIC_ITPARSER_DECL_H_ - -namespace mimetic -{ - -// gcc gives a warning if I move this into IteratorParser -typedef unsigned int ParsingElem; - -/** - * Ignore Mask - * constants to use with load(...) functions if you don't want to load - * in memory the whole message but just some parts of it - * to save execution memory and time - */ -enum { - imNone = 0, - imHeader = 1 << 6, - imBody = 1 << 7, - imChildParts = 1 << 8, - imPreamble = 1 << 9, - imEpilogue = 1 << 10 -}; - -// forward declaration -template -struct IteratorParser; - -} - -#endif - diff --git a/mimetic098/rfc822/address.cxx b/mimetic098/rfc822/address.cxx deleted file mode 100644 index 269e9b567..000000000 --- a/mimetic098/rfc822/address.cxx +++ /dev/null @@ -1,193 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: address.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -#include - -namespace mimetic -{ -using namespace std; -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// Rfc822::Address -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// address = mailbox / group - -Address::Address() -: m_isGroup(false) -{ -} -/** - * Construct an Address object reading free form text from \p ctext - * \param text input text - */ -Address::Address(const char* text) -: m_isGroup(false) -{ - set(text); -} - -/** - Construct an Address object reading free form text from \p text - \param text input text - */ -Address::Address(const string& text) -: m_isGroup(false) -{ - set(text); -} - - -void Address::set(const string& text) -{ - bool in_dquote = false; - m_isGroup = false; - string::const_iterator p = text.begin(); - for(; p < text.end(); ++p) - { - if(*p == '"') { - in_dquote = !in_dquote; - } else if(*p == ':' && !in_dquote) { - m_isGroup = true; - m_group = Group(text); - return; - } else if(*p == '<' && !in_dquote) { - m_mbx = Mailbox(text); - return; - } - } - m_mbx = Mailbox(text); - return; -} - -std::string Address::str() const -{ - if(isGroup()) - return m_group.str(); - else - return m_mbx.str(); -} - -/** - * \return returns true if *this represents a \e group as defined in RFC822 - * \return false if *this represents a \e mailbox as defined in ../RFC/rfc822.txt - */ -bool Address::isGroup() const -{ - return m_isGroup; -} - - -/** - * \return Mailbox object pointer or NULL if this->isGroup() - */ -Mailbox& Address::mailbox() -{ return m_mbx; } - -/** - * \return const Mailbox object pointer or NULL if this->isGroup() - */ -const Mailbox& Address::mailbox() const -{ return m_mbx; } - -/** - * \return Group object pointer or NULL if !this->isGroup() - */ -Group& Address::group() -{ return m_group; } - -/** - * \return const Group object pointer or NULL if !this->isGroup() - */ -const Group& Address::group() const -{ return m_group; } - -FieldValue* Address::clone() const -{ - return new Address(*this); -} - - -bool Address::operator==(const Address& r) const -{ - return ( isGroup() ? m_group == r.m_group : m_mbx == r.m_mbx ); -} - -bool Address::operator!=(const Address& r) const -{ - return !operator==(r); -} - -} - diff --git a/mimetic098/rfc822/address.h b/mimetic098/rfc822/address.h deleted file mode 100644 index c794faa96..000000000 --- a/mimetic098/rfc822/address.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: address.h,v 1.14 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_ADDRESS_H_ -#define _MIMETIC_RFC822_ADDRESS_H_ -#include -#include -#include -#include - -namespace mimetic -{ -/// Address class as defined by RFC822 -/*! - - Address class is a C++ representation of RFC822 \e address structure. - Use this class to parse fields that contains email addresses or email group. - - \code - Rfc822::Address adr(msg.from()); - if(adr.isGroup()) - cout << *adr.group(); - else - cout << *adr.mailbox(); - \endcode - - \sa RFC822 - */ -struct Address: public FieldValue -{ - Address(); - Address(const char*); - Address(const std::string&); - bool isGroup() const; - Mailbox& mailbox(); - const Mailbox& mailbox() const; - Group& group(); - const Group& group() const; - void set(const std::string&); - std::string str() const; - bool operator==(const Address&) const; - bool operator!=(const Address&) const; -private: - FieldValue* clone() const; - Mailbox m_mbx; - Group m_group; - bool m_isGroup; -}; - - -} - -#endif - diff --git a/mimetic098/rfc822/addresslist.cxx b/mimetic098/rfc822/addresslist.cxx deleted file mode 100644 index 120461eb1..000000000 --- a/mimetic098/rfc822/addresslist.cxx +++ /dev/null @@ -1,153 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: addresslist.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -#include - -namespace mimetic -{ - -using namespace std; - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// Rfc822::AddressList -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// 1#address (i.e. comma-separated list of address) - -AddressList::AddressList() -{ -} -/** - Parses \p text and adds Address objects to the list - \param text input text - */ -AddressList::AddressList(const string& text) -{ - set(text); -} - -AddressList::AddressList(const char* cstr) -{ - set(cstr); -} - -void AddressList::set(const string& text) -{ - bool in_group = false, in_dquote = false; - int blanks = 0; - string item; - string::const_iterator p = text.begin(); - string::const_iterator beg = p; - for(; p < text.end(); p++) - { - if(*p == '"') { - in_dquote = !in_dquote; - } else if(*p == ':' && !in_dquote) { - in_group = true; - } else if(*p == ';' && !in_dquote) { - in_group = false; - } else if(*p == ',' && !in_dquote) { - if(in_group) - continue; - push_back(Address(string(beg,p))); - beg = p + 1; - blanks = 0; - } else if(*p == ' ') { - blanks++; - } - } - if( (p-beg) != blanks)// not a only-blanks-string - push_back(Address(string(beg,p))); -} - -std::string AddressList::str() const -{ - string rs; - const_iterator first = begin(), bit = first, eit = end(); - for(; bit != eit; ++bit) - { - if(bit != first) - rs += ", "; - rs += bit->str(); - } - return rs; -} - -FieldValue* AddressList::clone() const -{ - return new AddressList(*this); -} - -} diff --git a/mimetic098/rfc822/addresslist.h b/mimetic098/rfc822/addresslist.h deleted file mode 100644 index 85cebfad5..000000000 --- a/mimetic098/rfc822/addresslist.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: addresslist.h,v 1.12 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_ADDRESSLIST_H_ -#define _MIMETIC_RFC822_ADDRESSLIST_H_ -#include -#include -#include -#include -namespace mimetic -{ - -/// List of Address -/** - AddressList class is a container class that holds Address objects which, - in turn can be a Group or a Mailbox. - - \code - const char* str = "dest@domain.com, friends: one@friends.net, " - "two@friends.net;, last@users.com"; - AddressList aList(str); - AddressList::const_iterator bit(aList.begin()), eit(aList.end()); - for(; bit != eit; ++bit) - { - Address& adr = *bit; - if(adr.isGroup()) - cout << *adr.group(); - else - cout << *adr.mailbox(); - } - \endcode - - \sa RFC822 - */ -struct AddressList: public FieldValue, public std::vector
    -{ - AddressList(); - AddressList(const char*); - AddressList(const std::string&); - - std::string str() const; - void set(const std::string&); -protected: - FieldValue* clone() const; -private: -}; - - -} - -#endif diff --git a/mimetic098/rfc822/body.h b/mimetic098/rfc822/body.h deleted file mode 100644 index 019fdca34..000000000 --- a/mimetic098/rfc822/body.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: body.h,v 1.9 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_BODY_H_ -#define _MIMETIC_RFC822_BODY_H_ -#include -namespace mimetic -{ - -/// RFC822 body type -typedef std::string Rfc822Body; - -} -#endif diff --git a/mimetic098/rfc822/datetime.cxx b/mimetic098/rfc822/datetime.cxx deleted file mode 100644 index 24ce99403..000000000 --- a/mimetic098/rfc822/datetime.cxx +++ /dev/null @@ -1,482 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: datetime.cxx,v 1.4 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -#include - -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" - -#include -#include -#include -#include - - -namespace mimetic -{ - - -using namespace std; -using namespace mimetic; - -DateTime::Zone::Zone(int iZone) -: m_iZone(iZone), m_iZoneIdx(0) -{ - for(int i = 0; ms_offset[i] != 0; ++i) - if(iZone == ms_offset[i]) - { - m_iZoneIdx = i; - } -} -DateTime::Zone::Zone(const string& txt) -: m_iZone(0), m_iZoneIdx(0), m_sZone(txt) -{ - if(txt.empty()) - return; - istring iTxt(txt.begin(), txt.end()); - for(int i = 0; ms_label[i] != 0; ++i) - { - if(iTxt == ms_label[i]) - { - m_iZone = ms_offset[i]; - m_iZoneIdx = i; - } - } - if(m_iZone == 0) - { // check if txt is a numeric timezone (+0200) - string tz = txt; - if(tz[0] == '+' || tz[0] == '-' || (tz[0] >= '0' && tz[0] <= '9')) - { - int sign = (tz[0] == '-' ? -1 : 1); - tz.erase(0,1); - m_iZone = utils::str2int(tz) * sign; - } - } -} -bool DateTime::Zone::operator==(const string& mText) -{ - istring txt(mText.begin(), mText.end()); - return txt == ms_label[m_iZoneIdx] || - utils::str2int(mText) == ms_offset[m_iZoneIdx]; -} -bool DateTime::Zone::operator==(int iZone) -{ - return m_iZone == iZone; -} -string DateTime::Zone::name() const -{ - if(m_iZoneIdx) - return ms_label[m_iZoneIdx]; - else { - string sTz = utils::int2str(m_iZone); - if(m_iZone >= 0) - { - sTz.insert(0u, 4-sTz.length(),'0'); // add zeroes - sTz.insert(0u, 1, '+'); - } else { - sTz.insert(1, 5-sTz.length(),'0'); // add zeroes - } - return sTz; - } -} -short DateTime::Zone::ordinal() const -{ - return m_iZone; -} - -DateTime::Month::Month(int iMonth) -: m_iMonth(iMonth) -{ - if(m_iMonth < 1 || m_iMonth > 12) - m_iMonth = 0; -} -DateTime::Month::Month(const string& txt) -: m_iMonth(0) -{ - istring iTxt(txt.begin(), txt.end()); - if(iTxt.length() == 3) - { - for(int i = 1; i < 13; ++i) - if(iTxt == ms_label[i][mnShort]) - { - m_iMonth = i; - return; - } - } else { - for(int i = 1; i < 13; ++i) - if(iTxt == ms_label[i][mnLong]) - { - m_iMonth = i; - return; - } - } -} -bool DateTime::Month::operator==(const string& mText) const -{ - istring imText(mText.begin(), mText.end()); - return imText == ms_label[m_iMonth][mnShort] || - imText == ms_label[m_iMonth][mnLong]; -} -bool DateTime::Month::operator==(int iMonth) const -{ - return m_iMonth == iMonth; -} -string DateTime::Month::name(bool longName) const -{ - return ms_label[m_iMonth][longName ? mnLong : mnShort]; -} -short DateTime::Month::ordinal() const -{ - return m_iMonth; -} - - -DateTime::DayOfWeek::DayOfWeek(int iDayOfWeek) -: m_iDayOfWeek(iDayOfWeek) -{ - if(m_iDayOfWeek < 1 || m_iDayOfWeek > 7) - m_iDayOfWeek = 0; -} - -DateTime::DayOfWeek::DayOfWeek(const string& txt) -: m_iDayOfWeek(0) -{ - istring iTxt(txt.begin(), txt.end()); - if(iTxt.length() == 3) - { - for(int i = 1; i < 8; ++i) - if(iTxt == ms_label[i][mnShort]) - { - m_iDayOfWeek = i; - return; - } - } else { - for(int i = 1; i < 8; ++i) - if(iTxt == ms_label[i][mnLong]) - { - m_iDayOfWeek = i; - return; - } - } -} -bool DateTime::DayOfWeek::operator==(const string& mText) -{ - istring imText(mText.begin(), mText.end()); - return imText == ms_label[m_iDayOfWeek][mnShort] || - imText == ms_label[m_iDayOfWeek][mnLong]; -} -bool DateTime::DayOfWeek::operator==(int iDayOfWeek) -{ - return m_iDayOfWeek == iDayOfWeek; -} -string DateTime::DayOfWeek::name(bool longName) const -{ - return ms_label[m_iDayOfWeek][longName ? mnLong : mnShort]; -} -short DateTime::DayOfWeek::ordinal() const -{ - return m_iDayOfWeek; -} - -////////////////////////////// - -const char *DateTime::DayOfWeek::ms_label[][2] = { - {"", ""}, - {"Mon", "Monday"}, - {"Tue", "Tuesday"}, - {"Wed", "Wednesday"}, - {"Thu", "Thursday"}, - {"Fri", "Friday"}, - {"Sat", "Saturday"}, - {"Sun", "Sunday"}, - {0, 0} -}; - -const char *DateTime::Month::ms_label[][2] = { - {"", ""}, - {"Jan", "January"}, - {"Feb", "February"}, - {"Mar", "March"}, - {"Apr", "April"}, - {"May", "May"}, - {"Jun", "June"}, - {"Jul", "July"}, - {"Aug", "August"}, - {"Sep", "September"}, - {"Oct", "October"}, - {"Nov", "November"}, - {"Dec", "December"}, - {0, 0} -}; - -//const char *DateTime::Zone::ms_label[] = { -// "UT", "GMT","EST","EDT","CST", "CDT", "MST", "MDT","PST", "PDT", 0 -//}; - -const char *DateTime::Zone::ms_label[] = { -"UNK", -"GMT", "UT", "BST", "CET", -"MET", "EET", "IST","METDST", "MET DST", -"EDT", "CDT", "EST", "CST", -"MDT", "MST", "PDT", "HKT", -"PST", "JST", 0 -}; - -int DateTime::Zone::ms_offset[] = { -0, -+000, +000, +100, +100, -+100, +200, +200, +200, +200, --400, -500, -500, -600, --600, -700, -700, +800, --800 +900, -0 -}; - -/** - * Default constructor sets the Date to the Epoch (00:00:00 UTC, January 1, 1970) - */ -DateTime::DateTime() -: m_iDayOfWeek(0), m_iDay(1), m_iMonth(1), m_iYear(1970), - m_iHour(0), m_iMinute(0), m_iSecond(0), - m_zone("UTC") -{ -} - -DateTime::DateTime(const string& text) -: m_iDayOfWeek(0), m_iDay(1), m_iMonth(1), m_iYear(1970), - m_iHour(0), m_iMinute(0), m_iSecond(0), - m_zone("UTC") -{ - set(text); -} - -DateTime::DateTime(const char* cstr) -: m_iDayOfWeek(0), m_iDay(1), m_iMonth(1), m_iYear(1970), - m_iHour(0), m_iMinute(0), m_iSecond(0), - m_zone("UTC") -{ - set(cstr); -} - -void DateTime::set(const string& input) -{ - if(input.empty()) - return; - string can_input = remove_external_blanks(canonical(input)); - StringTokenizer stok(&can_input, " ,"); - string tok; int i = 0; - if(!stok.next(tok)) return; - if(!tok.empty() && !isdigit(tok[0])) - m_iDayOfWeek = DayOfWeek(tok).ordinal(); - else { - // there's no day of week - m_iDay = utils::str2int(tok); - ++i; - } - - // gg mon aa[aa] - while(i < 3) - { - if(!stok.next(tok)) return; - if(tok.empty()) - continue; /* there's a ' ' after ',' ("Wed, 23 Nov...") */ - switch(i) - { - case 0: m_iDay = utils::str2int(tok); break; - case 1: m_iMonth = Month(tok).ordinal(); break; - case 2: m_iYear = utils::str2int(tok); break; - } - ++i; - } - - stok.setDelimList(" :"); - for(i = 0; i < 3; ++i) - { - if(!stok.next(tok)) return; - switch(i) - { - case 0: m_iHour = utils::str2int(tok); break; - case 1: m_iMinute = utils::str2int(tok); break; - case 2: // seconds field is optional - if(tok.length() == 2) - { - m_zone = ""; - m_iSecond = utils::str2int(tok); - } else { - m_zone = tok; - } - break; - } - } - - stok.setDelimList(" "); - // handles multi word timezones (MET DST) - while(stok.next(tok)) - { - if(!m_zone.empty()) - m_zone += " "; - m_zone += tok; - } -} - - -/* - based on an algorithm of J.I. Perelman [1907]. -*/ -DateTime::DayOfWeek DateTime::dayOfWeek() const -{ - if(!m_iDayOfWeek) - { // code from C-Faq Question 20.31 - int y = year(), m = month().ordinal(), d = day(); - static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; - y -= m < 3; - m_iDayOfWeek = (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; - // we use 1(Mon)..7 not 0(Sun)..6 as returned by the previous algorithm - // so convert - m_iDayOfWeek = (m_iDayOfWeek == 0 ? 7 : m_iDayOfWeek); - } - return DayOfWeek(m_iDayOfWeek); -} - -short DateTime::day() const -{ - return m_iDay; -} - -DateTime::Month DateTime::month() const -{ - return Month(m_iMonth); -} - -short DateTime::year() const -{ - return m_iYear; -} - -short DateTime::hour() const -{ - return m_iHour; -} - -short DateTime::minute() const -{ - return m_iMinute; -} - -short DateTime::second() const -{ - return m_iSecond; -} - -DateTime::Zone DateTime::zone() const -{ - return Zone(m_zone); -} - - -std::string DateTime::str() const -{ - stringstream ss; - ss << *this; - return ss.str(); -} - -FieldValue* DateTime::clone() const -{ - return new DateTime(*this); -} - -ostream& operator<<(ostream& os, const DateTime& dt) -{ - size_t width = os.width(), fill = os.fill(); - - os << dt.dayOfWeek().name() << ", " - << setw(2) << setfill('0') << dt.day() << " " - << dt.month().name() << " " - << setw(2) << setfill('0') << dt.year() << " " - << setw(2) << setfill('0') << dt.hour() << ":" - << setw(2) << setfill('0') << dt.minute() << ":" - << setw(2) << setfill('0') << dt.second() << " " - << dt.zone().name(); - - os.width(width); - os.fill(fill); - return os; -} - - -} - diff --git a/mimetic098/rfc822/datetime.h b/mimetic098/rfc822/datetime.h deleted file mode 100644 index 4d9c5a6bf..000000000 --- a/mimetic098/rfc822/datetime.h +++ /dev/null @@ -1,116 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: datetime.h,v 1.13 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_DATETIME_H -#define _MIMETIC_RFC822_DATETIME_H -#include -#include -#include -#include - -namespace mimetic -{ - - -/// RFC822 DateTime field representation -struct DateTime: public FieldValue -{ - struct DayOfWeek { - enum DayName { mnShort = 0, mnLong = 1 }; - DayOfWeek(int iDayOfWeek); - DayOfWeek(const std::string&); - bool operator==(const std::string&); - bool operator==(int iDayOfWeek); - std::string name(bool longName = false) const; - short ordinal() const; - private: - static const char *ms_label[][2]; - short m_iDayOfWeek; - }; - struct Month { - enum MonthName { mnShort = 0, mnLong = 1 }; - Month(int iMonth); - Month(const std::string& ); - bool operator==(const std::string& ) const; - bool operator==(int iMonth) const; - std::string name(bool longName = false) const; - short ordinal() const; - private: - static const char *ms_label[][2]; - short m_iMonth; - }; - struct Zone { - Zone(int iZone); - Zone(const std::string& ); - bool operator==(const std::string&); - bool operator==(int iZone); - std::string name() const; - short ordinal() const; - private: - static int ms_offset[]; - static const char *ms_label[]; - short m_iZone, m_iZoneIdx; - std::string m_sZone; - }; - - // DateTime - enum { - Jan = 1, Feb, Mar, Apr, May, Jun, Jul, - Aug, Sep, Oct, Nov, Dec - }; - enum { - Mon = 1, Tue, Wed, Thu, Fri, Sat, Sun - }; - - enum { - GMT = +000, - UT = +000, - BST = +100, - CET = +100, - MET = +100, - EET = +200, - IST = +200, - METDST= +200, - EDT = -400, - CDT = -500, - EST = -500, - CST = -600, - MDT = -600, - MST = -700, - PDT = -700, - HKT = +800, - PST = -800, - JST = +900 - }; - DateTime(); - DateTime(const char*); - DateTime(const std::string&); - DayOfWeek dayOfWeek() const; - short day() const; - Month month() const; - short year() const; - short hour() const; - short minute() const; - short second() const; - Zone zone() const; - std::string str() const; - friend std::ostream& operator<<(std::ostream&, const DateTime&); -protected: - FieldValue* clone() const; -private: - void set(const std::string&); - mutable int m_iDayOfWeek; - int m_iDay, m_iMonth, m_iYear; - int m_iHour, m_iMinute, m_iSecond; - std::string m_zone; -}; - - -} - -#endif diff --git a/mimetic098/rfc822/field.cxx b/mimetic098/rfc822/field.cxx deleted file mode 100644 index 80c6b7940..000000000 --- a/mimetic098/rfc822/field.cxx +++ /dev/null @@ -1,273 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: field.cxx,v 1.7 2009-02-27 15:56:34 tat Exp $ - ***************************************************************************/ - -#pragma GCC diagnostic ignored "-Wsign-conversion" - -#include -#include -#include -#include -#include - -namespace mimetic -{ - -using namespace std; - -// static init -const Field Field::null; - -/** - Constructs a null Field -*/ -Field::Field() -:m_pValue(0) -{ -} - - -/** - Parses \p line and sets \e name, \e value and \e valueText of *this - \param line input field string as defined in RFC822 (fieldname: text) -*/ -Field::Field(const string& line) -:m_pValue(0) -{ - string::size_type colon = line.find(':'); - if(colon != std::string::npos) - { - m_name.assign(line.begin(), line.begin() + colon); - size_t i; - for(i = 1 + colon; i < line.length() - 1 && line[i] == ' '; ++i) - ; // skip spaces before field-body - string val(line.begin() +i, line.end()); - value(val); - } -} - - -/** - Initialize *this with \p n and \p v - \param n field %name - \param v content of the %field -*/ -Field::Field(const string& n , const string& v) -:m_pValue(0) -{ - m_name.assign(n); - m_pValue = new StringFieldValue(v); -} - -/** - Copy constructor -*/ -Field::Field(const Field& r) -:m_name(r.m_name), m_pValue(0) -{ - if(r.m_pValue) - m_pValue = r.m_pValue->clone(); -} - -Field& Field::operator=(const Field& r) -{ - m_name.assign(r.m_name); - if(m_pValue) - { - delete m_pValue; - m_pValue = 0; - } - if(r.m_pValue) - m_pValue = r.m_pValue->clone(); - return *this; -} - -/** - Destructor -*/ -Field::~Field() -{ - if(m_pValue) - { - delete m_pValue; - m_pValue = 0; - } -} - -/** - Sets the field name to \p n - \param name new %field %name -*/ -void Field::name(const string& name) -{ - m_name.assign(name); - if(m_pValue != 0) - { - delete m_pValue; - m_pValue = 0; - } -} - -/** - Sets the field value to \p v - \param val new %value %name -*/ -void Field::value(const string& val) -{ - if(m_pValue == 0) - m_pValue = new StringFieldValue(val); - else - m_pValue->set(val); -} - -/** - Returns the field name -*/ -const istring& Field::name() const -{ - return m_name; -} - - - - -/** - Returns the field value. -*/ -string Field::value() const -{ - if(m_pValue == 0) - return nullstring; - return m_pValue->str(); -} - -std::ostream& operator<<(std::ostream& os, const Field& f) -{ - return f.write(os, 0); -} - -ostream& Field::write(ostream& os, unsigned int fold) const -{ - int in_quote, prev, skip; - - // default folding idiot-algorithm - // override to customize - if(fold) - { - int i; - int sp; - string ostr = name() + ": " + value(); - - // skip the "fieldname: " part just on the first inner iteration - skip = (int)name().length() + 2; - - while(ostr.length() > fold) - { - prev = 0; // prev char processed - in_quote = 0; - sp = 0; - - for(i = skip; i < (int)(ostr.length()); ++i) - { - if(ostr[i] == '"' && prev != '\\') - in_quote = !in_quote; - - if(!in_quote && isblank(ostr[i])) - sp = i; // last blank found - - if(i >= (int)fold && sp) - { - os.write(ostr.c_str(), sp); - ostr.erase(0, 1+sp); - if(ostr.length() && !utils::string_is_blank(ostr)) - os << crlf << "\t"; // keep folding - break; - } - - prev = ostr[i]; - } - if(sp == 0) - break; // can't fold anymore - skip = 0; - } - - os << ostr; - return os; - } else - return os << name() << ": " << value(); -} - - -} diff --git a/mimetic098/rfc822/field.h b/mimetic098/rfc822/field.h deleted file mode 100644 index c638c2fd8..000000000 --- a/mimetic098/rfc822/field.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: field.h,v 1.14 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_FIELD_H_ -#define _MIMETIC_RFC822_FIELD_H_ -#include -#include -#include - -namespace mimetic -{ - - - -/// Field class as defined by RFC822 -/** - Field class is a C++ representation of RFC822 \e header \e field. - Use this class when you need to create or parse messages' header fields. - Note that field name is case insensitive. - - Parsing: - \code - Rfc822::Field f1("X-My-Field: some text(with a trailing comment)"); - cout << f.name() << endl; - cout << f.value() << endl; - cout << f.value(true) << endl; // canonicalize (see RFC822) - \endcode - - Building: - \code - Rfc822::Field f; - f.name("X-Unknown"); - f.value("some text(with a trailing comment)"); - cout << f; - \endcode - - \sa RFC822 - */ -struct Field -{ - typedef mimetic::istring istring; - static const Field null; - Field(); - Field(const std::string&); - Field(const std::string&, const std::string&); - ~Field(); - - Field(const Field&); - Field& operator=(const Field&); - - void name(const std::string&); - const istring& name() const; - - void value(const std::string&); - std::string value() const; - - std::ostream& write(std::ostream&, unsigned int fold = 0) const; - friend std::ostream& operator<<(std::ostream&, const Field&); -private: - friend class Rfc822Header; - istring m_name; - FieldValue* m_pValue; -}; - - -} -#endif diff --git a/mimetic098/rfc822/fieldvalue.cxx b/mimetic098/rfc822/fieldvalue.cxx deleted file mode 100644 index f29a32322..000000000 --- a/mimetic098/rfc822/fieldvalue.cxx +++ /dev/null @@ -1,143 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: fieldvalue.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include -namespace mimetic -{ -using namespace std; - -std::ostream& operator<<(std::ostream& os, const FieldValue& fv) -{ - return os << fv.str(); -} - -FieldValue::FieldValue() -:m_typeChecked(true) // true for all class that don't handle this flag -{ -} - -FieldValue::~FieldValue() -{ -} - -bool FieldValue::typeChecked() const -{ - return m_typeChecked; -} - -void FieldValue::typeChecked(bool b) -{ - m_typeChecked = b; -} - -// StringFieldValue -StringFieldValue::StringFieldValue() -{ - typeChecked(false); -} - -StringFieldValue::StringFieldValue(const string& val) -: m_value(val) -{ - typeChecked(false); -} - -void StringFieldValue::set(const string& val) -{ - m_value = val; -} - -std::string StringFieldValue::str() const -{ - return m_value; -} - -const std::string& StringFieldValue::ref() const -{ - return m_value; -} - -std::string& StringFieldValue::ref() -{ - return m_value; -} - -FieldValue* StringFieldValue::clone() const -{ - return new StringFieldValue(*this); -} - - -} diff --git a/mimetic098/rfc822/fieldvalue.h b/mimetic098/rfc822/fieldvalue.h deleted file mode 100644 index 8c2abd109..000000000 --- a/mimetic098/rfc822/fieldvalue.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: fieldvalue.h,v 1.13 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_FIELDVALUE_H_ -#define _MIMETIC_RFC822_FIELDVALUE_H_ -#include -#include - -namespace mimetic -{ - - -/// Value of an header field (base class) -struct FieldValue -{ - FieldValue(); - virtual ~FieldValue(); - virtual void set(const std::string& val) = 0; - virtual std::string str() const = 0; - virtual FieldValue* clone() const = 0; - friend std::ostream& operator<<(std::ostream&, const FieldValue&); -protected: - friend class Rfc822Header; - bool typeChecked() const; - void typeChecked(bool); -private: - bool m_typeChecked; -}; - -/// Unstructured field value -struct StringFieldValue: public FieldValue -{ - StringFieldValue(); - StringFieldValue(const std::string&); - void set(const std::string&); - std::string str() const; - const std::string& ref() const; - std::string& ref(); -protected: - FieldValue* clone() const; -private: - std::string m_value; -}; - -} - -#endif - diff --git a/mimetic098/rfc822/group.cxx b/mimetic098/rfc822/group.cxx deleted file mode 100644 index 06ca21cbe..000000000 --- a/mimetic098/rfc822/group.cxx +++ /dev/null @@ -1,186 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: group.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ - -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" - -#include -#include - -namespace mimetic -{ - -using namespace std; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// Rfc822::Group -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// group = phrase ":" [#mailbox] ";" -Group::Group() -{ -} - -Group::Group(const char* cstr) -{ - set(cstr); -} - -Group::Group(const string& text) -{ - set(text); -} - -static string::size_type find_not_in_quote(const string& s, const string::value_type& c) -{ - size_t len = s.length(); - bool in_dquote = false; - for(size_t i = 0; i < len; ++i) - { - if(s[i] == '"') - in_dquote = !in_dquote; - else if( s[i] == c && !in_dquote) { - return i; - } - } - return string::npos; -} - -std::string Group::str() const -{ - string rs = m_name; - const_iterator bit = begin(), first = bit, eit = end(); - for(; bit != eit; ++bit) - { - if(bit != first) - rs += ","; - rs += bit->str(); - } - return rs + ";"; -} - -void Group::set(const string& text) -{ - m_text = text; - size_type colon = find_not_in_quote(m_text, ':'); - if(colon == std::string::npos) - return; // empty or invalid - bool in_dquote = false; - int in_par = 0, in_angle = 0; - string mailbox; - string::iterator p = m_text.begin(), start; - m_name.assign(m_text, 0, colon); - m_name = remove_external_blanks(m_name); - for(p += ++colon, start = p; p < m_text.end(); ++p) - { - if(*p == ';' || *p == ',') - { - if(in_dquote || in_par || in_angle) - continue; - string mbx(start, p); - mbx = remove_external_blanks(mbx); - push_back(Mailbox(mbx)); - if(*p == ';') - return; - start = p + 1; - } else if(*p == '"') { - in_dquote = !in_dquote; - } else if(*p == '<') { - ++in_angle; - } else if(*p == '>') { - --in_angle; - } else if(*p == '(') { - ++in_par; - } else if(*p == ')') { - --in_par; - } - } - // trailing ';' missing - push_back(Mailbox(string(start, p-1))); -} - -string Group::name(int bCanonical) const -{ return (bCanonical ? canonical(m_name) : m_name); } - -void Group::name(const string& name) -{ m_name = name; } - -FieldValue* Group::clone() const -{ - return new Group(*this); -} - -} diff --git a/mimetic098/rfc822/group.h b/mimetic098/rfc822/group.h deleted file mode 100644 index 4fa0529be..000000000 --- a/mimetic098/rfc822/group.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: group.h,v 1.12 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_GROUP_H_ -#define _MIMETIC_RFC822_GROUP_H_ -#include -#include -#include - -namespace mimetic -{ - - -/// Represent the \e group type in the RFC822 -/** - Groups class is a container class that stores Rfc822::Mailbox objects. - Use this class when you need to create or parse rfc822 \e email \e groups - - Parsing: - \code - Rfc822::Group grp("drivers: first@do.com, second@dom.com, last@dom.com;"); - Rfc822::Group::const_iterator bit(grp.begin()), eit(grp.end()); - cout << "Group " << grp.name() << endl; - for(; bit != eit; ++bit) - cout << " " << *bit << endl; - \endcode - - Building: - \code - Rfc822::Group grp; - grp.push_back("first@dom.com"); - grp.push_back(Rfc822::Mailbox("second@dom.com")); - grp.push_back(string("last@dom.com")); - \endcode - - \sa RFC822 - */ -struct Group: public FieldValue, public std::vector -{ - Group(); - Group(const char*); - Group(const std::string&); - void name(const std::string&); - std::string name(int bCanonical = 0) const; - void set(const std::string&); - std::string str() const; -protected: - FieldValue* clone() const; -private: - std::string m_text, m_name; -}; - - -} -#endif diff --git a/mimetic098/rfc822/header.cxx b/mimetic098/rfc822/header.cxx deleted file mode 100644 index 140314830..000000000 --- a/mimetic098/rfc822/header.cxx +++ /dev/null @@ -1,283 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: header.cxx,v 1.3 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#include -#include -#include - -namespace mimetic -{ -using namespace std; - -// find_by_name -Rfc822Header::find_by_name::find_by_name(const std::string& name) -: m_name(name) -{ -} - -bool Rfc822Header::find_by_name::operator()(const Field& f) const -{ - return m_name == f.name(); -} - -#if 0 -// Rfc822Header -Rfc822Header::~Rfc822Header() -{ - /* - iterator bit = begin(), eit = end(); - for(; bit != eit; ++bit) - delete *bit; - */ - clear(); -} -#endif - -bool Rfc822Header::hasField(const string& name) const -{ - const_iterator it; - it = find_if(begin(),end(), find_by_name(name)); - return it != end(); -} - - -const Field& Rfc822Header::field(const std::string& name) const -{ - const_iterator it; - it = find_if(begin(),end(), find_by_name(name)); - if(it != end()) - return *it; - else - return Field::null; -} - -Field& Rfc822Header::field(const std::string& name) -{ - iterator it = find_if(begin(),end(), find_by_name(name)); - if (it != end()) return *it; - Field f; - it = insert(end(), f); - it->name(name); - it->m_pValue = new StringFieldValue; - return *it; -} - -// Sender: -const Mailbox& Rfc822Header::sender() const -{ - return getField("Sender"); -} -Mailbox& Rfc822Header::sender() -{ - return getField("Sender"); -} -void Rfc822Header::sender(const Mailbox& r) -{ - setField("Sender", r); -} - -// From: -const MailboxList& Rfc822Header::from() const -{ - return getField("From"); -} - -MailboxList& Rfc822Header::from() -{ - return getField("From"); -} - -void Rfc822Header::from(const MailboxList& mbxList) -{ - setField("From", mbxList); -} - -// Subject: -const std::string& Rfc822Header::subject() const -{ - const StringFieldValue& fv = getField("Subject"); - return fv.ref(); -} - -std::string& Rfc822Header::subject() -{ - StringFieldValue& fv = getField("Subject"); - return fv.ref(); -} - -void Rfc822Header::subject(const std::string& s) -{ - setField("Subject", StringFieldValue(s)); -} - -// To: -const AddressList& Rfc822Header::to() const -{ - return getField("To"); -} - -AddressList& Rfc822Header::to() -{ - return getField("To"); -} - -void Rfc822Header::to(const AddressList& al) -{ - setField("To", al); -} - - -// Reply-To -const AddressList& Rfc822Header::replyto() const -{ - return getField("Reply-To"); -} - -AddressList& Rfc822Header::replyto() -{ - return getField("Reply-To"); -} - -void Rfc822Header::replyto(const AddressList& al) -{ - setField("Reply-To", al); -} - -// CC -const AddressList& Rfc822Header::cc() const -{ - return getField("CC"); -} - -AddressList& Rfc822Header::cc() -{ - return getField("CC"); -} - -void Rfc822Header::cc(const AddressList& al) -{ - setField("CC", al); -} - -// BCC -const AddressList& Rfc822Header::bcc() const -{ - return getField("BCC"); -} - -AddressList& Rfc822Header::bcc() -{ - return getField("BCC"); -} - -void Rfc822Header::bcc(const AddressList& al) -{ - setField("BCC", al); -} - -// Message-ID -const MessageId& Rfc822Header::messageid() const -{ - return getField("Message-ID"); -} - -MessageId& Rfc822Header::messageid() -{ - return getField("Message-ID"); -} - -void Rfc822Header::messageid(const MessageId& al) -{ - setField("Message-ID", al); -} -#if 0 - -// Message-ID: -const Field Rfc822Header::messageid() const -{ - return getField("Message-ID"); -} -Field& Rfc822Header::messageid() -{ - return getField("Message-ID"); -} -Field& Rfc822Header::messageid(const string& value) -{ - return getField("Message-ID", value); -} - -#endif - -} diff --git a/mimetic098/rfc822/header.h b/mimetic098/rfc822/header.h deleted file mode 100644 index f073f5efe..000000000 --- a/mimetic098/rfc822/header.h +++ /dev/null @@ -1,172 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: header.h,v 1.16 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_HEADER_H_ -#define _MIMETIC_RFC822_HEADER_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mimetic -{ - - -/// RFC822 header class object -/*! - Use this class to build or parse message header fields. - This is a STL container so you can browse fields using iterators(see ex. below). - - \sa RFC822 - */ -class Rfc822Header: public std::deque -{ -public: - struct find_by_name - { - find_by_name(const std::string&); - bool operator()(const Field&) const; - private: - const istring m_name; - }; - - bool hasField(const std::string&) const; - - const Field& field(const std::string&) const; - Field& field(const std::string&); - - const Mailbox& sender() const; - Mailbox& sender(); - void sender(const Mailbox&); - - const MailboxList& from() const; - MailboxList& from(); - void from(const MailboxList&); - - const AddressList& to() const; - AddressList& to(); - void to(const AddressList&); - - const std::string& subject() const; - std::string& subject(); - void subject(const std::string&); - - const AddressList& replyto() const; - AddressList& replyto(); - void replyto(const AddressList&); - - const AddressList& cc() const; - AddressList& cc(); - void cc(const AddressList&); - - const AddressList& bcc() const; - AddressList& bcc(); - void bcc(const AddressList&); - - const MessageId& messageid() const; - MessageId& messageid(); - void messageid(const MessageId&); -protected: - template - const T& getField(const std::string&) const; - template - T& getField(const std::string&); - template - void setField(const std::string&, const T&); -}; - - -// template member functions -template -const T& Rfc822Header::getField(const std::string& name) const -{ - const_iterator it; - it = find_if(begin(), end(), find_by_name(name)); - if(it != end()) - { - // cast away constness - Field& f = const_cast(*it); - // to be sure that it's the correct type - FieldValue* pFv = f.m_pValue; - if(!pFv->typeChecked()) - { - std::string val = pFv->str(); - delete pFv; - pFv = new T(val); - f.m_pValue = pFv; - } - return static_cast(*pFv); - } else { - static const T null; - return null; - } -} -template -T& Rfc822Header::getField(const std::string& name) -{ - iterator it; - it = find_if(begin(), end(), find_by_name(name)); - if(it != end()) - { - FieldValue* pFv = it->m_pValue; - if(pFv == 0) - { - pFv = new T; - assert(pFv); - it->m_pValue = pFv; - } - // be sure that it's the correct type - else if(!pFv->typeChecked()) - { - std::string val = pFv->str(); - delete pFv; - pFv = new T(val); - it->m_pValue = pFv; - } - return static_cast(*pFv); - } else { - // insert and get the reference of the actual - // obj in the container, then modify its fields - Field f; - it = insert(end(), f); - it->name(name); - T* pT = new T; - assert(pT); - it->m_pValue = pT; - assert(it->m_pValue->typeChecked()); - return *pT; - } -} - -template -void Rfc822Header::setField(const std::string& name, const T& obj) -{ - // remove if already exists - iterator bit = begin(), eit = end(); - iterator found = find_if(bit, eit, find_by_name(name)); - if(found != eit) - erase(found); - // add field - Field f; - iterator it; - it = insert(end(), f); - it->name(name); - it->m_pValue = new T(obj); -} - -} - -#endif diff --git a/mimetic098/rfc822/mailbox.cxx b/mimetic098/rfc822/mailbox.cxx deleted file mode 100644 index b9383df84..000000000 --- a/mimetic098/rfc822/mailbox.cxx +++ /dev/null @@ -1,277 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mailbox.cxx,v 1.3 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ - -#pragma GCC diagnostic ignored "-Wsign-conversion" - -#include -#include - -namespace mimetic -{ -using namespace std; - - -/** Basic constructor */ -Mailbox::Mailbox() -{ -} - - -/** - Parses \p text and sets \e mailbox, \e domain, \e sourceroute and \e label -*/ -Mailbox::Mailbox(const char* cstr) -{ - set(cstr); -} -Mailbox::Mailbox(const string& text) -{ - set(text); -} - - -std::string Mailbox::str() const -{ - string rs; - bool hasLabel = !m_label.empty(), hasRoute = !m_route.empty(); - - if(hasLabel) - { - rs = m_label + " <"; - if(hasRoute) - rs = m_route+ ":"; - } - - rs += m_mailbox + "@" + m_domain; - if(hasLabel) - rs += ">"; - return rs; -} - -void Mailbox::set(const string& input) -{ - if(!input.size()) - return; - - // NOTE - // std::string uses copy-on-write so all char* pointer - // will be invalidated after the first modify (op+, op+=, - // string::erase, etc) so we must reset all pointers after - // the string::erase or/and we cannot cache begin() end() - - int t = (int)input.length() - 1; - if(input[t] == '>') - { - bool in_dquote = false, in_comment = false; - int endoff = t - 1; - for(int x = (int)input.length() - 1 ; x >= 0; --x) - { - string::value_type ch = input[x]; - if(in_comment && ch == '(') { - in_comment = false; - continue; - } else if(ch == ')') { - in_comment = true; - } else if(ch == '@' && m_domain.size() == 0) { - m_domain.assign(input, x+1, endoff - x); - endoff = x-1; - } else if(ch == ':') { - m_mailbox.assign(input, x+1, endoff - x); - endoff = x-1; - } else if(ch == '<') { - if(input[endoff+1] == ':') - m_route.assign(input, x+1, endoff - x); - else - m_mailbox.assign(input, x+1, endoff - x); - m_label.assign(input, 0 , x); - for(int t2 = (int)m_label.length()-1; t2 > 0; --t2) - { - if(m_label[t2] == ' ') - m_label.erase(t2, 1); - else - break; - } - return; - } else if(ch == '"') { - in_dquote = !in_dquote; - } - } - } else { - bool in_dquote = false, in_comment = false; - for(int x = (int)input.length() -1 ; x >= 0; --x) - { - string::value_type ch = input[x]; - string::size_type len = input.length(); - - if(in_comment && ch == '(') { - in_comment = false; - continue; - } else if(ch == ')') { - in_comment = true; - } else if(ch == '@' && !in_dquote && !in_comment) { - m_domain.assign(input, x+1, len - x); - m_mailbox.assign(input, 0, x); - break; - } else if(ch == '"') { - in_dquote = !in_dquote; - } - } - } -} - - -/** - Returns \e true if \e *this is equal to \p right. - Two Mailbox objects are equal if have the same \e mailbox, the same - \e domain and the same \e source \e routing (if set) - Note that \e domain and \e source \e route comparisons - are case-insensitive - \param right object to compare against -*/ -bool Mailbox::operator==(const Mailbox& right) const -{ - return mailbox() == right.mailbox() && - istring(domain()) == domain() && - istring(sourceroute()) == right.sourceroute(); -} - -/** - Returns \e true if \e *this is NOT equal to \p right - Two Mailbox objects are different if have different \e mailbox or different - \e domain. - Note that \e domain comparison is case-insensitive - \param right object to compare against -*/ -bool Mailbox::operator!=(const Mailbox& right) const -{ - return !operator==(right); -} - - -/** Sets the \e mailbox */ -void Mailbox::mailbox(const string& mbx) -{ - m_mailbox = mbx; -} - -/** Sets the \e domain */ -void Mailbox::domain(const string& dom) -{ - m_domain = dom; -} - -/** Sets the \e label */ -void Mailbox::label(const string& label) -{ - m_label = label; -} - -/** Sets the \e source route */ -void Mailbox::sourceroute(const string& route) -{ - m_route = route; -} - -/** Gets the \e mailbox */ -string Mailbox::mailbox(int bCanonical) const -{ - return (bCanonical ? canonical(m_mailbox, true): m_mailbox); -} - -/** Gets the \e domain */ -string Mailbox::domain(int bCanonical) const -{ - return (bCanonical ? canonical(m_domain, true) : m_domain); -} - -/** Gets the \e label */ -string Mailbox::label(int bCanonical) const -{ - return (bCanonical ? canonical(m_label) : m_label); -} - -/** Gets the \e source route */ -string Mailbox::sourceroute(int bCanonical) const -{ - return (bCanonical ? canonical(m_route, true) : m_route); -} - -FieldValue* Mailbox::clone() const -{ - return new Mailbox(*this); -} - -} diff --git a/mimetic098/rfc822/mailbox.h b/mimetic098/rfc822/mailbox.h deleted file mode 100644 index ce4e88131..000000000 --- a/mimetic098/rfc822/mailbox.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mailbox.h,v 1.14 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_MAILBOX_H_ -#define _MIMETIC_RFC822_MAILBOX_H_ -#include -#include -namespace mimetic -{ - - - -/// Represents a \e mailbox email address as defined in the RFC822 -/** - Use this class if you want to build or parse email addresses. Each email address - as defined by RFC822 have a mailbox std::string, a domain name, a sourceroute and - a label. Note that just mailbox and domain are mandatory. - Mailboxes can be represented in different ways, can contain rfc822 comments and - blank spaces, can be double-quoted and contain source route. Please read the - RFC822 for details. - - Parsing: - \code - Mailbox mbx("Mario (Spider)Rossi <@free.it@move.it:mrossi@dom.it>"); - cout << mbx.mailbox() << endl; - cout << mbx.domain() << endl; - cout << mbx.label() << endl; - cout << mbx.sourceroute() << endl; - cout << mbx.text() << endl; - \endcode - - Building: - \code - Mailbox mbx; - mbx.mailbox("mrossi"); - mbx.domain("dom.it"); - mbx.label("Mario (Spider)Rossi"); - mbx.sourceroute("@free.it@move.it"); - \endcode - - \sa RFC822 - */ -struct Mailbox: public FieldValue -{ - Mailbox(); - Mailbox(const char*); - Mailbox(const std::string&); - void mailbox(const std::string&); - void domain(const std::string&); - void label(const std::string&); - void sourceroute(const std::string&); - std::string mailbox(int bCanonical = 1) const; - std::string domain(int bCanonical = 1) const; - std::string label(int bCanonical = 0) const; - std::string sourceroute(int bCanonical = 1) const; - bool operator==(const Mailbox&) const; - bool operator!=(const Mailbox&) const; - void set(const std::string&); - std::string str() const; -protected: - FieldValue* clone() const; -private: - std::string m_mailbox, m_domain, m_label, m_route; -}; - - -} - -#endif diff --git a/mimetic098/rfc822/mailboxlist.cxx b/mimetic098/rfc822/mailboxlist.cxx deleted file mode 100644 index 2ef152a5e..000000000 --- a/mimetic098/rfc822/mailboxlist.cxx +++ /dev/null @@ -1,151 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mailboxlist.cxx,v 1.3 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#include -#include - -namespace mimetic -{ - -using namespace std; - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// Rfc822::MailboxList -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// 1#mailbox (i.e. comma-separated list of mailbox) - -MailboxList::MailboxList() -{ -} - -/** - Parses \p text and adds Mailbox objects to the list - \param text input text - */ -MailboxList::MailboxList(const char* text) -{ - set(text); -} - -MailboxList::MailboxList(const string& text) -{ - set(text); -} - -void MailboxList::set(const std::string& value) -{ - bool in_dquote = false; - int blanks = 0; - string item; - string::const_iterator bit = value.begin(), eit = value.end(); - string::const_iterator p = bit; - for(; p != eit; ++p) - { - if(*p == '"') { - in_dquote = !in_dquote; - } else if(*p == ',' && !in_dquote) { - push_back( Mailbox(string(bit,p)) ); - bit = p + 1; - blanks = 0; - } else if(*p == ' ') { - blanks++; - } - } - if( (p-bit) != blanks)// not a only-blanks-string - push_back( Mailbox(string(bit,p)) ); -} - -string MailboxList::str() const -{ - string rs; - const_iterator first = begin(); - const_iterator bit = begin(), eit = end(); - for(; bit != eit; ++bit) - { - if(bit != first) - rs += ", "; - rs += bit->str(); - } - return rs; -} - - -FieldValue* MailboxList::clone() const -{ - return new MailboxList(*this); -} - - -} diff --git a/mimetic098/rfc822/mailboxlist.h b/mimetic098/rfc822/mailboxlist.h deleted file mode 100644 index ac2a634ea..000000000 --- a/mimetic098/rfc822/mailboxlist.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: mailboxlist.h,v 1.12 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_MAILBOXLIST_H_ -#define _MIMETIC_RFC822_MAILBOXLIST_H_ -#include -#include -#include -#include - - -namespace mimetic -{ -/// List of Mailbox objects -/*! - MailboxList class is a container class that holds Mailbox objects - - \code - const char* str = "dest@domain.com, friends: one@friends.net, " - "two@friends.net;, last@users.com"; - MailboxList aList(str); - MailboxList::const_iterator bit(aList.begin()), eit(aList.end()); - for(; bit != eit; ++bit) - { - cout << *bit; - } - \endcode - - \sa RFC822 - */ -struct MailboxList: public FieldValue, public std::vector -{ - MailboxList(); - MailboxList(const char*); - MailboxList(const std::string&); - MailboxList(const std::string&, const std::string&); - - std::string str() const; -protected: - FieldValue* clone() const; -private: - void set(const std::string&); - istring m_name; -}; - - - -} - -#endif diff --git a/mimetic098/rfc822/message.cxx b/mimetic098/rfc822/message.cxx deleted file mode 100644 index be3332076..000000000 --- a/mimetic098/rfc822/message.cxx +++ /dev/null @@ -1,121 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: message.cxx,v 1.4 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#include -#include -#include - - -namespace mimetic -{ - -using namespace std; - -ostream& operator<<(ostream& os, const Message& m) -{ - // header field - Rfc822Header::const_iterator hbit, heit; - hbit = m.header().begin(); - heit = m.header().end(); - for(; hbit != heit; ++hbit) - os << *hbit; - // empty line, header/body separator - os << crlf; - // body - os << m.body(); - os.flush(); - return os; -} - -Rfc822Header& Message::header() -{ - return m_header; -} - -const Rfc822Header& Message::header() const -{ - return m_header; -} - -Rfc822Body& Message::body() -{ - return m_body; -} - -const Rfc822Body& Message::body() const -{ - return m_body; -} - -} diff --git a/mimetic098/rfc822/message.h b/mimetic098/rfc822/message.h deleted file mode 100644 index e9c38b30c..000000000 --- a/mimetic098/rfc822/message.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: message.h,v 1.9 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_MESSAGE_H_ -#define _MIMETIC_RFC822_MESSAGE_H_ -#include -#include -#include -#include - -namespace mimetic -{ - -/// Simple RFC 822 message type -struct Message -{ - Message(); - virtual ~Message(){} - Rfc822Header& header(); - const Rfc822Header& header() const; - Rfc822Body& body(); - const Rfc822Body& body() const; - - friend std::ostream& operator<<(std::ostream&, const Message&); -private: - Rfc822Header m_header; - Rfc822Body m_body; -}; - -} - -#endif diff --git a/mimetic098/rfc822/messageid.cxx b/mimetic098/rfc822/messageid.cxx deleted file mode 100644 index b307aa015..000000000 --- a/mimetic098/rfc822/messageid.cxx +++ /dev/null @@ -1,117 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" - -#pragma GCC diagnostic ignored "-Wconversion" - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: messageid.cxx,v 1.4 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#include - -#pragma GCC diagnostic ignored "-Wsign-conversion" - -#include - -namespace mimetic -{ - -unsigned int MessageId::ms_sequence_number = 0; - -/// pass the thread_id argument if you're using mimetic with threads -MessageId::MessageId(uint32_t thread_identifier) -{ - std::string host {gethostname()}; - if(!host.length()) { - host = "unknown"; - } - m_msgid = "m" + utils::int2str((int)time(0)) + "." + utils::int2str(getpid()) + "." + utils::int2str(thread_identifier) + utils::int2str(++ms_sequence_number) + "@" + host; -} - -MessageId::MessageId(const std::string& value) -: m_msgid(value) -{ -} - -std::string MessageId::str() const -{ - return m_msgid; -} - -void MessageId::set(const std::string& value) -{ - m_msgid = value; -} - -FieldValue* MessageId::clone() const -{ - return new MessageId(*this); -} - -} diff --git a/mimetic098/rfc822/messageid.h b/mimetic098/rfc822/messageid.h deleted file mode 100644 index 809992c14..000000000 --- a/mimetic098/rfc822/messageid.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: messageid.h,v 1.15 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_MESSAGEID_H_ -#define _MIMETIC_MESSAGEID_H_ -#ifdef HAVE_STDINT_H -#include -#endif -#include -#include -#ifdef HAVE_INTTYPES_H -#include -#endif -#include -#include -#include -#include - -namespace mimetic -{ - - -/// Message-ID field value -/// On Win32 Winsock library must be initialized before using this class. -struct MessageId: public FieldValue -{ - MessageId(uint32_t thread_identifier); - MessageId(const std::string&); - MessageId() : MessageId(0) {}; - std::string str() const; - void set(const std::string&); -protected: - FieldValue* clone() const; -private: - static unsigned int ms_sequence_number; - std::string m_msgid; -}; - - -} - -#endif diff --git a/mimetic098/rfc822/rfc822.h b/mimetic098/rfc822/rfc822.h deleted file mode 100644 index 5ec049622..000000000 --- a/mimetic098/rfc822/rfc822.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: rfc822.h,v 1.7 2008-10-07 11:06:27 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_RFC822_RFC822_H_ -#define _MIMETIC_RFC822_RFC822_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif diff --git a/mimetic098/streambufs.h b/mimetic098/streambufs.h deleted file mode 100644 index edb9d7f09..000000000 --- a/mimetic098/streambufs.h +++ /dev/null @@ -1,221 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: streambufs.h,v 1.7 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_MIMESTREAMBUF_H_ -#define _MIMETIC_MIMESTREAMBUF_H_ -#include -#include -#include -#include - -namespace mimetic -{ - - -struct read_streambuf: public std::streambuf -{ - enum { bufsz = 512 }; - typedef unsigned int size_type; - read_streambuf() - : m_iBuf(new char_type[bufsz]) - { - setg(m_iBuf, m_iBuf + bufsz, m_iBuf + bufsz); - } - virtual ~read_streambuf() - { - if(m_iBuf) - delete[] m_iBuf; - m_iBuf = 0; - } - int_type underflow() - { - int bread; - - if(gptr() < egptr()) - return traits_type::to_int_type(*gptr()); - - if((bread = read(eback(), bufsz)) == 0) - return traits_type::eof(); - else - setg(eback(), eback(), eback() + bread); - - return traits_type::to_int_type(*gptr()); - } - // must return number of bytes read or 0 on eof - virtual int_type read(char*, int) = 0; -private: - read_streambuf(const read_streambuf&); - read_streambuf& operator=(const read_streambuf&); - char_type* m_iBuf; -}; - - -template -struct inputit_streambuf: public read_streambuf -{ - inputit_streambuf(InputIt beg, InputIt end) - : m_beg(beg), m_end(end) - { - } - // returns number of bytes read or 0 on eof - int_type read(char* buf, int bufsz) - { - // fill buffer - int c; - for(c = 0; m_beg != m_end && c < bufsz; ++m_beg, ++buf, ++c) - *buf = *m_beg; - return c; - } -private: - InputIt m_beg, m_end; -}; - -struct transform_streambuf: public std::streambuf -{ - typedef unsigned int size_type; - transform_streambuf() - : m_oBuf(new char_type[512]) - { - setp(m_oBuf, m_oBuf + 512); - } - virtual ~transform_streambuf() - { - if(m_oBuf) - { - sync(); - delete[] m_oBuf; - } - } - int overflow(int meta = EOF) - { - if(sync() == -1) - return EOF; - if(meta != EOF) - { - *pptr() = meta; - pbump(1); - } - return meta; - } - int sync() - { - int toSend = (int)(pptr() - pbase()); - if(toSend) - { - write(pbase(), pbase() + toSend); - setp(m_oBuf, epptr()); - } - return 0; - } - virtual void write(const char_type* beg, const char_type* end)=0; -private: - transform_streambuf(const transform_streambuf&); - transform_streambuf& operator=(const transform_streambuf&); - char_type* m_oBuf; -}; - -/* - * stream buffer that does nothing except counting character written into it. - * characters count is available through the size() method - */ -struct count_streambuf: public transform_streambuf -{ - count_streambuf() - : m_count(0) - { - } - void write(const char_type* beg, const char_type* end) - { - long toSend = end - beg; - if(toSend) - m_count += toSend; - } - size_type size() - { - return m_count; - } -private: - size_type m_count; -}; - - - -/* - * stream buffer that count char written into it and copy every char to the - * output iterator passed as ctor parameter - * characters count is available through the size() method - */ -template -struct passthrough_streambuf: public transform_streambuf -{ - typedef unsigned int size_type; - passthrough_streambuf(const OutputIt& out) - : m_out(out), m_count(0) - { - } - void write(const char_type* beg, const char_type* end) - { - int toSend = end - beg; - if(toSend) - { - m_count += toSend; - copy(beg, end, m_out); - } - } - size_type size() - { - return m_count; - } -private: - OutputIt m_out; - size_type m_count; -}; - - - -struct crlftolf_streambuf: public transform_streambuf -{ - typedef unsigned int size_type; - crlftolf_streambuf(std::streambuf* osbuf) - : m_osbuf(osbuf) - { - } - void write(const char_type* beg, const char_type* end) - { - enum { cr = 0xD, lf = 0xA }; - char_type c = 0; - bool got_cr = 0; - for(; beg != end; ++beg) - { - c = *beg; - if(got_cr) - { - if(c == lf) - m_osbuf->sputc(lf); - else { - m_osbuf->sputc(cr); - m_osbuf->sputc(c); - } - got_cr = 0; - } else if(c == cr) { - got_cr = 1; - continue; - } else - m_osbuf->sputc(c); - } - if(got_cr) - m_osbuf->sputc(c); - } -private: - std::streambuf* m_osbuf; -}; - - -} - -#endif diff --git a/mimetic098/strutils.cxx b/mimetic098/strutils.cxx deleted file mode 100644 index f8ad4db07..000000000 --- a/mimetic098/strutils.cxx +++ /dev/null @@ -1,141 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: strutils.cxx,v 1.3 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ - -#pragma GCC diagnostic ignored "-Wsign-conversion" - -#include - -namespace mimetic -{ -using namespace std; - -const string nullstring; - - -string canonical(const string& s, bool no_ws) -{ - if(s.empty()) - return s; - string input = s; - // removes leading spaces - int idx = 0; - while(input[idx] == ' ') - idx++; - if(idx) - input.erase(0, idx); - // removes trailing spaces - idx = (int)input.length() - 1; - while(input[idx] == ' ') - idx--; - int idx1 = idx; - int idx2 = ++idx; - input.erase(idx1, input.length() - idx2); - // removes rfc822 comments and non-required spaces - bool in_dquote = false, has_brack = false; - int in_par = 0, in_brack = 0, par_last = 0; - for(int t = (int)input.length() - 1; t >= 0; --t) - { - if(input[t] == '"') { - in_dquote = !in_dquote; - } else if(in_dquote) { - continue; - } else if(input[t] == '<') { - in_brack--; - } else if(input[t] == '>') { - has_brack = true; - in_brack++; - } else if(input[t] == ')') { - in_par++; - if(in_par == 1) - par_last = t; - } else if(input[t] == '(') { - in_par--; - if(in_par == 0) - { - input.erase(t, 1 + par_last - t); - // comments will be replaced with a space in - // !no_ws - if(!no_ws) - input.insert(t, " "); - } - } else if(no_ws && input[t] == ' ' && !in_par && !has_brack) { - input.erase(t, 1); - } - } - return input; -} - -} diff --git a/mimetic098/strutils.h b/mimetic098/strutils.h deleted file mode 100644 index f62da9406..000000000 --- a/mimetic098/strutils.h +++ /dev/null @@ -1,170 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: strutils.h,v 1.10 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_STRINGUTILS_H_ -#define _MIMETIC_STRINGUTILS_H_ -#include -#include -#include -#include -#include - -namespace mimetic -{ - -extern const std::string nullstring; - -struct ichar_traits : public std::char_traits -{ - static bool eq (const char_type & c1, const char_type& c2) - { return (toupper(c1) == toupper(c2)); } - static bool ne (const char_type& c1, const char_type& c2) - { return (toupper(c1) != toupper(c2)); } - static bool lt (const char_type& c1, const char_type& c2) - { return (toupper(c1) < toupper(c2)); } - static int compare (const char_type* s1, const char_type* s2, size_t n) - { - for(size_t i=0; i < n; ++i) - if(toupper(s1[i]) != toupper(s2[i])) - return (toupper(s1[i]) < toupper(s2[i])) ?-1: 1; - return 0; - } - static const char* find( const char* s, int n, char a ) - { - while( n-- > 0 && tolower(*s) != tolower(a) ) - ++s; - return s; - } -}; - -//typedef std::istring istring; -using std::string; - -struct istring: public string -{ - istring() - {} - //typedef std::string::allocator_type allocator_type; - istring(const std::string& right) - : string(right) - {} - explicit istring(const allocator_type& al) - : string(al) - {} - istring(const istring& right) - : string(right) - {} - istring(const istring& right, size_type roff, size_type count = npos) - : string(right, roff, count) - {} - istring(const istring& right, size_type roff, size_type count, - const allocator_type& al) - : string(right, roff, count, al) - {} - istring(const value_type *ptr, size_type count) - : string(ptr, count) - {} - istring(const value_type *ptr, size_type count,const allocator_type& al) - : string(ptr, count, al) - {} - istring(const value_type *ptr) - : string(ptr) - {} - istring(const value_type *ptr,const allocator_type& al) - : string(ptr, al) - {} - istring(size_type count, value_type ch) - : string(count,ch) - {} - istring(size_type count, value_type ch,const allocator_type& al) - : string(count,ch,al) - {} - template - istring(InIt first, InIt last) - : string(first, last) - {} - template - istring(InIt first, InIt last,const allocator_type& al) - : string(first, last, al) - {} -}; - - -inline bool operator==(const istring& is, const std::string& s) -{ - return (0 == ichar_traits::compare(is.c_str(),s.c_str(), - std::max(is.length(),s.length())) ); -} - -inline bool operator!=(const istring& is, const std::string& s) -{ - return (0 != ichar_traits::compare(is.c_str(),s.c_str(), - std::max(is.length(),s.length())) ); -} - -inline bool operator!=(const istring& is, const char* str) -{ - return (0 != ichar_traits::compare(is.c_str(),str, - std::max(is.length(),::strlen(str))) ); -} - -inline bool operator==(const istring& is, const char* str) -{ - return (0 == ichar_traits::compare(is.c_str(),str, - std::max(is.length(),::strlen(str))) ); -} - -inline std::string dquoted(const std::string& s) -{ - return "\"" + s + "\""; -} - -inline std::string parenthed(const std::string& s) -{ - return "(" + s + ")"; -} - -/// removes double quotes -inline std::string remove_dquote(const std::string& s) -{ - size_t len = s.length(); - if( len < 2) - return s; - if(s[0] == '"' && s[len-1] == '"') - return std::string(s, 1, len-2); - return s; -} - -/** - * returns the \e canonical representation of \p s (see RFC822) - * if \p no_ws is true removes all blanks from the resulting string - */ -std::string canonical(const std::string& s, bool no_ws = false); - -/// removes leading and trailing blanks -inline std::string remove_external_blanks(const std::string& in) -{ - if(!in.length()) - return in; - std::string s = in; - size_t beg = 0, end = s.length(); - for(; beg < end; ++beg) - if(s[beg] != ' ' && s[beg] != '\t') - break; - end = s.length() - 1; - for(; end > beg; --end) - if(s[end] != ' ' && s[end] != '\t') - break; - s.assign(std::string(s, beg, end - beg + 1)); - return s; -} - -} - -#endif - diff --git a/mimetic098/tokenizer.h b/mimetic098/tokenizer.h deleted file mode 100644 index bb72c6e33..000000000 --- a/mimetic098/tokenizer.h +++ /dev/null @@ -1,169 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: tokenizer.h,v 1.18 2008-10-07 11:44:38 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_TOKENIZER_H_ -#define _MIMETIC_TOKENIZER_H_ -#include -#include -#include -#include -#include - -namespace mimetic -{ - -template -struct IsDelim -{ - bool operator()(const value_type& val) const - { - return m_delims.count(val) != 0; - } - template - void setDelimList(const Container& cont) - { - typename Container::const_iterator bit, eit; - bit = cont.begin(), eit = cont.end(); - for(; bit != eit; ++bit) - m_delims.insert(*bit); - } - template - void setDelimList(Iterator bit, Iterator eit) - { - for(; bit != eit; ++bit) - m_delims.insert(*bit); - } - void addDelim(const value_type& value) - { - m_delims.insert(value); - } - void removeDelim(const value_type& value) - { - m_delims.erase(value); - } -private: - std::set m_delims; -}; - -template<> -struct IsDelim -{ - void setDelimList(const std::string& delims) - { - setDelimList(delims.begin(), delims.end()); - } - template - void setDelimList(Iterator bit, Iterator eit) - { - memset(&m_lookup, 0, sizeof(m_lookup)); - for(; bit != eit; ++bit) - m_lookup[(int)*bit] = 1; - } - bool operator()(unsigned char val) const - { - return m_lookup[val] != 0; - } -private: - char m_lookup[256]; -}; - - -/// Iterator tokenizer template class -template -class ItTokenizer -{ -public: - ItTokenizer(Iterator bit, Iterator eit) - : m_bit(bit), m_eit(eit), m_tok_eit(bit) - { - } - void setSource(Iterator bit, Iterator eit) - { - m_bit = bit; - m_eit = eit; - m_tok_eit = bit; - } - template - void setDelimList(const DelimCont& cont) - { - m_delimPred.setDelimList(cont); - } - template - void setDelimList(It bit, It eit) - { - m_delimPred.setDelimList(bit, eit); - } - template - bool next(DestCont& dst) - { - dst.erase(dst.begin(), dst.end()); - if(m_tok_eit == m_eit) - return false; - m_tok_eit = std::find_if(m_bit, m_eit, m_delimPred); - m_matched = 0; // end of input - if(m_tok_eit != m_eit) - m_matched = *m_tok_eit; // matched delimiter - std::copy(m_bit, m_tok_eit, std::back_inserter(dst)); - m_bit = (m_tok_eit != m_eit && ++m_tok_eit != m_eit ? m_tok_eit :m_eit); - return true; - } - const value_type& matched() const - { - return m_matched; - } - void addDelim(const value_type& value) - { - m_delimPred.addDelim(value); - } - void removeDelim(const value_type& value) - { - m_delimPred.removeDelim(value); - } -private: - Iterator m_bit, m_eit, m_tok_eit; - IsDelim m_delimPred; - value_type m_matched; -}; - - -/// char container tokenizer template class -template -struct ContTokenizer: public ItTokenizer -{ - typedef typename Container::value_type value_type; - typedef typename Container::iterator iterator; - typedef typename Container::const_iterator const_iterator; - // i want to be fast here so i don't want to copy "cont" - // so "cont" MUST be in scope for all following calls - // to next(...). - ContTokenizer(const Container* cont) - : ItTokenizer(cont->begin(), cont->end()) - { - } - template - ContTokenizer(const Container* cont, const DelimCont& delims) - : ItTokenizer(cont->begin(), cont->end()) - { - this->setDelimList(delims); - } - void setSource(const Container* cont) - { - ItTokenizer::setSource(cont->begin(), cont->end()); - } -private: - ContTokenizer(const ContTokenizer&); - ContTokenizer& operator=(const ContTokenizer&); -}; - -/// std::string tokenizer -typedef ContTokenizer StringTokenizer; - -} - -#endif - diff --git a/mimetic098/tree.h b/mimetic098/tree.h deleted file mode 100644 index ff9ed82f1..000000000 --- a/mimetic098/tree.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: tree.h,v 1.5 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_TREE_H_ -#define _MIMETIC_TREE_H_ -#include -#include - -namespace mimetic -{ - -/// INTERNAL: N-tree impl. -template -struct TreeNode -{ - typedef TreeNode self_type; - typedef std::list > NodeList; - TreeNode() - { - } - TreeNode(const value_type& data) - : m_data(data) - { - } - void set(const value_type& data) - { - m_data = data; - } - value_type& get() - { - return m_data; - } - const value_type& get() const - { - return m_data; - } - NodeList& childList() - { - return m_nList; - } - const NodeList& childList() const - { - return m_nList; - } -private: - NodeList m_nList; - value_type m_data; -}; - -template -struct FindNodePred -{ - FindNodePred(const value_type& data) - : m_data(data) - { - } - inline bool operator()(const TreeNode& node) const - { - return node.get() == m_data; - } -private: - value_type m_data; -}; - -} - -#endif - diff --git a/mimetic098/utils.cxx b/mimetic098/utils.cxx deleted file mode 100644 index 765c412de..000000000 --- a/mimetic098/utils.cxx +++ /dev/null @@ -1,206 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: utils.cxx,v 1.4 2008-10-07 15:43:55 tat Exp $ - ***************************************************************************/ -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wchar-subscripts" - -namespace mimetic -{ - -using namespace std; - - -/** - * same as std::endl but NOT flush the buffer - */ -std::ostream& nl(std::ostream& os) -{ - return os.put('\n'); -} - -/** - * writes "\r\n" to the ostream \p ps - */ -std::ostream& crlf(std::ostream& os) -{ - return os.write("\r\n", 2); -} - -namespace utils -{ - -struct Int -{ - Int(int n) - : m_i(n) - { - stringstream ss; - ss << m_i; - ss >> m_si; - } - Int(const std::string& ns) - { - stringstream ss; - ss << ns; - ss >> m_i; - if(ss.fail()) - m_i = 0; - stringstream ss2; - ss2 << m_i; - ss2 >> m_si; - } - operator int() const - { - return m_i; - } - - operator string() const - { - return m_si; - } -private: - int m_i; - std::string m_si; -}; - - -bool string_is_blank(const std::string& s) -{ - size_t i, len = s.length(); - - for(i = 0; i < len; ++i) - if(!isblank(s[i])) - return false; - return true; -} - -/// extract the filename from a fqn -string extractFilename(const string& fqn) -{ - string::size_type pos; - if((pos = fqn.find_last_of(PATH_SEPARATOR)) != std::string::npos) - { - return fqn.substr(++pos); - } else - return fqn; -} - - -string int2hex(unsigned int n) -{ - if(n == 0) - return "0"; - static char tb[] = { - '0', '1', '2', '3', - '4', '5', '6', '7', - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f' - }; - size_t sz = sizeof(n), zeros = 0; - string r; - char cp; - for(size_t i = 0; i < sz*2; ++i) - { - cp = (n >> (i*4)) & 0xF; - if(cp == 0) - zeros++; - else { - if(zeros) - r.insert((string::size_type)0, zeros, '0'); - zeros = 0; - r.insert((string::size_type)0, 1, (char)(tb[cp])); - } - } - return r; -} - - -string int2str(int n) -{ - Int i(n); - return i; -} - -int str2int(const string& str) -{ - return ::atoi(str.c_str()); -} - -} // ns utils - -} // ns mimetic diff --git a/mimetic098/utils.h b/mimetic098/utils.h deleted file mode 100644 index 374990b81..000000000 --- a/mimetic098/utils.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: utils.h,v 1.23 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_UTILS_H_ -#define _MIMETIC_UTILS_H_ -#include -#include -#include -#include -#include - -namespace mimetic -{ - -std::ostream& crlf(std::ostream&); -std::ostream& nl(std::ostream&); - -#ifndef isblank -inline int isblank(char c) -{ - return c == ' ' || c == '\t'; -} -#endif - -namespace utils -{ - -/// returns the filename out of the fqn (fully qualified name) -std::string extractFilename(const std::string&); - -/// returns a string representation of \p n -std::string int2str(int n); - -/// return true if the string contains just blanks (space and tabs) -bool string_is_blank(const std::string&); - -/// returns the integer value represented by \p s -int str2int(const std::string& s); - -/// returns a string hexadecimal representation of \p n -std::string int2hex(unsigned int n); - -// find_bm specialization for random access iterators -template -Iterator find_bm(Iterator bit, Iterator eit, const std::string& word, const std::random_access_iterator_tag&) -{ - int bLen = (int)word.length(); - const char* pWord = word.c_str(); - int i, t, shift[256]; - unsigned char c; - - for(i = 0; i < 256; ++i) - shift[i] = bLen; - - for(i = 0; i < bLen; ++i) - shift[ (unsigned char) pWord[i] ] = bLen -i - 1; - - for(i = t = bLen-1; t >= 0; --i, --t) - { - if((bit + i) >= eit) - return eit; - - while((c = *(bit + i)) != pWord[t]) - { - i += std::max(bLen-t, shift[c]); - if((bit + i) >= eit) return eit; - t = bLen-1; - } - } - - return bit + i + 1; -} - -// boyer-moore find -/** - * find the first occurrence of \p word in (\p bit, \p eit] - * - * returns an Iterator pointing at the first character of the found pattern - * or \p eit if the search fails - */ -template -Iterator find_bm(Iterator bit, Iterator eit, const std::string& word) -{ - return find_bm(bit, eit, word, - typename std::iterator_traits::iterator_category()); -} - - - -} // ns utils - -} - -#endif diff --git a/mimetic098/version.cxx b/mimetic098/version.cxx deleted file mode 100644 index bcc1dcaa5..000000000 --- a/mimetic098/version.cxx +++ /dev/null @@ -1,201 +0,0 @@ -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wuseless-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wswitch-default" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsuggest-override" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wold-style-cast" - -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wold-style-cast" - - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: version.cxx,v 1.4 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#include - -#pragma GCC diagnostic ignored "-Wsign-conversion" - -#include -#include -#include -#include - -namespace mimetic -{ -using namespace std; - -#define VERSION "0.9.8" - -const Version version(VERSION); - - -Version::Version() -: m_maj(0), m_min(0), m_build(0) -{ -} - -Version::Version(const string& s) -: m_maj(0), m_min(0), m_build(0) -{ - set(s); -} - -Version::Version(ver_type maj, ver_type min, ver_type build) -: m_maj(maj), m_min(min), m_build(build) -{ -} - -Version::ver_type Version::maj() const -{ - return m_maj; -} - -Version::ver_type Version::min() const -{ - return m_min; -} - -Version::ver_type Version::build() const -{ - return m_build; -} - -void Version::maj(Version::ver_type maj) -{ - m_maj = maj; -} - -void Version::min(Version::ver_type min) -{ - m_min = min; -} - -void Version::build(Version::ver_type build) -{ - m_build = build; -} - -void Version::set(ver_type maj, ver_type min, ver_type build) -{ - m_maj = maj; - m_min = min; - m_build = build; -} - -string Version::str() const -{ - return utils::int2str(m_maj) + "." + utils::int2str(m_min) + - (m_build > 0 ? "." + utils::int2str(m_build) : ""); -} - -void Version::set(const string& s) -{ - StringTokenizer stok(&s, "."); - string tok; - if(stok.next(tok)) - m_maj = utils::str2int(tok); - if(stok.next(tok)) - m_min = utils::str2int(tok); - if(stok.next(tok)) - m_build = utils::str2int(tok); -} - -bool Version::operator==(const Version& r) const -{ - return m_maj == r.m_maj && m_min == r.m_min && m_build == r.m_build; - -} - -bool Version::operator!=(const Version& r) const -{ - return m_maj != r.m_maj || m_min != r.m_min || m_build != r.m_build; -} - -bool Version::operator<(const Version& r) const -{ - return m_maj < r.m_maj || m_min < r.m_min || m_build < r.m_build; -} - -bool Version::operator>(const Version& r) const -{ - return m_maj > r.m_maj || m_min > r.m_min || m_build > r.m_build; -} - -bool Version::operator<=(const Version& r) const -{ - return m_maj <= r.m_maj || m_min <= r.m_min || m_build <= r.m_build; -} - -bool Version::operator>=(const Version& r) const -{ - return m_maj >= r.m_maj || m_min >= r.m_min || m_build >= r.m_build; -} - -ostream& operator<<(ostream& os, const Version& v) -{ - return os << v.str(); -} - -} diff --git a/mimetic098/version.h b/mimetic098/version.h deleted file mode 100644 index 35726d7b3..000000000 --- a/mimetic098/version.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma GCC system_header - -/*************************************************************************** - copyright : (C) 2002-2008 by Stefano Barbato - email : stefano@codesink.org - - $Id: version.h,v 1.9 2008-10-07 11:06:26 tat Exp $ - ***************************************************************************/ -#ifndef _MIMETIC_VERSION_H_ -#define _MIMETIC_VERSION_H_ -#include -#include - -namespace mimetic -{ -struct Version; - - -// library version -extern const Version version; - - -// major & minor are macro defined in /usr/include/sys/sysmacros.h (linux) -// so we'll use maj & min instead - -/// A three levels version string class -/** - format: - maj.min[.build] - \d+\.\d+(\.\d+)? - es. 1.1, 1.23.5, 1.2.3, 1.2.3, 1.11 - 22.1.3, 0.1.234 -*/ -struct Version -{ - typedef unsigned int ver_type; - Version(); - Version(const std::string&); - Version(ver_type, ver_type, ver_type build = 0); - void maj(ver_type); - void min(ver_type); - void build(ver_type); - ver_type maj() const; - ver_type min() const; - ver_type build() const; - - void set(ver_type, ver_type, ver_type build = 0); - void set(const std::string&); - std::string str() const; - - bool operator==(const Version&) const; - bool operator!=(const Version&) const; - bool operator<(const Version&) const; - bool operator>(const Version&) const; - bool operator<=(const Version&) const; - bool operator>=(const Version&) const; - friend std::ostream& operator<<(std::ostream&, const Version&); -protected: - ver_type m_maj, m_min, m_build; -}; - -} - -#endif - diff --git a/miniz/miniz.c b/miniz/miniz.c deleted file mode 100755 index db47b6352..000000000 --- a/miniz/miniz.c +++ /dev/null @@ -1,7250 +0,0 @@ -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wimplicit-int-conversion" -#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - -#include "miniz.h" - -typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1]; -typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1]; -typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1]; - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- zlib-style API's */ - -mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) -{ - mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); - size_t block_len = buf_len % 5552; - if (!ptr) - return MZ_ADLER32_INIT; - while (buf_len) - { - for (i = 0; i + 7 < block_len; i += 8, ptr += 8) - { - (void)(s1 += ptr[0]), s2 += s1; - (void)(s1 += ptr[1]), s2 += s1; - (void)(s1 += ptr[2]), s2 += s1; - (void)(s1 += ptr[3]), s2 += s1; - (void)(s1 += ptr[4]), s2 += s1; - (void)(s1 += ptr[5]), s2 += s1; - (void)(s1 += ptr[6]), s2 += s1; - (void)(s1 += ptr[7]), s2 += s1; - } - for (; i < block_len; ++i) - (void)(s1 += *ptr++), s2 += s1; - (void)(s1 %= 65521U), s2 %= 65521U; - buf_len -= block_len; - block_len = 5552; - } - return (s2 << 16) + s1; -} - -/* Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ */ -#if 0 - mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) - { - static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; - mz_uint32 crcu32 = (mz_uint32)crc; - if (!ptr) - return MZ_CRC32_INIT; - crcu32 = ~crcu32; - while (buf_len--) - { - mz_uint8 b = *ptr++; - crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; - crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; - } - return ~crcu32; - } -#else -/* Faster, but larger CPU cache footprint. - */ -mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) -{ - static const mz_uint32 s_crc_table[256] = - { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, - 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, - 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, - 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, - 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, - 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, - 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, - 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, - 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, - 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, - 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, - 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, - 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, - 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, - 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, - 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, - 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, - 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, - 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, - 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, - 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, - 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, - 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, - 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, - 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D - }; - - mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF; - const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr; - - while (buf_len >= 4) - { - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF]; - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF]; - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF]; - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF]; - pByte_buf += 4; - buf_len -= 4; - } - - while (buf_len) - { - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF]; - ++pByte_buf; - --buf_len; - } - - return ~crc32; -} -#endif - -void mz_free(void *p) -{ - MZ_FREE(p); -} - -void *miniz_def_alloc_func(void *opaque, size_t items, size_t size) -{ - (void)opaque, (void)items, (void)size; - return MZ_MALLOC(items * size); -} -void miniz_def_free_func(void *opaque, void *address) -{ - (void)opaque, (void)address; - MZ_FREE(address); -} -void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size) -{ - (void)opaque, (void)address, (void)items, (void)size; - return MZ_REALLOC(address, items * size); -} - -const char *mz_version(void) -{ - return MZ_VERSION; -} - -#ifndef MINIZ_NO_ZLIB_APIS - -int mz_deflateInit(mz_streamp pStream, int level) -{ - return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY); -} - -int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) -{ - tdefl_compressor *pComp; - mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); - - if (!pStream) - return MZ_STREAM_ERROR; - if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) - return MZ_PARAM_ERROR; - - pStream->data_type = 0; - pStream->adler = MZ_ADLER32_INIT; - pStream->msg = NULL; - pStream->reserved = 0; - pStream->total_in = 0; - pStream->total_out = 0; - if (!pStream->zalloc) - pStream->zalloc = miniz_def_alloc_func; - if (!pStream->zfree) - pStream->zfree = miniz_def_free_func; - - pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor)); - if (!pComp) - return MZ_MEM_ERROR; - - pStream->state = (struct mz_internal_state *)pComp; - - if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) - { - mz_deflateEnd(pStream); - return MZ_PARAM_ERROR; - } - - return MZ_OK; -} - -int mz_deflateReset(mz_streamp pStream) -{ - if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) - return MZ_STREAM_ERROR; - pStream->total_in = pStream->total_out = 0; - tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags); - return MZ_OK; -} - -int mz_deflate(mz_streamp pStream, int flush) -{ - size_t in_bytes, out_bytes; - mz_ulong orig_total_in, orig_total_out; - int mz_status = MZ_OK; - - if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) - return MZ_STREAM_ERROR; - if (!pStream->avail_out) - return MZ_BUF_ERROR; - - if (flush == MZ_PARTIAL_FLUSH) - flush = MZ_SYNC_FLUSH; - - if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE) - return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; - - orig_total_in = pStream->total_in; - orig_total_out = pStream->total_out; - for (;;) - { - tdefl_status defl_status; - in_bytes = pStream->avail_in; - out_bytes = pStream->avail_out; - - defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush); - pStream->next_in += (mz_uint)in_bytes; - pStream->avail_in -= (mz_uint)in_bytes; - pStream->total_in += (mz_uint)in_bytes; - pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state); - - pStream->next_out += (mz_uint)out_bytes; - pStream->avail_out -= (mz_uint)out_bytes; - pStream->total_out += (mz_uint)out_bytes; - - if (defl_status < 0) - { - mz_status = MZ_STREAM_ERROR; - break; - } - else if (defl_status == TDEFL_STATUS_DONE) - { - mz_status = MZ_STREAM_END; - break; - } - else if (!pStream->avail_out) - break; - else if ((!pStream->avail_in) && (flush != MZ_FINISH)) - { - if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out)) - break; - return MZ_BUF_ERROR; /* Can't make forward progress without some input. - */ - } - } - return mz_status; -} - -int mz_deflateEnd(mz_streamp pStream) -{ - if (!pStream) - return MZ_STREAM_ERROR; - if (pStream->state) - { - pStream->zfree(pStream->opaque, pStream->state); - pStream->state = NULL; - } - return MZ_OK; -} - -mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) -{ - (void)pStream; - /* This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) */ - return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); -} - -int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level) -{ - int status; - mz_stream stream; - memset(&stream, 0, sizeof(stream)); - - /* In case mz_ulong is 64-bits (argh I hate longs). */ - if ((source_len | *pDest_len) > 0xFFFFFFFFU) - return MZ_PARAM_ERROR; - - stream.next_in = pSource; - stream.avail_in = (mz_uint32)source_len; - stream.next_out = pDest; - stream.avail_out = (mz_uint32) * pDest_len; - - status = mz_deflateInit(&stream, level); - if (status != MZ_OK) - return status; - - status = mz_deflate(&stream, MZ_FINISH); - if (status != MZ_STREAM_END) - { - mz_deflateEnd(&stream); - return (status == MZ_OK) ? MZ_BUF_ERROR : status; - } - - *pDest_len = stream.total_out; - return mz_deflateEnd(&stream); -} - -int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) -{ - return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION); -} - -mz_ulong mz_compressBound(mz_ulong source_len) -{ - return mz_deflateBound(NULL, source_len); -} - -typedef struct -{ - tinfl_decompressor m_decomp; - mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; - int m_window_bits; - mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; - tinfl_status m_last_status; -} inflate_state; - -int mz_inflateInit2(mz_streamp pStream, int window_bits) -{ - inflate_state *pDecomp; - if (!pStream) - return MZ_STREAM_ERROR; - if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) - return MZ_PARAM_ERROR; - - pStream->data_type = 0; - pStream->adler = 0; - pStream->msg = NULL; - pStream->total_in = 0; - pStream->total_out = 0; - pStream->reserved = 0; - if (!pStream->zalloc) - pStream->zalloc = miniz_def_alloc_func; - if (!pStream->zfree) - pStream->zfree = miniz_def_free_func; - - pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state)); - if (!pDecomp) - return MZ_MEM_ERROR; - - pStream->state = (struct mz_internal_state *)pDecomp; - - tinfl_init(&pDecomp->m_decomp); - pDecomp->m_dict_ofs = 0; - pDecomp->m_dict_avail = 0; - pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; - pDecomp->m_first_call = 1; - pDecomp->m_has_flushed = 0; - pDecomp->m_window_bits = window_bits; - - return MZ_OK; -} - -int mz_inflateInit(mz_streamp pStream) -{ - return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); -} - -int mz_inflate(mz_streamp pStream, int flush) -{ - inflate_state *pState; - mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; - size_t in_bytes, out_bytes, orig_avail_in; - tinfl_status status; - - if ((!pStream) || (!pStream->state)) - return MZ_STREAM_ERROR; - if (flush == MZ_PARTIAL_FLUSH) - flush = MZ_SYNC_FLUSH; - if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) - return MZ_STREAM_ERROR; - - pState = (inflate_state *)pStream->state; - if (pState->m_window_bits > 0) - decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; - orig_avail_in = pStream->avail_in; - - first_call = pState->m_first_call; - pState->m_first_call = 0; - if (pState->m_last_status < 0) - return MZ_DATA_ERROR; - - if (pState->m_has_flushed && (flush != MZ_FINISH)) - return MZ_STREAM_ERROR; - pState->m_has_flushed |= (flush == MZ_FINISH); - - if ((flush == MZ_FINISH) && (first_call)) - { - /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */ - decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; - in_bytes = pStream->avail_in; - out_bytes = pStream->avail_out; - status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags); - pState->m_last_status = status; - pStream->next_in += (mz_uint)in_bytes; - pStream->avail_in -= (mz_uint)in_bytes; - pStream->total_in += (mz_uint)in_bytes; - pStream->adler = tinfl_get_adler32(&pState->m_decomp); - pStream->next_out += (mz_uint)out_bytes; - pStream->avail_out -= (mz_uint)out_bytes; - pStream->total_out += (mz_uint)out_bytes; - - if (status < 0) - return MZ_DATA_ERROR; - else if (status != TINFL_STATUS_DONE) - { - pState->m_last_status = TINFL_STATUS_FAILED; - return MZ_BUF_ERROR; - } - return MZ_STREAM_END; - } - /* flush != MZ_FINISH then we must assume there's more input. */ - if (flush != MZ_FINISH) - decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; - - if (pState->m_dict_avail) - { - n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); - memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); - pStream->next_out += n; - pStream->avail_out -= n; - pStream->total_out += n; - pState->m_dict_avail -= n; - pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); - return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; - } - - for (;;) - { - in_bytes = pStream->avail_in; - out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; - - status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); - pState->m_last_status = status; - - pStream->next_in += (mz_uint)in_bytes; - pStream->avail_in -= (mz_uint)in_bytes; - pStream->total_in += (mz_uint)in_bytes; - pStream->adler = tinfl_get_adler32(&pState->m_decomp); - - pState->m_dict_avail = (mz_uint)out_bytes; - - n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); - memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); - pStream->next_out += n; - pStream->avail_out -= n; - pStream->total_out += n; - pState->m_dict_avail -= n; - pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); - - if (status < 0) - return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */ - else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) - return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */ - else if (flush == MZ_FINISH) - { - /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */ - if (status == TINFL_STATUS_DONE) - return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; - /* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */ - else if (!pStream->avail_out) - return MZ_BUF_ERROR; - } - else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail)) - break; - } - - return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; -} - -int mz_inflateEnd(mz_streamp pStream) -{ - if (!pStream) - return MZ_STREAM_ERROR; - if (pStream->state) - { - pStream->zfree(pStream->opaque, pStream->state); - pStream->state = NULL; - } - return MZ_OK; -} - -int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) -{ - mz_stream stream; - int status; - memset(&stream, 0, sizeof(stream)); - - /* In case mz_ulong is 64-bits (argh I hate longs). */ - if ((source_len | *pDest_len) > 0xFFFFFFFFU) - return MZ_PARAM_ERROR; - - stream.next_in = pSource; - stream.avail_in = (mz_uint32)source_len; - stream.next_out = pDest; - stream.avail_out = (mz_uint32) * pDest_len; - - status = mz_inflateInit(&stream); - if (status != MZ_OK) - return status; - - status = mz_inflate(&stream, MZ_FINISH); - if (status != MZ_STREAM_END) - { - mz_inflateEnd(&stream); - return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status; - } - *pDest_len = stream.total_out; - - return mz_inflateEnd(&stream); -} - -const char *mz_error(int err) -{ - static struct - { - int m_err; - const char *m_pDesc; - } s_error_descs[] = - { - { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, - { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" } - }; - mz_uint i; - for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) - if (s_error_descs[i].m_err == err) - return s_error_descs[i].m_pDesc; - return NULL; -} - -#endif /*MINIZ_NO_ZLIB_APIS */ - -#ifdef __cplusplus -} -#endif - -/* - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to -*/ -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - - - - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- Low-level Compression (independent from all decompression API's) */ - -/* Purposely making these tables static for faster init and thread safety. */ -static const mz_uint16 s_tdefl_len_sym[256] = - { - 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272, - 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285 - }; - -static const mz_uint8 s_tdefl_len_extra[256] = - { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0 - }; - -static const mz_uint8 s_tdefl_small_dist_sym[512] = - { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17 - }; - -static const mz_uint8 s_tdefl_small_dist_extra[512] = - { - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7 - }; - -static const mz_uint8 s_tdefl_large_dist_sym[128] = - { - 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 - }; - -static const mz_uint8 s_tdefl_large_dist_extra[128] = - { - 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13 - }; - -/* Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. */ -typedef struct -{ - mz_uint16 m_key, m_sym_index; -} tdefl_sym_freq; -static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *pSyms0, tdefl_sym_freq *pSyms1) -{ - mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; - tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1; - MZ_CLEAR_OBJ(hist); - for (i = 0; i < num_syms; i++) - { - mz_uint freq = pSyms0[i].m_key; - hist[freq & 0xFF]++; - hist[256 + ((freq >> 8) & 0xFF)]++; - } - while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) - total_passes--; - for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) - { - const mz_uint32 *pHist = &hist[pass << 8]; - mz_uint offsets[256], cur_ofs = 0; - for (i = 0; i < 256; i++) - { - offsets[i] = cur_ofs; - cur_ofs += pHist[i]; - } - for (i = 0; i < num_syms; i++) - pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i]; - { - tdefl_sym_freq *t = pCur_syms; - pCur_syms = pNew_syms; - pNew_syms = t; - } - } - return pCur_syms; -} - -/* tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. */ -static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) -{ - int root, leaf, next, avbl, used, dpth; - if (n == 0) - return; - else if (n == 1) - { - A[0].m_key = 1; - return; - } - A[0].m_key += A[1].m_key; - root = 0; - leaf = 2; - for (next = 1; next < n - 1; next++) - { - if (leaf >= n || A[root].m_key < A[leaf].m_key) - { - A[next].m_key = A[root].m_key; - A[root++].m_key = (mz_uint16)next; - } - else - A[next].m_key = A[leaf++].m_key; - if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key)) - { - A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); - A[root++].m_key = (mz_uint16)next; - } - else - A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key); - } - A[n - 2].m_key = 0; - for (next = n - 3; next >= 0; next--) - A[next].m_key = A[A[next].m_key].m_key + 1; - avbl = 1; - used = dpth = 0; - root = n - 2; - next = n - 1; - while (avbl > 0) - { - while (root >= 0 && (int)A[root].m_key == dpth) - { - used++; - root--; - } - while (avbl > used) - { - A[next--].m_key = (mz_uint16)(dpth); - avbl--; - } - avbl = 2 * used; - dpth++; - used = 0; - } -} - -/* Limits canonical Huffman code table's max code size. */ -enum -{ - TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 -}; -static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size) -{ - int i; - mz_uint32 total = 0; - if (code_list_len <= 1) - return; - for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) - pNum_codes[max_code_size] += pNum_codes[i]; - for (i = max_code_size; i > 0; i--) - total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); - while (total != (1UL << max_code_size)) - { - pNum_codes[max_code_size]--; - for (i = max_code_size - 1; i > 0; i--) - if (pNum_codes[i]) - { - pNum_codes[i]--; - pNum_codes[i + 1] += 2; - break; - } - total--; - } -} - -static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table) -{ - int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; - mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; - MZ_CLEAR_OBJ(num_codes); - if (static_table) - { - for (i = 0; i < table_len; i++) - num_codes[d->m_huff_code_sizes[table_num][i]]++; - } - else - { - tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms; - int num_used_syms = 0; - const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; - for (i = 0; i < table_len; i++) - if (pSym_count[i]) - { - syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; - syms0[num_used_syms++].m_sym_index = (mz_uint16)i; - } - - pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); - tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); - - for (i = 0; i < num_used_syms; i++) - num_codes[pSyms[i].m_key]++; - - tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit); - - MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); - MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); - for (i = 1, j = num_used_syms; i <= code_size_limit; i++) - for (l = num_codes[i]; l > 0; l--) - d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); - } - - next_code[1] = 0; - for (j = 0, i = 2; i <= code_size_limit; i++) - next_code[i] = j = ((j + num_codes[i - 1]) << 1); - - for (i = 0; i < table_len; i++) - { - mz_uint rev_code = 0, code, code_size; - if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) - continue; - code = next_code[code_size]++; - for (l = code_size; l > 0; l--, code >>= 1) - rev_code = (rev_code << 1) | (code & 1); - d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; - } -} - -#define TDEFL_PUT_BITS(b, l) \ - do \ - { \ - mz_uint bits = b; \ - mz_uint len = l; \ - MZ_ASSERT(bits <= ((1U << len) - 1U)); \ - d->m_bit_buffer |= (bits << d->m_bits_in); \ - d->m_bits_in += len; \ - while (d->m_bits_in >= 8) \ - { \ - if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ - *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ - d->m_bit_buffer >>= 8; \ - d->m_bits_in -= 8; \ - } \ - } \ - MZ_MACRO_END - -#define TDEFL_RLE_PREV_CODE_SIZE() \ - { \ - if (rle_repeat_count) \ - { \ - if (rle_repeat_count < 3) \ - { \ - d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \ - while (rle_repeat_count--) \ - packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ - } \ - else \ - { \ - d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \ - packed_code_sizes[num_packed_code_sizes++] = 16; \ - packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \ - } \ - rle_repeat_count = 0; \ - } \ - } - -#define TDEFL_RLE_ZERO_CODE_SIZE() \ - { \ - if (rle_z_count) \ - { \ - if (rle_z_count < 3) \ - { \ - d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \ - while (rle_z_count--) \ - packed_code_sizes[num_packed_code_sizes++] = 0; \ - } \ - else if (rle_z_count <= 10) \ - { \ - d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \ - packed_code_sizes[num_packed_code_sizes++] = 17; \ - packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \ - } \ - else \ - { \ - d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \ - packed_code_sizes[num_packed_code_sizes++] = 18; \ - packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \ - } \ - rle_z_count = 0; \ - } \ - } - -static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; - -static void tdefl_start_dynamic_block(tdefl_compressor *d) -{ - int num_lit_codes, num_dist_codes, num_bit_lengths; - mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index; - mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF; - - d->m_huff_count[0][256] = 1; - - tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); - tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); - - for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) - if (d->m_huff_code_sizes[0][num_lit_codes - 1]) - break; - for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) - if (d->m_huff_code_sizes[1][num_dist_codes - 1]) - break; - - memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); - memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes); - total_code_sizes_to_pack = num_lit_codes + num_dist_codes; - num_packed_code_sizes = 0; - rle_z_count = 0; - rle_repeat_count = 0; - - memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); - for (i = 0; i < total_code_sizes_to_pack; i++) - { - mz_uint8 code_size = code_sizes_to_pack[i]; - if (!code_size) - { - TDEFL_RLE_PREV_CODE_SIZE(); - if (++rle_z_count == 138) - { - TDEFL_RLE_ZERO_CODE_SIZE(); - } - } - else - { - TDEFL_RLE_ZERO_CODE_SIZE(); - if (code_size != prev_code_size) - { - TDEFL_RLE_PREV_CODE_SIZE(); - d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); - packed_code_sizes[num_packed_code_sizes++] = code_size; - } - else if (++rle_repeat_count == 6) - { - TDEFL_RLE_PREV_CODE_SIZE(); - } - } - prev_code_size = code_size; - } - if (rle_repeat_count) - { - TDEFL_RLE_PREV_CODE_SIZE(); - } - else - { - TDEFL_RLE_ZERO_CODE_SIZE(); - } - - tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); - - TDEFL_PUT_BITS(2, 2); - - TDEFL_PUT_BITS(num_lit_codes - 257, 5); - TDEFL_PUT_BITS(num_dist_codes - 1, 5); - - for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) - if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) - break; - num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); - TDEFL_PUT_BITS(num_bit_lengths - 4, 4); - for (i = 0; (int)i < num_bit_lengths; i++) - TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); - - for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes;) - { - mz_uint code = packed_code_sizes[packed_code_sizes_index++]; - MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); - TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); - if (code >= 16) - TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]); - } -} - -static void tdefl_start_static_block(tdefl_compressor *d) -{ - mz_uint i; - mz_uint8 *p = &d->m_huff_code_sizes[0][0]; - - for (i = 0; i <= 143; ++i) - *p++ = 8; - for (; i <= 255; ++i) - *p++ = 9; - for (; i <= 279; ++i) - *p++ = 7; - for (; i <= 287; ++i) - *p++ = 8; - - memset(d->m_huff_code_sizes[1], 5, 32); - - tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); - tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); - - TDEFL_PUT_BITS(1, 2); -} - -static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES &&MINIZ_LITTLE_ENDIAN &&MINIZ_HAS_64BIT_REGISTERS -static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) -{ - mz_uint flags; - mz_uint8 *pLZ_codes; - mz_uint8 *pOutput_buf = d->m_pOutput_buf; - mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; - mz_uint64 bit_buffer = d->m_bit_buffer; - mz_uint bits_in = d->m_bits_in; - -#define TDEFL_PUT_BITS_FAST(b, l) \ - { \ - bit_buffer |= (((mz_uint64)(b)) << bits_in); \ - bits_in += (l); \ - } - - flags = 1; - for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1) - { - if (flags == 1) - flags = *pLZ_codes++ | 0x100; - - if (flags & 1) - { - mz_uint s0, s1, n0, n1, sym, num_extra_bits; - mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); - pLZ_codes += 3; - - MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); - TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); - - /* This sequence coaxes MSVC into using cmov's vs. jmp's. */ - s0 = s_tdefl_small_dist_sym[match_dist & 511]; - n0 = s_tdefl_small_dist_extra[match_dist & 511]; - s1 = s_tdefl_large_dist_sym[match_dist >> 8]; - n1 = s_tdefl_large_dist_extra[match_dist >> 8]; - sym = (match_dist < 512) ? s0 : s1; - num_extra_bits = (match_dist < 512) ? n0 : n1; - - MZ_ASSERT(d->m_huff_code_sizes[1][sym]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); - TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); - } - else - { - mz_uint lit = *pLZ_codes++; - MZ_ASSERT(d->m_huff_code_sizes[0][lit]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); - - if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) - { - flags >>= 1; - lit = *pLZ_codes++; - MZ_ASSERT(d->m_huff_code_sizes[0][lit]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); - - if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) - { - flags >>= 1; - lit = *pLZ_codes++; - MZ_ASSERT(d->m_huff_code_sizes[0][lit]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); - } - } - } - - if (pOutput_buf >= d->m_pOutput_buf_end) - return MZ_FALSE; - - *(mz_uint64 *)pOutput_buf = bit_buffer; - pOutput_buf += (bits_in >> 3); - bit_buffer >>= (bits_in & ~7); - bits_in &= 7; - } - -#undef TDEFL_PUT_BITS_FAST - - d->m_pOutput_buf = pOutput_buf; - d->m_bits_in = 0; - d->m_bit_buffer = 0; - - while (bits_in) - { - mz_uint32 n = MZ_MIN(bits_in, 16); - TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); - bit_buffer >>= n; - bits_in -= n; - } - - TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); - - return (d->m_pOutput_buf < d->m_pOutput_buf_end); -} -#else -static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) -{ - mz_uint flags; - mz_uint8 *pLZ_codes; - - flags = 1; - for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1) - { - if (flags == 1) - flags = *pLZ_codes++ | 0x100; - if (flags & 1) - { - mz_uint sym, num_extra_bits; - mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); - pLZ_codes += 3; - - MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); - TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); - TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); - - if (match_dist < 512) - { - sym = s_tdefl_small_dist_sym[match_dist]; - num_extra_bits = s_tdefl_small_dist_extra[match_dist]; - } - else - { - sym = s_tdefl_large_dist_sym[match_dist >> 8]; - num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; - } - MZ_ASSERT(d->m_huff_code_sizes[1][sym]); - TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); - TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); - } - else - { - mz_uint lit = *pLZ_codes++; - MZ_ASSERT(d->m_huff_code_sizes[0][lit]); - TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); - } - } - - TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); - - return (d->m_pOutput_buf < d->m_pOutput_buf_end); -} -#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS */ - -static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) -{ - if (static_block) - tdefl_start_static_block(d); - else - tdefl_start_dynamic_block(d); - return tdefl_compress_lz_codes(d); -} - -static int tdefl_flush_block(tdefl_compressor *d, int flush) -{ - mz_uint saved_bit_buf, saved_bits_in; - mz_uint8 *pSaved_output_buf; - mz_bool comp_block_succeeded = MZ_FALSE; - int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; - mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf; - - d->m_pOutput_buf = pOutput_buf_start; - d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; - - MZ_ASSERT(!d->m_output_flush_remaining); - d->m_output_flush_ofs = 0; - d->m_output_flush_remaining = 0; - - *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); - d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); - - if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) - { - TDEFL_PUT_BITS(0x78, 8); - TDEFL_PUT_BITS(0x01, 8); - } - - TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); - - pSaved_output_buf = d->m_pOutput_buf; - saved_bit_buf = d->m_bit_buffer; - saved_bits_in = d->m_bits_in; - - if (!use_raw_block) - comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48)); - - /* If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. */ - if (((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) && - ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size)) - { - mz_uint i; - d->m_pOutput_buf = pSaved_output_buf; - (void)(d->m_bit_buffer = saved_bit_buf), d->m_bits_in = saved_bits_in; - TDEFL_PUT_BITS(0, 2); - if (d->m_bits_in) - { - TDEFL_PUT_BITS(0, 8 - d->m_bits_in); - } - for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) - { - TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); - } - for (i = 0; i < d->m_total_lz_bytes; ++i) - { - TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8); - } - } - /* Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. */ - else if (!comp_block_succeeded) - { - d->m_pOutput_buf = pSaved_output_buf; - (void)(d->m_bit_buffer = saved_bit_buf), d->m_bits_in = saved_bits_in; - tdefl_compress_block(d, MZ_TRUE); - } - - if (flush) - { - if (flush == TDEFL_FINISH) - { - if (d->m_bits_in) - { - TDEFL_PUT_BITS(0, 8 - d->m_bits_in); - } - if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) - { - mz_uint i, a = d->m_adler32; - for (i = 0; i < 4; i++) - { - TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); - a <<= 8; - } - } - } - else - { - mz_uint i, z = 0; - TDEFL_PUT_BITS(0, 3); - if (d->m_bits_in) - { - TDEFL_PUT_BITS(0, 8 - d->m_bits_in); - } - for (i = 2; i; --i, z ^= 0xFFFF) - { - TDEFL_PUT_BITS(z & 0xFFFF, 16); - } - } - } - - MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); - - memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); - memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); - - d->m_pLZ_code_buf = d->m_lz_code_buf + 1; - d->m_pLZ_flags = d->m_lz_code_buf; - d->m_num_flags_left = 8; - d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; - d->m_total_lz_bytes = 0; - d->m_block_index++; - - if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) - { - if (d->m_pPut_buf_func) - { - *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; - if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) - return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); - } - else if (pOutput_buf_start == d->m_output_buf) - { - int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); - memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy); - d->m_out_buf_ofs += bytes_to_copy; - if ((n -= bytes_to_copy) != 0) - { - d->m_output_flush_ofs = bytes_to_copy; - d->m_output_flush_remaining = n; - } - } - else - { - d->m_out_buf_ofs += n; - } - } - - return d->m_output_flush_remaining; -} - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES -#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p) -static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) -{ - mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; - mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; - const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q; - mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s); - MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); - if (max_match_len <= match_len) - return; - for (;;) - { - for (;;) - { - if (--num_probes_left == 0) - return; -#define TDEFL_PROBE \ - next_probe_pos = d->m_next[probe_pos]; \ - if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \ - return; \ - probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ - if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \ - break; - TDEFL_PROBE; - TDEFL_PROBE; - TDEFL_PROBE; - } - if (!dist) - break; - q = (const mz_uint16 *)(d->m_dict + probe_pos); - if (TDEFL_READ_UNALIGNED_WORD(q) != s01) - continue; - p = s; - probe_len = 32; - do - { - } while ((TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && - (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0)); - if (!probe_len) - { - *pMatch_dist = dist; - *pMatch_len = MZ_MIN(max_match_len, (mz_uint)TDEFL_MAX_MATCH_LEN); - break; - } - else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q)) > match_len) - { - *pMatch_dist = dist; - if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) - break; - c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); - } - } -} -#else -static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) -{ - mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; - mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; - const mz_uint8 *s = d->m_dict + pos, *p, *q; - mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; - MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); - if (max_match_len <= match_len) - return; - for (;;) - { - for (;;) - { - if (--num_probes_left == 0) - return; -#define TDEFL_PROBE \ - next_probe_pos = d->m_next[probe_pos]; \ - if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \ - return; \ - probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ - if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) \ - break; - TDEFL_PROBE; - TDEFL_PROBE; - TDEFL_PROBE; - } - if (!dist) - break; - p = s; - q = d->m_dict + probe_pos; - for (probe_len = 0; probe_len < max_match_len; probe_len++) - if (*p++ != *q++) - break; - if (probe_len > match_len) - { - *pMatch_dist = dist; - if ((*pMatch_len = match_len = probe_len) == max_match_len) - return; - c0 = d->m_dict[pos + match_len]; - c1 = d->m_dict[pos + match_len - 1]; - } - } -} -#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES */ - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES &&MINIZ_LITTLE_ENDIAN -static mz_bool tdefl_compress_fast(tdefl_compressor *d) -{ - /* Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. */ - mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left; - mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; - mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; - - while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) - { - const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; - mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; - mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); - d->m_src_buf_left -= num_bytes_to_process; - lookahead_size += num_bytes_to_process; - - while (num_bytes_to_process) - { - mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); - memcpy(d->m_dict + dst_pos, d->m_pSrc, n); - if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) - memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); - d->m_pSrc += n; - dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; - num_bytes_to_process -= n; - } - - dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); - if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) - break; - - while (lookahead_size >= 4) - { - mz_uint cur_match_dist, cur_match_len = 1; - mz_uint8 *pCur_dict = d->m_dict + cur_pos; - mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF; - mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK; - mz_uint probe_pos = d->m_hash[hash]; - d->m_hash[hash] = (mz_uint16)lookahead_pos; - - if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram)) - { - const mz_uint16 *p = (const mz_uint16 *)pCur_dict; - const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); - mz_uint32 probe_len = 32; - do - { - } while ((TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && - (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0)); - cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); - if (!probe_len) - cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; - - if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U))) - { - cur_match_len = 1; - *pLZ_code_buf++ = (mz_uint8)first_trigram; - *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); - d->m_huff_count[0][(mz_uint8)first_trigram]++; - } - else - { - mz_uint32 s0, s1; - cur_match_len = MZ_MIN(cur_match_len, lookahead_size); - - MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); - - cur_match_dist--; - - pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); - *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; - pLZ_code_buf += 3; - *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); - - s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; - s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; - d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; - - d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++; - } - } - else - { - *pLZ_code_buf++ = (mz_uint8)first_trigram; - *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); - d->m_huff_count[0][(mz_uint8)first_trigram]++; - } - - if (--num_flags_left == 0) - { - num_flags_left = 8; - pLZ_flags = pLZ_code_buf++; - } - - total_lz_bytes += cur_match_len; - lookahead_pos += cur_match_len; - dict_size = MZ_MIN(dict_size + cur_match_len, (mz_uint)TDEFL_LZ_DICT_SIZE); - cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; - MZ_ASSERT(lookahead_size >= cur_match_len); - lookahead_size -= cur_match_len; - - if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) - { - int n; - d->m_lookahead_pos = lookahead_pos; - d->m_lookahead_size = lookahead_size; - d->m_dict_size = dict_size; - d->m_total_lz_bytes = total_lz_bytes; - d->m_pLZ_code_buf = pLZ_code_buf; - d->m_pLZ_flags = pLZ_flags; - d->m_num_flags_left = num_flags_left; - if ((n = tdefl_flush_block(d, 0)) != 0) - return (n < 0) ? MZ_FALSE : MZ_TRUE; - total_lz_bytes = d->m_total_lz_bytes; - pLZ_code_buf = d->m_pLZ_code_buf; - pLZ_flags = d->m_pLZ_flags; - num_flags_left = d->m_num_flags_left; - } - } - - while (lookahead_size) - { - mz_uint8 lit = d->m_dict[cur_pos]; - - total_lz_bytes++; - *pLZ_code_buf++ = lit; - *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); - if (--num_flags_left == 0) - { - num_flags_left = 8; - pLZ_flags = pLZ_code_buf++; - } - - d->m_huff_count[0][lit]++; - - lookahead_pos++; - dict_size = MZ_MIN(dict_size + 1, (mz_uint)TDEFL_LZ_DICT_SIZE); - cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; - lookahead_size--; - - if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) - { - int n; - d->m_lookahead_pos = lookahead_pos; - d->m_lookahead_size = lookahead_size; - d->m_dict_size = dict_size; - d->m_total_lz_bytes = total_lz_bytes; - d->m_pLZ_code_buf = pLZ_code_buf; - d->m_pLZ_flags = pLZ_flags; - d->m_num_flags_left = num_flags_left; - if ((n = tdefl_flush_block(d, 0)) != 0) - return (n < 0) ? MZ_FALSE : MZ_TRUE; - total_lz_bytes = d->m_total_lz_bytes; - pLZ_code_buf = d->m_pLZ_code_buf; - pLZ_flags = d->m_pLZ_flags; - num_flags_left = d->m_num_flags_left; - } - } - } - - d->m_lookahead_pos = lookahead_pos; - d->m_lookahead_size = lookahead_size; - d->m_dict_size = dict_size; - d->m_total_lz_bytes = total_lz_bytes; - d->m_pLZ_code_buf = pLZ_code_buf; - d->m_pLZ_flags = pLZ_flags; - d->m_num_flags_left = num_flags_left; - return MZ_TRUE; -} -#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */ - -static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit) -{ - d->m_total_lz_bytes++; - *d->m_pLZ_code_buf++ = lit; - *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); - if (--d->m_num_flags_left == 0) - { - d->m_num_flags_left = 8; - d->m_pLZ_flags = d->m_pLZ_code_buf++; - } - d->m_huff_count[0][lit]++; -} - -static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) -{ - mz_uint32 s0, s1; - - MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE)); - - d->m_total_lz_bytes += match_len; - - d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); - - match_dist -= 1; - d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); - d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); - d->m_pLZ_code_buf += 3; - - *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); - if (--d->m_num_flags_left == 0) - { - d->m_num_flags_left = 8; - d->m_pLZ_flags = d->m_pLZ_code_buf++; - } - - s0 = s_tdefl_small_dist_sym[match_dist & 511]; - s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127]; - d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; - - if (match_len >= TDEFL_MIN_MATCH_LEN) - d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; -} - -static mz_bool tdefl_compress_normal(tdefl_compressor *d) -{ - const mz_uint8 *pSrc = d->m_pSrc; - size_t src_buf_left = d->m_src_buf_left; - tdefl_flush flush = d->m_flush; - - while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) - { - mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; - /* Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. */ - if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) - { - mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; - mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; - mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); - const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; - src_buf_left -= num_bytes_to_process; - d->m_lookahead_size += num_bytes_to_process; - while (pSrc != pSrc_end) - { - mz_uint8 c = *pSrc++; - d->m_dict[dst_pos] = c; - if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) - d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; - hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); - d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; - d->m_hash[hash] = (mz_uint16)(ins_pos); - dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; - ins_pos++; - } - } - else - { - while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) - { - mz_uint8 c = *pSrc++; - mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; - src_buf_left--; - d->m_dict[dst_pos] = c; - if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) - d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; - if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) - { - mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; - mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); - d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; - d->m_hash[hash] = (mz_uint16)(ins_pos); - } - } - } - d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); - if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) - break; - - /* Simple lazy/greedy parsing state machine. */ - len_to_move = 1; - cur_match_dist = 0; - cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); - cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; - if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) - { - if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) - { - mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; - cur_match_len = 0; - while (cur_match_len < d->m_lookahead_size) - { - if (d->m_dict[cur_pos + cur_match_len] != c) - break; - cur_match_len++; - } - if (cur_match_len < TDEFL_MIN_MATCH_LEN) - cur_match_len = 0; - else - cur_match_dist = 1; - } - } - else - { - tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len); - } - if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) - { - cur_match_dist = cur_match_len = 0; - } - if (d->m_saved_match_len) - { - if (cur_match_len > d->m_saved_match_len) - { - tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); - if (cur_match_len >= 128) - { - tdefl_record_match(d, cur_match_len, cur_match_dist); - d->m_saved_match_len = 0; - len_to_move = cur_match_len; - } - else - { - d->m_saved_lit = d->m_dict[cur_pos]; - d->m_saved_match_dist = cur_match_dist; - d->m_saved_match_len = cur_match_len; - } - } - else - { - tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); - len_to_move = d->m_saved_match_len - 1; - d->m_saved_match_len = 0; - } - } - else if (!cur_match_dist) - tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]); - else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128)) - { - tdefl_record_match(d, cur_match_len, cur_match_dist); - len_to_move = cur_match_len; - } - else - { - d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; - d->m_saved_match_dist = cur_match_dist; - d->m_saved_match_len = cur_match_len; - } - /* Move the lookahead forward by len_to_move bytes. */ - d->m_lookahead_pos += len_to_move; - MZ_ASSERT(d->m_lookahead_size >= len_to_move); - d->m_lookahead_size -= len_to_move; - d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE); - /* Check if it's time to flush the current LZ codes to the internal output buffer. */ - if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || - ((d->m_total_lz_bytes > 31 * 1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))) - { - int n; - d->m_pSrc = pSrc; - d->m_src_buf_left = src_buf_left; - if ((n = tdefl_flush_block(d, 0)) != 0) - return (n < 0) ? MZ_FALSE : MZ_TRUE; - } - } - - d->m_pSrc = pSrc; - d->m_src_buf_left = src_buf_left; - return MZ_TRUE; -} - -static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) -{ - if (d->m_pIn_buf_size) - { - *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; - } - - if (d->m_pOut_buf_size) - { - size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining); - memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n); - d->m_output_flush_ofs += (mz_uint)n; - d->m_output_flush_remaining -= (mz_uint)n; - d->m_out_buf_ofs += n; - - *d->m_pOut_buf_size = d->m_out_buf_ofs; - } - - return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY; -} - -tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush) -{ - if (!d) - { - if (pIn_buf_size) - *pIn_buf_size = 0; - if (pOut_buf_size) - *pOut_buf_size = 0; - return TDEFL_STATUS_BAD_PARAM; - } - - d->m_pIn_buf = pIn_buf; - d->m_pIn_buf_size = pIn_buf_size; - d->m_pOut_buf = pOut_buf; - d->m_pOut_buf_size = pOut_buf_size; - d->m_pSrc = (const mz_uint8 *)(pIn_buf); - d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; - d->m_out_buf_ofs = 0; - d->m_flush = flush; - - if (((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) || - (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf)) - { - if (pIn_buf_size) - *pIn_buf_size = 0; - if (pOut_buf_size) - *pOut_buf_size = 0; - return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); - } - d->m_wants_to_finish |= (flush == TDEFL_FINISH); - - if ((d->m_output_flush_remaining) || (d->m_finished)) - return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES &&MINIZ_LITTLE_ENDIAN - if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && - ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && - ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0)) - { - if (!tdefl_compress_fast(d)) - return d->m_prev_return_status; - } - else -#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */ - { - if (!tdefl_compress_normal(d)) - return d->m_prev_return_status; - } - - if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf)) - d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); - - if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining)) - { - if (tdefl_flush_block(d, flush) < 0) - return d->m_prev_return_status; - d->m_finished = (flush == TDEFL_FINISH); - if (flush == TDEFL_FULL_FLUSH) - { - MZ_CLEAR_OBJ(d->m_hash); - MZ_CLEAR_OBJ(d->m_next); - d->m_dict_size = 0; - } - } - - return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); -} - -tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush) -{ - MZ_ASSERT(d->m_pPut_buf_func); - return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); -} - -tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) -{ - d->m_pPut_buf_func = pPut_buf_func; - d->m_pPut_buf_user = pPut_buf_user; - d->m_flags = (mz_uint)(flags); - d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; - d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; - d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; - if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) - MZ_CLEAR_OBJ(d->m_hash); - d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; - d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; - d->m_pLZ_code_buf = d->m_lz_code_buf + 1; - d->m_pLZ_flags = d->m_lz_code_buf; - d->m_num_flags_left = 8; - d->m_pOutput_buf = d->m_output_buf; - d->m_pOutput_buf_end = d->m_output_buf; - d->m_prev_return_status = TDEFL_STATUS_OKAY; - d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; - d->m_adler32 = 1; - d->m_pIn_buf = NULL; - d->m_pOut_buf = NULL; - d->m_pIn_buf_size = NULL; - d->m_pOut_buf_size = NULL; - d->m_flush = TDEFL_NO_FLUSH; - d->m_pSrc = NULL; - d->m_src_buf_left = 0; - d->m_out_buf_ofs = 0; - memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); - memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); - return TDEFL_STATUS_OKAY; -} - -tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) -{ - return d->m_prev_return_status; -} - -mz_uint32 tdefl_get_adler32(tdefl_compressor *d) -{ - return d->m_adler32; -} - -mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) -{ - tdefl_compressor *pComp; - mz_bool succeeded; - if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) - return MZ_FALSE; - pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); - if (!pComp) - return MZ_FALSE; - succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY); - succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE); - MZ_FREE(pComp); - return succeeded; -} - -typedef struct -{ - size_t m_size, m_capacity; - mz_uint8 *m_pBuf; - mz_bool m_expandable; -} tdefl_output_buffer; - -static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser) -{ - tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; - size_t new_size = p->m_size + len; - if (new_size > p->m_capacity) - { - size_t new_capacity = p->m_capacity; - mz_uint8 *pNew_buf; - if (!p->m_expandable) - return MZ_FALSE; - do - { - new_capacity = MZ_MAX(128U, new_capacity << 1U); - } while (new_size > new_capacity); - pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity); - if (!pNew_buf) - return MZ_FALSE; - p->m_pBuf = pNew_buf; - p->m_capacity = new_capacity; - } - memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len); - p->m_size = new_size; - return MZ_TRUE; -} - -void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) -{ - tdefl_output_buffer out_buf; - MZ_CLEAR_OBJ(out_buf); - if (!pOut_len) - return MZ_FALSE; - else - *pOut_len = 0; - out_buf.m_expandable = MZ_TRUE; - if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) - return NULL; - *pOut_len = out_buf.m_size; - return out_buf.m_pBuf; -} - -size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) -{ - tdefl_output_buffer out_buf; - MZ_CLEAR_OBJ(out_buf); - if (!pOut_buf) - return 0; - out_buf.m_pBuf = (mz_uint8 *)pOut_buf; - out_buf.m_capacity = out_buf_len; - if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) - return 0; - return out_buf.m_size; -} - -static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; - -/* level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). */ -mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy) -{ - mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); - if (window_bits > 0) - comp_flags |= TDEFL_WRITE_ZLIB_HEADER; - - if (!level) - comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; - else if (strategy == MZ_FILTERED) - comp_flags |= TDEFL_FILTER_MATCHES; - else if (strategy == MZ_HUFFMAN_ONLY) - comp_flags &= ~TDEFL_MAX_PROBES_MASK; - else if (strategy == MZ_FIXED) - comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; - else if (strategy == MZ_RLE) - comp_flags |= TDEFL_RLE_MATCHES; - - return comp_flags; -} - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4204) /* nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) */ -#endif - -/* Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at - http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. - This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. */ -void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip) -{ - /* Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. */ - static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; - tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); - tdefl_output_buffer out_buf; - int i, bpl = w * num_chans, y, z; - mz_uint32 c; - *pLen_out = 0; - if (!pComp) - return NULL; - MZ_CLEAR_OBJ(out_buf); - out_buf.m_expandable = MZ_TRUE; - out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h); - if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity))) - { - MZ_FREE(pComp); - return NULL; - } - /* write dummy header */ - for (z = 41; z; --z) - tdefl_output_buffer_putter(&z, 1, &out_buf); - /* compress image data */ - tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER); - for (y = 0; y < h; ++y) - { - tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); - tdefl_compress_buffer(pComp, (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH); - } - if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) - { - MZ_FREE(pComp); - MZ_FREE(out_buf.m_pBuf); - return NULL; - } - /* write real header */ - *pLen_out = out_buf.m_size - 41; - { - static const mz_uint8 chans[] = { 0x00, 0x00, 0x04, 0x02, 0x06 }; - mz_uint8 pnghdr[41] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, - 0x0a, 0x1a, 0x0a, 0x00, 0x00, - 0x00, 0x0d, 0x49, 0x48, 0x44, - 0x52, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x44, 0x41, - 0x54 }; - pnghdr[18] = (mz_uint8)(w >> 8); - pnghdr[19] = (mz_uint8)w; - pnghdr[22] = (mz_uint8)(h >> 8); - pnghdr[22] = (mz_uint8)h; - pnghdr[25] = chans[num_chans]; - pnghdr[33] = (mz_uint8)(*pLen_out >> 24); - pnghdr[34] = (mz_uint8)(*pLen_out >> 16); - pnghdr[35] = (mz_uint8)(*pLen_out >> 8); - pnghdr[36] = (mz_uint8)*pLen_out; - c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17); - for (i = 0; i < 4; ++i, c <<= 8) - ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24); - memcpy(out_buf.m_pBuf, pnghdr, 41); - } - /* write footer (IDAT CRC-32, followed by IEND chunk) */ - if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) - { - *pLen_out = 0; - MZ_FREE(pComp); - MZ_FREE(out_buf.m_pBuf); - return NULL; - } - c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, *pLen_out + 4); - for (i = 0; i < 4; ++i, c <<= 8) - (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24); - /* compute final size of file, grab compressed data buffer and return */ - *pLen_out += 57; - MZ_FREE(pComp); - return out_buf.m_pBuf; -} -void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) -{ - /* Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out) */ - return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE); -} - -/* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that */ -/* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */ -/* structure size and allocation mechanism. */ -tdefl_compressor *tdefl_compressor_alloc() -{ - return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); -} - -void tdefl_compressor_free(tdefl_compressor *pComp) -{ - MZ_FREE(pComp); -} - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#ifdef __cplusplus -} -#endif -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - - - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- Low-level Decompression (completely independent from all compression API's) */ - -#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) -#define TINFL_MEMSET(p, c, l) memset(p, c, l) - -#define TINFL_CR_BEGIN \ - switch (r->m_state) \ - { \ - case 0: -#define TINFL_CR_RETURN(state_index, result) \ - do \ - { \ - status = result; \ - r->m_state = state_index; \ - goto common_exit; \ - case state_index: \ - ; \ - } \ - MZ_MACRO_END -#define TINFL_CR_RETURN_FOREVER(state_index, result) \ - do \ - { \ - for (;;) \ - { \ - TINFL_CR_RETURN(state_index, result); \ - } \ - } \ - MZ_MACRO_END -#define TINFL_CR_FINISH } - -#define TINFL_GET_BYTE(state_index, c) \ - do \ - { \ - while (pIn_buf_cur >= pIn_buf_end) \ - { \ - TINFL_CR_RETURN(state_index, (decomp_flags &TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \ - } \ - c = *pIn_buf_cur++; \ - } \ - MZ_MACRO_END - -#define TINFL_NEED_BITS(state_index, n) \ - do \ - { \ - mz_uint c; \ - TINFL_GET_BYTE(state_index, c); \ - bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \ - num_bits += 8; \ - } while (num_bits < (mz_uint)(n)) -#define TINFL_SKIP_BITS(state_index, n) \ - do \ - { \ - if (num_bits < (mz_uint)(n)) \ - { \ - TINFL_NEED_BITS(state_index, n); \ - } \ - bit_buf >>= (n); \ - num_bits -= (n); \ - } \ - MZ_MACRO_END -#define TINFL_GET_BITS(state_index, b, n) \ - do \ - { \ - if (num_bits < (mz_uint)(n)) \ - { \ - TINFL_NEED_BITS(state_index, n); \ - } \ - b = bit_buf & ((1 << (n)) - 1); \ - bit_buf >>= (n); \ - num_bits -= (n); \ - } \ - MZ_MACRO_END - -/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */ -/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */ -/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */ -/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */ -#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ - do \ - { \ - temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ - if (temp >= 0) \ - { \ - code_len = temp >> 9; \ - if ((code_len) && (num_bits >= code_len)) \ - break; \ - } \ - else if (num_bits > TINFL_FAST_LOOKUP_BITS) \ - { \ - code_len = TINFL_FAST_LOOKUP_BITS; \ - do \ - { \ - temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ - } while ((temp < 0) && (num_bits >= (code_len + 1))); \ - if (temp >= 0) \ - break; \ - } \ - TINFL_GET_BYTE(state_index, c); \ - bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \ - num_bits += 8; \ - } while (num_bits < 15); - -/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */ -/* beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully */ -/* decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. */ -/* The slow path is only executed at the very end of the input buffer. */ -/* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes */ -/* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */ -#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \ - do \ - { \ - int temp; \ - mz_uint code_len, c; \ - if (num_bits < 15) \ - { \ - if ((pIn_buf_end - pIn_buf_cur) < 2) \ - { \ - TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ - } \ - else \ - { \ - bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \ - pIn_buf_cur += 2; \ - num_bits += 16; \ - } \ - } \ - if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ - code_len = temp >> 9, temp &= 511; \ - else \ - { \ - code_len = TINFL_FAST_LOOKUP_BITS; \ - do \ - { \ - temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ - } while (temp < 0); \ - } \ - sym = temp; \ - bit_buf >>= code_len; \ - num_bits -= code_len; \ - } \ - MZ_MACRO_END - -tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) -{ - static const int s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 }; - static const int s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 }; - static const int s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 }; - static const int s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 }; - static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; - static const int s_min_table_sizes[3] = { 257, 1, 4 }; - - tinfl_status status = TINFL_STATUS_FAILED; - mz_uint32 num_bits, dist, counter, num_extra; - tinfl_bit_buf_t bit_buf; - const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; - mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; - size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t) - 1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; - - /* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */ - if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) - { - *pIn_buf_size = *pOut_buf_size = 0; - return TINFL_STATUS_BAD_PARAM; - } - - num_bits = r->m_num_bits; - bit_buf = r->m_bit_buf; - dist = r->m_dist; - counter = r->m_counter; - num_extra = r->m_num_extra; - dist_from_out_buf_start = r->m_dist_from_out_buf_start; - TINFL_CR_BEGIN - - bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; - r->m_z_adler32 = r->m_check_adler32 = 1; - if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) - { - TINFL_GET_BYTE(1, r->m_zhdr0); - TINFL_GET_BYTE(2, r->m_zhdr1); - counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); - if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) - counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); - if (counter) - { - TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); - } - } - - do - { - TINFL_GET_BITS(3, r->m_final, 3); - r->m_type = r->m_final >> 1; - if (r->m_type == 0) - { - TINFL_SKIP_BITS(5, num_bits & 7); - for (counter = 0; counter < 4; ++counter) - { - if (num_bits) - TINFL_GET_BITS(6, r->m_raw_header[counter], 8); - else - TINFL_GET_BYTE(7, r->m_raw_header[counter]); - } - if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) - { - TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); - } - while ((counter) && (num_bits)) - { - TINFL_GET_BITS(51, dist, 8); - while (pOut_buf_cur >= pOut_buf_end) - { - TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); - } - *pOut_buf_cur++ = (mz_uint8)dist; - counter--; - } - while (counter) - { - size_t n; - while (pOut_buf_cur >= pOut_buf_end) - { - TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); - } - while (pIn_buf_cur >= pIn_buf_end) - { - TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); - } - n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); - TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); - pIn_buf_cur += n; - pOut_buf_cur += n; - counter -= (mz_uint)n; - } - } - else if (r->m_type == 3) - { - TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); - } - else - { - if (r->m_type == 1) - { - mz_uint8 *p = r->m_tables[0].m_code_size; - mz_uint i; - r->m_table_sizes[0] = 288; - r->m_table_sizes[1] = 32; - TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); - for (i = 0; i <= 143; ++i) - *p++ = 8; - for (; i <= 255; ++i) - *p++ = 9; - for (; i <= 279; ++i) - *p++ = 7; - for (; i <= 287; ++i) - *p++ = 8; - } - else - { - for (counter = 0; counter < 3; counter++) - { - TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); - r->m_table_sizes[counter] += s_min_table_sizes[counter]; - } - MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); - for (counter = 0; counter < r->m_table_sizes[2]; counter++) - { - mz_uint s; - TINFL_GET_BITS(14, s, 3); - r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; - } - r->m_table_sizes[2] = 19; - } - for (; (int)r->m_type >= 0; r->m_type--) - { - int tree_next, tree_cur; - tinfl_huff_table *pTable; - mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; - pTable = &r->m_tables[r->m_type]; - MZ_CLEAR_OBJ(total_syms); - MZ_CLEAR_OBJ(pTable->m_look_up); - MZ_CLEAR_OBJ(pTable->m_tree); - for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) - total_syms[pTable->m_code_size[i]]++; - (void)(used_syms = 0), total = 0; - next_code[0] = next_code[1] = 0; - for (i = 1; i <= 15; ++i) - { - used_syms += total_syms[i]; - next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); - } - if ((65536 != total) && (used_syms > 1)) - { - TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); - } - for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) - { - mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; - if (!code_size) - continue; - cur_code = next_code[code_size]++; - for (l = code_size; l > 0; l--, cur_code >>= 1) - rev_code = (rev_code << 1) | (cur_code & 1); - if (code_size <= TINFL_FAST_LOOKUP_BITS) - { - mz_int16 k = (mz_int16)((code_size << 9) | sym_index); - while (rev_code < TINFL_FAST_LOOKUP_SIZE) - { - pTable->m_look_up[rev_code] = k; - rev_code += (1 << code_size); - } - continue; - } - if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) - { - pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; - tree_cur = tree_next; - tree_next -= 2; - } - rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); - for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) - { - tree_cur -= ((rev_code >>= 1) & 1); - if (!pTable->m_tree[-tree_cur - 1]) - { - pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; - tree_cur = tree_next; - tree_next -= 2; - } - else - tree_cur = pTable->m_tree[-tree_cur - 1]; - } - tree_cur -= ((rev_code >>= 1) & 1); - pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; - } - if (r->m_type == 2) - { - for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) - { - mz_uint s; - TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); - if (dist < 16) - { - r->m_len_codes[counter++] = (mz_uint8)dist; - continue; - } - if ((dist == 16) && (!counter)) - { - TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); - } - num_extra = "\02\03\07"[dist - 16]; - TINFL_GET_BITS(18, s, num_extra); - s += "\03\03\013"[dist - 16]; - TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); - counter += s; - } - if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) - { - TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); - } - TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); - TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); - } - } - for (;;) - { - mz_uint8 *pSrc; - for (;;) - { - if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) - { - TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); - if (counter >= 256) - break; - while (pOut_buf_cur >= pOut_buf_end) - { - TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); - } - *pOut_buf_cur++ = (mz_uint8)counter; - } - else - { - int sym2; - mz_uint code_len; -#if TINFL_USE_64BIT_BITBUF - if (num_bits < 30) - { - bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); - pIn_buf_cur += 4; - num_bits += 32; - } -#else - if (num_bits < 15) - { - bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); - pIn_buf_cur += 2; - num_bits += 16; - } -#endif - if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) - code_len = sym2 >> 9; - else - { - code_len = TINFL_FAST_LOOKUP_BITS; - do - { - sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; - } while (sym2 < 0); - } - counter = sym2; - bit_buf >>= code_len; - num_bits -= code_len; - if (counter & 256) - break; - -#if !TINFL_USE_64BIT_BITBUF - if (num_bits < 15) - { - bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); - pIn_buf_cur += 2; - num_bits += 16; - } -#endif - if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) - code_len = sym2 >> 9; - else - { - code_len = TINFL_FAST_LOOKUP_BITS; - do - { - sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; - } while (sym2 < 0); - } - bit_buf >>= code_len; - num_bits -= code_len; - - pOut_buf_cur[0] = (mz_uint8)counter; - if (sym2 & 256) - { - pOut_buf_cur++; - counter = sym2; - break; - } - pOut_buf_cur[1] = (mz_uint8)sym2; - pOut_buf_cur += 2; - } - } - if ((counter &= 511) == 256) - break; - - num_extra = s_length_extra[counter - 257]; - counter = s_length_base[counter - 257]; - if (num_extra) - { - mz_uint extra_bits; - TINFL_GET_BITS(25, extra_bits, num_extra); - counter += extra_bits; - } - - TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); - num_extra = s_dist_extra[dist]; - dist = s_dist_base[dist]; - if (num_extra) - { - mz_uint extra_bits; - TINFL_GET_BITS(27, extra_bits, num_extra); - dist += extra_bits; - } - - dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; - if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) - { - TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); - } - - pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); - - if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) - { - while (counter--) - { - while (pOut_buf_cur >= pOut_buf_end) - { - TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); - } - *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; - } - continue; - } -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES - else if ((counter >= 9) && (counter <= dist)) - { - const mz_uint8 *pSrc_end = pSrc + (counter & ~7); - do - { - ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; - ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; - pOut_buf_cur += 8; - } while ((pSrc += 8) < pSrc_end); - if ((counter &= 7) < 3) - { - if (counter) - { - pOut_buf_cur[0] = pSrc[0]; - if (counter > 1) - pOut_buf_cur[1] = pSrc[1]; - pOut_buf_cur += counter; - } - continue; - } - } -#endif - do - { - pOut_buf_cur[0] = pSrc[0]; - pOut_buf_cur[1] = pSrc[1]; - pOut_buf_cur[2] = pSrc[2]; - pOut_buf_cur += 3; - pSrc += 3; - } while ((int)(counter -= 3) > 2); - if ((int)counter > 0) - { - pOut_buf_cur[0] = pSrc[0]; - if ((int)counter > 1) - pOut_buf_cur[1] = pSrc[1]; - pOut_buf_cur += counter; - } - } - } - } while (!(r->m_final & 1)); - - /* Ensure byte alignment and put back any bytes from the bitbuf if we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */ - /* I'm being super conservative here. A number of simplifications can be made to the byte alignment part, and the Adler32 check shouldn't ever need to worry about reading from the bitbuf now. */ - TINFL_SKIP_BITS(32, num_bits & 7); - while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) - { - --pIn_buf_cur; - num_bits -= 8; - } - bit_buf &= (tinfl_bit_buf_t)(( ((mz_uint64)1) << num_bits) - (mz_uint64)1); - MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */ - - if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) - { - for (counter = 0; counter < 4; ++counter) - { - mz_uint s; - if (num_bits) - TINFL_GET_BITS(41, s, 8); - else - TINFL_GET_BYTE(42, s); - r->m_z_adler32 = (r->m_z_adler32 << 8) | s; - } - } - TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); - - TINFL_CR_FINISH - -common_exit: - /* As long as we aren't telling the caller that we NEED more input to make forward progress: */ - /* Put back any bytes from the bitbuf in case we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */ - /* We need to be very careful here to NOT push back any bytes we definitely know we need to make forward progress, though, or we'll lock the caller up into an inf loop. */ - if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS)) - { - while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) - { - --pIn_buf_cur; - num_bits -= 8; - } - } - r->m_num_bits = num_bits; - r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)(( ((mz_uint64)1) << num_bits) - (mz_uint64)1); - r->m_dist = dist; - r->m_counter = counter; - r->m_num_extra = num_extra; - r->m_dist_from_out_buf_start = dist_from_out_buf_start; - *pIn_buf_size = pIn_buf_cur - pIn_buf_next; - *pOut_buf_size = pOut_buf_cur - pOut_buf_next; - if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) - { - const mz_uint8 *ptr = pOut_buf_next; - size_t buf_len = *pOut_buf_size; - mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; - size_t block_len = buf_len % 5552; - while (buf_len) - { - for (i = 0; i + 7 < block_len; i += 8, ptr += 8) - { - (void)(s1 += ptr[0]), s2 += s1; - (void)(s1 += ptr[1]), s2 += s1; - (void)(s1 += ptr[2]), s2 += s1; - (void)(s1 += ptr[3]), s2 += s1; - (void)(s1 += ptr[4]), s2 += s1; - (void)(s1 += ptr[5]), s2 += s1; - (void)(s1 += ptr[6]), s2 += s1; - (void)(s1 += ptr[7]), s2 += s1; - } - for (; i < block_len; ++i) - (void)(s1 += *ptr++), s2 += s1; - (void)(s1 %= 65521U), s2 %= 65521U; - buf_len -= block_len; - block_len = 5552; - } - r->m_check_adler32 = (s2 << 16) + s1; - if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) - status = TINFL_STATUS_ADLER32_MISMATCH; - } - return status; -} - -/* Higher level helper functions. */ -void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) -{ - tinfl_decompressor decomp; - void *pBuf = NULL, *pNew_buf; - size_t src_buf_ofs = 0, out_buf_capacity = 0; - *pOut_len = 0; - tinfl_init(&decomp); - for (;;) - { - size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; - tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL, &dst_buf_size, - (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); - if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) - { - MZ_FREE(pBuf); - *pOut_len = 0; - return NULL; - } - src_buf_ofs += src_buf_size; - *pOut_len += dst_buf_size; - if (status == TINFL_STATUS_DONE) - break; - new_out_buf_capacity = out_buf_capacity * 2; - if (new_out_buf_capacity < 128) - new_out_buf_capacity = 128; - pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); - if (!pNew_buf) - { - MZ_FREE(pBuf); - *pOut_len = 0; - return NULL; - } - pBuf = pNew_buf; - out_buf_capacity = new_out_buf_capacity; - } - return pBuf; -} - -size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) -{ - tinfl_decompressor decomp; - tinfl_status status; - tinfl_init(&decomp); - status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf, &src_buf_len, (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); - return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len; -} - -int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) -{ - int result = 0; - tinfl_decompressor decomp; - mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE); - size_t in_buf_ofs = 0, dict_ofs = 0; - if (!pDict) - return TINFL_STATUS_FAILED; - tinfl_init(&decomp); - for (;;) - { - size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; - tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, - (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); - in_buf_ofs += in_buf_size; - if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) - break; - if (status != TINFL_STATUS_HAS_MORE_OUTPUT) - { - result = (status == TINFL_STATUS_DONE); - break; - } - dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); - } - MZ_FREE(pDict); - *pIn_buf_size = in_buf_ofs; - return result; -} - -tinfl_decompressor *tinfl_decompressor_alloc() -{ - tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor)); - if (pDecomp) - tinfl_init(pDecomp); - return pDecomp; -} - -void tinfl_decompressor_free(tinfl_decompressor *pDecomp) -{ - MZ_FREE(pDecomp); -} - -#ifdef __cplusplus -} -#endif -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * Copyright 2016 Martin Raiber - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef MINIZ_NO_ARCHIVE_APIS - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- .ZIP archive reading */ - -#ifdef MINIZ_NO_STDIO -#define MZ_FILE void * -#else -#include - -#if defined(_MSC_VER) || defined(__MINGW64__) -static FILE *mz_fopen(const char *pFilename, const char *pMode) -{ - FILE *pFile = NULL; - fopen_s(&pFile, pFilename, pMode); - return pFile; -} -static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) -{ - FILE *pFile = NULL; - if (freopen_s(&pFile, pPath, pMode, pStream)) - return NULL; - return pFile; -} -#ifndef MINIZ_NO_TIME -#include -#endif -#define MZ_FOPEN mz_fopen -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 _ftelli64 -#define MZ_FSEEK64 _fseeki64 -#define MZ_FILE_STAT_STRUCT _stat -#define MZ_FILE_STAT _stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN mz_freopen -#define MZ_DELETE_FILE remove -#elif defined(__MINGW32__) -#ifndef MINIZ_NO_TIME -#include -#endif -#define MZ_FOPEN(f, m) fopen(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 ftello64 -#define MZ_FSEEK64 fseeko64 -#define MZ_FILE_STAT_STRUCT _stat -#define MZ_FILE_STAT _stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(f, m, s) freopen(f, m, s) -#define MZ_DELETE_FILE remove -#elif defined(__TINYC__) -#ifndef MINIZ_NO_TIME -#include -#endif -#define MZ_FOPEN(f, m) fopen(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 ftell -#define MZ_FSEEK64 fseek -#define MZ_FILE_STAT_STRUCT stat -#define MZ_FILE_STAT stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(f, m, s) freopen(f, m, s) -#define MZ_DELETE_FILE remove -#elif defined(__GNUC__) && _LARGEFILE64_SOURCE -#ifndef MINIZ_NO_TIME -#include -#endif -#define MZ_FOPEN(f, m) fopen64(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 ftello64 -#define MZ_FSEEK64 fseeko64 -#define MZ_FILE_STAT_STRUCT stat64 -#define MZ_FILE_STAT stat64 -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(p, m, s) freopen64(p, m, s) -#define MZ_DELETE_FILE remove -#elif defined(__APPLE__) && _LARGEFILE64_SOURCE -#ifndef MINIZ_NO_TIME -#include -#endif -#define MZ_FOPEN(f, m) fopen(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 ftello -#define MZ_FSEEK64 fseeko -#define MZ_FILE_STAT_STRUCT stat -#define MZ_FILE_STAT stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(p, m, s) freopen(p, m, s) -#define MZ_DELETE_FILE remove - -#else -// The following warning is not relevant to how miniz is used by Bibledit. -// It clutters the output of compilation on Android. -// It was disabled. -// #pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.") -#ifndef MINIZ_NO_TIME -#include -#endif -#define MZ_FOPEN(f, m) fopen(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#ifdef __STRICT_ANSI__ -#define MZ_FTELL64 ftell -#define MZ_FSEEK64 fseek -#else -#define MZ_FTELL64 ftello -#define MZ_FSEEK64 fseeko -#endif -#define MZ_FILE_STAT_STRUCT stat -#define MZ_FILE_STAT stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(f, m, s) freopen(f, m, s) -#define MZ_DELETE_FILE remove -#endif /* #ifdef _MSC_VER */ -#endif /* #ifdef MINIZ_NO_STDIO */ - -#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) - -/* Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff. */ -enum -{ - /* ZIP archive identifiers and record sizes */ - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, - MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, - MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50, - MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22, - - /* ZIP64 archive identifier and record sizes */ - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06064b50, - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50, - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE = 56, - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20, - MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001, - MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50, - MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24, - MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16, - - /* Central directory header record offsets */ - MZ_ZIP_CDH_SIG_OFS = 0, - MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, - MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, - MZ_ZIP_CDH_BIT_FLAG_OFS = 8, - MZ_ZIP_CDH_METHOD_OFS = 10, - MZ_ZIP_CDH_FILE_TIME_OFS = 12, - MZ_ZIP_CDH_FILE_DATE_OFS = 14, - MZ_ZIP_CDH_CRC32_OFS = 16, - MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, - MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, - MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, - MZ_ZIP_CDH_EXTRA_LEN_OFS = 30, - MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, - MZ_ZIP_CDH_DISK_START_OFS = 34, - MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, - MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, - MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42, - - /* Local directory header offsets */ - MZ_ZIP_LDH_SIG_OFS = 0, - MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, - MZ_ZIP_LDH_BIT_FLAG_OFS = 6, - MZ_ZIP_LDH_METHOD_OFS = 8, - MZ_ZIP_LDH_FILE_TIME_OFS = 10, - MZ_ZIP_LDH_FILE_DATE_OFS = 12, - MZ_ZIP_LDH_CRC32_OFS = 14, - MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, - MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22, - MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, - MZ_ZIP_LDH_EXTRA_LEN_OFS = 28, - MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR = 1 << 3, - - /* End of central directory offsets */ - MZ_ZIP_ECDH_SIG_OFS = 0, - MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, - MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, - MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8, - MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, - MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, - MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, - MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20, - - /* ZIP64 End of central directory locator offsets */ - MZ_ZIP64_ECDL_SIG_OFS = 0, /* 4 bytes */ - MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS = 4, /* 4 bytes */ - MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS = 8, /* 8 bytes */ - MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS = 16, /* 4 bytes */ - - /* ZIP64 End of central directory header offsets */ - MZ_ZIP64_ECDH_SIG_OFS = 0, /* 4 bytes */ - MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS = 4, /* 8 bytes */ - MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS = 12, /* 2 bytes */ - MZ_ZIP64_ECDH_VERSION_NEEDED_OFS = 14, /* 2 bytes */ - MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS = 16, /* 4 bytes */ - MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS = 20, /* 4 bytes */ - MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 24, /* 8 bytes */ - MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS = 32, /* 8 bytes */ - MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40, /* 8 bytes */ - MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48, /* 8 bytes */ - MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID = 0, - MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG = 0x10, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED = 1, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG = 32, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION = 64, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED = 8192, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 = 1 << 11 -}; - -typedef struct -{ - void *m_p; - size_t m_size, m_capacity; - mz_uint m_element_size; -} mz_zip_array; - -struct mz_zip_internal_state_tag -{ - mz_zip_array m_central_dir; - mz_zip_array m_central_dir_offsets; - mz_zip_array m_sorted_central_dir_offsets; - - /* The flags passed in when the archive is initially opened. */ - uint32_t m_init_flags; - - /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. */ - mz_bool m_zip64; - - /* MZ_TRUE if we found zip64 extended info in the central directory (m_zip64 will also be slammed to true too, even if we didn't find a zip64 end of central dir header, etc.) */ - mz_bool m_zip64_has_extended_info_fields; - - /* These fields are used by the file, FILE, memory, and memory/heap read/write helpers. */ - MZ_FILE *m_pFile; - mz_uint64 m_file_archive_start_ofs; - - void *m_pMem; - size_t m_mem_size; - size_t m_mem_capacity; -}; - -#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size - -#if defined(DEBUG) || defined(_DEBUG) || defined(NDEBUG) -static MZ_FORCEINLINE mz_uint mz_zip_array_range_check(const mz_zip_array *pArray, mz_uint index) -{ - MZ_ASSERT(index < pArray->m_size); - return index; -} -#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[mz_zip_array_range_check(array_ptr, index)] -#else -#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index] -#endif - -static MZ_FORCEINLINE void mz_zip_array_init(mz_zip_array *pArray, mz_uint32 element_size) -{ - memset(pArray, 0, sizeof(mz_zip_array)); - pArray->m_element_size = element_size; -} - -static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray) -{ - pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p); - memset(pArray, 0, sizeof(mz_zip_array)); -} - -static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing) -{ - void *pNew_p; - size_t new_capacity = min_new_capacity; - MZ_ASSERT(pArray->m_element_size); - if (pArray->m_capacity >= min_new_capacity) - return MZ_TRUE; - if (growing) - { - new_capacity = MZ_MAX(1, pArray->m_capacity); - while (new_capacity < min_new_capacity) - new_capacity *= 2; - } - if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity))) - return MZ_FALSE; - pArray->m_p = pNew_p; - pArray->m_capacity = new_capacity; - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing) -{ - if (new_capacity > pArray->m_capacity) - { - if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) - return MZ_FALSE; - } - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing) -{ - if (new_size > pArray->m_capacity) - { - if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) - return MZ_FALSE; - } - pArray->m_size = new_size; - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n) -{ - return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE); -} - -static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n) -{ - size_t orig_size = pArray->m_size; - if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) - return MZ_FALSE; - memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size); - return MZ_TRUE; -} - -#ifndef MINIZ_NO_TIME -static MZ_TIME_T mz_zip_dos_to_time_t(int dos_time, int dos_date) -{ - struct tm tm; - memset(&tm, 0, sizeof(tm)); - tm.tm_isdst = -1; - tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; - tm.tm_mon = ((dos_date >> 5) & 15) - 1; - tm.tm_mday = dos_date & 31; - tm.tm_hour = (dos_time >> 11) & 31; - tm.tm_min = (dos_time >> 5) & 63; - tm.tm_sec = (dos_time << 1) & 62; - return mktime(&tm); -} - -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS -static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date) -{ -#ifdef _MSC_VER - struct tm tm_struct; - struct tm *tm = &tm_struct; - errno_t err = localtime_s(tm, &time); - if (err) - { - *pDOS_date = 0; - *pDOS_time = 0; - return; - } -#else - struct tm *tm = localtime(&time); -#endif /* #ifdef _MSC_VER */ - - *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1)); - *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday); -} -#endif /* MINIZ_NO_ARCHIVE_WRITING_APIS */ - -#ifndef MINIZ_NO_STDIO -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS -static mz_bool mz_zip_get_file_modified_time(const char *pFilename, MZ_TIME_T *pTime) -{ - struct MZ_FILE_STAT_STRUCT file_stat; - - /* On Linux with x86 glibc, this call will fail on large files (I think >= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. */ - if (MZ_FILE_STAT(pFilename, &file_stat) != 0) - return MZ_FALSE; - - *pTime = file_stat.st_mtime; - - return MZ_TRUE; -} -#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS*/ - -static mz_bool mz_zip_set_file_times(const char *pFilename, MZ_TIME_T access_time, MZ_TIME_T modified_time) -{ - struct utimbuf t; - - memset(&t, 0, sizeof(t)); - t.actime = access_time; - t.modtime = modified_time; - - return !utime(pFilename, &t); -} -#endif /* #ifndef MINIZ_NO_STDIO */ -#endif /* #ifndef MINIZ_NO_TIME */ - -static MZ_FORCEINLINE mz_bool mz_zip_set_error(mz_zip_archive *pZip, mz_zip_error err_num) -{ - if (pZip) - pZip->m_last_error = err_num; - return MZ_FALSE; -} - -static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint flags) -{ - (void)flags; - if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!pZip->m_pAlloc) - pZip->m_pAlloc = miniz_def_alloc_func; - if (!pZip->m_pFree) - pZip->m_pFree = miniz_def_free_func; - if (!pZip->m_pRealloc) - pZip->m_pRealloc = miniz_def_realloc_func; - - pZip->m_archive_size = 0; - pZip->m_central_directory_file_ofs = 0; - pZip->m_total_files = 0; - pZip->m_last_error = MZ_ZIP_NO_ERROR; - - if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); - pZip->m_pState->m_init_flags = flags; - pZip->m_pState->m_zip64 = MZ_FALSE; - pZip->m_pState->m_zip64_has_extended_info_fields = MZ_FALSE; - - pZip->m_zip_mode = MZ_ZIP_MODE_READING; - - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index) -{ - const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; - const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index)); - mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS); - mz_uint8 l = 0, r = 0; - pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; - pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; - pE = pL + MZ_MIN(l_len, r_len); - while (pL < pE) - { - if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) - break; - pL++; - pR++; - } - return (pL == pE) ? (l_len < r_len) : (l < r); -} - -#define MZ_SWAP_UINT32(a, b) \ - do \ - { \ - mz_uint32 t = a; \ - a = b; \ - b = t; \ - } \ - MZ_MACRO_END - -/* Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.) */ -static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip) -{ - mz_zip_internal_state *pState = pZip->m_pState; - const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; - const mz_zip_array *pCentral_dir = &pState->m_central_dir; - mz_uint32 *pIndices; - mz_uint32 start, end; - const mz_uint32 size = pZip->m_total_files; - - if (size <= 1U) - return; - - pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); - - start = (size - 2U) >> 1U; - for (;;) - { - mz_uint64 child, root = start; - for (;;) - { - if ((child = (root << 1U) + 1U) >= size) - break; - child += (((child + 1U) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U]))); - if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) - break; - MZ_SWAP_UINT32(pIndices[root], pIndices[child]); - root = child; - } - if (!start) - break; - start--; - } - - end = size - 1; - while (end > 0) - { - mz_uint64 child, root = 0; - MZ_SWAP_UINT32(pIndices[end], pIndices[0]); - for (;;) - { - if ((child = (root << 1U) + 1U) >= end) - break; - child += (((child + 1U) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U])); - if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) - break; - MZ_SWAP_UINT32(pIndices[root], pIndices[child]); - root = child; - } - end--; - } -} - -static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 record_sig, mz_uint32 record_size, mz_int64 *pOfs) -{ - mz_int64 cur_file_ofs; - mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; - mz_uint8 *pBuf = (mz_uint8 *)buf_u32; - - /* Basic sanity checks - reject files which are too small */ - if (pZip->m_archive_size < record_size) - return MZ_FALSE; - - /* Find the record by scanning the file from the end towards the beginning. */ - cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0); - for (;;) - { - int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); - - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) - return MZ_FALSE; - - for (i = n - 4; i >= 0; --i) - { - mz_uint s = MZ_READ_LE32(pBuf + i); - if (s == record_sig) - { - if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size) - break; - } - } - - if (i >= 0) - { - cur_file_ofs += i; - break; - } - - /* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */ - if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (MZ_UINT16_MAX + record_size))) - return MZ_FALSE; - - cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); - } - - *pOfs = cur_file_ofs; - return MZ_TRUE; -} - -static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags) -{ - mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0; - mz_uint64 cdir_ofs = 0; - mz_int64 cur_file_ofs = 0; - const mz_uint8 *p; - - mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; - mz_uint8 *pBuf = (mz_uint8 *)buf_u32; - mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0); - mz_uint32 zip64_end_of_central_dir_locator_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; - mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32; - - mz_uint32 zip64_end_of_central_dir_header_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; - mz_uint8 *pZip64_end_of_central_dir = (mz_uint8 *)zip64_end_of_central_dir_header_u32; - - mz_uint64 zip64_end_of_central_dir_ofs = 0; - - /* Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. */ - if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - - if (!mz_zip_reader_locate_header_sig(pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs)) - return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR); - - /* Read and verify the end of central directory record. */ - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - - if (cur_file_ofs >= (MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) - { - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, pZip64_locator, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) - { - if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG) - { - zip64_end_of_central_dir_ofs = MZ_READ_LE64(pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS); - if (zip64_end_of_central_dir_ofs > (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - - if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs, pZip64_end_of_central_dir, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) - { - if (MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG) - { - pZip->m_pState->m_zip64 = MZ_TRUE; - } - } - } - } - } - - pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS); - cdir_entries_on_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS); - num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS); - cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS); - cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS); - cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); - - if (pZip->m_pState->m_zip64) - { - mz_uint32 zip64_total_num_of_disks = MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS); - mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS); - mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS); - mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS); - mz_uint64 zip64_size_of_central_directory = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS); - - if (zip64_size_of_end_of_central_dir_record < (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (zip64_total_num_of_disks != 1U) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); - - /* Check for miniz's practical limits */ - if (zip64_cdir_total_entries > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - - pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries; - - if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - - cdir_entries_on_this_disk = (mz_uint32)zip64_cdir_total_entries_on_this_disk; - - /* Check for miniz's current practical limits (sorry, this should be enough for millions of files) */ - if (zip64_size_of_central_directory > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - cdir_size = (mz_uint32)zip64_size_of_central_directory; - - num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS); - - cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS); - - cdir_ofs = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS); - } - - if (pZip->m_total_files != cdir_entries_on_this_disk) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); - - if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1))) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); - - if (cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - pZip->m_central_directory_file_ofs = cdir_ofs; - - if (pZip->m_total_files) - { - mz_uint i, n; - /* Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and possibly another to hold the sorted indices. */ - if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) || - (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if (sort_central_dir) - { - if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - /* Now create an index into the central directory file records, do some basic sanity checking on each record */ - p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p; - for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) - { - mz_uint total_header_size, disk_index, bit_flags, filename_size, ext_data_size; - mz_uint64 comp_size, decomp_size, local_header_ofs; - - if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p); - - if (sort_central_dir) - MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i; - - comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); - decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); - local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); - filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS); - - if ((!pZip->m_pState->m_zip64_has_extended_info_fields) && - (ext_data_size) && - (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == MZ_UINT32_MAX)) - { - /* Attempt to find zip64 extended information field in the entry's extra data */ - mz_uint32 extra_size_remaining = ext_data_size; - - if (extra_size_remaining) - { - const mz_uint8 *pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size; - - do - { - mz_uint32 field_id; - mz_uint32 field_data_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - - if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) - { - /* Ok, the archive didn't have any zip64 headers but it uses a zip64 extended information field so mark it as zip64 anyway (this can occur with infozip's zip util when it reads compresses files from stdin). */ - pZip->m_pState->m_zip64 = MZ_TRUE; - pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE; - break; - } - - pExtra_data += sizeof(mz_uint16) * 2 + field_data_size; - extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size; - } while (extra_size_remaining); - } - } - - /* I've seen archives that aren't marked as zip64 that uses zip64 ext data, argh */ - if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX)) - { - if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS); - if ((disk_index == MZ_UINT16_MAX) || ((disk_index != num_this_disk) && (disk_index != 1))) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); - - if (comp_size != MZ_UINT32_MAX) - { - if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); - if (bit_flags & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - - if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - n -= total_header_size; - p += total_header_size; - } - } - - if (sort_central_dir) - mz_zip_reader_sort_central_dir_offsets_by_filename(pZip); - - return MZ_TRUE; -} - -void mz_zip_zero_struct(mz_zip_archive *pZip) -{ - if (pZip) - MZ_CLEAR_OBJ(*pZip); -} - -static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, mz_bool set_last_error) -{ - mz_bool status = MZ_TRUE; - - if (!pZip) - return MZ_FALSE; - - if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) - { - if (set_last_error) - pZip->m_last_error = MZ_ZIP_INVALID_PARAMETER; - - return MZ_FALSE; - } - - if (pZip->m_pState) - { - mz_zip_internal_state *pState = pZip->m_pState; - pZip->m_pState = NULL; - - mz_zip_array_clear(pZip, &pState->m_central_dir); - mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); - mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); - -#ifndef MINIZ_NO_STDIO - if (pState->m_pFile) - { - if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) - { - if (MZ_FCLOSE(pState->m_pFile) == EOF) - { - if (set_last_error) - pZip->m_last_error = MZ_ZIP_FILE_CLOSE_FAILED; - status = MZ_FALSE; - } - } - pState->m_pFile = NULL; - } -#endif /* #ifndef MINIZ_NO_STDIO */ - - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - } - pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; - - return status; -} - -mz_bool mz_zip_reader_end(mz_zip_archive *pZip) -{ - return mz_zip_reader_end_internal(pZip, MZ_TRUE); -} -mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags) -{ - if ((!pZip) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_reader_init_internal(pZip, flags)) - return MZ_FALSE; - - pZip->m_zip_type = MZ_ZIP_TYPE_USER; - pZip->m_archive_size = size; - - if (!mz_zip_reader_read_central_dir(pZip, flags)) - { - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) -{ - mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; - size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n); - memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s); - return s; -} - -mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags) -{ - if (!pMem) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - - if (!mz_zip_reader_init_internal(pZip, flags)) - return MZ_FALSE; - - pZip->m_zip_type = MZ_ZIP_TYPE_MEMORY; - pZip->m_archive_size = size; - pZip->m_pRead = mz_zip_mem_read_func; - pZip->m_pIO_opaque = pZip; - pZip->m_pNeeds_keepalive = NULL; - -#ifdef __cplusplus - pZip->m_pState->m_pMem = const_cast(pMem); -#else - pZip->m_pState->m_pMem = (void *)pMem; -#endif - - pZip->m_pState->m_mem_size = size; - - if (!mz_zip_reader_read_central_dir(pZip, flags)) - { - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -#ifndef MINIZ_NO_STDIO -static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) -{ - mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; - mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); - - file_ofs += pZip->m_pState->m_file_archive_start_ofs; - - if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) - return 0; - - return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile); -} - -mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags) -{ - return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0); -} - -mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size) -{ - mz_uint64 file_size; - MZ_FILE *pFile; - - if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) { - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - pFile = MZ_FOPEN(pFilename, "rb"); - if (!pFile) { - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - } - - file_size = archive_size; - if (!file_size) - { - if (MZ_FSEEK64(pFile, 0, SEEK_END)) - { - MZ_FCLOSE(pFile); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); - } - - file_size = MZ_FTELL64(pFile); - } - - /* Better sanity check archive_size and the # of actual remaining bytes */ - - if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - - if (!mz_zip_reader_init_internal(pZip, flags)) - { - MZ_FCLOSE(pFile); - return MZ_FALSE; - } - - pZip->m_zip_type = MZ_ZIP_TYPE_FILE; - pZip->m_pRead = mz_zip_file_read_func; - pZip->m_pIO_opaque = pZip; - pZip->m_pState->m_pFile = pFile; - pZip->m_archive_size = file_size; - pZip->m_pState->m_file_archive_start_ofs = file_start_ofs; - - if (!mz_zip_reader_read_central_dir(pZip, flags)) - { - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags) -{ - mz_uint64 cur_file_ofs; - - if ((!pZip) || (!pFile)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - - cur_file_ofs = MZ_FTELL64(pFile); - - if (!archive_size) - { - if (MZ_FSEEK64(pFile, 0, SEEK_END)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); - - archive_size = MZ_FTELL64(pFile) - cur_file_ofs; - - if (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - } - - if (!mz_zip_reader_init_internal(pZip, flags)) - return MZ_FALSE; - - pZip->m_zip_type = MZ_ZIP_TYPE_CFILE; - pZip->m_pRead = mz_zip_file_read_func; - - pZip->m_pIO_opaque = pZip; - pZip->m_pState->m_pFile = pFile; - pZip->m_archive_size = archive_size; - pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs; - - if (!mz_zip_reader_read_central_dir(pZip, flags)) - { - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -#endif /* #ifndef MINIZ_NO_STDIO */ - -static MZ_FORCEINLINE const mz_uint8 *mz_zip_get_cdh(mz_zip_archive *pZip, mz_uint file_index) -{ - if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files)) - return NULL; - return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); -} - -mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index) -{ - mz_uint m_bit_flag; - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); - if (!p) - { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return MZ_FALSE; - } - - m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); - return (m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) != 0; -} - -mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index) -{ - mz_uint bit_flag; - mz_uint method; - - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); - if (!p) - { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return MZ_FALSE; - } - - method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); - bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); - - if ((method != 0) && (method != MZ_DEFLATED)) - { - mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); - return MZ_FALSE; - } - - if (bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) - { - mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - return MZ_FALSE; - } - - if (bit_flag & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG) - { - mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index) -{ - mz_uint filename_len, attribute_mapping_id, external_attr; - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); - if (!p) - { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return MZ_FALSE; - } - - filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - if (filename_len) - { - if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/') - return MZ_TRUE; - } - - /* Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct. */ - /* Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field. */ - /* FIXME: Remove this check? Is it necessary - we already check the filename. */ - attribute_mapping_id = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS) >> 8; - (void)attribute_mapping_id; - - external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); - if ((external_attr & MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG) != 0) - { - return MZ_TRUE; - } - - return MZ_FALSE; -} - -static mz_bool mz_zip_file_stat_internal(mz_zip_archive *pZip, mz_uint file_index, const mz_uint8 *pCentral_dir_header, mz_zip_archive_file_stat *pStat, mz_bool *pFound_zip64_extra_data) -{ - mz_uint n; - const mz_uint8 *p = pCentral_dir_header; - - if (pFound_zip64_extra_data) - *pFound_zip64_extra_data = MZ_FALSE; - - if ((!p) || (!pStat)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* Extract fields from the central directory record. */ - pStat->m_file_index = file_index; - pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index); - pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS); - pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS); - pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); - pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); -#ifndef MINIZ_NO_TIME - pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS)); -#endif - pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS); - pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); - pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); - pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); - pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); - pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); - - /* Copy as much of the filename and comment as possible. */ - n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1); - memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); - pStat->m_filename[n] = '\0'; - - n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); - n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1); - pStat->m_comment_size = n; - memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n); - pStat->m_comment[n] = '\0'; - - /* Set some flags for convienance */ - pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index); - pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index); - pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index); - - /* See if we need to read any zip64 extended information fields. */ - /* Confusingly, these zip64 fields can be present even on non-zip64 archives (Debian zip on a huge files from stdin piped to stdout creates them). */ - if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), pStat->m_local_header_ofs) == MZ_UINT32_MAX) - { - /* Attempt to find zip64 extended information field in the entry's extra data */ - mz_uint32 extra_size_remaining = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS); - - if (extra_size_remaining) - { - const mz_uint8 *pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - - do - { - mz_uint32 field_id; - mz_uint32 field_data_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - - if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) - { - const mz_uint8 *pField_data = pExtra_data + sizeof(mz_uint16) * 2; - mz_uint32 field_data_remaining = field_data_size; - - if (pFound_zip64_extra_data) - *pFound_zip64_extra_data = MZ_TRUE; - - if (pStat->m_uncomp_size == MZ_UINT32_MAX) - { - if (field_data_remaining < sizeof(mz_uint64)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - pStat->m_uncomp_size = MZ_READ_LE64(pField_data); - pField_data += sizeof(mz_uint64); - field_data_remaining -= sizeof(mz_uint64); - } - - if (pStat->m_comp_size == MZ_UINT32_MAX) - { - if (field_data_remaining < sizeof(mz_uint64)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - pStat->m_comp_size = MZ_READ_LE64(pField_data); - pField_data += sizeof(mz_uint64); - field_data_remaining -= sizeof(mz_uint64); - } - - if (pStat->m_local_header_ofs == MZ_UINT32_MAX) - { - if (field_data_remaining < sizeof(mz_uint64)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - pStat->m_local_header_ofs = MZ_READ_LE64(pField_data); - pField_data += sizeof(mz_uint64); - field_data_remaining -= sizeof(mz_uint64); - } - - break; - } - - pExtra_data += sizeof(mz_uint16) * 2 + field_data_size; - extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size; - } while (extra_size_remaining); - } - } - - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags) -{ - mz_uint i; - if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE) - return 0 == memcmp(pA, pB, len); - for (i = 0; i < len; ++i) - if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i])) - return MZ_FALSE; - return MZ_TRUE; -} - -static MZ_FORCEINLINE int mz_zip_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len) -{ - const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; - mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS); - mz_uint8 l = 0, r = 0; - pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; - pE = pL + MZ_MIN(l_len, r_len); - while (pL < pE) - { - if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) - break; - pL++; - pR++; - } - return (pL == pE) ? (int)(l_len - r_len) : (l - r); -} - -static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename, mz_uint32 *pIndex) -{ - mz_zip_internal_state *pState = pZip->m_pState; - const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; - const mz_zip_array *pCentral_dir = &pState->m_central_dir; - mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); - const uint32_t size = pZip->m_total_files; - const mz_uint filename_len = (mz_uint)strlen(pFilename); - - if (pIndex) - *pIndex = 0; - - if (size) - { - /* yes I could use uint32_t's, but then we would have to add some special case checks in the loop, argh, and */ - /* honestly the major expense here on 32-bit CPU's will still be the filename compare */ - mz_int64 l = 0, h = (mz_int64)size - 1; - - while (l <= h) - { - mz_int64 m = l + ((h - l) >> 1); - uint32_t file_index = pIndices[(uint32_t)m]; - - int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len); - if (!comp) - { - if (pIndex) - *pIndex = file_index; - return MZ_TRUE; - } - else if (comp < 0) - l = m + 1; - else - h = m - 1; - } - } - - return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND); -} - -int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags) -{ - mz_uint32 index; - if (!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index)) - return -1; - else - return (int)index; -} - -mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex) -{ - mz_uint file_index; - size_t name_len, comment_len; - - if (pIndex) - *pIndex = 0; - - if ((!pZip) || (!pZip->m_pState) || (!pName)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* See if we can use a binary search */ - if (((pZip->m_pState->m_init_flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) && - (pZip->m_zip_mode == MZ_ZIP_MODE_READING) && - ((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size)) - { - return mz_zip_locate_file_binary_search(pZip, pName, pIndex); - } - - /* Locate the entry by scanning the entire central directory */ - name_len = strlen(pName); - if (name_len > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - comment_len = pComment ? strlen(pComment) : 0; - if (comment_len > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - for (file_index = 0; file_index < pZip->m_total_files; file_index++) - { - const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); - mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS); - const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; - if (filename_len < name_len) - continue; - if (comment_len) - { - mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS); - const char *pFile_comment = pFilename + filename_len + file_extra_len; - if ((file_comment_len != comment_len) || (!mz_zip_string_equal(pComment, pFile_comment, file_comment_len, flags))) - continue; - } - if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) - { - int ofs = filename_len - 1; - do - { - if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':')) - break; - } while (--ofs >= 0); - ofs++; - pFilename += ofs; - filename_len -= ofs; - } - if ((filename_len == name_len) && (mz_zip_string_equal(pName, pFilename, filename_len, flags))) - { - if (pIndex) - *pIndex = file_index; - return MZ_TRUE; - } - } - - return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND); -} - -mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) -{ - int status = TINFL_STATUS_DONE; - mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail; - mz_zip_archive_file_stat file_stat; - void *pRead_buf; - mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; - mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; - tinfl_decompressor inflator; - - if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) - return MZ_FALSE; - - /* A directory or zero length file */ - if ((file_stat.m_is_directory) || (!file_stat.m_comp_size)) - return MZ_TRUE; - - /* Encryption and patch files are not supported. */ - if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - - /* This function only supports decompressing stored and deflate. */ - if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); - - /* Ensure supplied output buffer is large enough. */ - needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size; - if (buf_size < needed_size) - return mz_zip_set_error(pZip, MZ_ZIP_BUF_TOO_SMALL); - - /* Read and parse the local directory entry. */ - cur_file_ofs = file_stat.m_local_header_ofs; - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); - if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) - { - /* The file is stored or the caller has requested the compressed data. */ - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0) - { - if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32) - return mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED); - } -#endif - - return MZ_TRUE; - } - - /* Decompress the file either directly from memory or from a file input buffer. */ - tinfl_init(&inflator); - - if (pZip->m_pState->m_pMem) - { - /* Read directly from the archive in memory. */ - pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; - read_buf_size = read_buf_avail = file_stat.m_comp_size; - comp_remaining = 0; - } - else if (pUser_read_buf) - { - /* Use a user provided read buffer. */ - if (!user_read_buf_size) - return MZ_FALSE; - pRead_buf = (mz_uint8 *)pUser_read_buf; - read_buf_size = user_read_buf_size; - read_buf_avail = 0; - comp_remaining = file_stat.m_comp_size; - } - else - { - /* Temporarily allocate a read buffer. */ - read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); - if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - read_buf_avail = 0; - comp_remaining = file_stat.m_comp_size; - } - - do - { - /* The size_t cast here should be OK because we've verified that the output buffer is >= file_stat.m_uncomp_size above */ - size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs); - if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) - { - read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) - { - status = TINFL_STATUS_FAILED; - mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED); - break; - } - cur_file_ofs += read_buf_avail; - comp_remaining -= read_buf_avail; - read_buf_ofs = 0; - } - in_buf_size = (size_t)read_buf_avail; - status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0)); - read_buf_avail -= in_buf_size; - read_buf_ofs += in_buf_size; - out_buf_ofs += out_buf_size; - } while (status == TINFL_STATUS_NEEDS_MORE_INPUT); - - if (status == TINFL_STATUS_DONE) - { - /* Make sure the entire file was decompressed, and check its CRC. */ - if (out_buf_ofs != file_stat.m_uncomp_size) - { - mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE); - status = TINFL_STATUS_FAILED; - } -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - else if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32) - { - mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED); - status = TINFL_STATUS_FAILED; - } -#endif - } - - if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf)) - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - - return status == TINFL_STATUS_DONE; -} - -mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) -{ - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) - return MZ_FALSE; - return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size); -} - -mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags) -{ - return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0); -} - -mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags) -{ - return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0); -} - -void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags) -{ - mz_uint64 comp_size, uncomp_size, alloc_size; - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); - void *pBuf; - - if (pSize) - *pSize = 0; - - if (!p) - { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return NULL; - } - - comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); - uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); - - alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size; - if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) - { - mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - return NULL; - } - - if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size))) - { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - return NULL; - } - - if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags)) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return NULL; - } - - if (pSize) - *pSize = (size_t)alloc_size; - return pBuf; -} - -void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags) -{ - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) - { - if (pSize) - *pSize = 0; - return MZ_FALSE; - } - return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags); -} - -mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) -{ - int status = TINFL_STATUS_DONE; - mz_uint file_crc32 = MZ_CRC32_INIT; - mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs; - mz_zip_archive_file_stat file_stat; - void *pRead_buf = NULL; - void *pWrite_buf = NULL; - mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; - mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; - - if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) - return MZ_FALSE; - - /* A directory or zero length file */ - if ((file_stat.m_is_directory) || (!file_stat.m_comp_size)) - return MZ_TRUE; - - /* Encryption and patch files are not supported. */ - if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - - /* This function only supports decompressing stored and deflate. */ - if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); - - /* Read and do some minimal validation of the local directory entry (this doesn't crack the zip64 stuff, which we already have from the central dir) */ - cur_file_ofs = file_stat.m_local_header_ofs; - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); - if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - /* Decompress the file either directly from memory or from a file input buffer. */ - if (pZip->m_pState->m_pMem) - { - pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; - read_buf_size = read_buf_avail = file_stat.m_comp_size; - comp_remaining = 0; - } - else - { - read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); - if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - read_buf_avail = 0; - comp_remaining = file_stat.m_comp_size; - } - - if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) - { - /* The file is stored or the caller has requested the compressed data. */ - if (pZip->m_pState->m_pMem) - { - if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size) - { - mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED); - status = TINFL_STATUS_FAILED; - } - else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) - { -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size); -#endif - } - - cur_file_ofs += file_stat.m_comp_size; - out_buf_ofs += file_stat.m_comp_size; - comp_remaining = 0; - } - else - { - while (comp_remaining) - { - read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) - { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) - { - file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail); - } -#endif - - if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) - { - mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - - cur_file_ofs += read_buf_avail; - out_buf_ofs += read_buf_avail; - comp_remaining -= read_buf_avail; - } - } - } - else - { - tinfl_decompressor inflator; - tinfl_init(&inflator); - - if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE))) - { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - status = TINFL_STATUS_FAILED; - } - else - { - do - { - mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); - size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); - if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) - { - read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) - { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - cur_file_ofs += read_buf_avail; - comp_remaining -= read_buf_avail; - read_buf_ofs = 0; - } - - in_buf_size = (size_t)read_buf_avail; - status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0); - read_buf_avail -= in_buf_size; - read_buf_ofs += in_buf_size; - - if (out_buf_size) - { - if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size) - { - mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size); -#endif - if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) - { - mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - } - } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT)); - } - } - - if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) - { - /* Make sure the entire file was decompressed, and check its CRC. */ - if (out_buf_ofs != file_stat.m_uncomp_size) - { - mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE); - status = TINFL_STATUS_FAILED; - } -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - else if (file_crc32 != file_stat.m_crc32) - { - mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED); - status = TINFL_STATUS_FAILED; - } -#endif - } - - if (!pZip->m_pState->m_pMem) - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - - if (pWrite_buf) - pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf); - - return status == TINFL_STATUS_DONE; -} - -mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) -{ - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) - return MZ_FALSE; - - return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags); -} - -#ifndef MINIZ_NO_STDIO -static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n) -{ - (void)ofs; - - return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque); -} - -mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags) -{ - mz_bool status; - mz_zip_archive_file_stat file_stat; - MZ_FILE *pFile; - - if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) - return MZ_FALSE; - - if ((file_stat.m_is_directory) || (!file_stat.m_is_supported)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); - - pFile = MZ_FOPEN(pDst_filename, "wb"); - if (!pFile) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - - status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags); - - if (MZ_FCLOSE(pFile) == EOF) - { - if (status) - mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED); - - status = MZ_FALSE; - } - -#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO) - if (status) - mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time); -#endif - - return status; -} - -mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags) -{ - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index)) - return MZ_FALSE; - - return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags); -} - -mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *pFile, mz_uint flags) -{ - mz_zip_archive_file_stat file_stat; - - if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) - return MZ_FALSE; - - if ((file_stat.m_is_directory) || (!file_stat.m_is_supported)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); - - return mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags); -} - -mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags) -{ - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index)) - return MZ_FALSE; - - return mz_zip_reader_extract_to_cfile(pZip, file_index, pFile, flags); -} -#endif /* #ifndef MINIZ_NO_STDIO */ - -static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) -{ - mz_uint32 *p = (mz_uint32 *)pOpaque; - (void)file_ofs; - *p = (mz_uint32)mz_crc32(*p, (const mz_uint8 *)pBuf, n); - return n; -} - -mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags) -{ - mz_zip_archive_file_stat file_stat; - mz_zip_internal_state *pState; - const mz_uint8 *pCentral_dir_header; - mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE; - mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE; - mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; - mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; - mz_uint64 local_header_ofs = 0; - mz_uint32 local_header_filename_len, local_header_extra_len, local_header_crc32; - mz_uint64 local_header_comp_size, local_header_uncomp_size; - mz_uint32 uncomp_crc32 = MZ_CRC32_INIT; - mz_bool has_data_descriptor; - mz_uint32 local_header_bit_flags; - - mz_zip_array file_data_array; - mz_zip_array_init(&file_data_array, 1); - - if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (file_index > pZip->m_total_files) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - pCentral_dir_header = mz_zip_get_cdh(pZip, file_index); - - if (!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header, &file_stat, &found_zip64_ext_data_in_cdir)) - return MZ_FALSE; - - /* A directory or zero length file */ - if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size)) - return MZ_TRUE; - - /* Encryption and patch files are not supported. */ - if (file_stat.m_is_encrypted) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - - /* This function only supports stored and deflate. */ - if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); - - if (!file_stat.m_is_supported) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); - - /* Read and parse the local directory entry. */ - local_header_ofs = file_stat.m_local_header_ofs; - if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - local_header_filename_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS); - local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); - local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS); - local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS); - local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS); - local_header_bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); - has_data_descriptor = (local_header_bit_flags & 8) != 0; - - if (local_header_filename_len != strlen(file_stat.m_filename)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if ((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (!mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if (local_header_filename_len) - { - if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE, file_data_array.m_p, local_header_filename_len) != local_header_filename_len) - { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - goto handle_failure; - } - - /* I've seen 1 archive that had the same pathname, but used backslashes in the local dir and forward slashes in the central dir. Do we care about this? For now, this case will fail validation. */ - if (memcmp(file_stat.m_filename, file_data_array.m_p, local_header_filename_len) != 0) - { - mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - goto handle_failure; - } - } - - if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX))) - { - mz_uint32 extra_size_remaining = local_header_extra_len; - const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p; - - if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len, file_data_array.m_p, local_header_extra_len) != local_header_extra_len) - { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - goto handle_failure; - } - - do - { - mz_uint32 field_id, field_data_size, field_total_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - field_total_size = field_data_size + sizeof(mz_uint16) * 2; - - if (field_total_size > extra_size_remaining) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) - { - const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32); - - if (field_data_size < sizeof(mz_uint64) * 2) - { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - goto handle_failure; - } - - local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data); - local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64)); - - found_zip64_ext_data_in_ldir = MZ_TRUE; - break; - } - - pExtra_data += field_total_size; - extra_size_remaining -= field_total_size; - } while (extra_size_remaining); - } - - /* parse local header extra data when local_header_comp_size is 0xFFFFFFFF! (big_descriptor.zip) */ - /* I've seen zips in the wild with the data descriptor bit set, but proper local header values and bogus data descriptors */ - if ((has_data_descriptor) && (!local_header_comp_size) && (!local_header_crc32)) - { - mz_uint8 descriptor_buf[32]; - mz_bool has_id; - const mz_uint8 *pSrc; - mz_uint32 file_crc32; - mz_uint64 comp_size = 0, uncomp_size = 0; - - mz_uint32 num_descriptor_uint32s = ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4; - - if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size, descriptor_buf, sizeof(mz_uint32) * num_descriptor_uint32s) != (sizeof(mz_uint32) * num_descriptor_uint32s)) - { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - goto handle_failure; - } - - has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID); - pSrc = has_id ? (descriptor_buf + sizeof(mz_uint32)) : descriptor_buf; - - file_crc32 = MZ_READ_LE32(pSrc); - - if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) - { - comp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32)); - uncomp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32) + sizeof(mz_uint64)); - } - else - { - comp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32)); - uncomp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32) + sizeof(mz_uint32)); - } - - if ((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size)) - { - mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - goto handle_failure; - } - } - else - { - if ((local_header_crc32 != file_stat.m_crc32) || (local_header_comp_size != file_stat.m_comp_size) || (local_header_uncomp_size != file_stat.m_uncomp_size)) - { - mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - goto handle_failure; - } - } - - mz_zip_array_clear(pZip, &file_data_array); - - if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0) - { - if (!mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0)) - return MZ_FALSE; - - /* 1 more check to be sure, although the extract checks too. */ - if (uncomp_crc32 != file_stat.m_crc32) - { - mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - return MZ_FALSE; - } - } - - return MZ_TRUE; - -handle_failure: - mz_zip_array_clear(pZip, &file_data_array); - return MZ_FALSE; -} - -mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags) -{ - mz_zip_internal_state *pState; - uint32_t i; - - if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - /* Basic sanity checks */ - if (!pState->m_zip64) - { - if (pZip->m_total_files > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - if (pZip->m_archive_size > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - } - else - { - if (pZip->m_total_files >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - if (pState->m_central_dir.m_size >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - } - - for (i = 0; i < pZip->m_total_files; i++) - { - if (MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG & flags) - { - mz_uint32 found_index; - mz_zip_archive_file_stat stat; - - if (!mz_zip_reader_file_stat(pZip, i, &stat)) - return MZ_FALSE; - - if (!mz_zip_reader_locate_file_v2(pZip, stat.m_filename, NULL, 0, &found_index)) - return MZ_FALSE; - - /* This check can fail if there are duplicate filenames in the archive (which we don't check for when writing - that's up to the user) */ - if (found_index != i) - return mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - } - - if (!mz_zip_validate_file(pZip, i, flags)) - return MZ_FALSE; - } - - return MZ_TRUE; -} - -mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr) -{ - mz_bool success = MZ_TRUE; - mz_zip_archive zip; - mz_zip_error actual_err = MZ_ZIP_NO_ERROR; - - if ((!pMem) || (!size)) - { - if (pErr) - *pErr = MZ_ZIP_INVALID_PARAMETER; - return MZ_FALSE; - } - - mz_zip_zero_struct(&zip); - - if (!mz_zip_reader_init_mem(&zip, pMem, size, flags)) - { - if (pErr) - *pErr = zip.m_last_error; - return MZ_FALSE; - } - - if (!mz_zip_validate_archive(&zip, flags)) - { - actual_err = zip.m_last_error; - success = MZ_FALSE; - } - - if (!mz_zip_reader_end_internal(&zip, success)) - { - if (!actual_err) - actual_err = zip.m_last_error; - success = MZ_FALSE; - } - - if (pErr) - *pErr = actual_err; - - return success; -} - -#ifndef MINIZ_NO_STDIO -mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr) -{ - mz_bool success = MZ_TRUE; - mz_zip_archive zip; - mz_zip_error actual_err = MZ_ZIP_NO_ERROR; - - if (!pFilename) - { - if (pErr) - *pErr = MZ_ZIP_INVALID_PARAMETER; - return MZ_FALSE; - } - - mz_zip_zero_struct(&zip); - - if (!mz_zip_reader_init_file_v2(&zip, pFilename, flags, 0, 0)) - { - if (pErr) - *pErr = zip.m_last_error; - return MZ_FALSE; - } - - if (!mz_zip_validate_archive(&zip, flags)) - { - actual_err = zip.m_last_error; - success = MZ_FALSE; - } - - if (!mz_zip_reader_end_internal(&zip, success)) - { - if (!actual_err) - actual_err = zip.m_last_error; - success = MZ_FALSE; - } - - if (pErr) - *pErr = actual_err; - - return success; -} -#endif /* #ifndef MINIZ_NO_STDIO */ - -/* ------------------- .ZIP archive writing */ - -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS - -static MZ_FORCEINLINE void mz_write_le16(mz_uint8 *p, mz_uint16 v) -{ - p[0] = (mz_uint8)v; - p[1] = (mz_uint8)(v >> 8); -} -static MZ_FORCEINLINE void mz_write_le32(mz_uint8 *p, mz_uint32 v) -{ - p[0] = (mz_uint8)v; - p[1] = (mz_uint8)(v >> 8); - p[2] = (mz_uint8)(v >> 16); - p[3] = (mz_uint8)(v >> 24); -} -static MZ_FORCEINLINE void mz_write_le64(mz_uint8 *p, mz_uint64 v) -{ - mz_write_le32(p, (mz_uint32)v); - mz_write_le32(p + sizeof(mz_uint32), (mz_uint32)(v >> 32)); -} - -#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v)) -#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v)) -#define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v)) - -static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) -{ - mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; - mz_zip_internal_state *pState = pZip->m_pState; - mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size); - - if (!n) - return 0; - - /* An allocation this big is likely to just fail on 32-bit systems, so don't even go there. */ - if ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)) - { - mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); - return 0; - } - - if (new_size > pState->m_mem_capacity) - { - void *pNew_block; - size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); - - while (new_capacity < new_size) - new_capacity *= 2; - - if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity))) - { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - return 0; - } - - pState->m_pMem = pNew_block; - pState->m_mem_capacity = new_capacity; - } - memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n); - pState->m_mem_size = (size_t)new_size; - return n; -} - -static mz_bool mz_zip_writer_end_internal(mz_zip_archive *pZip, mz_bool set_last_error) -{ - mz_zip_internal_state *pState; - mz_bool status = MZ_TRUE; - - if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))) - { - if (set_last_error) - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return MZ_FALSE; - } - - pState = pZip->m_pState; - pZip->m_pState = NULL; - mz_zip_array_clear(pZip, &pState->m_central_dir); - mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); - mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); - -#ifndef MINIZ_NO_STDIO - if (pState->m_pFile) - { - if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) - { - if (MZ_FCLOSE(pState->m_pFile) == EOF) - { - if (set_last_error) - mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED); - status = MZ_FALSE; - } - } - - pState->m_pFile = NULL; - } -#endif /* #ifndef MINIZ_NO_STDIO */ - - if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem); - pState->m_pMem = NULL; - } - - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; - return status; -} - -mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags) -{ - mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0; - - if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) - { - if (!pZip->m_pRead) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - if (pZip->m_file_offset_alignment) - { - /* Ensure user specified file offset alignment is a power of 2. */ - if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - if (!pZip->m_pAlloc) - pZip->m_pAlloc = miniz_def_alloc_func; - if (!pZip->m_pFree) - pZip->m_pFree = miniz_def_free_func; - if (!pZip->m_pRealloc) - pZip->m_pRealloc = miniz_def_realloc_func; - - pZip->m_archive_size = existing_size; - pZip->m_central_directory_file_ofs = 0; - pZip->m_total_files = 0; - - if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); - - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); - - pZip->m_pState->m_zip64 = zip64; - pZip->m_pState->m_zip64_has_extended_info_fields = zip64; - - pZip->m_zip_type = MZ_ZIP_TYPE_USER; - pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size) -{ - return mz_zip_writer_init_v2(pZip, existing_size, 0); -} - -mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags) -{ - pZip->m_pWrite = mz_zip_heap_write_func; - pZip->m_pNeeds_keepalive = NULL; - - if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) - pZip->m_pRead = mz_zip_mem_read_func; - - pZip->m_pIO_opaque = pZip; - - if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags)) - return MZ_FALSE; - - pZip->m_zip_type = MZ_ZIP_TYPE_HEAP; - - if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning))) - { - if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size))) - { - mz_zip_writer_end_internal(pZip, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - pZip->m_pState->m_mem_capacity = initial_allocation_size; - } - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size) -{ - return mz_zip_writer_init_heap_v2(pZip, size_to_reserve_at_beginning, initial_allocation_size, 0); -} - -#ifndef MINIZ_NO_STDIO -static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) -{ - mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; - mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); - - file_ofs += pZip->m_pState->m_file_archive_start_ofs; - - if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) - { - mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); - return 0; - } - - return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile); -} - -mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning) -{ - return mz_zip_writer_init_file_v2(pZip, pFilename, size_to_reserve_at_beginning, 0); -} - -mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags) -{ - MZ_FILE *pFile; - - pZip->m_pWrite = mz_zip_file_write_func; - pZip->m_pNeeds_keepalive = NULL; - - if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) - pZip->m_pRead = mz_zip_file_read_func; - - pZip->m_pIO_opaque = pZip; - - if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags)) - return MZ_FALSE; - - if (NULL == (pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ? "w+b" : "wb"))) - { - mz_zip_writer_end(pZip); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - } - - pZip->m_pState->m_pFile = pFile; - pZip->m_zip_type = MZ_ZIP_TYPE_FILE; - - if (size_to_reserve_at_beginning) - { - mz_uint64 cur_ofs = 0; - char buf[4096]; - - MZ_CLEAR_OBJ(buf); - - do - { - size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning); - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) - { - mz_zip_writer_end(pZip); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - cur_ofs += n; - size_to_reserve_at_beginning -= n; - } while (size_to_reserve_at_beginning); - } - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags) -{ - pZip->m_pWrite = mz_zip_file_write_func; - pZip->m_pNeeds_keepalive = NULL; - - if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) - pZip->m_pRead = mz_zip_file_read_func; - - pZip->m_pIO_opaque = pZip; - - if (!mz_zip_writer_init_v2(pZip, 0, flags)) - return MZ_FALSE; - - pZip->m_pState->m_pFile = pFile; - pZip->m_pState->m_file_archive_start_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); - pZip->m_zip_type = MZ_ZIP_TYPE_CFILE; - - return MZ_TRUE; -} -#endif /* #ifndef MINIZ_NO_STDIO */ - -mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags) -{ - mz_zip_internal_state *pState; - - if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (flags & MZ_ZIP_FLAG_WRITE_ZIP64) - { - /* We don't support converting a non-zip64 file to zip64 - this seems like more trouble than it's worth. (What about the existing 32-bit data descriptors that could follow the compressed data?) */ - if (!pZip->m_pState->m_zip64) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - /* No sense in trying to write to an archive that's already at the support max size */ - if (pZip->m_pState->m_zip64) - { - if (pZip->m_total_files == MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } - else - { - if (pZip->m_total_files == MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - - if ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); - } - - pState = pZip->m_pState; - - if (pState->m_pFile) - { -#ifdef MINIZ_NO_STDIO - (void)pFilename; - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); -#else - if (pZip->m_pIO_opaque != pZip) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) - { - if (!pFilename) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* Archive is being read from stdio and was originally opened only for reading. Try to reopen as writable. */ - if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile))) - { - /* The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it. */ - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - } - } - - pZip->m_pWrite = mz_zip_file_write_func; - pZip->m_pNeeds_keepalive = NULL; -#endif /* #ifdef MINIZ_NO_STDIO */ - } - else if (pState->m_pMem) - { - /* Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback. */ - if (pZip->m_pIO_opaque != pZip) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState->m_mem_capacity = pState->m_mem_size; - pZip->m_pWrite = mz_zip_heap_write_func; - pZip->m_pNeeds_keepalive = NULL; - } - /* Archive is being read via a user provided read function - make sure the user has specified a write function too. */ - else if (!pZip->m_pWrite) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* Start writing new files at the archive's current central directory location. */ - /* We could add a flag that lets the user start writing immediately AFTER the existing central dir - this would be safer. */ - pZip->m_archive_size = pZip->m_central_directory_file_ofs; - pZip->m_central_directory_file_ofs = 0; - - /* Clear the sorted central dir offsets, they aren't useful or maintained now. */ - /* Even though we're now in write mode, files can still be extracted and verified, but file locates will be slow. */ - /* We could easily maintain the sorted central directory offsets. */ - mz_zip_array_clear(pZip, &pZip->m_pState->m_sorted_central_dir_offsets); - - pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename) -{ - return mz_zip_writer_init_from_reader_v2(pZip, pFilename, 0); -} - -/* pArchive_name is a terrible name here! */ -mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags) -{ - return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0); -} - -typedef struct -{ - mz_zip_archive *m_pZip; - mz_uint64 m_cur_archive_file_ofs; - mz_uint64 m_comp_size; -} mz_zip_writer_add_state; - -static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len, void *pUser) -{ - mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser; - if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len) - return MZ_FALSE; - - pState->m_cur_archive_file_ofs += len; - pState->m_comp_size += len; - return MZ_TRUE; -} - -#define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2) -#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3) -static mz_uint32 mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 *pUncomp_size, mz_uint64 *pComp_size, mz_uint64 *pLocal_header_ofs) -{ - mz_uint8 *pDst = pBuf; - mz_uint32 field_size = 0; - - MZ_WRITE_LE16(pDst + 0, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID); - MZ_WRITE_LE16(pDst + 2, 0); - pDst += sizeof(mz_uint16) * 2; - - if (pUncomp_size) - { - MZ_WRITE_LE64(pDst, *pUncomp_size); - pDst += sizeof(mz_uint64); - field_size += sizeof(mz_uint64); - } - - if (pComp_size) - { - MZ_WRITE_LE64(pDst, *pComp_size); - pDst += sizeof(mz_uint64); - field_size += sizeof(mz_uint64); - } - - if (pLocal_header_ofs) - { - MZ_WRITE_LE64(pDst, *pLocal_header_ofs); - pDst += sizeof(mz_uint64); - field_size += sizeof(mz_uint64); - } - - MZ_WRITE_LE16(pBuf + 2, field_size); - - return (mz_uint32)(pDst - pBuf); -} - -static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date) -{ - (void)pZip; - memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX)); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX)); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size); - return MZ_TRUE; -} - -static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, - mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, - mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, - mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, - mz_uint64 local_header_ofs, mz_uint32 ext_attributes) -{ - (void)pZip; - memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX)); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX)); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_MIN(local_header_ofs, MZ_UINT32_MAX)); - return MZ_TRUE; -} - -static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, - const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, - mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, - mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, - mz_uint64 local_header_ofs, mz_uint32 ext_attributes, - const char *user_extra_data, mz_uint user_extra_data_len) -{ - mz_zip_internal_state *pState = pZip->m_pState; - mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size; - size_t orig_central_dir_size = pState->m_central_dir.m_size; - mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; - - if (!pZip->m_pState->m_zip64) - { - if (local_header_ofs > 0xFFFFFFFF) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); - } - - /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */ - if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + user_extra_data_len + comment_size) >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size + user_extra_data_len, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data, user_extra_data_len)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1))) - { - /* Try to resize the central directory array back into its original state. */ - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - return MZ_TRUE; -} - -static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name) -{ - /* Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes. */ - if (*pArchive_name == '/') - return MZ_FALSE; - - while (*pArchive_name) - { - if ((*pArchive_name == '\\') || (*pArchive_name == ':')) - return MZ_FALSE; - - pArchive_name++; - } - - return MZ_TRUE; -} - -static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) -{ - mz_uint32 n; - if (!pZip->m_file_offset_alignment) - return 0; - n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1)); - return (mz_uint)((pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1)); -} - -static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n) -{ - char buf[4096]; - memset(buf, 0, MZ_MIN(sizeof(buf), n)); - while (n) - { - mz_uint32 s = MZ_MIN(sizeof(buf), n); - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_file_ofs += s; - n -= s; - } - return MZ_TRUE; -} - -mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, - mz_uint64 uncomp_size, mz_uint32 uncomp_crc32) -{ - return mz_zip_writer_add_mem_ex_v2(pZip, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, uncomp_size, uncomp_crc32, NULL, NULL, 0, NULL, 0); -} - -mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, - const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) -{ - mz_uint16 method = 0, dos_time = 0, dos_date = 0; - mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; - mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; - size_t archive_name_size; - mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; - tdefl_compressor *pComp = NULL; - mz_bool store_data_uncompressed; - mz_zip_internal_state *pState; - mz_uint8 *pExtra_data = NULL; - mz_uint32 extra_size = 0; - mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; - mz_uint16 bit_flags = 0; - - if (uncomp_size || (buf_size && !(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) - bit_flags |= MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR; - - if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME)) - bit_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8; - - if ((int)level_and_flags < 0) - level_and_flags = MZ_DEFAULT_LEVEL; - level = level_and_flags & 0xF; - store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)); - - if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - if (pState->m_zip64) - { - if (pZip->m_total_files == MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } - else - { - if (pZip->m_total_files == MZ_UINT16_MAX) - { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */ - } - if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) - { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ - } - } - - if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_writer_validate_archive_name(pArchive_name)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); - -#ifndef MINIZ_NO_TIME - if (last_modified != NULL) - { - mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date); - } - else - { - MZ_TIME_T cur_time; - time(&cur_time); - mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date); - } -#endif /* #ifndef MINIZ_NO_TIME */ - - archive_name_size = strlen(pArchive_name); - if (archive_name_size > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); - - num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); - - /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */ - if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - if (!pState->m_zip64) - { - /* Bail early if the archive would obviously become too large */ - if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF) - { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ - } - } - - if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) - { - /* Set DOS Subdirectory attribute bit. */ - ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG; - - /* Subdirectories cannot contain data. */ - if ((buf_size) || (uncomp_size)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - /* Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.) */ - if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + (pState->m_zip64 ? MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE : 0))) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if ((!store_data_uncompressed) && (buf_size)) - { - if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes)) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return MZ_FALSE; - } - - local_dir_header_ofs += num_alignment_padding_bytes; - if (pZip->m_file_offset_alignment) - { - MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); - } - cur_archive_file_ofs += num_alignment_padding_bytes; - - MZ_CLEAR_OBJ(local_dir_header); - - if (!store_data_uncompressed || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) - { - method = MZ_DEFLATED; - } - - if (pState->m_zip64) - { - if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) - { - pExtra_data = extra_data; - extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); - } - - if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, extra_size + user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += sizeof(local_dir_header); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - cur_archive_file_ofs += archive_name_size; - - if (pExtra_data != NULL) - { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += extra_size; - } - } - else - { - if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += sizeof(local_dir_header); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - cur_archive_file_ofs += archive_name_size; - } - - if (user_extra_data_len > 0) - { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += user_extra_data_len; - } - - if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) - { - uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size); - uncomp_size = buf_size; - if (uncomp_size <= 3) - { - level = 0; - store_data_uncompressed = MZ_TRUE; - } - } - - if (store_data_uncompressed) - { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_archive_file_ofs += buf_size; - comp_size = buf_size; - } - else if (buf_size) - { - mz_zip_writer_add_state state; - - state.m_pZip = pZip; - state.m_cur_archive_file_ofs = cur_archive_file_ofs; - state.m_comp_size = 0; - - if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) || - (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE)) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED); - } - - comp_size = state.m_comp_size; - cur_archive_file_ofs = state.m_cur_archive_file_ofs; - } - - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - pComp = NULL; - - if (uncomp_size) - { - mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; - mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32; - - MZ_ASSERT(bit_flags & MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR); - - MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID); - MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32); - if (pExtra_data == NULL) - { - if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - MZ_WRITE_LE32(local_dir_footer + 8, comp_size); - MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size); - } - else - { - MZ_WRITE_LE64(local_dir_footer + 8, comp_size); - MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size); - local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64; - } - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size) - return MZ_FALSE; - - cur_archive_file_ofs += local_dir_footer_size; - } - - if (pExtra_data != NULL) - { - extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); - } - - if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment, - comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes, - user_extra_data_central, user_extra_data_central_len)) - return MZ_FALSE; - - pZip->m_total_files++; - pZip->m_archive_size = cur_archive_file_ofs; - - return MZ_TRUE; -} - -#ifndef MINIZ_NO_STDIO -mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, - const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) -{ - mz_uint16 gen_flags = MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR; - mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; - mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; - mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = size_to_add, comp_size = 0; - size_t archive_name_size; - mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; - mz_uint8 *pExtra_data = NULL; - mz_uint32 extra_size = 0; - mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; - mz_zip_internal_state *pState; - - if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME)) - gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8; - - if ((int)level_and_flags < 0) - level_and_flags = MZ_DEFAULT_LEVEL; - level = level_and_flags & 0xF; - - /* Sanity checks */ - if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - if ((!pState->m_zip64) && (uncomp_size > MZ_UINT32_MAX)) - { - /* Source file is too large for non-zip64 */ - /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ - pState->m_zip64 = MZ_TRUE; - } - - /* We could support this, but why? */ - if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_writer_validate_archive_name(pArchive_name)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); - - if (pState->m_zip64) - { - if (pZip->m_total_files == MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } - else - { - if (pZip->m_total_files == MZ_UINT16_MAX) - { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */ - } - } - - archive_name_size = strlen(pArchive_name); - if (archive_name_size > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); - - num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); - - /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */ - if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - if (!pState->m_zip64) - { - /* Bail early if the archive would obviously become too large */ - if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024) > 0xFFFFFFFF) - { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ - } - } - -#ifndef MINIZ_NO_TIME - if (pFile_time) - { - mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date); - } -#endif - - if (uncomp_size <= 3) - level = 0; - - if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes)) - { - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_archive_file_ofs += num_alignment_padding_bytes; - local_dir_header_ofs = cur_archive_file_ofs; - - if (pZip->m_file_offset_alignment) - { - MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0); - } - - if (uncomp_size && level) - { - method = MZ_DEFLATED; - } - - MZ_CLEAR_OBJ(local_dir_header); - if (pState->m_zip64) - { - if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) - { - pExtra_data = extra_data; - extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); - } - - if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, extra_size + user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += sizeof(local_dir_header); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) - { - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_archive_file_ofs += archive_name_size; - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += extra_size; - } - else - { - if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += sizeof(local_dir_header); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) - { - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_archive_file_ofs += archive_name_size; - } - - if (user_extra_data_len > 0) - { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += user_extra_data_len; - } - - if (uncomp_size) - { - mz_uint64 uncomp_remaining = uncomp_size; - void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE); - if (!pRead_buf) - { - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!level) - { - while (uncomp_remaining) - { - mz_uint n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining); - if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); - uncomp_remaining -= n; - cur_archive_file_ofs += n; - } - comp_size = uncomp_size; - } - else - { - mz_bool result = MZ_FALSE; - mz_zip_writer_add_state state; - tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)); - if (!pComp) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - state.m_pZip = pZip; - state.m_cur_archive_file_ofs = cur_archive_file_ofs; - state.m_comp_size = 0; - - if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - } - - for (;;) - { - size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); - tdefl_status status; - tdefl_flush flush = TDEFL_NO_FLUSH; - - if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size) - { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - break; - } - - uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size); - uncomp_remaining -= in_buf_size; - - if (pZip->m_pNeeds_keepalive != NULL && pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque)) - flush = TDEFL_FULL_FLUSH; - - status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? flush : TDEFL_FINISH); - if (status == TDEFL_STATUS_DONE) - { - result = MZ_TRUE; - break; - } - else if (status != TDEFL_STATUS_OKAY) - { - mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED); - break; - } - } - - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - - if (!result) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - return MZ_FALSE; - } - - comp_size = state.m_comp_size; - cur_archive_file_ofs = state.m_cur_archive_file_ofs; - } - - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - } - - { - mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; - mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32; - - MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID); - MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32); - if (pExtra_data == NULL) - { - if (comp_size > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - MZ_WRITE_LE32(local_dir_footer + 8, comp_size); - MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size); - } - else - { - MZ_WRITE_LE64(local_dir_footer + 8, comp_size); - MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size); - local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64; - } - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size) - return MZ_FALSE; - - cur_archive_file_ofs += local_dir_footer_size; - } - - if (pExtra_data != NULL) - { - extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); - } - - if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment, comment_size, - uncomp_size, comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes, - user_extra_data_central, user_extra_data_central_len)) - return MZ_FALSE; - - pZip->m_total_files++; - pZip->m_archive_size = cur_archive_file_ofs; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) -{ - MZ_FILE *pSrc_file = NULL; - mz_uint64 uncomp_size = 0; - MZ_TIME_T file_modified_time; - MZ_TIME_T *pFile_time = NULL; - mz_bool status; - - memset(&file_modified_time, 0, sizeof(file_modified_time)); - -#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO) - pFile_time = &file_modified_time; - if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_STAT_FAILED); -#endif - - pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); - if (!pSrc_file) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - - MZ_FSEEK64(pSrc_file, 0, SEEK_END); - uncomp_size = MZ_FTELL64(pSrc_file); - MZ_FSEEK64(pSrc_file, 0, SEEK_SET); - - status = mz_zip_writer_add_cfile(pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment, comment_size, level_and_flags, NULL, 0, NULL, 0); - - MZ_FCLOSE(pSrc_file); - - return status; -} -#endif /* #ifndef MINIZ_NO_STDIO */ - -static mz_bool mz_zip_writer_update_zip64_extension_block(mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, uint32_t ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start) -{ - /* + 64 should be enough for any new zip64 data */ - if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - mz_zip_array_resize(pZip, pNew_ext, 0, MZ_FALSE); - - if ((pUncomp_size) || (pComp_size) || (pLocal_header_ofs) || (pDisk_start)) - { - mz_uint8 new_ext_block[64]; - mz_uint8 *pDst = new_ext_block; - mz_write_le16(pDst, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID); - mz_write_le16(pDst + sizeof(mz_uint16), 0); - pDst += sizeof(mz_uint16) * 2; - - if (pUncomp_size) - { - mz_write_le64(pDst, *pUncomp_size); - pDst += sizeof(mz_uint64); - } - - if (pComp_size) - { - mz_write_le64(pDst, *pComp_size); - pDst += sizeof(mz_uint64); - } - - if (pLocal_header_ofs) - { - mz_write_le64(pDst, *pLocal_header_ofs); - pDst += sizeof(mz_uint64); - } - - if (pDisk_start) - { - mz_write_le32(pDst, *pDisk_start); - pDst += sizeof(mz_uint32); - } - - mz_write_le16(new_ext_block + sizeof(mz_uint16), (mz_uint16)((pDst - new_ext_block) - sizeof(mz_uint16) * 2)); - - if (!mz_zip_array_push_back(pZip, pNew_ext, new_ext_block, pDst - new_ext_block)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if ((pExt) && (ext_len)) - { - mz_uint32 extra_size_remaining = ext_len; - const mz_uint8 *pExtra_data = pExt; - - do - { - mz_uint32 field_id, field_data_size, field_total_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - field_total_size = field_data_size + sizeof(mz_uint16) * 2; - - if (field_total_size > extra_size_remaining) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (field_id != MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) - { - if (!mz_zip_array_push_back(pZip, pNew_ext, pExtra_data, field_total_size)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - pExtra_data += field_total_size; - extra_size_remaining -= field_total_size; - } while (extra_size_remaining); - } - - return MZ_TRUE; -} - -/* This func is now pretty freakin complex due to zip64, split it up? */ -mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index) -{ - mz_uint n, bit_flags, num_alignment_padding_bytes, src_central_dir_following_data_size; - mz_uint64 src_archive_bytes_remaining, local_dir_header_ofs; - mz_uint64 cur_src_file_ofs, cur_dst_file_ofs; - mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; - mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; - mz_uint8 new_central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; - size_t orig_central_dir_size; - mz_zip_internal_state *pState; - void *pBuf; - const mz_uint8 *pSrc_central_header; - mz_zip_archive_file_stat src_file_stat; - mz_uint32 src_filename_len, src_comment_len, src_ext_len; - mz_uint32 local_header_filename_size, local_header_extra_len; - mz_uint64 local_header_comp_size, local_header_uncomp_size; - mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE; - - /* Sanity checks */ - if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - /* Don't support copying files from zip64 archives to non-zip64, even though in some cases this is possible */ - if ((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* Get pointer to the source central dir header and crack it */ - if (NULL == (pSrc_central_header = mz_zip_get_cdh(pSource_zip, src_file_index))) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_SIG_OFS) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - src_filename_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS); - src_comment_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS); - src_ext_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS); - src_central_dir_following_data_size = src_filename_len + src_ext_len + src_comment_len; - - /* We don't support central dir's >= MZ_UINT32_MAX bytes right now (+32 fudge factor in case we need to add more extra data) */ - if ((pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + 32) >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); - - if (!pState->m_zip64) - { - if (pZip->m_total_files == MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } - else - { - /* Our zip64 support still has some 32-bit limits that may not be worth fixing. */ - if (pZip->m_total_files == MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } - - if (!mz_zip_file_stat_internal(pSource_zip, src_file_index, pSrc_central_header, &src_file_stat, NULL)) - return MZ_FALSE; - - cur_src_file_ofs = src_file_stat.m_local_header_ofs; - cur_dst_file_ofs = pZip->m_archive_size; - - /* Read the source archive's local dir header */ - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; - - /* Compute the total size we need to copy (filename+extra data+compressed data) */ - local_header_filename_size = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS); - local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); - local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS); - local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS); - src_archive_bytes_remaining = local_header_filename_size + local_header_extra_len + src_file_stat.m_comp_size; - - /* Try to find a zip64 extended information field */ - if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX))) - { - mz_zip_array file_data_array; - const mz_uint8 *pExtra_data; - mz_uint32 extra_size_remaining = local_header_extra_len; - - mz_zip_array_init(&file_data_array, 1); - if (!mz_zip_array_resize(pZip, &file_data_array, local_header_extra_len, MZ_FALSE)) - { - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, src_file_stat.m_local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_size, file_data_array.m_p, local_header_extra_len) != local_header_extra_len) - { - mz_zip_array_clear(pZip, &file_data_array); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - - pExtra_data = (const mz_uint8 *)file_data_array.m_p; - - do - { - mz_uint32 field_id, field_data_size, field_total_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - { - mz_zip_array_clear(pZip, &file_data_array); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - field_total_size = field_data_size + sizeof(mz_uint16) * 2; - - if (field_total_size > extra_size_remaining) - { - mz_zip_array_clear(pZip, &file_data_array); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) - { - const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32); - - if (field_data_size < sizeof(mz_uint64) * 2) - { - mz_zip_array_clear(pZip, &file_data_array); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data); - local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64)); /* may be 0 if there's a descriptor */ - - found_zip64_ext_data_in_ldir = MZ_TRUE; - break; - } - - pExtra_data += field_total_size; - extra_size_remaining -= field_total_size; - } while (extra_size_remaining); - - mz_zip_array_clear(pZip, &file_data_array); - } - - if (!pState->m_zip64) - { - /* Try to detect if the new archive will most likely wind up too big and bail early (+(sizeof(mz_uint32) * 4) is for the optional descriptor which could be present, +64 is a fudge factor). */ - /* We also check when the archive is finalized so this doesn't need to be perfect. */ - mz_uint64 approx_new_archive_size = cur_dst_file_ofs + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + src_archive_bytes_remaining + (sizeof(mz_uint32) * 4) + - pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 64; - - if (approx_new_archive_size >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - } - - /* Write dest archive padding */ - if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes)) - return MZ_FALSE; - - cur_dst_file_ofs += num_alignment_padding_bytes; - - local_dir_header_ofs = cur_dst_file_ofs; - if (pZip->m_file_offset_alignment) - { - MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); - } - - /* The original zip's local header+ext block doesn't change, even with zip64, so we can just copy it over to the dest zip */ - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; - - /* Copy over the source archive bytes to the dest archive, also ensure we have enough buf space to handle optional data descriptor */ - if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(32U, MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining))))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - while (src_archive_bytes_remaining) - { - n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining); - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - cur_src_file_ofs += n; - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - cur_dst_file_ofs += n; - - src_archive_bytes_remaining -= n; - } - - /* Now deal with the optional data descriptor */ - bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); - if (bit_flags & 8) - { - /* Copy data descriptor */ - if ((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir)) - { - /* src is zip64, dest must be zip64 */ - - /* name uint32_t's */ - /* id 1 (optional in zip64?) */ - /* crc 1 */ - /* comp_size 2 */ - /* uncomp_size 2 */ - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (sizeof(mz_uint32) * 6)) != (sizeof(mz_uint32) * 6)) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - - n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID) ? 6 : 5); - } - else - { - /* src is NOT zip64 */ - mz_bool has_id; - - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - - has_id = (MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID); - - if (pZip->m_pState->m_zip64) - { - /* dest is zip64, so upgrade the data descriptor */ - const mz_uint32 *pSrc_descriptor = (const mz_uint32 *)((const mz_uint8 *)pBuf + (has_id ? sizeof(mz_uint32) : 0)); - const mz_uint32 src_crc32 = pSrc_descriptor[0]; - const mz_uint64 src_comp_size = pSrc_descriptor[1]; - const mz_uint64 src_uncomp_size = pSrc_descriptor[2]; - - mz_write_le32((mz_uint8 *)pBuf, MZ_ZIP_DATA_DESCRIPTOR_ID); - mz_write_le32((mz_uint8 *)pBuf + sizeof(mz_uint32) * 1, src_crc32); - mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 2, src_comp_size); - mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 4, src_uncomp_size); - - n = sizeof(mz_uint32) * 6; - } - else - { - /* dest is NOT zip64, just copy it as-is */ - n = sizeof(mz_uint32) * (has_id ? 4 : 3); - } - } - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) - { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_src_file_ofs += n; - cur_dst_file_ofs += n; - } - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - - /* Finally, add the new central dir header */ - orig_central_dir_size = pState->m_central_dir.m_size; - - memcpy(new_central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); - - if (pState->m_zip64) - { - /* This is the painful part: We need to write a new central dir header + ext block with updated zip64 fields, and ensure the old fields (if any) are not included. */ - const mz_uint8 *pSrc_ext = pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len; - mz_zip_array new_ext_block; - - mz_zip_array_init(&new_ext_block, sizeof(mz_uint8)); - - MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_UINT32_MAX); - MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_UINT32_MAX); - MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_UINT32_MAX); - - if (!mz_zip_writer_update_zip64_extension_block(&new_ext_block, pZip, pSrc_ext, src_ext_len, &src_file_stat.m_comp_size, &src_file_stat.m_uncomp_size, &local_dir_header_ofs, NULL)) - { - mz_zip_array_clear(pZip, &new_ext_block); - return MZ_FALSE; - } - - MZ_WRITE_LE16(new_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS, new_ext_block.m_size); - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) - { - mz_zip_array_clear(pZip, &new_ext_block); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_filename_len)) - { - mz_zip_array_clear(pZip, &new_ext_block); - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.m_p, new_ext_block.m_size)) - { - mz_zip_array_clear(pZip, &new_ext_block); - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len + src_ext_len, src_comment_len)) - { - mz_zip_array_clear(pZip, &new_ext_block); - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - mz_zip_array_clear(pZip, &new_ext_block); - } - else - { - /* sanity checks */ - if (cur_dst_file_ofs > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - if (local_dir_header_ofs >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs); - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_central_dir_following_data_size)) - { - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - } - - /* This shouldn't trigger unless we screwed up during the initial sanity checks */ - if (pState->m_central_dir.m_size >= MZ_UINT32_MAX) - { - /* Support central dirs >= 32-bits in size */ - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - } - - n = (mz_uint32)orig_central_dir_size; - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) - { - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - pZip->m_total_files++; - pZip->m_archive_size = cur_dst_file_ofs; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) -{ - mz_zip_internal_state *pState; - mz_uint64 central_dir_ofs, central_dir_size; - mz_uint8 hdr[256]; - - if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - if (pState->m_zip64) - { - if ((pZip->m_total_files > MZ_UINT32_MAX) || (pState->m_central_dir.m_size >= MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } - else - { - if ((pZip->m_total_files > MZ_UINT16_MAX) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } - - central_dir_ofs = 0; - central_dir_size = 0; - if (pZip->m_total_files) - { - /* Write central directory */ - central_dir_ofs = pZip->m_archive_size; - central_dir_size = pState->m_central_dir.m_size; - pZip->m_central_directory_file_ofs = central_dir_ofs; - if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - pZip->m_archive_size += central_dir_size; - } - - if (pState->m_zip64) - { - /* Write zip64 end of central directory header */ - mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size; - - MZ_CLEAR_OBJ(hdr); - MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDH_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - sizeof(mz_uint32) - sizeof(mz_uint64)); - MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, 0x031E); /* : always Unix */ - MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_NEEDED_OFS, 0x002D); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_SIZE_OFS, central_dir_size); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_OFS_OFS, central_dir_ofs); - if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE; - - /* Write zip64 end of central directory locator */ - MZ_CLEAR_OBJ(hdr); - MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS, rel_ofs_to_zip64_ecdr); - MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS, 1); - if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) != MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE; - } - - /* Write end of central directory record */ - MZ_CLEAR_OBJ(hdr); - MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG); - MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files)); - MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files)); - MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_size)); - MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_ofs)); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - -#ifndef MINIZ_NO_STDIO - if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED); -#endif /* #ifndef MINIZ_NO_STDIO */ - - pZip->m_archive_size += MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE; - - pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED; - return MZ_TRUE; -} - -mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize) -{ - if ((!ppBuf) || (!pSize)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - *ppBuf = NULL; - *pSize = 0; - - if ((!pZip) || (!pZip->m_pState)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (pZip->m_pWrite != mz_zip_heap_write_func) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_writer_finalize_archive(pZip)) - return MZ_FALSE; - - *ppBuf = pZip->m_pState->m_pMem; - *pSize = pZip->m_pState->m_mem_size; - pZip->m_pState->m_pMem = NULL; - pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_end(mz_zip_archive *pZip) -{ - return mz_zip_writer_end_internal(pZip, MZ_TRUE); -} - -#ifndef MINIZ_NO_STDIO -mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) -{ - return mz_zip_add_mem_to_archive_file_in_place_v2(pZip_filename, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, NULL); -} - -mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr) -{ - mz_bool status, created_new_archive = MZ_FALSE; - mz_zip_archive zip_archive; - struct MZ_FILE_STAT_STRUCT file_stat; - mz_zip_error actual_err = MZ_ZIP_NO_ERROR; - - mz_zip_zero_struct(&zip_archive); - if ((int)level_and_flags < 0) - level_and_flags = MZ_DEFAULT_LEVEL; - - if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION)) - { - if (pErr) - *pErr = MZ_ZIP_INVALID_PARAMETER; - return MZ_FALSE; - } - - if (!mz_zip_writer_validate_archive_name(pArchive_name)) - { - if (pErr) - *pErr = MZ_ZIP_INVALID_FILENAME; - return MZ_FALSE; - } - - /* Important: The regular non-64 bit version of stat() can fail here if the file is very large, which could cause the archive to be overwritten. */ - /* So be sure to compile with _LARGEFILE64_SOURCE 1 */ - if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) - { - /* Create a new archive. */ - if (!mz_zip_writer_init_file_v2(&zip_archive, pZip_filename, 0, level_and_flags)) - { - if (pErr) - *pErr = zip_archive.m_last_error; - return MZ_FALSE; - } - - created_new_archive = MZ_TRUE; - } - else - { - /* Append to an existing archive. */ - if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) - { - if (pErr) - *pErr = zip_archive.m_last_error; - return MZ_FALSE; - } - - if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags)) - { - if (pErr) - *pErr = zip_archive.m_last_error; - - mz_zip_reader_end_internal(&zip_archive, MZ_FALSE); - - return MZ_FALSE; - } - } - - status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0); - actual_err = zip_archive.m_last_error; - - /* Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) */ - if (!mz_zip_writer_finalize_archive(&zip_archive)) - { - if (!actual_err) - actual_err = zip_archive.m_last_error; - - status = MZ_FALSE; - } - - if (!mz_zip_writer_end_internal(&zip_archive, status)) - { - if (!actual_err) - actual_err = zip_archive.m_last_error; - - status = MZ_FALSE; - } - - if ((!status) && (created_new_archive)) - { - /* It's a new archive and something went wrong, so just delete it. */ - int ignoredStatus = MZ_DELETE_FILE(pZip_filename); - (void)ignoredStatus; - } - - if (pErr) - *pErr = actual_err; - - return status; -} - -void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr) -{ - mz_uint32 file_index; - mz_zip_archive zip_archive; - void *p = NULL; - - if (pSize) - *pSize = 0; - - if ((!pZip_filename) || (!pArchive_name)) - { - if (pErr) - *pErr = MZ_ZIP_INVALID_PARAMETER; - - return NULL; - } - - mz_zip_zero_struct(&zip_archive); - if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) - { - if (pErr) - *pErr = zip_archive.m_last_error; - - return NULL; - } - - if (mz_zip_reader_locate_file_v2(&zip_archive, pArchive_name, pComment, flags, &file_index)) - { - p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags); - } - - mz_zip_reader_end_internal(&zip_archive, p != NULL); - - if (pErr) - *pErr = zip_archive.m_last_error; - - return p; -} - -void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags) -{ - return mz_zip_extract_archive_file_to_heap_v2(pZip_filename, pArchive_name, NULL, pSize, flags, NULL); -} - -#endif /* #ifndef MINIZ_NO_STDIO */ - -#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */ - -/* ------------------- Misc utils */ - -mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip) -{ - return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID; -} - -mz_zip_type mz_zip_get_type(mz_zip_archive *pZip) -{ - return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID; -} - -mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num) -{ - mz_zip_error prev_err; - - if (!pZip) - return MZ_ZIP_INVALID_PARAMETER; - - prev_err = pZip->m_last_error; - - pZip->m_last_error = err_num; - return prev_err; -} - -mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip) -{ - if (!pZip) - return MZ_ZIP_INVALID_PARAMETER; - - return pZip->m_last_error; -} - -mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip) -{ - return mz_zip_set_last_error(pZip, MZ_ZIP_NO_ERROR); -} - -mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip) -{ - mz_zip_error prev_err; - - if (!pZip) - return MZ_ZIP_INVALID_PARAMETER; - - prev_err = pZip->m_last_error; - - pZip->m_last_error = MZ_ZIP_NO_ERROR; - return prev_err; -} - -const char *mz_zip_get_error_string(mz_zip_error mz_err) -{ - switch (mz_err) - { - case MZ_ZIP_NO_ERROR: - return "no error"; - case MZ_ZIP_UNDEFINED_ERROR: - return "undefined error"; - case MZ_ZIP_TOO_MANY_FILES: - return "too many files"; - case MZ_ZIP_FILE_TOO_LARGE: - return "file too large"; - case MZ_ZIP_UNSUPPORTED_METHOD: - return "unsupported method"; - case MZ_ZIP_UNSUPPORTED_ENCRYPTION: - return "unsupported encryption"; - case MZ_ZIP_UNSUPPORTED_FEATURE: - return "unsupported feature"; - case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR: - return "failed finding central directory"; - case MZ_ZIP_NOT_AN_ARCHIVE: - return "not a ZIP archive"; - case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED: - return "invalid header or archive is corrupted"; - case MZ_ZIP_UNSUPPORTED_MULTIDISK: - return "unsupported multidisk archive"; - case MZ_ZIP_DECOMPRESSION_FAILED: - return "decompression failed or archive is corrupted"; - case MZ_ZIP_COMPRESSION_FAILED: - return "compression failed"; - case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE: - return "unexpected decompressed size"; - case MZ_ZIP_CRC_CHECK_FAILED: - return "CRC-32 check failed"; - case MZ_ZIP_UNSUPPORTED_CDIR_SIZE: - return "unsupported central directory size"; - case MZ_ZIP_ALLOC_FAILED: - return "allocation failed"; - case MZ_ZIP_FILE_OPEN_FAILED: - return "file open failed"; - case MZ_ZIP_FILE_CREATE_FAILED: - return "file create failed"; - case MZ_ZIP_FILE_WRITE_FAILED: - return "file write failed"; - case MZ_ZIP_FILE_READ_FAILED: - return "file read failed"; - case MZ_ZIP_FILE_CLOSE_FAILED: - return "file close failed"; - case MZ_ZIP_FILE_SEEK_FAILED: - return "file seek failed"; - case MZ_ZIP_FILE_STAT_FAILED: - return "file stat failed"; - case MZ_ZIP_INVALID_PARAMETER: - return "invalid parameter"; - case MZ_ZIP_INVALID_FILENAME: - return "invalid filename"; - case MZ_ZIP_BUF_TOO_SMALL: - return "buffer too small"; - case MZ_ZIP_INTERNAL_ERROR: - return "internal error"; - case MZ_ZIP_FILE_NOT_FOUND: - return "file not found"; - case MZ_ZIP_ARCHIVE_TOO_LARGE: - return "archive is too large"; - case MZ_ZIP_VALIDATION_FAILED: - return "validation failed"; - case MZ_ZIP_WRITE_CALLBACK_FAILED: - return "write calledback failed"; - default: - break; - } - - return "unknown error"; -} - -/* Note: Just because the archive is not zip64 doesn't necessarily mean it doesn't have Zip64 extended information extra field, argh. */ -mz_bool mz_zip_is_zip64(mz_zip_archive *pZip) -{ - if ((!pZip) || (!pZip->m_pState)) - return MZ_FALSE; - - return pZip->m_pState->m_zip64; -} - -size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip) -{ - if ((!pZip) || (!pZip->m_pState)) - return 0; - - return pZip->m_pState->m_central_dir.m_size; -} - -mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip) -{ - return pZip ? pZip->m_total_files : 0; -} - -mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip) -{ - if (!pZip) - return 0; - return pZip->m_archive_size; -} - -mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip) -{ - if ((!pZip) || (!pZip->m_pState)) - return 0; - return pZip->m_pState->m_file_archive_start_ofs; -} - -MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip) -{ - if ((!pZip) || (!pZip->m_pState)) - return 0; - return pZip->m_pState->m_pFile; -} - -size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n) -{ - if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n); -} - -mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size) -{ - mz_uint n; - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); - if (!p) - { - if (filename_buf_size) - pFilename[0] = '\0'; - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return 0; - } - n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - if (filename_buf_size) - { - n = MZ_MIN(n, filename_buf_size - 1); - memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); - pFilename[n] = '\0'; - } - return n + 1; -} - -mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat) -{ - return mz_zip_file_stat_internal(pZip, file_index, mz_zip_get_cdh(pZip, file_index), pStat, NULL); -} - -mz_bool mz_zip_end(mz_zip_archive *pZip) -{ - if (!pZip) - return MZ_FALSE; - - if (pZip->m_zip_mode == MZ_ZIP_MODE_READING) - return mz_zip_reader_end(pZip); -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS - else if ((pZip->m_zip_mode == MZ_ZIP_MODE_WRITING) || (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)) - return mz_zip_writer_end(pZip); -#endif - - return MZ_FALSE; -} - -#ifdef __cplusplus -} -#endif - -#endif /*#ifndef MINIZ_NO_ARCHIVE_APIS*/ - diff --git a/miniz/miniz.h b/miniz/miniz.h deleted file mode 100755 index bd0be81f2..000000000 --- a/miniz/miniz.h +++ /dev/null @@ -1,1322 +0,0 @@ -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - -/* miniz.c v1.16 beta r1 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing - See "unlicense" statement at the end of this file. - Rich Geldreich , last updated Oct. 13, 2013 - Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt - - Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define - MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros). - - * Low-level Deflate/Inflate implementation notes: - - Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or - greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses - approximately as well as zlib. - - Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function - coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory - block large enough to hold the entire file. - - The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation. - - * zlib-style API notes: - - miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in - zlib replacement in many apps: - The z_stream struct, optional memory allocation callbacks - deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound - inflateInit/inflateInit2/inflate/inflateEnd - compress, compress2, compressBound, uncompress - CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines. - Supports raw deflate streams or standard zlib streams with adler-32 checking. - - Limitations: - The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries. - I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but - there are no guarantees that miniz.c pulls this off perfectly. - - * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by - Alex Evans. Supports 1-4 bytes/pixel images. - - * ZIP archive API notes: - - The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to - get the job done with minimal fuss. There are simple API's to retrieve file information, read files from - existing archives, create new archives, append new files to existing archives, or clone archive data from - one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h), - or you can specify custom file read/write callbacks. - - - Archive reading: Just call this function to read a single file from a disk archive: - - void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, - size_t *pSize, mz_uint zip_flags); - - For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central - directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files. - - - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file: - - int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); - - The locate operation can optionally check file comments too, which (as one example) can be used to identify - multiple versions of the same file in an archive. This function uses a simple linear search through the central - directory, so it's not very fast. - - Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and - retrieve detailed info on each file by calling mz_zip_reader_file_stat(). - - - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data - to disk and builds an exact image of the central directory in memory. The central directory image is written - all at once at the end of the archive file when the archive is finalized. - - The archive writer can optionally align each file's local header and file data to any power of 2 alignment, - which can be useful when the archive will be read from optical media. Also, the writer supports placing - arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still - readable by any ZIP tool. - - - Archive appending: The simple way to add a single file to an archive is to call this function: - - mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, - const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); - - The archive will be created if it doesn't already exist, otherwise it'll be appended to. - Note the appending is done in-place and is not an atomic operation, so if something goes wrong - during the operation it's possible the archive could be left without a central directory (although the local - file headers and file data will be fine, so the archive will be recoverable). - - For more complex archive modification scenarios: - 1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to - preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the - compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and - you're done. This is safe but requires a bunch of temporary disk space or heap memory. - - 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(), - append new files as needed, then finalize the archive which will write an updated central directory to the - original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a - possibility that the archive's central directory could be lost with this method if anything goes wrong, though. - - - ZIP archive support limitations: - No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files. - Requires streams capable of seeking. - - * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the - below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it. - - * Important: For best perf. be sure to customize the below macros for your target platform: - #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 - #define MINIZ_LITTLE_ENDIAN 1 - #define MINIZ_HAS_64BIT_REGISTERS 1 - - * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz - uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files - (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes). -*/ -#pragma once - - - - - -/* Defines to completely disable specific portions of miniz.c: - If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. */ - -/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */ -/*#define MINIZ_NO_STDIO */ - -/* If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or */ -/* get/set file times, and the C run-time funcs that get/set times won't be called. */ -/* The current downside is the times written to your archives will be from 1979. */ -/*#define MINIZ_NO_TIME */ - -/* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */ -/*#define MINIZ_NO_ARCHIVE_APIS */ - -/* Define MINIZ_NO_ARCHIVE_WRITING_APIS to disable all writing related ZIP archive API's. */ -/*#define MINIZ_NO_ARCHIVE_WRITING_APIS */ - -/* Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. */ -/*#define MINIZ_NO_ZLIB_APIS */ - -/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. */ -/*#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES */ - -/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. - Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc - callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user - functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */ -/*#define MINIZ_NO_MALLOC */ - -#if defined(__TINYC__) && (defined(__linux) || defined(__linux__)) -/* : Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux */ -#define MINIZ_NO_TIME -#endif - -#include - -#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS) -#include -#endif - -#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) -/* MINIZ_X86_OR_X64_CPU is only used to help set the below macros. */ -#define MINIZ_X86_OR_X64_CPU 1 -#endif - -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU -/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */ -#define MINIZ_LITTLE_ENDIAN 1 -#endif - -#if MINIZ_X86_OR_X64_CPU -/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. */ -#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 -#endif - -#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__) -/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). */ -#define MINIZ_HAS_64BIT_REGISTERS 1 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- zlib-style API Definitions. */ - -/* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! */ -typedef unsigned long mz_ulong; - -/* mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. */ -void mz_free(void *p); - -#define MZ_ADLER32_INIT (1) -/* mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. */ -mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len); - -#define MZ_CRC32_INIT (0) -/* mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. */ -mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len); - -/* Compression strategies. */ -enum -{ - MZ_DEFAULT_STRATEGY = 0, - MZ_FILTERED = 1, - MZ_HUFFMAN_ONLY = 2, - MZ_RLE = 3, - MZ_FIXED = 4 -}; - -/* Method */ -#define MZ_DEFLATED 8 - -/* Heap allocation callbacks. -Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. */ -typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); -typedef void(*mz_free_func)(void *opaque, void *address); -typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); - -/* Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. */ -enum -{ - MZ_NO_COMPRESSION = 0, - MZ_BEST_SPEED = 1, - MZ_BEST_COMPRESSION = 9, - MZ_UBER_COMPRESSION = 10, - MZ_DEFAULT_LEVEL = 6, - MZ_DEFAULT_COMPRESSION = -1 -}; - -#define MZ_VERSION "10.0.0" -#define MZ_VERNUM 0xA000 -#define MZ_VER_MAJOR 10 -#define MZ_VER_MINOR 0 -#define MZ_VER_REVISION 0 -#define MZ_VER_SUBREVISION 0 - -#ifndef MINIZ_NO_ZLIB_APIS - -/* Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). */ -enum -{ - MZ_NO_FLUSH = 0, - MZ_PARTIAL_FLUSH = 1, - MZ_SYNC_FLUSH = 2, - MZ_FULL_FLUSH = 3, - MZ_FINISH = 4, - MZ_BLOCK = 5 -}; - -/* Return status codes. MZ_PARAM_ERROR is non-standard. */ -enum -{ - MZ_OK = 0, - MZ_STREAM_END = 1, - MZ_NEED_DICT = 2, - MZ_ERRNO = -1, - MZ_STREAM_ERROR = -2, - MZ_DATA_ERROR = -3, - MZ_MEM_ERROR = -4, - MZ_BUF_ERROR = -5, - MZ_VERSION_ERROR = -6, - MZ_PARAM_ERROR = -10000 -}; - -/* Window bits */ -#define MZ_DEFAULT_WINDOW_BITS 15 - -struct mz_internal_state; - -/* Compression/decompression stream struct. */ -typedef struct mz_stream_s -{ - const unsigned char *next_in; /* pointer to next byte to read */ - unsigned int avail_in; /* number of bytes available at next_in */ - mz_ulong total_in; /* total number of bytes consumed so far */ - - unsigned char *next_out; /* pointer to next byte to write */ - unsigned int avail_out; /* number of bytes that can be written to next_out */ - mz_ulong total_out; /* total number of bytes produced so far */ - - char *msg; /* error msg (unused) */ - struct mz_internal_state *state; /* internal state, allocated by zalloc/zfree */ - - mz_alloc_func zalloc; /* optional heap allocation function (defaults to malloc) */ - mz_free_func zfree; /* optional heap free function (defaults to free) */ - void *opaque; /* heap alloc function user pointer */ - - int data_type; /* data_type (unused) */ - mz_ulong adler; /* adler32 of the source or uncompressed data */ - mz_ulong reserved; /* not used */ -} mz_stream; - -typedef mz_stream *mz_streamp; - -/* Returns the version string of miniz.c. */ -const char *mz_version(void); - -/* mz_deflateInit() initializes a compressor with default options: */ -/* Parameters: */ -/* pStream must point to an initialized mz_stream struct. */ -/* level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. */ -/* level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. */ -/* (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) */ -/* Return values: */ -/* MZ_OK on success. */ -/* MZ_STREAM_ERROR if the stream is bogus. */ -/* MZ_PARAM_ERROR if the input parameters are bogus. */ -/* MZ_MEM_ERROR on out of memory. */ -int mz_deflateInit(mz_streamp pStream, int level); - -/* mz_deflateInit2() is like mz_deflate(), except with more control: */ -/* Additional parameters: */ -/* method must be MZ_DEFLATED */ -/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) */ -/* mem_level must be between [1, 9] (it's checked but ignored by miniz.c) */ -int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); - -/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). */ -int mz_deflateReset(mz_streamp pStream); - -/* mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. */ -/* Parameters: */ -/* pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */ -/* flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. */ -/* Return values: */ -/* MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). */ -/* MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. */ -/* MZ_STREAM_ERROR if the stream is bogus. */ -/* MZ_PARAM_ERROR if one of the parameters is invalid. */ -/* MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) */ -int mz_deflate(mz_streamp pStream, int flush); - -/* mz_deflateEnd() deinitializes a compressor: */ -/* Return values: */ -/* MZ_OK on success. */ -/* MZ_STREAM_ERROR if the stream is bogus. */ -int mz_deflateEnd(mz_streamp pStream); - -/* mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. */ -mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); - -/* Single-call compression functions mz_compress() and mz_compress2(): */ -/* Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. */ -int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); -int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level); - -/* mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). */ -mz_ulong mz_compressBound(mz_ulong source_len); - -/* Initializes a decompressor. */ -int mz_inflateInit(mz_streamp pStream); - -/* mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: */ -/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). */ -int mz_inflateInit2(mz_streamp pStream, int window_bits); - -/* Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. */ -/* Parameters: */ -/* pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */ -/* flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. */ -/* On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). */ -/* MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. */ -/* Return values: */ -/* MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. */ -/* MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. */ -/* MZ_STREAM_ERROR if the stream is bogus. */ -/* MZ_DATA_ERROR if the deflate stream is invalid. */ -/* MZ_PARAM_ERROR if one of the parameters is invalid. */ -/* MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again */ -/* with more input data, or with more room in the output buffer (except when using single call decompression, described above). */ -int mz_inflate(mz_streamp pStream, int flush); - -/* Deinitializes a decompressor. */ -int mz_inflateEnd(mz_streamp pStream); - -/* Single-call decompression. */ -/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */ -int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); - -/* Returns a string description of the specified error code, or NULL if the error code is invalid. */ -const char *mz_error(int err); - -/* Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. */ -/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. */ -#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES -typedef unsigned char Byte; -typedef unsigned int uInt; -typedef mz_ulong uLong; -typedef Byte Bytef; -typedef uInt uIntf; -typedef char charf; -typedef int intf; -typedef void *voidpf; -typedef uLong uLongf; -typedef void *voidp; -typedef void *const voidpc; -#define Z_NULL 0 -#define Z_NO_FLUSH MZ_NO_FLUSH -#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH -#define Z_SYNC_FLUSH MZ_SYNC_FLUSH -#define Z_FULL_FLUSH MZ_FULL_FLUSH -#define Z_FINISH MZ_FINISH -#define Z_BLOCK MZ_BLOCK -#define Z_OK MZ_OK -#define Z_STREAM_END MZ_STREAM_END -#define Z_NEED_DICT MZ_NEED_DICT -#define Z_ERRNO MZ_ERRNO -#define Z_STREAM_ERROR MZ_STREAM_ERROR -#define Z_DATA_ERROR MZ_DATA_ERROR -#define Z_MEM_ERROR MZ_MEM_ERROR -#define Z_BUF_ERROR MZ_BUF_ERROR -#define Z_VERSION_ERROR MZ_VERSION_ERROR -#define Z_PARAM_ERROR MZ_PARAM_ERROR -#define Z_NO_COMPRESSION MZ_NO_COMPRESSION -#define Z_BEST_SPEED MZ_BEST_SPEED -#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION -#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION -#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY -#define Z_FILTERED MZ_FILTERED -#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY -#define Z_RLE MZ_RLE -#define Z_FIXED MZ_FIXED -#define Z_DEFLATED MZ_DEFLATED -#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS -#define alloc_func mz_alloc_func -#define free_func mz_free_func -#define internal_state mz_internal_state -#define z_stream mz_stream -#define deflateInit mz_deflateInit -#define deflateInit2 mz_deflateInit2 -#define deflateReset mz_deflateReset -#define deflate mz_deflate -#define deflateEnd mz_deflateEnd -#define deflateBound mz_deflateBound -#define compress mz_compress -#define compress2 mz_compress2 -#define compressBound mz_compressBound -#define inflateInit mz_inflateInit -#define inflateInit2 mz_inflateInit2 -#define inflate mz_inflate -#define inflateEnd mz_inflateEnd -#define uncompress mz_uncompress -#define crc32 mz_crc32 -#define adler32 mz_adler32 -#define MAX_WBITS 15 -#define MAX_MEM_LEVEL 9 -#define zError mz_error -#define ZLIB_VERSION MZ_VERSION -#define ZLIB_VERNUM MZ_VERNUM -#define ZLIB_VER_MAJOR MZ_VER_MAJOR -#define ZLIB_VER_MINOR MZ_VER_MINOR -#define ZLIB_VER_REVISION MZ_VER_REVISION -#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION -#define zlibVersion mz_version -#define zlib_version mz_version() -#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */ - -#endif /* MINIZ_NO_ZLIB_APIS */ - -#ifdef __cplusplus -} -#endif -#pragma once -#include -#include -#include -#include - -/* ------------------- Types and macros */ -typedef unsigned char mz_uint8; -typedef signed short mz_int16; -typedef unsigned short mz_uint16; -typedef unsigned int mz_uint32; -typedef unsigned int mz_uint; -typedef int64_t mz_int64; -typedef uint64_t mz_uint64; -typedef int mz_bool; - -#define MZ_FALSE (0) -#define MZ_TRUE (1) - -/* Works around MSVC's spammy "warning C4127: conditional expression is constant" message. */ -#ifdef _MSC_VER -#define MZ_MACRO_END while (0, 0) -#else -#define MZ_MACRO_END while (0) -#endif - -#ifdef MINIZ_NO_STDIO -#define MZ_FILE void * -#else -#include -#define MZ_FILE FILE -#endif /* #ifdef MINIZ_NO_STDIO */ - -#ifdef MINIZ_NO_TIME -typedef struct mz_dummy_time_t_tag -{ - int m_dummy; -} mz_dummy_time_t; -#define MZ_TIME_T mz_dummy_time_t -#else -#define MZ_TIME_T time_t -#endif - -#define MZ_ASSERT(x) assert(x) - -#ifdef MINIZ_NO_MALLOC -#define MZ_MALLOC(x) NULL -#define MZ_FREE(x) (void) x, ((void)0) -#define MZ_REALLOC(p, x) NULL -#else -#define MZ_MALLOC(x) malloc(x) -#define MZ_FREE(x) free(x) -#define MZ_REALLOC(p, x) realloc(p, x) -#endif - -#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES &&MINIZ_LITTLE_ENDIAN -#define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) -#define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) -#else -#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) -#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) -#endif - -#define MZ_READ_LE64(p) (((mz_uint64)MZ_READ_LE32(p)) | (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) << 32U)) - -#ifdef _MSC_VER -#define MZ_FORCEINLINE __forceinline -#elif defined(__GNUC__) -#define MZ_FORCEINLINE __inline__ __attribute__((__always_inline__)) -#else -#define MZ_FORCEINLINE inline -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern void *miniz_def_alloc_func(void *opaque, size_t items, size_t size); -extern void miniz_def_free_func(void *opaque, void *address); -extern void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size); - -#define MZ_UINT16_MAX (0xFFFFU) -#define MZ_UINT32_MAX (0xFFFFFFFFU) - -#ifdef __cplusplus -} -#endif -#pragma once - - -#ifdef __cplusplus -extern "C" { -#endif -/* ------------------- Low-level Compression API Definitions */ - -/* Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). */ -#define TDEFL_LESS_MEMORY 0 - -/* tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): */ -/* TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). */ -enum -{ - TDEFL_HUFFMAN_ONLY = 0, - TDEFL_DEFAULT_MAX_PROBES = 128, - TDEFL_MAX_PROBES_MASK = 0xFFF -}; - -/* TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. */ -/* TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). */ -/* TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. */ -/* TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). */ -/* TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) */ -/* TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. */ -/* TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. */ -/* TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. */ -/* The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK). */ -enum -{ - TDEFL_WRITE_ZLIB_HEADER = 0x01000, - TDEFL_COMPUTE_ADLER32 = 0x02000, - TDEFL_GREEDY_PARSING_FLAG = 0x04000, - TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000, - TDEFL_RLE_MATCHES = 0x10000, - TDEFL_FILTER_MATCHES = 0x20000, - TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000, - TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000 -}; - -/* High level compression functions: */ -/* tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). */ -/* On entry: */ -/* pSrc_buf, src_buf_len: Pointer and size of source block to compress. */ -/* flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. */ -/* On return: */ -/* Function returns a pointer to the compressed data, or NULL on failure. */ -/* *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. */ -/* The caller must free() the returned block when it's no longer needed. */ -void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); - -/* tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. */ -/* Returns 0 on failure. */ -size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); - -/* Compresses an image to a compressed PNG file in memory. */ -/* On entry: */ -/* pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. */ -/* The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. */ -/* level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL */ -/* If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps). */ -/* On return: */ -/* Function returns a pointer to the compressed data, or NULL on failure. */ -/* *pLen_out will be set to the size of the PNG image file. */ -/* The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. */ -void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip); -void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out); - -/* Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. */ -typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser); - -/* tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. */ -mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); - -enum -{ - TDEFL_MAX_HUFF_TABLES = 3, - TDEFL_MAX_HUFF_SYMBOLS_0 = 288, - TDEFL_MAX_HUFF_SYMBOLS_1 = 32, - TDEFL_MAX_HUFF_SYMBOLS_2 = 19, - TDEFL_LZ_DICT_SIZE = 32768, - TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, - TDEFL_MIN_MATCH_LEN = 3, - TDEFL_MAX_MATCH_LEN = 258 -}; - -/* TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). */ -#if TDEFL_LESS_MEMORY -enum -{ - TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, - TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, - TDEFL_MAX_HUFF_SYMBOLS = 288, - TDEFL_LZ_HASH_BITS = 12, - TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, - TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, - TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS -}; -#else -enum -{ - TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, - TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, - TDEFL_MAX_HUFF_SYMBOLS = 288, - TDEFL_LZ_HASH_BITS = 15, - TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, - TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, - TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS -}; -#endif - -/* The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. */ -typedef enum -{ - TDEFL_STATUS_BAD_PARAM = -2, - TDEFL_STATUS_PUT_BUF_FAILED = -1, - TDEFL_STATUS_OKAY = 0, - TDEFL_STATUS_DONE = 1 -} tdefl_status; - -/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */ -typedef enum -{ - TDEFL_NO_FLUSH = 0, - TDEFL_SYNC_FLUSH = 2, - TDEFL_FULL_FLUSH = 3, - TDEFL_FINISH = 4 -} tdefl_flush; - -/* tdefl's compression state structure. */ -typedef struct -{ - tdefl_put_buf_func_ptr m_pPut_buf_func; - void *m_pPut_buf_user; - mz_uint m_flags, m_max_probes[2]; - int m_greedy_parsing; - mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size; - mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; - mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer; - mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish; - tdefl_status m_prev_return_status; - const void *m_pIn_buf; - void *m_pOut_buf; - size_t *m_pIn_buf_size, *m_pOut_buf_size; - tdefl_flush m_flush; - const mz_uint8 *m_pSrc; - size_t m_src_buf_left, m_out_buf_ofs; - mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; - mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; - mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; - mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; - mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; - mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; - mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; - mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; -} tdefl_compressor; - -/* Initializes the compressor. */ -/* There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. */ -/* pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. */ -/* If pBut_buf_func is NULL the user should always call the tdefl_compress() API. */ -/* flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) */ -tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); - -/* Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. */ -tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush); - -/* tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. */ -/* tdefl_compress_buffer() always consumes the entire input buffer. */ -tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush); - -tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); -mz_uint32 tdefl_get_adler32(tdefl_compressor *d); - -/* Create tdefl_compress() flags given zlib-style compression parameters. */ -/* level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) */ -/* window_bits may be -15 (raw deflate) or 15 (zlib) */ -/* strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED */ -mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy); - -/* Allocate the tdefl_compressor structure in C so that */ -/* non-C language bindings to tdefl_ API don't need to worry about */ -/* structure size and allocation mechanism. */ -tdefl_compressor *tdefl_compressor_alloc(void); -void tdefl_compressor_free(tdefl_compressor *pComp); - -#ifdef __cplusplus -} -#endif -#pragma once - -/* ------------------- Low-level Decompression API Definitions */ - -#ifdef __cplusplus -extern "C" { -#endif -/* Decompression flags used by tinfl_decompress(). */ -/* TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. */ -/* TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. */ -/* TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). */ -/* TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. */ -enum -{ - TINFL_FLAG_PARSE_ZLIB_HEADER = 1, - TINFL_FLAG_HAS_MORE_INPUT = 2, - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, - TINFL_FLAG_COMPUTE_ADLER32 = 8 -}; - -/* High level decompression functions: */ -/* tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). */ -/* On entry: */ -/* pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. */ -/* On return: */ -/* Function returns a pointer to the decompressed data, or NULL on failure. */ -/* *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. */ -/* The caller must call mz_free() on the returned block when it's no longer needed. */ -void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); - -/* tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. */ -/* Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. */ -#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) -size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); - -/* tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. */ -/* Returns 1 on success or 0 on failure. */ -typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser); -int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); - -struct tinfl_decompressor_tag; -typedef struct tinfl_decompressor_tag tinfl_decompressor; - -/* Allocate the tinfl_decompressor structure in C so that */ -/* non-C language bindings to tinfl_ API don't need to worry about */ -/* structure size and allocation mechanism. */ - -tinfl_decompressor *tinfl_decompressor_alloc(void); -void tinfl_decompressor_free(tinfl_decompressor *pDecomp); - -/* Max size of LZ dictionary. */ -#define TINFL_LZ_DICT_SIZE 32768 - -/* Return status. */ -typedef enum -{ - /* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */ - /* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */ - /* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */ - TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4, - - /* This flag indicates that one or more of the input parameters was obviously bogus. (You can try calling it again, but if you get this error the calling code is wrong.) */ - TINFL_STATUS_BAD_PARAM = -3, - - /* This flags indicate the inflator is finished but the adler32 check of the uncompressed data didn't match. If you call it again it'll return TINFL_STATUS_DONE. */ - TINFL_STATUS_ADLER32_MISMATCH = -2, - - /* This flags indicate the inflator has somehow failed (bad code, corrupted input, etc.). If you call it again without resetting via tinfl_init() it it'll just keep on returning the same status failure code. */ - TINFL_STATUS_FAILED = -1, - - /* Any status code less than TINFL_STATUS_DONE must indicate a failure. */ - - /* This flag indicates the inflator has returned every byte of uncompressed data that it can, has consumed every byte that it needed, has successfully reached the end of the deflate stream, and */ - /* if zlib headers and adler32 checking enabled that it has successfully checked the uncompressed data's adler32. If you call it again you'll just get TINFL_STATUS_DONE over and over again. */ - TINFL_STATUS_DONE = 0, - - /* This flag indicates the inflator MUST have more input data (even 1 byte) before it can make any more forward progress, or you need to clear the TINFL_FLAG_HAS_MORE_INPUT */ - /* flag on the next call if you don't have any more source data. If the source data was somehow corrupted it's also possible (but unlikely) for the inflator to keep on demanding input to */ - /* proceed, so be sure to properly set the TINFL_FLAG_HAS_MORE_INPUT flag. */ - TINFL_STATUS_NEEDS_MORE_INPUT = 1, - - /* This flag indicates the inflator definitely has 1 or more bytes of uncompressed data available, but it cannot write this data into the output buffer. */ - /* Note if the source compressed data was corrupted it's possible for the inflator to return a lot of uncompressed data to the caller. I've been assuming you know how much uncompressed data to expect */ - /* (either exact or worst case) and will stop calling the inflator and fail after receiving too much. In pure streaming scenarios where you have no idea how many bytes to expect this may not be possible */ - /* so I may need to add some code to address this. */ - TINFL_STATUS_HAS_MORE_OUTPUT = 2 -} tinfl_status; - -/* Initializes the decompressor to its initial state. */ -#define tinfl_init(r) \ - do \ - { \ - (r)->m_state = 0; \ - } \ - MZ_MACRO_END -#define tinfl_get_adler32(r) (r)->m_check_adler32 - -/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */ -/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */ -tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); - -/* Internal/private bits follow. */ -enum -{ - TINFL_MAX_HUFF_TABLES = 3, - TINFL_MAX_HUFF_SYMBOLS_0 = 288, - TINFL_MAX_HUFF_SYMBOLS_1 = 32, - TINFL_MAX_HUFF_SYMBOLS_2 = 19, - TINFL_FAST_LOOKUP_BITS = 10, - TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS -}; - -typedef struct -{ - mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; - mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; -} tinfl_huff_table; - -#if MINIZ_HAS_64BIT_REGISTERS -#define TINFL_USE_64BIT_BITBUF 1 -#endif - -#if TINFL_USE_64BIT_BITBUF -typedef mz_uint64 tinfl_bit_buf_t; -#define TINFL_BITBUF_SIZE (64) -#else -typedef mz_uint32 tinfl_bit_buf_t; -#define TINFL_BITBUF_SIZE (32) -#endif - -struct tinfl_decompressor_tag -{ - mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; - tinfl_bit_buf_t m_bit_buf; - size_t m_dist_from_out_buf_start; - tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; - mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; -}; - -#ifdef __cplusplus -} -#endif - -#pragma once - - -/* ------------------- ZIP archive reading/writing */ - -#ifndef MINIZ_NO_ARCHIVE_APIS - -#ifdef __cplusplus -extern "C" { -#endif - -enum -{ - /* Note: These enums can be reduced as needed to save memory or stack space - they are pretty conservative. */ - MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024, - MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 512, - MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 512 -}; - -typedef struct -{ - /* Central directory file index. */ - mz_uint32 m_file_index; - - /* Byte offset of this entry in the archive's central directory. Note we currently only support up to UINT_MAX or less bytes in the central dir. */ - mz_uint64 m_central_dir_ofs; - - /* These fields are copied directly from the zip's central dir. */ - mz_uint16 m_version_made_by; - mz_uint16 m_version_needed; - mz_uint16 m_bit_flag; - mz_uint16 m_method; - -#ifndef MINIZ_NO_TIME - MZ_TIME_T m_time; -#endif - - /* CRC-32 of uncompressed data. */ - mz_uint32 m_crc32; - - /* File's compressed size. */ - mz_uint64 m_comp_size; - - /* File's uncompressed size. Note, I've seen some old archives where directory entries had 512 bytes for their uncompressed sizes, but when you try to unpack them you actually get 0 bytes. */ - mz_uint64 m_uncomp_size; - - /* Zip internal and external file attributes. */ - mz_uint16 m_internal_attr; - mz_uint32 m_external_attr; - - /* Entry's local header file offset in bytes. */ - mz_uint64 m_local_header_ofs; - - /* Size of comment in bytes. */ - mz_uint32 m_comment_size; - - /* MZ_TRUE if the entry appears to be a directory. */ - mz_bool m_is_directory; - - /* MZ_TRUE if the entry uses encryption/strong encryption (which miniz_zip doesn't support) */ - mz_bool m_is_encrypted; - - /* MZ_TRUE if the file is not encrypted, a patch file, and if it uses a compression method we support. */ - mz_bool m_is_supported; - - /* Filename. If string ends in '/' it's a subdirectory entry. */ - /* Guaranteed to be zero terminated, may be truncated to fit. */ - char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]; - - /* Comment field. */ - /* Guaranteed to be zero terminated, may be truncated to fit. */ - char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE]; - -} mz_zip_archive_file_stat; - -typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n); -typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n); -typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque); - -struct mz_zip_internal_state_tag; -typedef struct mz_zip_internal_state_tag mz_zip_internal_state; - -typedef enum -{ - MZ_ZIP_MODE_INVALID = 0, - MZ_ZIP_MODE_READING = 1, - MZ_ZIP_MODE_WRITING = 2, - MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 -} mz_zip_mode; - -typedef enum -{ - MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100, - MZ_ZIP_FLAG_IGNORE_PATH = 0x0200, - MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400, - MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800, - MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG = 0x1000, /* if enabled, mz_zip_reader_locate_file() will be called on each file as its validated to ensure the func finds the file in the central dir (intended for testing) */ - MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000, /* validate the local headers, but don't decompress the entire file and check the crc32 */ - MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* use the zip64 file format, instead of the original zip file format */ - MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000, - MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000 -} mz_zip_flags; - -typedef enum -{ - MZ_ZIP_TYPE_INVALID = 0, - MZ_ZIP_TYPE_USER, - MZ_ZIP_TYPE_MEMORY, - MZ_ZIP_TYPE_HEAP, - MZ_ZIP_TYPE_FILE, - MZ_ZIP_TYPE_CFILE, - MZ_ZIP_TOTAL_TYPES -} mz_zip_type; - -/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */ -typedef enum -{ - MZ_ZIP_NO_ERROR = 0, - MZ_ZIP_UNDEFINED_ERROR, - MZ_ZIP_TOO_MANY_FILES, - MZ_ZIP_FILE_TOO_LARGE, - MZ_ZIP_UNSUPPORTED_METHOD, - MZ_ZIP_UNSUPPORTED_ENCRYPTION, - MZ_ZIP_UNSUPPORTED_FEATURE, - MZ_ZIP_FAILED_FINDING_CENTRAL_DIR, - MZ_ZIP_NOT_AN_ARCHIVE, - MZ_ZIP_INVALID_HEADER_OR_CORRUPTED, - MZ_ZIP_UNSUPPORTED_MULTIDISK, - MZ_ZIP_DECOMPRESSION_FAILED, - MZ_ZIP_COMPRESSION_FAILED, - MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE, - MZ_ZIP_CRC_CHECK_FAILED, - MZ_ZIP_UNSUPPORTED_CDIR_SIZE, - MZ_ZIP_ALLOC_FAILED, - MZ_ZIP_FILE_OPEN_FAILED, - MZ_ZIP_FILE_CREATE_FAILED, - MZ_ZIP_FILE_WRITE_FAILED, - MZ_ZIP_FILE_READ_FAILED, - MZ_ZIP_FILE_CLOSE_FAILED, - MZ_ZIP_FILE_SEEK_FAILED, - MZ_ZIP_FILE_STAT_FAILED, - MZ_ZIP_INVALID_PARAMETER, - MZ_ZIP_INVALID_FILENAME, - MZ_ZIP_BUF_TOO_SMALL, - MZ_ZIP_INTERNAL_ERROR, - MZ_ZIP_FILE_NOT_FOUND, - MZ_ZIP_ARCHIVE_TOO_LARGE, - MZ_ZIP_VALIDATION_FAILED, - MZ_ZIP_WRITE_CALLBACK_FAILED, - MZ_ZIP_TOTAL_ERRORS -} mz_zip_error; - -typedef struct -{ - mz_uint64 m_archive_size; - mz_uint64 m_central_directory_file_ofs; - - /* We only support up to UINT32_MAX files in zip64 mode. */ - mz_uint32 m_total_files; - mz_zip_mode m_zip_mode; - mz_zip_type m_zip_type; - mz_zip_error m_last_error; - - mz_uint64 m_file_offset_alignment; - - mz_alloc_func m_pAlloc; - mz_free_func m_pFree; - mz_realloc_func m_pRealloc; - void *m_pAlloc_opaque; - - mz_file_read_func m_pRead; - mz_file_write_func m_pWrite; - mz_file_needs_keepalive m_pNeeds_keepalive; - void *m_pIO_opaque; - - mz_zip_internal_state *m_pState; - -} mz_zip_archive; - -/* -------- ZIP reading */ - -/* Inits a ZIP archive reader. */ -/* These functions read and validate the archive's central directory. */ -mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags); - -mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags); - -#ifndef MINIZ_NO_STDIO -/* Read a archive from a disk file. */ -/* file_start_ofs is the file offset where the archive actually begins, or 0. */ -/* actual_archive_size is the true total size of the archive, which may be smaller than the file's actual size on disk. If zero the entire file is treated as the archive. */ -mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags); -mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size); - -/* Read an archive from an already opened FILE, beginning at the current file position. */ -/* The archive is assumed to be archive_size bytes long. If archive_size is < 0, then the entire rest of the file is assumed to contain the archive. */ -/* The FILE will NOT be closed when mz_zip_reader_end() is called. */ -mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags); -#endif - -/* Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. */ -mz_bool mz_zip_reader_end(mz_zip_archive *pZip); - -/* -------- ZIP reading or writing */ - -/* Clears a mz_zip_archive struct to all zeros. */ -/* Important: This must be done before passing the struct to any mz_zip functions. */ -void mz_zip_zero_struct(mz_zip_archive *pZip); - -mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip); -mz_zip_type mz_zip_get_type(mz_zip_archive *pZip); - -/* Returns the total number of files in the archive. */ -mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip); - -mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip); -mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip); -MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip); - -/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. */ -size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n); - -/* Attempts to locates a file in the archive's central directory. */ -/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */ -/* Returns -1 if the file cannot be found. */ -int mz_zip_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); -/* Returns MZ_FALSE if the file cannot be found. */ -mz_bool mz_zip_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex); - -/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. These functions retrieve/manipulate this field. */ -/* Note that the m_last_error functionality is not thread safe. */ -mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num); -mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip); -mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip); -mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip); -const char *mz_zip_get_error_string(mz_zip_error mz_err); - -/* MZ_TRUE if the archive file entry is a directory entry. */ -mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index); - -/* MZ_TRUE if the file is encrypted/strong encrypted. */ -mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index); - -/* MZ_TRUE if the compression method is supported, and the file is not encrypted, and the file is not a compressed patch file. */ -mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index); - -/* Retrieves the filename of an archive file entry. */ -/* Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. */ -mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size); - -/* Attempts to locates a file in the archive's central directory. */ -/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */ -/* Returns -1 if the file cannot be found. */ -int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); -int mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *file_index); - -/* Returns detailed information about an archive file entry. */ -mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat); - -/* MZ_TRUE if the file is in zip64 format. */ -/* A file is considered zip64 if it contained a zip64 end of central directory marker, or if it contained any zip64 extended file information fields in the central directory. */ -mz_bool mz_zip_is_zip64(mz_zip_archive *pZip); - -/* Returns the total central directory size in bytes. */ -/* The current max supported size is <= MZ_UINT32_MAX. */ -size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip); - -/* Extracts a archive file to a memory buffer using no memory allocation. */ -/* There must be at least enough room on the stack to store the inflator's state (~34KB or so). */ -mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); -mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); - -/* Extracts a archive file to a memory buffer. */ -mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags); -mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags); - -/* Extracts a archive file to a dynamically allocated heap buffer. */ -/* The memory will be allocated via the mz_zip_archive's alloc/realloc functions. */ -/* Returns NULL and sets the last error on failure. */ -void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags); -void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags); - -/* Extracts a archive file using a callback function to output the file's data. */ -mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); -mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); - -#ifndef MINIZ_NO_STDIO -/* Extracts a archive file to a disk file and sets its last accessed and modified times. */ -/* This function only extracts files, not archive directory records. */ -mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags); -mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags); - -/* Extracts a archive file starting at the current position in the destination FILE stream. */ -mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *File, mz_uint flags); -mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags); -#endif - -#if 0 -/* */ - typedef void *mz_zip_streaming_extract_state_ptr; - mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); - uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs); - size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size); - mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); -#endif - -/* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */ -/* It also validates that each file can be successfully uncompressed unless the MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY is specified. */ -mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); - -/* Validates an entire archive by calling mz_zip_validate_file() on each file. */ -mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags); - -/* Misc utils/helpers, valid for ZIP reading or writing */ -mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr); -mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr); - -/* Universal end function - calls either mz_zip_reader_end() or mz_zip_writer_end(). */ -mz_bool mz_zip_end(mz_zip_archive *pZip); - -/* -------- ZIP writing */ - -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS - -/* Inits a ZIP archive writer. */ -mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size); -mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags); -mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size); -mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags); - -#ifndef MINIZ_NO_STDIO -mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning); -mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags); -mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags); -#endif - -/* Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. */ -/* For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called. */ -/* For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it). */ -/* Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. */ -/* Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before */ -/* the archive is finalized the file's central directory will be hosed. */ -mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename); -mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags); - -/* Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. */ -/* To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. */ -/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */ -mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags); - -/* Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. */ -/* uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. */ -mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, - mz_uint64 uncomp_size, mz_uint32 uncomp_crc32); - -mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, - mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, const char *user_extra_data_local, mz_uint user_extra_data_local_len, - const char *user_extra_data_central, mz_uint user_extra_data_central_len); - -#ifndef MINIZ_NO_STDIO -/* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */ -/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */ -mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); - -/* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */ -mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, - const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len, - const char *user_extra_data_central, mz_uint user_extra_data_central_len); -#endif - -/* Adds a file to an archive by fully cloning the data from another archive. */ -/* This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data (it may add or modify the zip64 local header extra data field), and the optional descriptor following the compressed data. */ -mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index); - -/* Finalizes the archive by writing the central directory records followed by the end of central directory record. */ -/* After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). */ -/* An archive must be manually finalized by calling this function for it to be valid. */ -mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip); - -/* Finalizes a heap archive, returning a poiner to the heap block and its size. */ -/* The heap block will be allocated using the mz_zip_archive's alloc/realloc callbacks. */ -mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize); - -/* Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. */ -/* Note for the archive to be valid, it *must* have been finalized before ending (this function will not do it for you). */ -mz_bool mz_zip_writer_end(mz_zip_archive *pZip); - -/* -------- Misc. high-level helper functions: */ - -/* mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive. */ -/* Note this is NOT a fully safe operation. If it crashes or dies in some way your archive can be left in a screwed up state (without a central directory). */ -/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */ -/* Perhaps add an option to leave the existing central dir in place in case the add dies? We could then truncate the file (so the old central dir would be at the end) if something goes wrong. */ -mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); -mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr); - -/* Reads a single file from an archive into a heap block. */ -/* If pComment is not NULL, only the file with the specified comment will be extracted. */ -/* Returns NULL on failure. */ -void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags); -void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr); - -#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */ - -#ifdef __cplusplus -} -#endif - -#endif /* MINIZ_NO_ARCHIVE_APIS */ diff --git a/navigation/paratext.cpp b/navigation/paratext.cpp deleted file mode 100644 index 273415492..000000000 --- a/navigation/paratext.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - -string navigation_paratext_url () -{ - return "navigation/paratext"; -} - - -string navigation_paratext (Webserver_Request& webserver_request) -{ - // Handle any reference received that was obtained from Paratext. - static string previous_from; - string from = webserver_request.query ["from"]; - // Reference should differ from the previous one. - if (!from.empty () && (from != previous_from)) { - previous_from = from; - Database_Logs::log("Paratext is at " + from); - // User should have set to receive references from Paratext. - if (webserver_request.database_config_user ()->getReceiveFocusedReferenceFromParatext ()) { - // Parse the reference from Paratext. - vector book_rest = filter::strings::explode (from, ' '); - if (book_rest.size() == 2) { - int book = static_cast(database::books::get_id_from_usfm (book_rest[0])); - vector chapter_verse = filter::strings::explode(book_rest[1], ':'); - if (chapter_verse.size() == 2) { - int chapter = filter::strings::convert_to_int(chapter_verse[0]); - int verse = filter::strings::convert_to_int(chapter_verse[1]); - // Set the user name on this client device. - string user = client_logic_get_username (); - webserver_request.session_logic()->set_username(user); - // "I believe how SantaFe works on Windows is - // that it always sends a standardised verse reference. - // So, for instance, a reference of Psalm 13:3 in the Hebrew Bible - // will instead send the standardised (KJV-like) Psalm 13:2." - // Assuming this to be the case for receiving a reference from Paratext, - // it means that the reference from Paratext - // may need to be mapped to the local versification system. - // Get the active Bible and its versification system. - string bible = webserver_request.database_config_user ()->getBible (); - string versification = Database_Config_Bible::getVersificationSystem (bible); - vector passages; - Database_Mappings database_mappings; - if ((versification != filter::strings::english()) && !versification.empty ()) { - passages = database_mappings.translate (filter::strings::english (), versification, book, chapter, verse); - } else { - passages.push_back (Passage ("", book, chapter, filter::strings::convert_to_string (verse))); - } - if (passages.empty()) return std::string(); - chapter = passages[0].m_chapter; - verse = filter::strings::convert_to_int (passages[0].m_verse); - // Set the focused passage for Bibledit. - Ipc_Focus::set (webserver_request, book, chapter, verse); - } - } - } - } - return ""; -} diff --git a/navigation/paratext.h b/navigation/paratext.h deleted file mode 100644 index 66918e84f..000000000 --- a/navigation/paratext.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright (©) 2003-2024 Teus Benschop. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - - -#pragma once - -#include - -class Webserver_Request; - -std::string navigation_paratext_url (); -std::string navigation_paratext (Webserver_Request& webserver_request); diff --git a/navigation/passage.cpp b/navigation/passage.cpp deleted file mode 100644 index 40984a71d..000000000 --- a/navigation/passage.cpp +++ /dev/null @@ -1,716 +0,0 @@ -/* - Copyright (©) 2003-2024 Teus Benschop. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsuggest-override" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef HAVE_PUGIXML -#include -#endif -#ifdef HAVE_PUGIXML -#include -#endif -#pragma GCC diagnostic pop -using namespace std; -using namespace pugi; - - -/* - On the iPad, Bibledit uses the UIWebView class as the web browser. - https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIWebView_Class/ - Bibledit used to have a verse navigator that used overlays for selecting book, chapter, and verse. - When selecting the verse, the UIWebView crashed with the following message: - UIPopoverPresentationController should have a non-nil sourceView or barButtonItem set before the presentation occurs. - This is a bug in the UIWebView. - To circumvent that bug, and also for better operation on the iPad with regard to touch operation, - Bibledit now uses a different verse navigator, one without the overlays. -*/ - - -string Navigation_Passage::get_mouse_navigator (Webserver_Request& webserver_request, string bible) -{ - Database_Navigation database_navigation; - - string user = webserver_request.session_logic()->currentUser (); - - bool passage_clipped = false; - - bool basic_mode = config::logic::basic_mode (webserver_request); - - xml_document document; - - // Links to go back and forward are available only when there's available history to go to. - // In basic mode they were not there initially. - // But later on it was decided to have them in basic mode too. - // See reasons here: https://github.com/bibledit/cloud/issues/641 - // Using the for detecting long press works well with the mouse. - // But on Android the long press brings up the context menu. - // It does not fire the long press event in Javascript. - // It was tried whether changing the to