pax_global_header00006660000000000000000000000064151616175510014522gustar00rootroot0000000000000052 comment=9d070de9194434adfb0203398223ff5d5113d791 xmlsec-1.3.10/000077500000000000000000000000001516161755100130775ustar00rootroot00000000000000xmlsec-1.3.10/.github/000077500000000000000000000000001516161755100144375ustar00rootroot00000000000000xmlsec-1.3.10/.github/workflows/000077500000000000000000000000001516161755100164745ustar00rootroot00000000000000xmlsec-1.3.10/.github/workflows/codeql.yml000066400000000000000000000111201516161755100204610ustar00rootroot00000000000000# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. # # ******** NOTE ******** # We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # name: "CodeQL Advanced" on: push: branches: [ "master" ] pull_request: branches: [ "master" ] schedule: - cron: '25 14 * * 2' jobs: analyze: name: Analyze (${{ matrix.language }}) # Runner size impacts CodeQL analysis time. To learn more, please see: # - https://gh.io/recommended-hardware-resources-for-running-codeql # - https://gh.io/supported-runners-and-hardware-resources # - https://gh.io/using-larger-runners (GitHub.com only) # Consider using larger runners or machines with greater resources for possible analysis time improvements. runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} permissions: # required for all workflows security-events: write # required to fetch internal or private CodeQL packs packages: read # only required for workflows in private repositories actions: read contents: read strategy: fail-fast: false matrix: include: - language: c-cpp build-mode: manual - language: javascript-typescript build-mode: none # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - name: install dependencies run: | sudo apt update sudo apt install automake autoconf libtool libtool-bin libltdl-dev libltdl7 sudo apt install libxml2 libxml2-dev libxslt1.1 libxslt1-dev sudo apt install libssl3 libssl-dev libnspr4 libnspr4-dev libnss3 libnss3-dev libnss3-tools libgcrypt20 libgcrypt20-dev libgnutls28-dev - name: Checkout repository uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality # If the analyze step fails for one of the languages you are analyzing with # "We were unable to automatically build your code", modify the matrix above # to set the build mode to "manual" for that language. Then modify this step # to build your code. # â„šī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - if: matrix.build-mode == 'manual' shell: bash run: | mkdir install.dir autoreconf -i -f ./configure --prefix=${GITHUB_WORKSPACE}/install.dir --enable-werror --enable-pedantic --enable-legacy-features --enable-ftp --enable-http make - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" xmlsec-1.3.10/.github/workflows/make-check.yml000066400000000000000000000323011516161755100212060ustar00rootroot00000000000000name: Make Check on: push: branches: - master - xmlsec-1_2_x pull_request: branches: - master - xmlsec-1_2_x jobs: # linux: check against latest versions of everything check-ubuntu: runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: # default build - config_flags: # default build with all legacy features - config_flags: --enable-legacy-features --enable-ftp --enable-http --enable-gcrypt # static openssl build - config_flags: --enable-static --enable-static-linking --disable-openssl3-engines --without-nss --without-gnutls --without-gcrypt --enable-legacy-features # static gnutls build with GOST - config_flags: --enable-static --enable-static-linking --without-openssl --without-nss --without-gcrypt --enable-gost --enable-gost2012 --enable-legacy-features steps: - name: install dependencies run: | sudo apt update sudo apt install automake autoconf libtool libtool-bin libltdl-dev libltdl7 sudo apt install libxml2 libxml2-dev libxslt1.1 libxslt1-dev sudo apt install libssl3 libssl-dev libnspr4 libnspr4-dev libnss3 libnss3-dev libnss3-tools libgcrypt20 libgcrypt20-dev libgnutls28-dev - uses: actions/checkout@v2 - name: create-build-dirs run: | mkdir build.dir install.dir - name: configure working-directory: build.dir run: | autoreconf -i -f .. ../configure --prefix=${GITHUB_WORKSPACE}/install.dir --enable-werror --enable-pedantic ${{ matrix.config_flags }} - name: make working-directory: build.dir run: | make - name: make check working-directory: build.dir run: | make check - name: make install working-directory: build.dir run: | make install - name: make examples working-directory: examples run: | export PATH=${GITHUB_WORKSPACE}/install.dir/bin:$PATH make # linux: docs + distcheck (separate from above to prevent running tests twice for all permutations) check-distcheck: runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: # default build - config_flags: steps: - name: install dependencies run: | sudo apt update sudo apt install automake autoconf libtool libtool-bin libltdl-dev libltdl7 sudo apt install libxml2 libxml2-dev libxslt1.1 libxslt1-dev sudo apt install libssl3 libssl-dev libnspr4 libnspr4-dev libnss3 libnss3-dev libnss3-tools libgcrypt20 libgcrypt20-dev libgnutls28-dev sudo apt install help2man man2html gtk-doc-tools - uses: actions/checkout@v2 - name: create-build-dirs run: | mkdir build.dir install.dir - name: configure working-directory: build.dir run: | autoreconf -i -f .. ../configure --prefix=${GITHUB_WORKSPACE}/install.dir --enable-werror --enable-pedantic ${{ matrix.config_flags }} - name: make working-directory: build.dir run: | make - name: make docs working-directory: build.dir run: | make -C docs docs - name: make distcheck working-directory: build.dir run: | make distcheck # linux: check AWS-LC check-ubuntu_aws_lc: runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: # default static build - config_flags: --enable-static --enable-static-linking env: AWS_LC_VERSION: "1.63.0" steps: - name: install dependencies run: | sudo apt update sudo apt install cmake ninja-build clang perl golang wget sudo apt install automake autoconf libtool libtool-bin libltdl-dev libltdl7 sudo apt install libxml2 libxml2-dev libxslt1.1 libxslt1-dev - name: build aws lc run: | mkdir ../aws-lc && cd ../aws-lc wget "https://github.com/aws/aws-lc/archive/refs/tags/v${{ env.AWS_LC_VERSION }}.zip" unzip "v${{ env.AWS_LC_VERSION }}.zip" mkdir build && cd build cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/../aws-lc/install ../aws-lc-${{ env.AWS_LC_VERSION }} ninja install - uses: actions/checkout@v2 - name: create-build-dirs run: | mkdir build.dir install.dir - name: configure working-directory: build.dir run: | autoreconf -i -f .. ../configure --prefix=${GITHUB_WORKSPACE}/install.dir ${{ matrix.config_flags }} \ --enable-werror --enable-pedantic \ --with-openssl=${GITHUB_WORKSPACE}/../aws-lc/install \ --without-gnutls --without-nss --without-gcrypt - name: make working-directory: build.dir run: | make - name: make check working-directory: build.dir run: | make check - name: make install working-directory: build.dir run: | make install # macosx check-osx: runs-on: macos-26 strategy: fail-fast: false matrix: include: # default build - config_flags: # default build with all legacy features -- not possible because MacOSX disables RIPEMD160 in OpenSSL # - config_flags: --enable-legacy-features --enable-ftp --enable-http steps: - name: Set up Homebrew id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master - name: install dependencies run: | pkg-config --modversion libxml-2.0 pkg-config --modversion libxslt HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install autoconf HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install automake HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install pkg-config libtool HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install libxml2 libxslt HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install openssl nspr nss gnutls libgcrypt - uses: actions/checkout@v2 - name: create-build-dirs run: | mkdir build.dir install.dir - name: configure working-directory: build.dir # NSS build is disabled because of header errors, try to re-enable in 2026 to see if it is fixed # --with-nspr=`brew --prefix nspr` \ # --with-nss=`brew --prefix nss` \ run: | autoreconf -i -f .. ../configure --prefix=${GITHUB_WORKSPACE}/install.dir --enable-werror --enable-pedantic \ --with-openssl=`brew --prefix openssl` \ --without-nss \ --with-gnutls=`brew --prefix gnutls` \ --with-gcrypt=`brew --prefix libgcrypt` \ ${{ matrix.config_flags }} - name: make working-directory: build.dir run: | make - name: make check working-directory: build.dir run: | export PATH=`brew --prefix openssl`/bin:$PATH export LD_LIBRARY_PATH=`brew --prefix openssl`/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=`brew --prefix nspr`/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=`brew --prefix nss`/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=`brew --prefix libgcrypt`/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=`brew --prefix gnutls`/lib:$LD_LIBRARY_PATH make check - name: make install working-directory: build.dir run: | make install - name: make examples working-directory: examples run: | export PATH=${GITHUB_WORKSPACE}/install.dir/bin:$PATH make # mingw check-mingw: runs-on: windows-latest strategy: fail-fast: false matrix: include: # default build - msystem: MINGW64 arch: x86_64 config_flags: --without-openssl --without-nss --without-gnutls --without-gcrypt --with-mscng --with-mscrypto # no unicode static build for mscng - msystem: MINGW64 arch: x86_64 config_flags: --enable-static --enable-static-linking --enable-unicode=no --without-openssl --without-nss --without-gnutls --without-gcrypt --without-mscrypto defaults: run: shell: msys2 {0} steps: - uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} release: false update: false install: >- autoconf automake base-devel git libtool mingw-w64-${{ matrix.arch }}-toolchain mingw-w64-${{ matrix.arch }}-libxml2 mingw-w64-${{ matrix.arch }}-libxslt mingw-w64-${{ matrix.arch }}-libltdl mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-libgcrypt mingw-w64-${{ matrix.arch }}-gnutls - name: configure-git run: | git config --global core.autocrlf input shell: bash - uses: actions/checkout@v2 - name: create-dirs run: | mkdir build.dir install.dir shell: bash - name: configure working-directory: build.dir run: | autoreconf -i -f .. ../configure --prefix=`cygpath -u "${GITHUB_WORKSPACE}/install.dir"` --enable-werror --enable-pedantic \ --enable-mscrypto --enable-mscng ${{ matrix.config_flags }} \ --build="${{ matrix.arch }}-w64-mingw32" \ --host="${{ matrix.arch }}-w64-mingw32" - name: make working-directory: build.dir run: | make - name: make check working-directory: build.dir run: | make check - name: make install working-directory: build.dir run: | make install - name: make examples working-directory: examples run: | export PATH=${GITHUB_WORKSPACE}/install.dir/bin:$PATH make # msvc check-msvc: runs-on: windows-latest strategy: fail-fast: false matrix: include: # mscng: default build - crypto: mscng config_flags: unicode=yes # mscng: no unicode, legacy crypto - crypto: mscng config_flags: unicode=no legacy-features=yes # mscrypto: default build - crypto: mscrypto config_flags: unicode=yes # mscrypto: no unicode, legacy crypto - crypto: mscrypto config_flags: unicode=no legacy-features=yes # mscng: default build - crypto: openssl-300 config_flags: unicode=yes # mscng: no unicode, legacy crypto - crypto: openssl-300 config_flags: unicode=no env: VISUAL_STUDIO_ROOT: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise" INSTALL_FOLDER: c:\install.dir LIBS_VERSION: 1.3.9 steps: - name: create-dirs run: | mkdir ${{ env.INSTALL_FOLDER }} - name: install dependencies shell: pwsh working-directory: ${{ env.INSTALL_FOLDER }} env: LIBS_URL: "https://github.com/lsh123/xmlsec/releases/download/${{ env.LIBS_VERSION }}/xmlsec1-${{ env.LIBS_VERSION }}-win64.zip" LIBS_FILE: "xmlsec1-${{ env.LIBS_VERSION }}-win64.zip" run: | Invoke-WebRequest ${{ env.LIBS_URL }} -OutFile ${{ env.LIBS_FILE }} Expand-Archive -Path ${{ env.LIBS_FILE }} -DestinationPath "." - name: configure-git shell: bash run: | git config --global core.autocrlf input - uses: actions/checkout@v2 - name: configure working-directory: win32 shell: cmd run: | call "${{ env.VISUAL_STUDIO_ROOT }}\VC\Auxiliary\Build\vcvars64.bat" cscript configure.js pedantic=yes memcheck=leaks static=no ^ crypto=${{ matrix.crypto }} ${{ matrix.config_flags }} ^ prefix=${{ env.INSTALL_FOLDER }}\xmlsec.build ^ include=${{ env.INSTALL_FOLDER }}\libxml2\include;${{ env.INSTALL_FOLDER }}\libxml2\include\libxml2;${{ env.INSTALL_FOLDER }}\libxslt\include;${{ env.INSTALL_FOLDER }}\openssl\include;%MSSDK_INCLUDE% ^ lib=${{ env.INSTALL_FOLDER }}\libxml2\lib;${{ env.INSTALL_FOLDER }}\libxslt\lib;${{ env.INSTALL_FOLDER }}\openssl\lib;%MSSDK_LIB% - name: make working-directory: win32 shell: cmd run: | call "${{ env.VISUAL_STUDIO_ROOT }}\VC\Auxiliary\Build\vcvars64.bat" set PATH=${{ env.INSTALL_FOLDER }}\libxml2\bin;${{ env.INSTALL_FOLDER }}\libxslt\bin;${{ env.INSTALL_FOLDER }}\openssl\bin;%PATH% nmake - name: make check working-directory: win32 shell: cmd run: | call "${{ env.VISUAL_STUDIO_ROOT }}\VC\Auxiliary\Build\vcvars64.bat" set PATH=${{ env.INSTALL_FOLDER }}\libxml2\bin;${{ env.INSTALL_FOLDER }}\libxslt\bin;${{ env.INSTALL_FOLDER }}\openssl\bin;%PATH% set OPENSSL_MODULES=${{ env.INSTALL_FOLDER }}\lib\ossl-modules nmake check - name: make install working-directory: win32 shell: cmd run: | call "${{ env.VISUAL_STUDIO_ROOT }}\VC\Auxiliary\Build\vcvars64.bat" nmake install xmlsec-1.3.10/.gitignore000066400000000000000000000021761516161755100150750ustar00rootroot00000000000000*~ *.orig .deps/ .libs/ .cproject .project compile clean depcomp install-sh missing *.o *.lo *.la .settings/ m4/ apps/xmlsec1 autom4te.cache/ config.guess config.sub aclocal.m4 config.h config.h.in config.log config.status configure ltmain.sh stamp-h1 xmlsec1-config xmlsec1-gcrypt.pc xmlsec1-gnutls.pc xmlsec1-nss.pc xmlsec1-openssl.pc xmlsec1.pc xmlsec1.spec xmlsec1Conf.sh Makefile.in Makefile apps/Makefile docs/Makefile docs/api/Makefile include/Makefile include/xmlsec/Makefile include/xmlsec/gcrypt/Makefile include/xmlsec/gnutls/Makefile include/xmlsec/nss/Makefile include/xmlsec/openssl/Makefile include/xmlsec/private/Makefile include/xmlsec/version.h libtool man/Makefile src/Makefile src/gcrypt/Makefile src/gnutls/Makefile src/nss/Makefile src/openssl/Makefile win32/apps_a.int/ win32/apps.int/ win32/binaries/ win32/configure.txt win32/libxmlsec.int/ win32/libxmlsec_a.int/ win32/libxmlsec_mscng.int/ win32/libxmlsec_mscrypto.int/ win32/libxmlsec_mscrypto_a.int/ win32/tmp win32/vc140.pdb docs/api/code docs/api/sgml.tmp docs/api/xmlsec-*.txt docs/api/*.bak docs/api/*.types docs/api/sgml.stamp docs/html.stamp .vscode/ .vs/ build-*/* xmlsec-1.3.10/AUTHORS000066400000000000000000000006531516161755100141530ustar00rootroot00000000000000Aleksey Sanin Windows port: Igor Zlatkovic Debian port: John Belmonte xmlsec-nss: Tej Arora , AOL Inc. xmlsec-mscrypto: Wouter Ketting , Cordys R&D BV xmlsec-mscng: Miklos Vajna GOST support: Dmitry Belyavsky , Cryptocom LTD (http://www.cryptocom.ru) xmlsec-1.3.10/COPYING000066400000000000000000000000671516161755100141350ustar00rootroot00000000000000See Copyright file for information about the copyright xmlsec-1.3.10/ChangeLog000066400000000000000000000003061516161755100146500ustar00rootroot00000000000000The changelog file is obsolete, please view the commits log on github: https://github.com/lsh123/xmlsec/commits/master Or News section on XMLSec website: https://www.aleksey.com/xmlsec/news.html xmlsec-1.3.10/Copyright000066400000000000000000000150261516161755100147760ustar00rootroot00000000000000xmlsec, xmlsec-openssl, xmlsec-gnutls, xmlsec-gcrypt libraries ------------------------------------------------------------------------------ Copyright (C) 2002-2024 Aleksey Sanin . 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 fur- nished 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, FIT- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ALEKSEY SANIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Aleksey Sanin shall not be used in advertising or otherwise to promote the sale, use or other deal- ings in this Software without prior written authorization from him. xmlsec-nss library ------------------------------------------------------------------------------ Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. Copyright (c) 2003 America Online, Inc. 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 fur- nished 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. Portions of the Software were created using source code and/or APIs governed by the Mozilla Public License (MPL). The MPL is available at http://www.mozilla.org/MPL/MPL-1.1.html. The MPL permits such portions to be distributed with code not governed by MPL, as long as the requirements of MPL are fulfilled for such portions. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ALEKSEY SANIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Aleksey Sanin shall not be used in advertising or otherwise to promote the sale, use or other deal- ings in this Software without prior written authorization from him. xmlsec-mscrypto library ------------------------------------------------------------------------------ Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. Copyright (C) 2003 Cordys R&D BV, All rights reserved. Copyright (C) 2007 Roumen Petrov. Copyright (c) 2005-2006 Cryptocom LTD (http://www.cryptocom.ru). 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 fur- nished 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, FIT- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ALEKSEY SANIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Aleksey Sanin shall not be used in advertising or otherwise to promote the sale, use or other deal- ings in this Software without prior written authorization from him. xmlsec-mscng library ------------------------------------------------------------------------------ Copyright (C) 2018-2024 Aleksey Sanin. All Rights Reserved. Copyright (C) 2018 Miklos Vajna. 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 fur- nished 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, FIT- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ALEKSEY SANIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Aleksey Sanin shall not be used in advertising or otherwise to promote the sale, use or other deal- ings in this Software without prior written authorization from him. References ------------------------------------------------------------------------------ * AOL http://www.aleksey.com/pipermail/xmlsec/2003/005488.html http://www.aleksey.com/pipermail/xmlsec/attachments/20030729/0e25648e/attachment.htm * Cordys R&D BV http://www.aleksey.com/pipermail/xmlsec/2003/005581.html * Cryptocom LTD http://www.aleksey.com/pipermail/xmlsec/2006/007410.html xmlsec-1.3.10/HACKING000066400000000000000000000001731516161755100140670ustar00rootroot00000000000000If you are interesting in contributing to XMLSec, then consider sending a PR on github: https://github.com/lsh123/xmlsec xmlsec-1.3.10/INSTALL000066400000000000000000000000171516161755100141260ustar00rootroot00000000000000See README.md xmlsec-1.3.10/MAINTAINERS000066400000000000000000000003031516161755100145700ustar00rootroot00000000000000Aleksey Sanin Source code: https://github.com/lsh123/xmlsec/ Bugs: https://github.com/lsh123/xmlsec/issues Announcements, etc: https://github.com/lsh123/xmlsec/discussions xmlsec-1.3.10/Makefile.am000066400000000000000000000121321516161755100151320ustar00rootroot00000000000000NULL = SAFE_VERSION = @XMLSEC_VERSION_SAFE@ SUBDIRS = include src if XMLSEC_APPS SUBDIRS += apps endif if XMLSEC_MANS SUBDIRS += man endif if XMLSEC_DOCS SUBDIRS += docs endif TEST_APP = apps/xmlsec1$(EXEEXT) UNIT_TEST_APP = apps/xmlsec_unit_tests$(EXEEXT) DEFAULT_CRYPTO = @XMLSEC_DEFAULT_CRYPTO@ bin_SCRIPTS = xmlsec1-config pkgconfig_DATA = xmlsec1.pc @XMLSEC_CRYPTO_PC_FILES_LIST@ pkgconfigdir = $(libdir)/pkgconfig confexecdir = $(libdir) confexec_DATA = xmlsec1Conf.sh m4datadir = $(datadir)/aclocal m4data_DATA = xmlsec1.m4 ACLOCAL_AMFLAGS = -I m4 DISTCLEANFILES = \ xmlsec1Conf.sh \ xmlsec1.pc \ xmlsec1-openssl.pc \ xmlsec1-nss.pc \ xmlsec1-gnutls.pc \ xmlsec1-gcrypt.pc \ xmlsec1-config \ xmlsec1.spec \ stamp-h2 \ stamp-h3 \ stamp-h4 \ stamp-h5 \ $NULL EXTRA_DIST = \ m4 \ examples \ scripts \ tests \ win32 \ NEWS \ ChangeLog \ Copyright \ HACKING \ README.md \ xmlsec-openssl.pc.in \ xmlsec-nss.pc.in\ xmlsec-gnutls.pc.in \ xmlsec-gcrypt.pc.in \ xmlsec-config.in \ xmlsecConf.sh.in \ xmlsec.spec.in \ xmlsec1Conf.sh \ xmlsec1.pc @XMLSEC_CRYPTO_PC_FILES_LIST@ \ xmlsec1-config \ xmlsec1.spec \ xmlsec1.m4 \ $(NULL) EXTRA_CLEAN = \ examples \ $(NULL) ABS_SRCDIR=@abs_srcdir@ ABS_BUILDDIR=@abs_builddir@ XMLSEC_OPENSSL_TEST_CONFIG=@OPENSSL_TEST_CONFIG@ XMLSEC_OPENSSL_VERSION=@OPENSSL_VERSION@ if XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING PRECHECK_COMMANDS = \ export XMLSEC_OPENSSL_TEST_CONFIG="$(XMLSEC_OPENSSL_TEST_CONFIG)" && \ export XMLSEC_OPENSSL_VERSION="$(XMLSEC_OPENSSL_VERSION)" && \ cd $(ABS_SRCDIR) \ $(NULL) else PRECHECK_COMMANDS= \ export XMLSEC_OPENSSL_TEST_CONFIG="$(XMLSEC_OPENSSL_TEST_CONFIG)" && \ export XMLSEC_OPENSSL_VERSION="$(XMLSEC_OPENSSL_VERSION)" && \ export LD_LIBRARY_PATH="$(ABS_BUILDDIR)/src/.libs:$$LD_LIBRARY_PATH" && \ for i in $(XMLSEC_CHECK_CRYPTO_LIST) ; do \ export LTDL_LIBRARY_PATH="$(ABS_BUILDDIR)/src/$$i/.libs:$$LTDL_LIBRARY_PATH" ; \ done && \ cd $(ABS_SRCDIR) \ $(NULL) endif CHECK_CRYPTO_LIST = \ $(XMLSEC_CHECK_CRYPTO_LIST) \ $(NULL) docs-man: @(cd man && $(MAKE) docs) check: check-all check-info check-unit-tests: $(UNIT_TEST_APP) @($(PRECHECK_COMMANDS) && $(ABS_BUILDDIR)/$(UNIT_TEST_APP)) check-all: $(TEST_APP) check-unit-tests for crypto in $(CHECK_CRYPTO_LIST) ; do \ make check-crypto-$$crypto || exit 1 ; \ done check-crypto-%: $(TEST_APP) @($(PRECHECK_COMMANDS) && \ echo "=================== Checking xmlsec-$* =================================" && \ $(SHELL) ./tests/testrun.sh \ $(ABS_SRCDIR)/tests/testKeys.sh \ $* \ $(ABS_SRCDIR)/tests \ $(ABS_BUILDDIR)/$(TEST_APP) der \ && \ $(SHELL) ./tests/testrun.sh \ $(ABS_SRCDIR)/tests/testDSig.sh \ $* \ $(ABS_SRCDIR)/tests \ $(ABS_BUILDDIR)/$(TEST_APP) \ der \ && \ $(SHELL) ./tests/testrun.sh \ $(ABS_SRCDIR)/tests/testEnc.sh \ $* \ $(ABS_SRCDIR)/tests \ $(ABS_BUILDDIR)/$(TEST_APP) \ der \ ; \ ) check-info: @echo "---------------------------- ATTENTION -----------------------------------" @echo "--- Some tests use resources hosted on external HTTP servers. ---" @echo "--- If you lack an Internet connection or an external resource is ---" @echo "--- unavailable, the test will fail. ---" @echo "---------------------------- ATTENTION -----------------------------------" check-keys: $(TEST_APP) @($(PRECHECK_COMMANDS) && \ $(SHELL) ./tests/testrun.sh \ $(ABS_SRCDIR)/tests/testKeys.sh \ $(DEFAULT_CRYPTO) \ $(ABS_SRCDIR)/tests \ $(ABS_BUILDDIR)/$(TEST_APP) \ der \ ) check-dsig: $(TEST_APP) @($(PRECHECK_COMMANDS) && \ $(SHELL) ./tests/testrun.sh \ $(ABS_SRCDIR)/tests/testDSig.sh \ $(DEFAULT_CRYPTO) \ $(ABS_SRCDIR)/tests \ $(ABS_BUILDDIR)/$(TEST_APP) \ der \ ) check-enc: $(TEST_APP) @($(PRECHECK_COMMANDS) && \ $(SHELL) ./tests/testrun.sh \ $(ABS_SRCDIR)/tests/testEnc.sh \ $(DEFAULT_CRYPTO) \ $(ABS_SRCDIR)/tests \ $(ABS_BUILDDIR)/$(TEST_APP) \ der \ ) memcheck-res: @$(GREP) -i 'ERROR SUMMARY' /tmp/xmlsec-test*/*.log | $(SED) 's/.*==.*== *//' | $(SORT) -u @$(GREP) -i 'in use at exit' /tmp/xmlsec-test*/*.log | $(SED) 's/.*==.*== *//' | $(SORT) -u @$(GREP) -i 'definitely lost:' /tmp/xmlsec-test*/*.log | $(SED) 's/.*==.*== *//' | $(SORT) -u @$(GREP) -i 'indirectly lost:' /tmp/xmlsec-test*/*.log | $(SED) 's/.*==.*== *//' | $(SORT) -u @$(GREP) -i 'possibly lost:' /tmp/xmlsec-test*/*.log | $(SED) 's/.*==.*== *//' | $(SORT) -u @$(GREP) -i 'still reachable:' /tmp/xmlsec-test*/*.log | $(SED) 's/.*==.*== *//' | $(SORT) -u @$(GREP) -i 'used_suppression:' /tmp/xmlsec-test*/*.log | $(SED) 's/.*--.*-- *//' | $(SORT) -u memcheck: $(TEST_APP) @(export DEBUG_MEMORY=1 && $(MAKE) check && $(MAKE) memcheck-res) memcheck-crypto-%: $(TEST_APP) @(export DEBUG_MEMORY=1 && $(MAKE) check-crypto-$* && $(MAKE) memcheck-res) perfcheck: $(TEST_APP) @(export PERF_TEST=10 && $(MAKE) check) dist-hook: cleantar: @($(RM) -f xmlsec*.tar.gz COPYING.LIB) tar-release: clean cleantar @(unset CDPATH && $(MAKE) dist) rpm: cleantar tar-release @(unset CDPATH && rpmbuild -ta $(distdir).tar.gz) rpm-release: clean cleantar rpm xmlsec-1.3.10/NEWS000066400000000000000000000000551516161755100135760ustar00rootroot00000000000000See https://www.aleksey.com/xmlsec/news.html xmlsec-1.3.10/README.md000066400000000000000000000057601516161755100143660ustar00rootroot00000000000000# XMLSec Library XMLSec library provides C based implementation for major XML Security standards: - [XML Signature Syntax and Processing](https://www.w3.org/TR/xmldsig-core) - [XML Encryption Syntax and Processing](https://www.w3.org/TR/xmlenc-core/) Detailed information about supported features and algorithms can be found in the [XMLDsig](https://www.aleksey.com/xmlsec/xmldsig.html) and the [XMLEnc](https://www.aleksey.com/xmlsec/xmlenc.html) interoperability reports. ## Documentation Complete XMLSec library documentation is published on [XMLSec website](https://www.aleksey.com/xmlsec/). ## License XMLSec library is released under the MIT Licence (see the [Copyright file](Copyright)). ## Building and installing XMLSec ### Prerequisites XMLSec requires the following libraries: - [LibXML2](http://xmlsoft.org) >= 2.9.13 - [LibXSLT](http://xmlsoft.org/XSLT/) >= 1.1.35 (optional) And at least one of the following cryptographic libraries: - [OpenSSL](http://www.openssl.org) >= 3.0.13 (>= 3.5.0 is recommended) - [LibreSSL](https://www.libressl.org/) >= 3.9.0 - [BoringSSL](https://boringssl.googlesource.com/boringssl/) >= 1.1.0 - [NSS](https://firefox-source-docs.mozilla.org/security/nss/index.html) >= 3.91 (with [NSPR](https://firefox-source-docs.mozilla.org/nspr/index.html) >= 4.34.1) - [GnuTLS](https://www.gnutls.org/) >= 3.8.3 - [Microsoft Cryptography API: Next Generation (CNG)](https://learn.microsoft.com/en-us/windows/win32/seccng/cng-portal) - (Deprecated) [Microsoft Cryptography API](https://learn.microsoft.com/en-us/windows/win32/seccrypto/cryptography-portal) - (Deprecated) [GCrypt](https://www.gnupg.org/software/libgcrypt/index.html) For example, the following packages need to be installed on Ubuntu to build XMLSec library: ``` # common build tools apt install automake autoconf libtool libtool-bin gcc # ltdl is required to support dynamic crypto libs loading apt install libltdl7 libltdl-dev # core libxml2 and libxslt libraries apt install libxml2 libxml2-dev libxslt1.1 libxslt1-dev # openssl libraries apt install openssl libssl3 libssl-dev # nspr/nss libraries apt install libnspr4 libnspr4-dev libnss3 libnss3-dev libnss3-tools # gnutls libraries apt install libgnutls30 # gnutls libraries apt install libgcrypt20 libgcrypt20-dev # required for building man pages and docs apt install help2man man2html gtk-doc-tools ``` ### Building XMLSec on Linux, Unix, MacOSX, MinGW, Cygwin, etc To build and install XMLSec library on Unix-like systems from a release tarball, run the following commands: ``` gunzip -c xmlsec1-.tar.gz | tar xvf - cd xmlsec1- ./configure [possible configure options] make make check make install ``` To see the configuration options, run: ``` ./configure --help ``` To build from GitHub, run the following commands: ``` git clone https://github.com/lsh123/xmlsec.git cd xmlsec autoreconf -i -f ./configure [possible configure options] make make check make install ``` ### Building XMLSec on Windows See [win32/README.md](win32/README.md) for details. xmlsec-1.3.10/SECURITY.md000066400000000000000000000037271516161755100147010ustar00rootroot00000000000000# Security Policy ## Supported Versions The XMLSec library WILL provide security updates / fixes for the released versions for 5 years since [the day of the release](https://www.aleksey.com/xmlsec/news.html). After 5 years, the support MIGHT be provided on case-by-case basis. ### 1.3.x (master) | Component/Version | Version | Release date | Full Support | Security Support | | ------------------|-----------| -------------------|-----------------------|---------------------| | xmlsec-core | >= 1.3.0 | April 12, 2023 | :white_check_mark: | :white_check_mark: | | xmlsec-openssl | >= 1.3.0 | April 12, 2023 | :white_check_mark: | :white_check_mark: | | xmlsec-nss | >= 1.3.0 | April 12, 2023 | :white_check_mark: | :white_check_mark: | | xmlsec-gnutls | >= 1.3.0 | April 12, 2023 | :white_check_mark: | :white_check_mark: | | xmlsec-mscng | >= 1.3.0 | April 12, 2023 | :white_check_mark: | :white_check_mark: | | xmlsec-gcrypt | >= 1.3.0 | April 12, 2023 | :x: | :white_check_mark: | | xmlsec-mscrypto | >= 1.3.0 | April 12, 2023 | :x: | :white_check_mark: | ### 1.2.x (mainanance mode from April 2023, planned End-Of-Life in April 2028) | Component/Version | Version | Release date | Full Support | Security Support | | ------------------|-----------| -------------------|-----------------------|---------------------| | all | >= 1.2.38 | July 5, 2023 | :x: | :white_check_mark: | | all | < 1.2.38 | October 15, 2019 | :x: | :x: | ## Reporting a Vulnerability Please use [GitHub private vulnerability reporting tool](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability) to report any security issues or vulnerabilities. xmlsec-1.3.10/TODO000066400000000000000000000000541516161755100135660ustar00rootroot00000000000000See https://github.com/lsh123/xmlsec/issues xmlsec-1.3.10/apps/000077500000000000000000000000001516161755100140425ustar00rootroot00000000000000xmlsec-1.3.10/apps/Makefile.am000066400000000000000000000036221516161755100161010ustar00rootroot00000000000000NULL = bin_PROGRAMS = xmlsec1 noinst_PROGRAMS = xmlsec_unit_tests XMLSEC_LIBS = $(top_builddir)/src/libxmlsec1.la # check if we use dynamic loading for xmlsec-crypto or not if XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING CRYPTO_DEPS = \ $(top_builddir)/src/@XMLSEC_DEFAULT_CRYPTO@/lib$(XMLSEC_CRYPTO_LIB).la \ $(NULL) CRYPTO_INCLUDES = \ $(XMLSEC_CRYPTO_CFLAGS) \ $(NULL) CRYPTO_LD_FLAGS = \ $(NULL) CRYPTO_LD_ADD = \ $(XMLSEC_CRYPTO_LIBS) \ $(CRYPTO_DEPS) \ $(NULL) else CRYPTO_DEPS = \ $(NULL) CRYPTO_INCLUDES = \ -DXMLSEC_CRYPTO_DYNAMIC_LOADING=1 $(NULL) CRYPTO_LD_FLAGS = \ $(NULL) CRYPTO_LD_ADD = \ $(CRYPTO_DEPS) \ $(NULL) endif AM_CFLAGS = \ -DPACKAGE=\"@PACKAGE@\" \ -I../include \ -I$(top_srcdir)/include \ $(XMLSEC_DEFINES) \ $(XMLSEC_APP_DEFINES) \ $(CRYPTO_INCLUDES) \ $(LIBXSLT_CFLAGS) \ $(LIBXML_CFLAGS) \ $(LIBLTDL_CFLAGS) \ $(NULL) # xmlsec command line utility xmlsec1_SOURCES = \ xmlsec.c \ crypto.c crypto.h \ cmdline.c cmdline.h \ $(NULL) xmlsec1_LDFLAGS = \ @XMLSEC_STATIC_BINARIES@ \ @XMLSEC_EXTRA_LDFLAGS@ \ $(CRYPTO_LD_FLAGS) \ $(NULL) xmlsec1_LDADD = \ $(LIBXSLT_LIBS) \ $(LIBXML_LIBS) \ $(CRYPTO_LD_ADD) \ $(XMLSEC_LIBS) \ $(LIBLTDL_LIBS) \ $(NULL) xmlsec1_DEPENDENCIES = \ $(CRYPTO_DEPS) \ $(XMLSEC_LIBS) \ $(NULL) # xmlsec unit tests xmlsec_unit_tests_SOURCES = \ unit_tests/base64_unit_tests.c \ unit_tests/transform_helpers_unit_tests.c \ unit_tests/x509_unit_tests.c \ unit_tests/xmltree_unit_tests.c \ unit_tests/templates_unit_tests.c \ unit_tests/xmlsec_unit_tests.h \ unit_tests/xmlsec_unit_tests.c \ $(NULL) xmlsec_unit_tests_LDFLAGS = \ @XMLSEC_STATIC_BINARIES@ \ @XMLSEC_EXTRA_LDFLAGS@ \ $(CRYPTO_LD_FLAGS) \ $(NULL) xmlsec_unit_tests_LDADD = \ $(LIBXSLT_LIBS) \ $(LIBXML_LIBS) \ $(CRYPTO_LD_ADD) \ $(XMLSEC_LIBS) \ $(LIBLTDL_LIBS) \ $(NULL) xmlsec_unit_tests_DEPENDENCIES = \ $(CRYPTO_DEPS) \ $(XMLSEC_LIBS) \ $(NULL) xmlsec-1.3.10/apps/cmdline.c000066400000000000000000000330271516161755100156260ustar00rootroot00000000000000/** * * XMLSec library * * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf #endif #include #include #include #include #include #include #include "cmdline.h" static int xmlSecAppCmdLineMatchParam (const char* argvParam, const char* paramName, int canHaveNameString); static xmlSecAppCmdLineParamPtr xmlSecAppCmdLineParamsListFind (xmlSecAppCmdLineParamPtr* params, xmlSecAppCmdLineParamTopic topics, const char* name); static int xmlSecAppCmdLineParamRead (xmlSecAppCmdLineParamPtr param, const char** argv, int argc, int pos); static int xmlSecAppCmdLineTimeParamRead (const char* str, time_t* t, int is_gmt_time); #if defined(_MSC_VER) #define XMLSEC_SCANF sscanf_s #define XMLSEC_MKGMTIME _mkgmtime #else /* defined(_MSC_VER) */ #define XMLSEC_SCANF sscanf #define XMLSEC_MKGMTIME xmlSecAppGetGmtTime static time_t xmlSecAppGetGmtTime (struct tm* timeptr); #endif /* defined(_MSC_VER) */ int xmlSecAppCmdLineParamIsSet(xmlSecAppCmdLineParamPtr param) { return(((param != NULL) && (param->value != NULL)) ? 1 : 0); } const char* xmlSecAppCmdLineParamGetString(xmlSecAppCmdLineParamPtr param) { if(param->type != xmlSecAppCmdLineParamTypeString) { fprintf(stderr, "Error: parameter \"%s\" is not string.\n", param->fullName); return(NULL); } return((param->value != NULL) ? param->value->strValue : NULL); } const char* xmlSecAppCmdLineParamGetStringList(xmlSecAppCmdLineParamPtr param) { if(param->type != xmlSecAppCmdLineParamTypeStringList) { fprintf(stderr, "Error: parameter \"%s\" is not string list.\n", param->fullName); return(NULL); } return((param->value != NULL) ? param->value->strListValue : NULL); } int xmlSecAppCmdLineParamGetInt(xmlSecAppCmdLineParamPtr param, int def) { if(param->type != xmlSecAppCmdLineParamTypeNumber) { fprintf(stderr, "Error: parameter \"%s\" is not integer.\n", param->fullName); return(def); } return((param->value != NULL) ? param->value->intValue : def); } time_t xmlSecAppCmdLineParamGetTime(xmlSecAppCmdLineParamPtr param, time_t def) { if((param->type != xmlSecAppCmdLineParamTypeTime) && (param->type != xmlSecAppCmdLineParamTypeGmtTime)) { fprintf(stderr, "Error: parameter \"%s\" is not time.\n", param->fullName); return(def); } return((param->value != NULL) ? param->value->timeValue : def); } int xmlSecAppCmdLineParamsListParse(xmlSecAppCmdLineParamPtr* params, xmlSecAppCmdLineParamTopic topics, const char** argv, int argc, int pos) { xmlSecAppCmdLineParamPtr param; int ii; int ret; assert(params != NULL); assert(argv != NULL); while((pos < argc) && (argv[pos][0] == '-') && (strcmp(argv[pos], XMLSEC_STDOUT_FILENAME) != 0)) { param = xmlSecAppCmdLineParamsListFind(params, topics, argv[pos]); if(param == NULL) { fprintf(stderr, "Error: parameter \"%s\" is not supported or the requested\nfeature might have been disabled during compilation.\n", argv[pos]); return(-1); } ret = xmlSecAppCmdLineParamRead(param, argv, argc, pos); if(ret < pos) { fprintf(stderr, "Error: failed to parse parameter \"%s\".\n", argv[pos]); return(-1); } pos = ret + 1; } /* check that all parameters at the end are filenames */ for(ii = pos; (ii < argc); ++ii) { if((argv[ii][0] == '-') && (strcmp(argv[pos], XMLSEC_STDOUT_FILENAME) != 0)) { fprintf(stderr, "Error: filename is expected instead of parameter \"%s\".\n", argv[ii]); return(-1); } } /* done */ return(pos); } void xmlSecAppCmdLineParamsListClean(xmlSecAppCmdLineParamPtr* params) { xmlSecAppCmdLineValuePtr tmp; size_t i; assert(params != NULL); for(i = 0; params[i] != NULL; ++i) { while(params[i]->value != NULL) { tmp = params[i]->value; params[i]->value = params[i]->value->next; xmlSecAppCmdLineValueDestroy(tmp); } } } void xmlSecAppCmdLineParamsListPrint(xmlSecAppCmdLineParamPtr* params, xmlSecAppCmdLineParamTopic topics, FILE* output) { size_t i; assert(params != NULL); assert(output != NULL); for(i = 0; params[i] != NULL; ++i) { if(((params[i]->topics & topics) != 0) && (params[i]->help != NULL)) { fprintf(output, " %s\n", params[i]->help); } } } xmlSecAppCmdLineValuePtr xmlSecAppCmdLineValueCreate(xmlSecAppCmdLineParamPtr param, int pos) { xmlSecAppCmdLineValuePtr value; assert(param != NULL); value = (xmlSecAppCmdLineValuePtr) malloc(sizeof(xmlSecAppCmdLineValue)); if(value == NULL) { fprintf(stderr, "Error: malloc failed (" XMLSEC_SIZE_T_FMT " bytes).\n", sizeof(xmlSecAppCmdLineValue)); return(NULL); } memset(value, 0, sizeof(xmlSecAppCmdLineValue)); value->param = param; value->pos = pos; return(value); } void xmlSecAppCmdLineValueDestroy(xmlSecAppCmdLineValuePtr value) { assert(value != NULL); if(value->strListValue != NULL) { free((void*)value->strListValue); } free(value); } static int xmlSecAppCmdLineMatchParam(const char* argvParam, const char* paramName, int canHaveNameString) { assert(argvParam != NULL); assert(paramName != NULL); if(canHaveNameString != 0) { size_t len = strlen(paramName); if(strncmp(argvParam, paramName, len) != 0) { return(0); } if((argvParam[len] != '\0') && (argvParam[len] != ':')) { return(0); } return(1); } else if(strcmp(argvParam, paramName) == 0) { return(1); } return(0); } static xmlSecAppCmdLineParamPtr xmlSecAppCmdLineParamsListFind(xmlSecAppCmdLineParamPtr* params, xmlSecAppCmdLineParamTopic topics, const char* name) { size_t i; int canHaveNameString; assert(params != NULL); assert(name != NULL); for(i = 0; params[i] != NULL; ++i) { if((params[i]->topics & topics) == 0) { continue; } canHaveNameString = ((params[i]->flags & xmlSecAppCmdLineParamFlagParamNameValue) != 0) ? 1 : 0; if(params[i]->fullName != NULL) { if(xmlSecAppCmdLineMatchParam(name, params[i]->fullName, canHaveNameString) == 1) { return(params[i]); } } if(params[i]->shortName != NULL) { if(xmlSecAppCmdLineMatchParam(name, params[i]->shortName, canHaveNameString) == 1) { return(params[i]); } } } return(NULL); } static int xmlSecAppCmdLineParamRead(xmlSecAppCmdLineParamPtr param, const char** argv, int argc, int pos) { xmlSecAppCmdLineValuePtr value; xmlSecAppCmdLineValuePtr prev = NULL; char* buf; assert(param != NULL); assert(argv != NULL); assert(pos < argc); /* first find the previous value in the list */ if((param->flags & xmlSecAppCmdLineParamFlagMultipleValues) != 0) { prev = param->value; while((prev != NULL) && (prev->next != NULL)) { prev = prev->next; } } else if(param->value != NULL) { fprintf(stderr, "Error: only one parameter \"%s\" is allowed.\n", argv[pos]); return(-1); } /* create new value and add to the list */ value = xmlSecAppCmdLineValueCreate(param, pos); if(value == NULL) { fprintf(stderr, "Error: failed to create value for parameter \"%s\".\n", argv[pos]); return(-1); } if(prev != NULL) { assert(prev->next == NULL); prev->next = value; } else { param->value = value; } /* if we can have a string value after the name, parse it */ if((param->flags & xmlSecAppCmdLineParamFlagParamNameValue) != 0) { value->paramNameValue = strchr(argv[pos], ':'); if(value->paramNameValue != NULL) { ++value->paramNameValue; } } switch(param->type) { case xmlSecAppCmdLineParamTypeFlag: /* do nothing */ break; case xmlSecAppCmdLineParamTypeString: if(pos + 1 >= argc) { fprintf(stderr, "Error: string argument expected for parameter \"%s\".\n", argv[pos]); return(-1); } value->strValue = argv[++pos]; break; case xmlSecAppCmdLineParamTypeStringList: if(pos + 1 >= argc) { fprintf(stderr, "Error: string list argument expected for parameter \"%s\".\n", argv[pos]); return(-1); } value->strValue = argv[++pos]; buf = (char*)malloc(strlen(value->strValue) + 2); if(buf == NULL) { fprintf(stderr, "Error: failed to allocate memory (" XMLSEC_SIZE_T_FMT " bytes).\n", strlen(value->strValue) + 2); return(-1); } memset(buf, 0, strlen(value->strValue) + 2); memcpy(buf, value->strValue, strlen(value->strValue)); value->strListValue = buf; while((*buf) != '\0') { if((*buf) == ',') { (*buf) = '\0'; } ++buf; } break; case xmlSecAppCmdLineParamTypeNumber: if(pos + 1 >= argc) { fprintf(stderr, "Error: integer argument expected for parameter \"%s\".\n", argv[pos]); return(-1); } value->strValue = argv[++pos]; if(XMLSEC_SCANF(value->strValue, "%d", &(value->intValue)) != 1) { fprintf(stderr, "Error: integer argument \"%s\" is invalid.\n", value->strValue); return(-1); } break; case xmlSecAppCmdLineParamTypeTime: if(pos + 1 >= argc) { fprintf(stderr, "Error: time argument expected for parameter \"%s\".\n", argv[pos]); return(-1); } value->strValue = argv[++pos]; if(xmlSecAppCmdLineTimeParamRead(value->strValue, &(value->timeValue), 0) < 0) { fprintf(stderr, "Error: time argument \"%s\" is invalid, expected format is \"YYYY-MM-DD HH:MM:SS\").\n", value->strValue); return(-1); } break; case xmlSecAppCmdLineParamTypeGmtTime: if(pos + 1 >= argc) { fprintf(stderr, "Error: gmt time argument expected for parameter \"%s\".\n", argv[pos]); return(-1); } value->strValue = argv[++pos]; if(xmlSecAppCmdLineTimeParamRead(value->strValue, &(value->timeValue), 1) < 0) { fprintf(stderr, "Error: gmt time argument \"%s\" is invalid, expected format is \"YYYY-MM-DD HH:MM:SS\").\n", value->strValue); return(-1); } break; } return(pos); } #if !defined(_MSC_VER) static time_t xmlSecAppGetGmtTime(struct tm* timeptr) { time_t t1, t2; struct tm * tm1; if(timeptr == NULL) { return(0); } /* t1 is gmt time "mapped" to localtime as-is */ t1 = mktime(timeptr); if(t1 == -1) { fprintf(stderr, "Error: mktime(timeptr) failed"); return(0); } tm1 = gmtime(&t1); if(tm1 == NULL) { fprintf(stderr, "Error: gmtime() failed for time=%lld.\n", (long long)t1); return(0); } /* t2 is "mapped" gmt time converted to gmt */ t2 = mktime(tm1); if(t2 == -1) { fprintf(stderr, "Error: mktime(tm1) failed"); return(0); } /* shift t1 back by the (t2 - t1) delta */ return(t1 - (t2 - t1)); } #endif /* !defined(_MSC_VER) */ static int xmlSecAppCmdLineTimeParamRead(const char* str, time_t* t, int is_gmt_time) { struct tm tm; int n; if((str == NULL) || (t == NULL)) { return(-1); } memset(&tm, 0, sizeof(tm)); tm.tm_isdst = -1; n = XMLSEC_SCANF(str, "%4d-%2d-%2d%*c%2d:%2d:%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); if(n != 6) { return(-1); } if((tm.tm_year < 1900) || (tm.tm_mon < 1) || (tm.tm_mon > 12) || (tm.tm_mday < 1) || (tm.tm_mday > 31) || (tm.tm_hour < 0) || (tm.tm_hour > 23) || (tm.tm_min < 0) || (tm.tm_min > 59) || (tm.tm_sec < 0) || (tm.tm_sec > 61)) { return(-1); } tm.tm_year -= 1900; /* tm relative format year */ tm.tm_mon -= 1; /* tm relative format month */ if(is_gmt_time != 0) { (*t) = XMLSEC_MKGMTIME(&tm); } else { (*t) = mktime(&tm); } return(0); } xmlsec-1.3.10/apps/cmdline.h000066400000000000000000000070021516161755100156250ustar00rootroot00000000000000/** * XMLSec library * * Command line parsing routines * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #ifndef __XMLSEC_APPS_CMDLINE_H__ #define __XMLSEC_APPS_CMDLINE_H__ #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct _xmlSecAppCmdLineParam xmlSecAppCmdLineParam, *xmlSecAppCmdLineParamPtr; typedef struct _xmlSecAppCmdLineValue xmlSecAppCmdLineValue, *xmlSecAppCmdLineValuePtr; typedef unsigned int xmlSecAppCmdLineParamTopic; #define xmlSecAppCmdLineParamFlagNone 0x0000 #define xmlSecAppCmdLineParamFlagParamNameValue 0x0001 #define xmlSecAppCmdLineParamFlagMultipleValues 0x0002 #define XMLSEC_STDOUT_FILENAME "-" typedef enum { xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamTypeNumber, xmlSecAppCmdLineParamTypeTime, xmlSecAppCmdLineParamTypeGmtTime } xmlSecAppCmdLineParamType; struct _xmlSecAppCmdLineParam { xmlSecAppCmdLineParamTopic topics; const char* fullName; const char* shortName; const char* help; xmlSecAppCmdLineParamType type; int flags; xmlSecAppCmdLineValuePtr value; }; int xmlSecAppCmdLineParamIsSet (xmlSecAppCmdLineParamPtr param); const char* xmlSecAppCmdLineParamGetString (xmlSecAppCmdLineParamPtr param); const char* xmlSecAppCmdLineParamGetStringList (xmlSecAppCmdLineParamPtr param); int xmlSecAppCmdLineParamGetInt (xmlSecAppCmdLineParamPtr param, int def); time_t xmlSecAppCmdLineParamGetTime (xmlSecAppCmdLineParamPtr param, time_t def); int xmlSecAppCmdLineParamsListParse (xmlSecAppCmdLineParamPtr* params, xmlSecAppCmdLineParamTopic topics, const char** argv, int argc, int pos); void xmlSecAppCmdLineParamsListClean (xmlSecAppCmdLineParamPtr* params); void xmlSecAppCmdLineParamsListPrint (xmlSecAppCmdLineParamPtr* params, xmlSecAppCmdLineParamTopic topic, FILE* output); struct _xmlSecAppCmdLineValue { xmlSecAppCmdLineParamPtr param; int pos; const char* paramNameValue; const char* strValue; const char* strListValue; int intValue; time_t timeValue; xmlSecAppCmdLineValuePtr next; }; xmlSecAppCmdLineValuePtr xmlSecAppCmdLineValueCreate (xmlSecAppCmdLineParamPtr param, int pos); void xmlSecAppCmdLineValueDestroy (xmlSecAppCmdLineValuePtr value); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __XMLSEC_APPS_CMDLINE_H__ */ xmlsec-1.3.10/apps/crypto.c000066400000000000000000000343411516161755100155330ustar00rootroot00000000000000/** * * XMLSec library * * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf #endif #include #include #include #include #include #include #include "crypto.h" #ifndef UNREFERENCED_PARAMETER #define UNREFERENCED_PARAMETER(param) ((void)(param)) #endif /* UNREFERENCED_PARAMETER */ int xmlSecAppCryptoInit(const char* config) { if(xmlSecCryptoAppInit(config) < 0) { fprintf(stderr, "Error: xmlSecCryptoAppInit failed\n"); return(-1); } if(xmlSecCryptoInit() < 0) { fprintf(stderr, "Error: xmlSecCryptoInit failed\n"); return(-1); } return(0); } int xmlSecAppCryptoShutdown(void) { if(xmlSecCryptoShutdown() < 0) { fprintf(stderr, "Error: xmlSecCryptoShutdown failed\n"); return(-1); } if(xmlSecCryptoAppShutdown() < 0) { fprintf(stderr, "Error: xmlSecCryptoAppShutdown failed\n"); return(-1); } return(0); } int xmlSecAppCryptoSimpleKeysMngrInit(xmlSecKeysMngrPtr mngr) { xmlSecAssert2(mngr != NULL, -1); return(xmlSecCryptoAppDefaultKeysMngrInit(mngr)); } int xmlSecAppCryptoSimpleKeysMngrLoad(xmlSecKeysMngrPtr mngr, const char *filename) { xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); return(xmlSecCryptoAppDefaultKeysMngrLoad(mngr, filename)); } int xmlSecAppCryptoSimpleKeysMngrSave(xmlSecKeysMngrPtr mngr, const char *filename, xmlSecKeyDataType type) { xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); return(xmlSecCryptoAppDefaultKeysMngrSave(mngr, filename, type)); } int xmlSecAppCryptoSimpleKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename, xmlSecKeyDataFormat format, xmlSecKeyDataType type) { xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); #ifndef XMLSEC_NO_X509 return(xmlSecCryptoAppKeysMngrCertLoad(mngr, filename, format, type)); #else /* XMLSEC_NO_X509 */ UNREFERENCED_PARAMETER(format); UNREFERENCED_PARAMETER(type); fprintf(stderr, "Error: X509 support is disabled\n"); return(-1); #endif /* XMLSEC_NO_X509 */ } int xmlSecAppCryptoSimpleKeysMngrCrlLoad(xmlSecKeysMngrPtr mngr, const char *filename, xmlSecKeyDataFormat format) { xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); #ifndef XMLSEC_NO_X509 return(xmlSecCryptoAppKeysMngrCrlLoad(mngr, filename, format)); #else /* XMLSEC_NO_X509 */ UNREFERENCED_PARAMETER(format); fprintf(stderr, "Error: X509 support is disabled\n"); return(-1); #endif /* XMLSEC_NO_X509 */ } int xmlSecAppCryptoSimpleKeysMngrCrlLoadAndVerify(xmlSecKeysMngrPtr mngr, const char *filename, xmlSecKeyDataFormat format, xmlSecKeyInfoCtxPtr keyInfoCtx) { xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); #ifndef XMLSEC_NO_X509 return(xmlSecCryptoAppKeysMngrCrlLoadAndVerify(mngr, filename, format, keyInfoCtx)); #else /* XMLSEC_NO_X509 */ UNREFERENCED_PARAMETER(format); fprintf(stderr, "Error: X509 support is disabled\n"); return(-1); #endif /* XMLSEC_NO_X509 */ } int xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(xmlSecKeysMngrPtr mngr, const char* files, const char* pwd, const char* name, xmlSecKeyDataType type, xmlSecKeyDataFormat format, xmlSecKeyInfoCtxPtr keyInfoCtx, int verifyKey ) { const char* cert_file; xmlSecKeyPtr key; int ret; xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(files != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); /* first is the key file */ key = xmlSecCryptoAppKeyLoadEx(files, type, format, pwd, xmlSecCryptoAppGetDefaultPwdCallback(), (void*)files); if(key == NULL) { fprintf(stderr, "Error: xmlSecCryptoAppKeyLoadEx failed: file=%s\n", xmlSecErrorsSafeString(files)); return(-1); } if(name != NULL) { ret = xmlSecKeySetName(key, BAD_CAST name); if(ret < 0) { fprintf(stderr, "Error: xmlSecKeySetName failed: name=%s\n", xmlSecErrorsSafeString(name)); xmlSecKeyDestroy(key); return(-1); } } #ifndef XMLSEC_NO_X509 for(cert_file = files + strlen(files) + 1; (cert_file[0] != '\0'); cert_file += strlen(cert_file) + 1) { ret = xmlSecCryptoAppKeyCertLoad(key, cert_file, format); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppKeyCertLoad failed: file=%s\n", xmlSecErrorsSafeString(cert_file)); xmlSecKeyDestroy(key); return(-1); } } #else /* XMLSEC_NO_X509 */ cert_file = files + strlen(files) + 1; if(cert_file[0] != '\0') { fprintf(stderr, "Error: X509 support is disabled\n"); xmlSecKeyDestroy(key); return(-1); } #endif /* XMLSEC_NO_X509 */ if(verifyKey != 0) { ret = xmlSecCryptoAppDefaultKeysMngrVerifyKey(mngr, key, keyInfoCtx); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppDefaultKeysMngrVerifyKey failed: filename='%s'\n", xmlSecErrorsSafeString(files)); xmlSecKeyDestroy(key); return(-1); } else if(ret != 1) { fprintf(stderr, "Error: key cannot be verified: filename='%s'\n", xmlSecErrorsSafeString(files)); xmlSecKeyDestroy(key); return(-1); } } ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppDefaultKeysMngrAdoptKey failed\n"); xmlSecKeyDestroy(key); return(-1); } return(0); } int xmlSecAppCryptoSimpleKeysMngrEngineKeyAndCertsLoad(xmlSecKeysMngrPtr mngr, const char* engineAndKeyId, const char* certFiles, const char* pwd, const char* name, xmlSecKeyDataType type, xmlSecKeyDataFormat keyFormat, xmlSecKeyDataFormat certFormat, xmlSecKeyInfoCtxPtr keyInfoCtx, int verifyKey ) { xmlSecKeyPtr key; int ret; xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(engineAndKeyId != NULL, -1); xmlSecAssert2(certFiles != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); /* load key */ key = xmlSecCryptoAppKeyLoadEx(engineAndKeyId, type, keyFormat, pwd, xmlSecCryptoAppGetDefaultPwdCallback(), (void*)engineAndKeyId); if(key == NULL) { fprintf(stderr, "Error: xmlSecCryptoAppKeyLoadEx failed: engineAndKeyId=%s\n", xmlSecErrorsSafeString(engineAndKeyId)); return(-1); } if(name != NULL) { ret = xmlSecKeySetName(key, BAD_CAST name); if(ret < 0) { fprintf(stderr, "Error: xmlSecKeySetName failed: name=%s\n", xmlSecErrorsSafeString(name)); xmlSecKeyDestroy(key); return(-1); } } /* load certs (if any) */ #ifndef XMLSEC_NO_X509 for(const char *file = certFiles; (file[0] != '\0'); file += strlen(file) + 1) { ret = xmlSecCryptoAppKeyCertLoad(key, file, certFormat); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppKeyCertLoad failed: file=%s\n", xmlSecErrorsSafeString(file)); xmlSecKeyDestroy(key); return(-1); } } #else /* XMLSEC_NO_X509 */ UNREFERENCED_PARAMETER(certFormat); if(certFiles[0] != '\0') { fprintf(stderr, "Error: X509 support is disabled\n"); xmlSecKeyDestroy(key); return(-1); } #endif /* XMLSEC_NO_X509 */ if(verifyKey != 0) { ret = xmlSecCryptoAppDefaultKeysMngrVerifyKey(mngr, key, keyInfoCtx); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppDefaultKeysMngrVerifyKey failed: engineAndKeyId='%s'\n", xmlSecErrorsSafeString(engineAndKeyId)); xmlSecKeyDestroy(key); return(-1); } else if(ret != 1) { fprintf(stderr, "Error: key cannot be verified: engineAndKeyId='%s'\n", xmlSecErrorsSafeString(engineAndKeyId)); xmlSecKeyDestroy(key); return(-1); } } /* add key to KM */ ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppDefaultKeysMngrAdoptKey failed\n"); xmlSecKeyDestroy(key); return(-1); } return(0); } int xmlSecAppCryptoSimpleKeysMngrPkcs12KeyLoad(xmlSecKeysMngrPtr mngr, const char *filename, const char* pwd, const char *name, xmlSecKeyInfoCtxPtr keyInfoCtx, int verifyKey ) { #ifndef XMLSEC_NO_X509 xmlSecKeyPtr key; int ret; xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); key = xmlSecCryptoAppKeyLoadEx(filename, xmlSecKeyDataTypePrivate, xmlSecKeyDataFormatPkcs12, pwd, xmlSecCryptoAppGetDefaultPwdCallback(), (void*)filename); if(key == NULL) { fprintf(stderr, "Error: xmlSecCryptoAppKeyLoadEx failed: filename='%s'\n", xmlSecErrorsSafeString(filename)); return(-1); } if(name != NULL) { ret = xmlSecKeySetName(key, BAD_CAST name); if(ret < 0) { fprintf(stderr, "Error: xmlSecKeySetName failed: name='%s'\n", xmlSecErrorsSafeString(name)); xmlSecKeyDestroy(key); return(-1); } } if(verifyKey != 0) { ret = xmlSecCryptoAppDefaultKeysMngrVerifyKey(mngr, key, keyInfoCtx); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppDefaultKeysMngrVerifyKey failed: filename='%s'\n", xmlSecErrorsSafeString(filename)); xmlSecKeyDestroy(key); return(-1); } else if(ret != 1) { fprintf(stderr, "Error: key cannot be verified: filename='%s'\n", xmlSecErrorsSafeString(filename)); xmlSecKeyDestroy(key); return(-1); } } ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppDefaultKeysMngrAdoptKey failed\n"); xmlSecKeyDestroy(key); return(-1); } return(0); #else /* XMLSEC_NO_X509 */ xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); UNREFERENCED_PARAMETER(pwd); UNREFERENCED_PARAMETER(name); UNREFERENCED_PARAMETER(verifyKey); fprintf(stderr, "Error: X509 support is disabled\n"); return(-1); #endif /* XMLSEC_NO_X509 */ } int xmlSecAppCryptoSimpleKeysMngrBinaryKeyLoad(xmlSecKeysMngrPtr mngr, const char* keyKlass, const char *filename, const char *name) { xmlSecKeyPtr key; xmlSecKeyDataId dataId; int ret; xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(keyKlass != NULL, -1); xmlSecAssert2(filename != NULL, -1); /* find requested data */ dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), BAD_CAST keyKlass, xmlSecKeyDataUsageReadFromFile); if(dataId == xmlSecKeyDataIdUnknown) { fprintf(stderr, "Error: xmlSecKeyDataIdListFindByName failed keyKlass=%s\n", xmlSecErrorsSafeString(keyKlass)); return(-1); } key = xmlSecKeyReadBinaryFile(dataId, filename); if(key == NULL) { fprintf(stderr, "Error: xmlSecKeyReadBinaryFile failed filename=%s\n", xmlSecErrorsSafeString(filename)); return(-1); } ret = xmlSecKeySetName(key, BAD_CAST name); if(ret < 0) { fprintf(stderr, "Error: xmlSecKeySetName failed: name=%s\n", xmlSecErrorsSafeString(name)); xmlSecKeyDestroy(key); return(-1); } /* finally add it to keys manager */ ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppDefaultKeysMngrAdoptKey failed\n"); xmlSecKeyDestroy(key); return(-1); } return(0); } int xmlSecAppCryptoSimpleKeysMngrKeyGenerate(xmlSecKeysMngrPtr mngr, const char* keyKlassAndSize, const char* name) { xmlSecKeyPtr key; int ret; xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(keyKlassAndSize != NULL, -1); key = xmlSecAppCryptoKeyGenerate(keyKlassAndSize, name, xmlSecKeyDataTypePermanent); if(key == NULL) { fprintf(stderr, "Error: xmlSecAppCryptoSimpleKeysMngrKeyGenerate failed: name=%s\n", xmlSecErrorsSafeString(name)); return(-1); } ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); if(ret < 0) { fprintf(stderr, "Error: xmlSecCryptoAppDefaultKeysMngrAdoptKey failed\n"); xmlSecKeyDestroy(key); return(-1); } return(0); } xmlSecKeyPtr xmlSecAppCryptoKeyGenerate(const char* keyKlassAndSize, const char* name, xmlSecKeyDataType type) { xmlSecKeyPtr key; char* buf; char* p; int size; int ret; xmlSecAssert2(keyKlassAndSize != NULL, NULL); buf = (char*) xmlStrdup(BAD_CAST keyKlassAndSize); if(buf == NULL) { fprintf(stderr, "Error: xmlSecStrdupError(keyKlassAndSize) failed\n"); return(NULL); } /* separate key klass and size */ p = strchr(buf, '-'); if(p == NULL) { fprintf(stderr, "Error: key size is not specified in the key definition \"%s\"\n", xmlSecErrorsSafeString(buf)); xmlFree(buf); return(NULL); } *(p++) = '\0'; size = atoi(p); if(size <= 0) { fprintf(stderr, "Error: key size should be greater than zero \"%s\"\n", xmlSecErrorsSafeString(buf)); xmlFree(buf); return(NULL); } key = xmlSecKeyGenerateByName(BAD_CAST buf, (xmlSecSize)size, type); if(key == NULL) { fprintf(stderr, "Error: xmlSecKeyGenerateByName() failed: name=%s;size=%d;type=%u\n", xmlSecErrorsSafeString(buf), size, type); xmlFree(buf); return(NULL); } ret = xmlSecKeySetName(key, BAD_CAST name); if(ret < 0) { fprintf(stderr, "Error: xmlSecKeySetName failed: name=%s\n", xmlSecErrorsSafeString(name)); xmlSecKeyDestroy(key); xmlFree(buf); return(NULL); } xmlFree(buf); return(key); } xmlsec-1.3.10/apps/crypto.h000066400000000000000000000124451516161755100155410ustar00rootroot00000000000000/** * XMLSec library * * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #ifndef __XMLSEC_APPS_CRYPTO_H__ #define __XMLSEC_APPS_CRYPTO_H__ #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int xmlSecAppCryptoInit (const char* config); int xmlSecAppCryptoShutdown (void); xmlSecKeyPtr xmlSecAppCryptoKeyGenerate (const char* keyKlassAndSize, const char* name, xmlSecKeyDataType type); /***************************************************************************** * * Simple keys manager * ****************************************************************************/ int xmlSecAppCryptoSimpleKeysMngrInit (xmlSecKeysMngrPtr mngr); int xmlSecAppCryptoSimpleKeysMngrLoad (xmlSecKeysMngrPtr mngr, const char* filename); int xmlSecAppCryptoSimpleKeysMngrSave (xmlSecKeysMngrPtr mngr, const char* filename, xmlSecKeyDataType type); int xmlSecAppCryptoSimpleKeysMngrCertLoad (xmlSecKeysMngrPtr mngr, const char* filename, xmlSecKeyDataFormat format, xmlSecKeyDataType type); int xmlSecAppCryptoSimpleKeysMngrCrlLoad (xmlSecKeysMngrPtr mngr, const char* filename, xmlSecKeyDataFormat format); int xmlSecAppCryptoSimpleKeysMngrCrlLoadAndVerify (xmlSecKeysMngrPtr mngr, const char* filename, xmlSecKeyDataFormat format, xmlSecKeyInfoCtxPtr keyInfoCtx); int xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad (xmlSecKeysMngrPtr mngr, const char* files, const char* pwd, const char* name, xmlSecKeyDataType type, xmlSecKeyDataFormat format, xmlSecKeyInfoCtxPtr keyInfoCtx, int verifyKey); int xmlSecAppCryptoSimpleKeysMngrEngineKeyAndCertsLoad (xmlSecKeysMngrPtr mngr, const char* engineAndKeyId, const char* certFiles, const char* pwd, const char* name, xmlSecKeyDataType type, xmlSecKeyDataFormat keyFormat, xmlSecKeyDataFormat certFormat, xmlSecKeyInfoCtxPtr keyInfoCtx, int verifyKey); int xmlSecAppCryptoSimpleKeysMngrPkcs12KeyLoad (xmlSecKeysMngrPtr mngr, const char* filename, const char* pwd, const char* name, xmlSecKeyInfoCtxPtr keyInfoCtx, int verifyKey); int xmlSecAppCryptoSimpleKeysMngrBinaryKeyLoad (xmlSecKeysMngrPtr mngr, const char* keyKlass, const char* filename, const char* name); int xmlSecAppCryptoSimpleKeysMngrKeyGenerate (xmlSecKeysMngrPtr mngr, const char* keyKlassAndSize, const char* name); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __XMLSEC_APPS_CRYPTO_H__ */ xmlsec-1.3.10/apps/unit_tests/000077500000000000000000000000001516161755100162435ustar00rootroot00000000000000xmlsec-1.3.10/apps/unit_tests/base64_unit_tests.c000066400000000000000000000074151516161755100217630ustar00rootroot00000000000000/** * XML Security Library (http://www.aleksey.com/xmlsec). * * base64 util unit tests * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #include #include #include #include /* must be included before any other xmlsec header */ #include "xmlsec_unit_tests.h" #include /* XMLSEC_EXPORT xmlChar* xmlSecBase64Encode (const xmlSecByte* in, xmlSecSize inSize, int columns); XMLSEC_EXPORT int xmlSecBase64Decode_ex (const xmlChar* str, xmlSecByte* out, xmlSecSize outSize, xmlSecSize* outWritten); */ static void test_base64_success( const char * name, const char * str, int columns, const char * expected ) { xmlSecByte decoded[256]; xmlSecSize decodedSize = 0; xmlChar * encoded; int ret; xmlSecAssert(name != NULL); xmlSecAssert(str != NULL); testStart(name); ret = xmlSecBase64Decode_ex(BAD_CAST str, decoded, sizeof(decoded), &decodedSize); if(ret < 0) { testLog("Error: base64 decode failed for '%s'\n", str); testFinishedFailure(); return; } encoded = xmlSecBase64Encode(decoded, decodedSize, columns); if(encoded == NULL) { testLog("Error: base64 encode failed for '%s'\n", str); testFinishedFailure(); return; } /* check results */ if(xmlStrcmp(encoded, (expected != NULL) ? BAD_CAST expected: BAD_CAST str) != 0) { testLog("Error: base64 encode returned in='%s' (expected: '%s')\n", (const char*)encoded, (expected != NULL) ? expected : str); testFinishedFailure(); return; } /* DONE */ testFinishedSuccess(); } static void test_base64_failure( const char * name, const char * str ) { xmlSecByte decoded[16]; xmlSecSize decodedSize = 0; int ret; xmlSecAssert(name != NULL); testStart(name); ret = xmlSecBase64Decode_ex(BAD_CAST str, decoded, sizeof(decoded), &decodedSize); if(ret >= 0) { testLog("Error: base64 decode expected to fail for '%s'\n", (str != NULL) ? str : "NULL"); testFinishedFailure(); return; } /* DONE */ testFinishedSuccess(); } int test_base64(void) { /* start */ testGroupStart("base64"); /* positive tests */ test_base64_success("check 1 char", "Rg==", 0, NULL); test_base64_success("check 2 chars", "Rm8=", 0, NULL); test_base64_success("check 3 chars", "Rm9v", 0, NULL); test_base64_success("check 4 chars", "Rm9vQg==", 0, NULL); test_base64_success("check 5 chars", "Rm9vQmE=", 0, NULL); test_base64_success("check 6 chars", "Rm9vQmFy", 0, NULL); test_base64_success("check multiline", "Rm9vQmFyIE\nZvb0JhciBG\nb29CYXI=", 10, NULL); test_base64_success("check multiline with space characters", "Rm9vQmFyIE\n Zvb0JhciBG\n b29CYXI=", 10, "Rm9vQmFyIE\nZvb0JhciBG\nb29CYXI="); /* negative tests */ test_base64_failure("check NULL", NULL); test_base64_failure("check missing both '='", "Rg"); test_base64_failure("check missing second '='", "Rg="); test_base64_failure("check missing first '='", "Rm8"); test_base64_failure("check output buffer too small", "Rm9vQmFyIEZvb0JhciBGb29CYXIgRm9vQmFyIEZvb0JhciBGb29CYXIgRm9vQmFyIEZvb0JhciBGb29CYXIgRm9vQmFyIA=="); test_base64_failure("check non base64 chars", "Rm9v;g=="); /* done */ return (testGroupFinished()); } xmlsec-1.3.10/apps/unit_tests/templates_unit_tests.c000066400000000000000000000726721516161755100227040ustar00rootroot00000000000000/** * XML Security Library (http://www.aleksey.com/xmlsec). * * templates unit tests * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #include #include #include /* must be included before any other xmlsec header */ #include "xmlsec_unit_tests.h" #include #include #include #include /* * Use core transforms (from the base library, no crypto backend needed): * xmlSecTransformInclC14NId => xmlSecTransformInclC14NGetKlass() (c14n) * xmlSecTransformEnvelopedId => xmlSecTransformEnvelopedGetKlass() (enveloped-signature) * xmlSecTransformExclC14NId => xmlSecTransformExclC14NGetKlass() (exc-c14n) * * Template functions only dereference ->href from the klass struct; they do not * require the crypto backend to be initialized. */ /************************************************************************* * xmlSecTmplSignatureCreate *************************************************************************/ static void test_xmlSecTmplSignatureCreate_structure(void) { xmlNodePtr signNode = NULL; xmlNodePtr signedInfoNode; xmlNodePtr signValueNode; xmlNodePtr c14nNode; xmlNodePtr signMethodNode; xmlChar* algo; testStart("xmlSecTmplSignatureCreate: creates correct node structure"); signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); testFinishedFailure(); return; } /* root must be */ if(!xmlSecCheckNodeName(signNode, xmlSecNodeSignature, xmlSecDSigNs)) { testLog("Error: root is not \n"); xmlFreeNode(signNode); testFinishedFailure(); return; } /* required: */ signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs); if(signedInfoNode == NULL) { testLog("Error: not found\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } /* required: */ signValueNode = xmlSecFindChild(signNode, xmlSecNodeSignatureValue, xmlSecDSigNs); if(signValueNode == NULL) { testLog("Error: not found\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } /* required: inside SignedInfo */ c14nNode = xmlSecFindChild(signedInfoNode, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs); if(c14nNode == NULL) { testLog("Error: not found\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } algo = xmlGetProp(c14nNode, xmlSecAttrAlgorithm); if(algo == NULL || xmlStrcmp(algo, xmlSecHrefC14N) != 0) { testLog("Error: CanonicalizationMethod Algorithm='%s', expected '%s'\n", algo ? (char*)algo : "NULL", (char*)xmlSecHrefC14N); xmlFree(algo); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFree(algo); /* required: inside SignedInfo */ signMethodNode = xmlSecFindChild(signedInfoNode, xmlSecNodeSignatureMethod, xmlSecDSigNs); if(signMethodNode == NULL) { testLog("Error: not found\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } algo = xmlGetProp(signMethodNode, xmlSecAttrAlgorithm); if(algo == NULL || xmlStrcmp(algo, xmlSecHrefEnveloped) != 0) { testLog("Error: SignatureMethod Algorithm='%s', expected '%s'\n", algo ? (char*)algo : "NULL", (char*)xmlSecHrefEnveloped); xmlFree(algo); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFree(algo); xmlFreeNode(signNode); testFinishedSuccess(); } static void test_xmlSecTmplSignatureCreate_with_id(void) { xmlNodePtr signNode = NULL; xmlChar* id; testStart("xmlSecTmplSignatureCreate: Id attribute is set when provided"); signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, BAD_CAST "sig1"); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); testFinishedFailure(); return; } id = xmlGetProp(signNode, BAD_CAST "Id"); if(id == NULL || xmlStrcmp(id, BAD_CAST "sig1") != 0) { testLog("Error: expected Id='sig1', got '%s'\n", id ? (char*)id : "NULL"); xmlFree(id); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFree(id); xmlFreeNode(signNode); testFinishedSuccess(); } /************************************************************************* * xmlSecTmplSignatureCreateNsPref *************************************************************************/ static void test_xmlSecTmplSignatureCreateNsPref_prefix_applied(void) { xmlNodePtr signNode = NULL; xmlNsPtr ns; testStart("xmlSecTmplSignatureCreateNsPref: namespace prefix is applied"); signNode = xmlSecTmplSignatureCreateNsPref(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL, BAD_CAST "dsig"); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreateNsPref returned NULL\n"); testFinishedFailure(); return; } /* The Signature node's namespace should have the requested prefix */ ns = signNode->ns; if(ns == NULL || ns->prefix == NULL || xmlStrcmp(ns->prefix, BAD_CAST "dsig") != 0) { testLog("Error: expected ns prefix 'dsig', got '%s'\n", (ns && ns->prefix) ? (char*)ns->prefix : "NULL"); xmlFreeNode(signNode); testFinishedFailure(); return; } if(xmlStrcmp(ns->href, xmlSecDSigNs) != 0) { testLog("Error: expected ns href '%s', got '%s'\n", (char*)xmlSecDSigNs, ns->href ? (char*)ns->href : "NULL"); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFreeNode(signNode); testFinishedSuccess(); } static void test_xmlSecTmplSignatureCreateNsPref_null_prefix(void) { xmlNodePtr signNode = NULL; testStart("xmlSecTmplSignatureCreateNsPref: NULL prefix produces valid node"); signNode = xmlSecTmplSignatureCreateNsPref(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreateNsPref returned NULL\n"); testFinishedFailure(); return; } if(!xmlSecCheckNodeName(signNode, xmlSecNodeSignature, xmlSecDSigNs)) { testLog("Error: result is not a valid node\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFreeNode(signNode); testFinishedSuccess(); } /************************************************************************* * xmlSecTmplSignatureGetSignMethodNode / xmlSecTmplSignatureGetC14NMethodNode *************************************************************************/ static void test_xmlSecTmplSignatureGetSignMethodNode(void) { xmlNodePtr signNode = NULL; xmlNodePtr methodNode; xmlChar* algo; testStart("xmlSecTmplSignatureGetSignMethodNode: returns SignatureMethod node"); signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); testFinishedFailure(); return; } methodNode = xmlSecTmplSignatureGetSignMethodNode(signNode); if(methodNode == NULL) { testLog("Error: xmlSecTmplSignatureGetSignMethodNode returned NULL\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } if(!xmlSecCheckNodeName(methodNode, xmlSecNodeSignatureMethod, xmlSecDSigNs)) { testLog("Error: returned node is not \n"); xmlFreeNode(signNode); testFinishedFailure(); return; } algo = xmlGetProp(methodNode, xmlSecAttrAlgorithm); if(algo == NULL || xmlStrcmp(algo, xmlSecHrefEnveloped) != 0) { testLog("Error: SignatureMethod Algorithm mismatch\n"); xmlFree(algo); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFree(algo); xmlFreeNode(signNode); testFinishedSuccess(); } static void test_xmlSecTmplSignatureGetC14NMethodNode(void) { xmlNodePtr signNode = NULL; xmlNodePtr methodNode; xmlChar* algo; testStart("xmlSecTmplSignatureGetC14NMethodNode: returns CanonicalizationMethod node"); signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); testFinishedFailure(); return; } methodNode = xmlSecTmplSignatureGetC14NMethodNode(signNode); if(methodNode == NULL) { testLog("Error: xmlSecTmplSignatureGetC14NMethodNode returned NULL\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } if(!xmlSecCheckNodeName(methodNode, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs)) { testLog("Error: returned node is not \n"); xmlFreeNode(signNode); testFinishedFailure(); return; } algo = xmlGetProp(methodNode, xmlSecAttrAlgorithm); if(algo == NULL || xmlStrcmp(algo, xmlSecHrefC14N) != 0) { testLog("Error: CanonicalizationMethod Algorithm mismatch\n"); xmlFree(algo); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFree(algo); xmlFreeNode(signNode); testFinishedSuccess(); } /************************************************************************* * xmlSecTmplSignatureEnsureKeyInfo *************************************************************************/ static void test_xmlSecTmplSignatureEnsureKeyInfo_adds_node(void) { xmlNodePtr signNode = NULL; xmlNodePtr keyInfoNode; testStart("xmlSecTmplSignatureEnsureKeyInfo: adds KeyInfo when absent"); signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); testFinishedFailure(); return; } /* initially no KeyInfo */ if(xmlSecFindChild(signNode, xmlSecNodeKeyInfo, xmlSecDSigNs) != NULL) { testLog("Error: unexpected KeyInfo present before ensure call\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL); if(keyInfoNode == NULL) { testLog("Error: xmlSecTmplSignatureEnsureKeyInfo returned NULL\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } if(!xmlSecCheckNodeName(keyInfoNode, xmlSecNodeKeyInfo, xmlSecDSigNs)) { testLog("Error: returned node is not \n"); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFreeNode(signNode); testFinishedSuccess(); } static void test_xmlSecTmplSignatureEnsureKeyInfo_idempotent(void) { xmlNodePtr signNode = NULL; xmlNodePtr keyInfoNode1; xmlNodePtr keyInfoNode2; testStart("xmlSecTmplSignatureEnsureKeyInfo: second call returns same node"); signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); testFinishedFailure(); return; } keyInfoNode1 = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL); keyInfoNode2 = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL); if(keyInfoNode1 == NULL || keyInfoNode2 == NULL || keyInfoNode1 != keyInfoNode2) { testLog("Error: expected same KeyInfo node on second call\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFreeNode(signNode); testFinishedSuccess(); } /************************************************************************* * xmlSecTmplSignatureAddReference *************************************************************************/ static void test_xmlSecTmplSignatureAddReference_with_uri(void) { xmlNodePtr signNode = NULL; xmlNodePtr refNode; xmlNodePtr digestMethodNode; xmlChar* attr; testStart("xmlSecTmplSignatureAddReference: creates Reference with URI and DigestMethod"); signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); testFinishedFailure(); return; } refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformInclC14NId, BAD_CAST "ref1", BAD_CAST "#data", NULL); if(refNode == NULL) { testLog("Error: xmlSecTmplSignatureAddReference returned NULL\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } /* check Reference node name / namespace */ if(!xmlSecCheckNodeName(refNode, xmlSecNodeReference, xmlSecDSigNs)) { testLog("Error: result is not \n"); xmlFreeNode(signNode); testFinishedFailure(); return; } /* check URI attribute */ attr = xmlGetProp(refNode, xmlSecAttrURI); if(attr == NULL || xmlStrcmp(attr, BAD_CAST "#data") != 0) { testLog("Error: expected URI='#data', got '%s'\n", attr ? (char*)attr : "NULL"); xmlFree(attr); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFree(attr); /* check Id attribute */ attr = xmlGetProp(refNode, xmlSecAttrId); if(attr == NULL || xmlStrcmp(attr, BAD_CAST "ref1") != 0) { testLog("Error: expected Id='ref1', got '%s'\n", attr ? (char*)attr : "NULL"); xmlFree(attr); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFree(attr); /* check DigestMethod child with Algorithm attribute */ digestMethodNode = xmlSecFindChild(refNode, xmlSecNodeDigestMethod, xmlSecDSigNs); if(digestMethodNode == NULL) { testLog("Error: not found inside Reference\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } attr = xmlGetProp(digestMethodNode, xmlSecAttrAlgorithm); if(attr == NULL || xmlStrcmp(attr, xmlSecHrefC14N) != 0) { testLog("Error: DigestMethod Algorithm mismatch: '%s'\n", attr ? (char*)attr : "NULL"); xmlFree(attr); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFree(attr); xmlFreeNode(signNode); testFinishedSuccess(); } static void test_xmlSecTmplSignatureAddReference_multiple(void) { xmlNodePtr signNode = NULL; xmlNodePtr ref1, ref2; testStart("xmlSecTmplSignatureAddReference: can add multiple references"); signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); testFinishedFailure(); return; } ref1 = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformInclC14NId, BAD_CAST "r1", BAD_CAST "#d1", NULL); ref2 = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformInclC14NId, BAD_CAST "r2", BAD_CAST "#d2", NULL); if(ref1 == NULL || ref2 == NULL || ref1 == ref2) { testLog("Error: expected two distinct Reference nodes\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFreeNode(signNode); testFinishedSuccess(); } /************************************************************************* * xmlSecTmplEncDataCreate *************************************************************************/ static void test_xmlSecTmplEncDataCreate_structure(void) { xmlNodePtr encNode = NULL; xmlNodePtr methodNode; xmlNodePtr cipherDataNode; xmlChar* algo; testStart("xmlSecTmplEncDataCreate: creates correct EncryptedData structure"); encNode = xmlSecTmplEncDataCreate(NULL, xmlSecTransformExclC14NId, BAD_CAST "enc1", NULL, NULL, NULL); if(encNode == NULL) { testLog("Error: xmlSecTmplEncDataCreate returned NULL\n"); testFinishedFailure(); return; } /* root must be */ if(!xmlSecCheckNodeName(encNode, xmlSecNodeEncryptedData, xmlSecEncNs)) { testLog("Error: root is not \n"); xmlFreeNode(encNode); testFinishedFailure(); return; } /* required: */ methodNode = xmlSecFindChild(encNode, xmlSecNodeEncryptionMethod, xmlSecEncNs); if(methodNode == NULL) { testLog("Error: not found\n"); xmlFreeNode(encNode); testFinishedFailure(); return; } algo = xmlGetProp(methodNode, xmlSecAttrAlgorithm); if(algo == NULL || xmlStrcmp(algo, xmlSecHrefExcC14N) != 0) { testLog("Error: EncryptionMethod Algorithm='%s', expected '%s'\n", algo ? (char*)algo : "NULL", (char*)xmlSecHrefExcC14N); xmlFree(algo); xmlFreeNode(encNode); testFinishedFailure(); return; } xmlFree(algo); /* required: */ cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs); if(cipherDataNode == NULL) { testLog("Error: not found\n"); xmlFreeNode(encNode); testFinishedFailure(); return; } /* check Id attribute is set */ algo = xmlGetProp(encNode, xmlSecAttrId); if(algo == NULL || xmlStrcmp(algo, BAD_CAST "enc1") != 0) { testLog("Error: expected Id='enc1', got '%s'\n", algo ? (char*)algo : "NULL"); xmlFree(algo); xmlFreeNode(encNode); testFinishedFailure(); return; } xmlFree(algo); xmlFreeNode(encNode); testFinishedSuccess(); } static void test_xmlSecTmplEncDataCreate_null_method(void) { xmlNodePtr encNode = NULL; xmlNodePtr methodNode; xmlNodePtr cipherDataNode; testStart("xmlSecTmplEncDataCreate: NULL encMethodId omits EncryptionMethod child"); encNode = xmlSecTmplEncDataCreate(NULL, NULL, NULL, NULL, NULL, NULL); if(encNode == NULL) { testLog("Error: xmlSecTmplEncDataCreate returned NULL\n"); testFinishedFailure(); return; } /* no EncryptionMethod when method is NULL */ methodNode = xmlSecFindChild(encNode, xmlSecNodeEncryptionMethod, xmlSecEncNs); if(methodNode != NULL) { testLog("Error: unexpected with NULL encMethodId\n"); xmlFreeNode(encNode); testFinishedFailure(); return; } /* CipherData must still be present */ cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs); if(cipherDataNode == NULL) { testLog("Error: not found\n"); xmlFreeNode(encNode); testFinishedFailure(); return; } xmlFreeNode(encNode); testFinishedSuccess(); } /************************************************************************* * xmlSecTmplEncDataEnsureCipherValue *************************************************************************/ static void test_xmlSecTmplEncDataEnsureCipherValue_adds_node(void) { xmlNodePtr encNode = NULL; xmlNodePtr cipherValueNode; testStart("xmlSecTmplEncDataEnsureCipherValue: adds CipherValue inside CipherData"); encNode = xmlSecTmplEncDataCreate(NULL, xmlSecTransformExclC14NId, NULL, NULL, NULL, NULL); if(encNode == NULL) { testLog("Error: xmlSecTmplEncDataCreate returned NULL\n"); testFinishedFailure(); return; } cipherValueNode = xmlSecTmplEncDataEnsureCipherValue(encNode); if(cipherValueNode == NULL) { testLog("Error: xmlSecTmplEncDataEnsureCipherValue returned NULL\n"); xmlFreeNode(encNode); testFinishedFailure(); return; } if(!xmlSecCheckNodeName(cipherValueNode, xmlSecNodeCipherValue, xmlSecEncNs)) { testLog("Error: returned node is not \n"); xmlFreeNode(encNode); testFinishedFailure(); return; } xmlFreeNode(encNode); testFinishedSuccess(); } static void test_xmlSecTmplEncDataEnsureCipherValue_idempotent(void) { xmlNodePtr encNode = NULL; xmlNodePtr cv1, cv2; testStart("xmlSecTmplEncDataEnsureCipherValue: second call returns same node"); encNode = xmlSecTmplEncDataCreate(NULL, xmlSecTransformExclC14NId, NULL, NULL, NULL, NULL); if(encNode == NULL) { testLog("Error: xmlSecTmplEncDataCreate returned NULL\n"); testFinishedFailure(); return; } cv1 = xmlSecTmplEncDataEnsureCipherValue(encNode); cv2 = xmlSecTmplEncDataEnsureCipherValue(encNode); if(cv1 == NULL || cv2 == NULL || cv1 != cv2) { testLog("Error: expected same CipherValue node on second call\n"); xmlFreeNode(encNode); testFinishedFailure(); return; } xmlFreeNode(encNode); testFinishedSuccess(); } /************************************************************************* * xmlSecTmplEncDataEnsureKeyInfo *************************************************************************/ static void test_xmlSecTmplEncDataEnsureKeyInfo_adds_node(void) { xmlNodePtr encNode = NULL; xmlNodePtr keyInfoNode; testStart("xmlSecTmplEncDataEnsureKeyInfo: adds KeyInfo before CipherData"); encNode = xmlSecTmplEncDataCreate(NULL, xmlSecTransformExclC14NId, NULL, NULL, NULL, NULL); if(encNode == NULL) { testLog("Error: xmlSecTmplEncDataCreate returned NULL\n"); testFinishedFailure(); return; } /* initially no KeyInfo */ if(xmlSecFindChild(encNode, xmlSecNodeKeyInfo, xmlSecDSigNs) != NULL) { testLog("Error: unexpected KeyInfo before ensure call\n"); xmlFreeNode(encNode); testFinishedFailure(); return; } keyInfoNode = xmlSecTmplEncDataEnsureKeyInfo(encNode, NULL); if(keyInfoNode == NULL) { testLog("Error: xmlSecTmplEncDataEnsureKeyInfo returned NULL\n"); xmlFreeNode(encNode); testFinishedFailure(); return; } if(!xmlSecCheckNodeName(keyInfoNode, xmlSecNodeKeyInfo, xmlSecDSigNs)) { testLog("Error: returned node is not \n"); xmlFreeNode(encNode); testFinishedFailure(); return; } xmlFreeNode(encNode); testFinishedSuccess(); } static void test_xmlSecTmplEncDataEnsureKeyInfo_idempotent(void) { xmlNodePtr encNode = NULL; xmlNodePtr ki1, ki2; testStart("xmlSecTmplEncDataEnsureKeyInfo: second call returns same node"); encNode = xmlSecTmplEncDataCreate(NULL, xmlSecTransformExclC14NId, NULL, NULL, NULL, NULL); if(encNode == NULL) { testLog("Error: xmlSecTmplEncDataCreate returned NULL\n"); testFinishedFailure(); return; } ki1 = xmlSecTmplEncDataEnsureKeyInfo(encNode, NULL); ki2 = xmlSecTmplEncDataEnsureKeyInfo(encNode, NULL); if(ki1 == NULL || ki2 == NULL || ki1 != ki2) { testLog("Error: expected same KeyInfo node on second call\n"); xmlFreeNode(encNode); testFinishedFailure(); return; } xmlFreeNode(encNode); testFinishedSuccess(); } /************************************************************************* * xmlSecTmplKeyInfoAddKeyName *************************************************************************/ static void test_xmlSecTmplKeyInfoAddKeyName_with_name(void) { xmlDocPtr doc = NULL; xmlNodePtr signNode = NULL; xmlNodePtr keyInfoNode; xmlNodePtr keyNameNode; xmlChar* content; testStart("xmlSecTmplKeyInfoAddKeyName: adds KeyName with correct content"); /* xmlSecNodeEncodeAndSetContent requires node->doc != NULL, so create a * real document and attach the signature node to it. */ doc = xmlNewDoc(BAD_CAST "1.0"); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlDocSetRootElement(doc, signNode); keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL); if(keyInfoNode == NULL) { testLog("Error: xmlSecTmplSignatureEnsureKeyInfo returned NULL\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } keyNameNode = xmlSecTmplKeyInfoAddKeyName(keyInfoNode, BAD_CAST "my-key-name"); if(keyNameNode == NULL) { testLog("Error: xmlSecTmplKeyInfoAddKeyName returned NULL\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } if(!xmlSecCheckNodeName(keyNameNode, xmlSecNodeKeyName, xmlSecDSigNs)) { testLog("Error: returned node is not \n"); xmlFreeDoc(doc); testFinishedFailure(); return; } content = xmlNodeGetContent(keyNameNode); if(content == NULL || xmlStrcmp(content, BAD_CAST "my-key-name") != 0) { testLog("Error: expected KeyName content 'my-key-name', got '%s'\n", content ? (char*)content : "NULL"); xmlFree(content); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFree(content); xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecTmplKeyInfoAddKeyName_null_name(void) { xmlNodePtr signNode = NULL; xmlNodePtr keyInfoNode; xmlNodePtr keyNameNode; testStart("xmlSecTmplKeyInfoAddKeyName: NULL name produces empty KeyName"); signNode = xmlSecTmplSignatureCreate(NULL, xmlSecTransformInclC14NId, xmlSecTransformEnvelopedId, NULL); if(signNode == NULL) { testLog("Error: xmlSecTmplSignatureCreate returned NULL\n"); testFinishedFailure(); return; } keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL); if(keyInfoNode == NULL) { testLog("Error: xmlSecTmplSignatureEnsureKeyInfo returned NULL\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } keyNameNode = xmlSecTmplKeyInfoAddKeyName(keyInfoNode, NULL); if(keyNameNode == NULL) { testLog("Error: xmlSecTmplKeyInfoAddKeyName returned NULL for NULL name\n"); xmlFreeNode(signNode); testFinishedFailure(); return; } if(!xmlSecCheckNodeName(keyNameNode, xmlSecNodeKeyName, xmlSecDSigNs)) { testLog("Error: returned node is not \n"); xmlFreeNode(signNode); testFinishedFailure(); return; } xmlFreeNode(signNode); testFinishedSuccess(); } /************************************************************************* * exported entry point *************************************************************************/ int test_templates(void) { int success = 1; testGroupStart("xmlSecTmplSignatureCreate"); test_xmlSecTmplSignatureCreate_structure(); test_xmlSecTmplSignatureCreate_with_id(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecTmplSignatureCreateNsPref"); test_xmlSecTmplSignatureCreateNsPref_prefix_applied(); test_xmlSecTmplSignatureCreateNsPref_null_prefix(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecTmplSignatureGetMethodNodes"); test_xmlSecTmplSignatureGetSignMethodNode(); test_xmlSecTmplSignatureGetC14NMethodNode(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecTmplSignatureEnsureKeyInfo"); test_xmlSecTmplSignatureEnsureKeyInfo_adds_node(); test_xmlSecTmplSignatureEnsureKeyInfo_idempotent(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecTmplSignatureAddReference"); test_xmlSecTmplSignatureAddReference_with_uri(); test_xmlSecTmplSignatureAddReference_multiple(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecTmplEncDataCreate"); test_xmlSecTmplEncDataCreate_structure(); test_xmlSecTmplEncDataCreate_null_method(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecTmplEncDataEnsureCipherValue"); test_xmlSecTmplEncDataEnsureCipherValue_adds_node(); test_xmlSecTmplEncDataEnsureCipherValue_idempotent(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecTmplEncDataEnsureKeyInfo"); test_xmlSecTmplEncDataEnsureKeyInfo_adds_node(); test_xmlSecTmplEncDataEnsureKeyInfo_idempotent(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecTmplKeyInfoAddKeyName"); test_xmlSecTmplKeyInfoAddKeyName_with_name(); test_xmlSecTmplKeyInfoAddKeyName_null_name(); if(testGroupFinished() != 1) { success = 0; } return(success); } xmlsec-1.3.10/apps/unit_tests/transform_helpers_unit_tests.c000066400000000000000000000272631516161755100244370ustar00rootroot00000000000000/** * XML Security Library (http://www.aleksey.com/xmlsec). * * transform helpers unit tests * * See Copyright for the status of this software. */ #include #include #include #include #include #include "xmlsec_unit_tests.h" #include #include #include "../src/transform_helpers.h" #ifndef XMLSEC_NO_CHACHA20 static xmlNodePtr xmlSecUnitTestParseNode(const char* xml, xmlDocPtr* doc) { xmlNodePtr node; xmlSecAssert2(xml != NULL, NULL); xmlSecAssert2(doc != NULL, NULL); (*doc) = xmlReadMemory(xml, (int)strlen(xml), "transform-helpers.xml", NULL, XML_PARSE_NONET | XML_PARSE_NOBLANKS); if((*doc) == NULL) { testLog("Error: failed to parse XML\n"); return(NULL); } node = xmlDocGetRootElement((*doc)); if(node == NULL) { testLog("Error: parsed XML does not have a root node\n"); xmlFreeDoc((*doc)); (*doc) = NULL; return(NULL); } return(node); } static xmlNodePtr xmlSecUnitTestFindChild(xmlNodePtr node, const xmlChar* name) { xmlNodePtr cur; xmlSecAssert2(node != NULL, NULL); xmlSecAssert2(name != NULL, NULL); for(cur = xmlSecGetNextElementNode(node->children); cur != NULL; cur = xmlSecGetNextElementNode(cur->next)) { if(xmlSecCheckNodeName(cur, name, xmlSecXmldsig2021MoreNs)) { return(cur); } } return(NULL); } static void test_xmlSecTransformChaCha20ParamsRead_missing_nonce(void) { static const char xml[] = "" "01020304" ""; xmlDocPtr doc = NULL; xmlNodePtr node; xmlSecByte iv[XMLSEC_CHACHA20_IV_SIZE]; xmlSecSize ivSize = 0; int noncePresent = 0; int ret; testStart("ChaCha20 read missing nonce"); node = xmlSecUnitTestParseNode(xml, &doc); if(node == NULL) { testFinishedFailure(); return; } memset(iv, 0xFF, sizeof(iv)); ret = xmlSecTransformChaCha20ParamsRead(node, iv, sizeof(iv), &ivSize, &noncePresent); if((ret < 0) || (ivSize != XMLSEC_CHACHA20_IV_SIZE) || (noncePresent != 0) || (memcmp(iv, "\x01\x02\x03\x04", XMLSEC_CHACHA20_COUNTER_SIZE) != 0) || (memcmp(iv + XMLSEC_CHACHA20_COUNTER_SIZE, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", XMLSEC_CHACHA20_NONCE_SIZE) != 0)) { testLog("Error: ChaCha20 params read did not accept missing nonce with required counter\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecTransformChaCha20ParamsRead_missing_counter(void) { static const char xml[] = "" "000102030405060708090a0b" ""; xmlDocPtr doc = NULL; xmlNodePtr node; xmlSecByte iv[XMLSEC_CHACHA20_IV_SIZE]; xmlSecSize ivSize = 0; int noncePresent = 0; int ret; testStart("ChaCha20 read missing counter"); node = xmlSecUnitTestParseNode(xml, &doc); if(node == NULL) { testFinishedFailure(); return; } memset(iv, 0xFF, sizeof(iv)); ret = xmlSecTransformChaCha20ParamsRead(node, iv, sizeof(iv), &ivSize, &noncePresent); if(ret >= 0) { testLog("Error: ChaCha20 params read accepted missing counter\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecTransformChaCha20ParamsRead_missing_nonce_strict(void) { static const char xml[] = "" "01020304" ""; xmlDocPtr doc = NULL; xmlNodePtr node; xmlSecByte iv[XMLSEC_CHACHA20_IV_SIZE]; int noncePresent = 0; xmlSecSize ivSize = 0; int ret; testStart("ChaCha20 read missing nonce strict"); node = xmlSecUnitTestParseNode(xml, &doc); if(node == NULL) { testFinishedFailure(); return; } memset(iv, 0xFF, sizeof(iv)); ret = xmlSecTransformChaCha20ParamsRead(node, iv, sizeof(iv), &ivSize, &noncePresent); if((ret < 0) || (ivSize != XMLSEC_CHACHA20_IV_SIZE) || (noncePresent != 0) || (memcmp(iv, "\x01\x02\x03\x04", XMLSEC_CHACHA20_COUNTER_SIZE) != 0) || (memcmp(iv + XMLSEC_CHACHA20_COUNTER_SIZE, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", XMLSEC_CHACHA20_NONCE_SIZE) != 0)) { testLog("Error: ChaCha20 params read did not accept missing nonce with required counter\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecTransformChaCha20ParamsWrite_roundtrip(void) { static const char xml[] = ""; static const xmlSecByte iv[XMLSEC_CHACHA20_IV_SIZE] = { 0x01, 0x02, 0x03, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }; xmlDocPtr doc = NULL; xmlNodePtr node; xmlNodePtr nonceNode; xmlNodePtr counterNode; xmlChar* nonceContent; xmlChar* counterContent; xmlSecByte ivRoundTrip[XMLSEC_CHACHA20_IV_SIZE]; xmlSecSize ivSize = 0; int noncePresent = 0; int ret; testStart("ChaCha20 write roundtrip"); node = xmlSecUnitTestParseNode(xml, &doc); if(node == NULL) { testFinishedFailure(); return; } ret = xmlSecTransformChaCha20ParamsWrite(node, iv, sizeof(iv)); if(ret < 0) { testLog("Error: failed to write ChaCha20 params\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } nonceNode = xmlSecUnitTestFindChild(node, xmlSecNodeChaCha20Nonce); counterNode = xmlSecUnitTestFindChild(node, xmlSecNodeChaCha20Counter); if((nonceNode == NULL) || (counterNode == NULL)) { testLog("Error: ChaCha20 params write did not create both nodes\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } nonceContent = xmlNodeGetContent(nonceNode); counterContent = xmlNodeGetContent(counterNode); if((nonceContent == NULL) || (counterContent == NULL) || (xmlStrcmp(nonceContent, BAD_CAST "000102030405060708090a0b") != 0) || (xmlStrcmp(counterContent, BAD_CAST "01020304") != 0)) { testLog("Error: ChaCha20 params write serialized unexpected values\n"); xmlFree(nonceContent); xmlFree(counterContent); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFree(nonceContent); xmlFree(counterContent); ret = xmlSecTransformChaCha20ParamsRead(node, ivRoundTrip, sizeof(ivRoundTrip), &ivSize, &noncePresent); if((ret < 0) || (ivSize != XMLSEC_CHACHA20_IV_SIZE) || (memcmp(ivRoundTrip, iv, sizeof(iv)) != 0)) { testLog("Error: ChaCha20 params write did not round-trip through strict read\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecTransformChaCha20Poly1305ParamsWrite_roundtrip(void) { static const char xml[] = ""; static const xmlSecByte iv[XMLSEC_CHACHA20_NONCE_SIZE] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }; xmlDocPtr doc = NULL; xmlNodePtr node; xmlNodePtr nonceNode; xmlChar* nonceContent; xmlSecBuffer aad; xmlSecByte ivRoundTrip[XMLSEC_CHACHA20_NONCE_SIZE]; xmlSecSize ivSize = 0; int noncePresent = 0; int ret; testStart("ChaCha20-Poly1305 write roundtrip"); node = xmlSecUnitTestParseNode(xml, &doc); if(node == NULL) { testFinishedFailure(); return; } ret = xmlSecTransformChaCha20Poly1305ParamsWrite(node, iv, sizeof(iv)); if(ret < 0) { testLog("Error: failed to write ChaCha20-Poly1305 params\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } nonceNode = xmlSecUnitTestFindChild(node, xmlSecNodeChaCha20Nonce); if(nonceNode == NULL) { testLog("Error: ChaCha20-Poly1305 params write did not create nonce node\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } nonceContent = xmlNodeGetContent(nonceNode); if((nonceContent == NULL) || (xmlStrcmp(nonceContent, BAD_CAST "000102030405060708090a0b") != 0)) { testLog("Error: ChaCha20-Poly1305 params write serialized unexpected nonce\n"); xmlDebugDumpDocument(stdout, doc); xmlFree(nonceContent); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFree(nonceContent); ret = xmlSecBufferInitialize(&aad, 0); if(ret < 0) { testLog("Error: failed to initialize AAD buffer\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } ret = xmlSecTransformChaCha20Poly1305ParamsRead(node, &aad, ivRoundTrip, sizeof(ivRoundTrip), &ivSize, &noncePresent); xmlSecBufferFinalize(&aad); if((ret < 0) || (ivSize != XMLSEC_CHACHA20_NONCE_SIZE) || (noncePresent != 1) || (memcmp(ivRoundTrip, iv, sizeof(iv)) != 0)) { testLog("Error: ChaCha20-Poly1305 params write did not round-trip through strict read\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecTransformChaCha20Poly1305ParamsRead_missing_nonce(void) { static const char xml[] = ""; xmlDocPtr doc = NULL; xmlNodePtr node; xmlSecBuffer aad; xmlSecByte iv[XMLSEC_CHACHA20_NONCE_SIZE]; xmlSecSize ivSize = 0; int noncePresent = 1; int ret; testStart("ChaCha20-Poly1305 read missing nonce"); node = xmlSecUnitTestParseNode(xml, &doc); if(node == NULL) { testFinishedFailure(); return; } ret = xmlSecBufferInitialize(&aad, 0); if(ret < 0) { testLog("Error: failed to initialize AAD buffer\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } memset(iv, 0xFF, sizeof(iv)); ret = xmlSecTransformChaCha20Poly1305ParamsRead(node, &aad, iv, sizeof(iv), &ivSize, &noncePresent); xmlSecBufferFinalize(&aad); if((ret < 0) || (ivSize != XMLSEC_CHACHA20_NONCE_SIZE) || (noncePresent != 0) || (memcmp(iv, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", XMLSEC_CHACHA20_NONCE_SIZE) != 0)) { testLog("Error: ChaCha20-Poly1305 params read did not accept missing nonce\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } #endif /* XMLSEC_NO_CHACHA20 */ int test_transform_helpers(void) { #ifndef XMLSEC_NO_CHACHA20 testGroupStart("transform helpers"); test_xmlSecTransformChaCha20ParamsRead_missing_nonce(); test_xmlSecTransformChaCha20ParamsRead_missing_counter(); test_xmlSecTransformChaCha20ParamsRead_missing_nonce_strict(); test_xmlSecTransformChaCha20ParamsWrite_roundtrip(); test_xmlSecTransformChaCha20Poly1305ParamsRead_missing_nonce(); test_xmlSecTransformChaCha20Poly1305ParamsWrite_roundtrip(); return(testGroupFinished()); #else return(1); #endif /* XMLSEC_NO_CHACHA20 */ } xmlsec-1.3.10/apps/unit_tests/x509_unit_tests.c000066400000000000000000000427071516161755100214070ustar00rootroot00000000000000/** * XML Security Library (http://www.aleksey.com/xmlsec). * * x509 utils unit tests * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #include #include #include #include /* must be included before any other xmlsec header */ #include "xmlsec_unit_tests.h" #include "../src/x509_helpers.h" /*********************************** test_xmlSecX509EscapedStringRead ***********************************/ static void test_xmlSecX509EscapedStringRead_success( const char * name, const char * str, const char delim, int ingoreTrailingSpaces, const char* expectedIn, const char* expectedOut ) { const xmlChar *inStr; xmlSecSize size, inSize; int len; xmlChar out[256]; xmlSecSize outSize; int ret; xmlSecAssert(name != NULL); xmlSecAssert(str != NULL); testStart(name); len = xmlStrlen(BAD_CAST str); XMLSEC_SAFE_CAST_INT_TO_SIZE(len, size, return, NULL); inStr = BAD_CAST str; inSize = size; outSize = 0; ret = xmlSecX509EscapedStringRead(&inStr, &inSize, out, sizeof(out) - 1, &outSize, (xmlChar)delim, ingoreTrailingSpaces); if(ret < 0) { testLog("Error: xmlSecX509EscapedStringRead failed for '%s'\n", str); testFinishedFailure(); return; } out[outSize] = '\0'; /* check results */ if(xmlStrcmp(inStr, BAD_CAST expectedIn) != 0) { testLog("Error: xmlSecX509EscapedStringRead returned in='%s' (expected: '%s')\n", (const char*)inStr, expectedIn); testFinishedFailure(); return; } if(xmlStrcmp(out, BAD_CAST expectedOut) != 0) { testLog("Error: xmlSecX509EscapedStringRead returned out='%s' (expected: '%s')\n", (const char*)out, expectedOut); testFinishedFailure(); return; } /* DONE */ testFinishedSuccess(); } static void test_xmlSecX509EscapedStringRead_failure( const char * name, const char * str, const char delim, int ingoreTrailingSpaces ) { const xmlChar *inStr; xmlSecSize size, inSize; int len; xmlChar out[16]; xmlSecSize outSize; int ret; xmlSecAssert(name != NULL); testStart(name); len = xmlStrlen(BAD_CAST str); XMLSEC_SAFE_CAST_INT_TO_SIZE(len, size, return, NULL); inStr = BAD_CAST str; inSize = size; outSize = 0; ret = xmlSecX509EscapedStringRead(&inStr, &inSize, out, sizeof(out) - 1, &outSize, (xmlChar)delim, ingoreTrailingSpaces); if(ret >= 0) { testLog("Error: xmlSecX509EscapedStringRead expected to fail for '%s'\n", (str != NULL) ? str : "NULL"); testFinishedFailure(); return; } /* DONE */ testFinishedSuccess(); } int test_xmlSecX509EscapedStringRead(void) { /* start */ testGroupStart("xmlSecX509EscapedStringRead"); /* positive tests */ test_xmlSecX509EscapedStringRead_success("check empty string", "=", '=', 0, "=", ""); test_xmlSecX509EscapedStringRead_success("check end of line with trailing spaces", "Foo Bar ", '=', 0, "", "Foo Bar "); test_xmlSecX509EscapedStringRead_success("check end of line without trailing spaces", "Foo Bar ", '=', 1, "", "Foo Bar"); test_xmlSecX509EscapedStringRead_success("check with trailing spaces", "Foo Bar =Value", '=', 0, "=Value", "Foo Bar "); test_xmlSecX509EscapedStringRead_success("check without trailing spaces", "Foo Bar =Value", '=', 1, "=Value", "Foo Bar"); test_xmlSecX509EscapedStringRead_success("check \\ converted to ", "Fo\\o Bar=Value", '=', 0, "=Value", "Foo Bar"); test_xmlSecX509EscapedStringRead_success("check \\XXX converted to ", "Fo\\6F Bar=Value", '=', 0, "=Value", "Foo Bar"); /* negative tests */ test_xmlSecX509EscapedStringRead_failure("check NULL", NULL, '=', 0); test_xmlSecX509EscapedStringRead_failure("check bad hex char", "Foo\\6XBar", '=', 0); test_xmlSecX509EscapedStringRead_failure("check output buffer too small", "FooBarFooBarFooBarFooBarFooBarFooBarFooBarFooBarFooBar=Value", '=', 0); /* done */ return (testGroupFinished()); } /*********************************** test_xmlSecX509AttrValueStringRead ***********************************/ static void test_xmlSecX509AttrValueStringRead_success( const char * name, const char * str, const char delim, int ingoreTrailingSpaces, const char* expectedIn, const char* expectedOut, int expectedType ) { const xmlChar *inStr; xmlSecSize size, inSize; int len; xmlChar out[256]; xmlSecSize outSize; int type = -1; int ret; xmlSecAssert(name != NULL); xmlSecAssert(str != NULL); testStart(name); len = xmlStrlen(BAD_CAST str); XMLSEC_SAFE_CAST_INT_TO_SIZE(len, size, return, NULL); inStr = BAD_CAST str; inSize = size; outSize = 0; ret = xmlSecX509AttrValueStringRead(&inStr, &inSize, out, sizeof(out) - 1, &outSize, &type, (xmlChar)delim, ingoreTrailingSpaces); if(ret < 0) { testLog("Error: xmlSecX509AttrValueStringRead failed for '%s'\n", str); testFinishedFailure(); return; } out[outSize] = '\0'; /* check results */ if(xmlStrcmp(inStr, BAD_CAST expectedIn) != 0) { testLog("Error: xmlSecX509AttrValueStringRead returned in='%s' (expected: '%s')\n", (const char*)inStr, expectedIn); testFinishedFailure(); return; } if(xmlStrcmp(out, BAD_CAST expectedOut) != 0) { testLog("Error: xmlSecX509AttrValueStringRead returned out='%s' (expected: '%s')\n", (const char*)out, expectedOut); testFinishedFailure(); return; } if(type != expectedType) { testLog("Error: xmlSecX509AttrValueStringRead returned type='%d' (expected: '%d')\n", type, expectedType); testFinishedFailure(); return; } /* DONE */ testFinishedSuccess(); } static void test_xmlSecX509AttrValueStringRead_failure( const char * name, const char * str, const char delim, int ingoreTrailingSpaces ) { const xmlChar *inStr; xmlSecSize size, inSize; int len; xmlChar out[16]; xmlSecSize outSize; int type = -1; int ret; xmlSecAssert(name != NULL); testStart(name); len = xmlStrlen(BAD_CAST str); XMLSEC_SAFE_CAST_INT_TO_SIZE(len, size, return, NULL); inStr = BAD_CAST str; inSize = size; outSize = 0; ret = xmlSecX509AttrValueStringRead(&inStr, &inSize, out, sizeof(out) - 1, &outSize, &type, (xmlChar)delim, ingoreTrailingSpaces); if(ret >= 0) { testLog("Error: xmlSecX509AttrValueStringRead expected to fail for '%s'\n", (str != NULL) ? str : "NULL"); testFinishedFailure(); return; } /* DONE */ testFinishedSuccess(); } int test_xmlSecX509AttrValueStringRead(void) { /* start */ testGroupStart("xmlSecX509AttrValueStringRead"); /* positive tests */ test_xmlSecX509AttrValueStringRead_success("check empty string", ",", ',', 0, ",", "", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check end of line with trailing spaces", "Foo Bar ", ',', 0, "", "Foo Bar ", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check end of line without trailing spaces", "Foo Bar ", ',', 1, "", "Foo Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check with trailing spaces", "Foo Bar ,name=value", ',', 0, ",name=value", "Foo Bar ", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check without trailing spaces", "Foo Bar ,name=value", ',', 1, ",name=value", "Foo Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check quoted end of line", "\"Foo Bar \"", ',', 0, "", "Foo Bar ", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check quoted with trailing spaces inside quotes", "\"Foo Bar \",name=value", ',', 0, ",name=value", "Foo Bar ", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check quoted without trailing spaces inside quotes", "\"Foo Bar \",name=value", ',', 1, ",name=value", "Foo Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check quoted with trailing spaces outside quotes", "\"Foo Bar \" ,name=value", ',', 0, " ,name=value", "Foo Bar ", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check quoted without trailing spaces outside quotes", "\"Foo Bar \" ,name=value", ',', 1, ",name=value", "Foo Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509AttrValueStringRead_success("check octet/hex", "#466F6F20426172,name=value", ',', 1, ",name=value", "Foo Bar", XMLSEC_X509_VALUE_TYPE_OCTET_STRING); test_xmlSecX509AttrValueStringRead_success("check octet/hex end of line", "#466F6F20426172", ',', 1, "", "Foo Bar", XMLSEC_X509_VALUE_TYPE_OCTET_STRING); test_xmlSecX509AttrValueStringRead_success("check octet/hex with trailing spaces", "#466F6F20426172 ,name=value", ',', 0, " ,name=value", "Foo Bar", XMLSEC_X509_VALUE_TYPE_OCTET_STRING); test_xmlSecX509AttrValueStringRead_success("check octet/hex without trailing spaces", "#466F6F20426172 ,name=value", ',', 1, ",name=value", "Foo Bar", XMLSEC_X509_VALUE_TYPE_OCTET_STRING); /* negative tests */ test_xmlSecX509AttrValueStringRead_failure("check NULL", NULL, ',', 0); test_xmlSecX509AttrValueStringRead_failure("check bad escaping", "\"Foo\6XBar ,name=value", ',', 0); test_xmlSecX509AttrValueStringRead_failure("check missing closing quote", "\"Foo Bar ,name=value", ',', 0); test_xmlSecX509AttrValueStringRead_failure("check output buffer too small", "FooBarFooBarFooBarFooBarFooBarFooBarFooBarFooBarFooBar=Value", ',', 0); test_xmlSecX509AttrValueStringRead_failure("check octet/hex with missing char end of line", "#4", ',', 0); test_xmlSecX509AttrValueStringRead_failure("check octet/hex with missing chars", "#4,name=value", ',', 0); test_xmlSecX509AttrValueStringRead_failure("check octet/hex with non-hex chars", "#4X,name=value", ',', 0); /* done */ return (testGroupFinished()); } /*********************************** test_xmlSecX509NameRead ***********************************/ #define TEST_X509_NAME_MAX_COUNT 16 typedef struct test_X509Name { xmlChar names[256][TEST_X509_NAME_MAX_COUNT]; xmlChar values[256][TEST_X509_NAME_MAX_COUNT]; xmlSecSize valueSizes[TEST_X509_NAME_MAX_COUNT]; int types[TEST_X509_NAME_MAX_COUNT]; int pos; } test_X509Name; static int test_xmlSecX509NameReadCallback( const xmlChar * name, const xmlChar * value, xmlSecSize valueSize, int type, void * context ) { test_X509Name * nm; xmlSecAssert2(name != NULL, -1); xmlSecAssert2(value != NULL, -1); xmlSecAssert2(context != NULL, -1); nm = (test_X509Name*)context; xmlSecAssert2(0 <= nm->pos && nm->pos < TEST_X509_NAME_MAX_COUNT, -1); #if defined(_MSC_VER) strcpy_s((char*)nm->names[nm->pos], sizeof(nm->names[nm->pos]), (const char*)name); strcpy_s((char*)nm->values[nm->pos], sizeof(nm->values[nm->pos]), (const char*)value); #else /* defined(_MSC_VER) */ strncpy((char*)nm->names[nm->pos], (const char*)name, sizeof(nm->names[nm->pos])); nm->names[nm->pos][sizeof(nm->names[nm->pos]) - 1] = '\0'; /* ensure \0 terminated */ strncpy((char*)nm->values[nm->pos], (const char*)value, sizeof(nm->values[nm->pos])); nm->values[nm->pos][sizeof(nm->values[nm->pos]) - 1] = '\0'; /* ensure \0 terminated */ #endif /* defined(_MSC_VER) */ nm->valueSizes[nm->pos] = valueSize; nm->types[nm->pos] = type; nm->pos += 1; return(0); } static void test_xmlSecX509NameRead_success( const char * name, const char * str, xmlSecx509NameReplacements * replacements, int expectedCount, const char * name0, const char * value0, int type0, const char * name1, const char * value1, int type1 ) { test_X509Name nms; int ret; xmlSecAssert(name != NULL); xmlSecAssert(str != NULL); testStart(name); memset(&nms, 0, sizeof(nms)); ret = xmlSecX509NameRead(BAD_CAST str, replacements, test_xmlSecX509NameReadCallback, &nms); if(ret < 0) { testLog("Error: xmlSecX509NameRead failed for '%s'\n", str); testFinishedFailure(); return; } /* check results */ if(nms.pos != expectedCount) { testLog("Error: xmlSecX509NameRead returned type='%d' (expected: '%d')\n", nms.pos , expectedCount); testFinishedFailure(); return; } if(nms.pos > 0 && xmlStrcmp(nms.names[0], BAD_CAST name0) != 0) { testLog("Error: xmlSecX509NameRead returned nms.names[0]='%s' (expected: '%s')\n", (const char*)nms.names[0], name0); testFinishedFailure(); return; } if(nms.pos > 0 && xmlStrcmp(nms.values[0], BAD_CAST value0) != 0) { testLog("Error: xmlSecX509NameRead returned nms.value[0]='%s' (expected: '%s')\n", (const char*)nms.values[0], value0); testFinishedFailure(); return; } if(nms.pos > 0 && (int)(nms.valueSizes[0]) != xmlStrlen(BAD_CAST value0)) { testLog("Error: xmlSecX509NameRead returned nms.valueSizes[0]='%d' (expected: '%d')\n", (int)(nms.valueSizes[0]), xmlStrlen(BAD_CAST value0)); testFinishedFailure(); return; } if(nms.pos > 0 && nms.types[0] != type0) { testLog("Error: xmlSecX509NameRead returned nms.types[0]='%d' (expected: '%d')\n", nms.types[0], type0); testFinishedFailure(); return; } if(nms.pos > 1 && xmlStrcmp(nms.names[1], BAD_CAST name1) != 0) { testLog("Error: xmlSecX509NameRead returned nms.names[1]='%s' (expected: '%s')\n", (const char*)nms.names[1], name1); testFinishedFailure(); return; } if(nms.pos > 1 && xmlStrcmp(nms.values[1], BAD_CAST value1) != 0) { testLog("Error: xmlSecX509NameRead returned nms.value[1]='%s' (expected: '%s')\n", (const char*)nms.values[1], value1); testFinishedFailure(); return; } if(nms.pos > 1 && (int)(nms.valueSizes[1]) != xmlStrlen(BAD_CAST value1)) { testLog("Error: xmlSecX509NameRead returned nms.valueSizes[0]='%d' (expected: '%d')\n", (int)(nms.valueSizes[1]), xmlStrlen(BAD_CAST value1)); testFinishedFailure(); return; } if(nms.pos > 1 && nms.types[1] != type1) { testLog("Error: xmlSecX509NameRead returned nms.types[1]='%d' (expected: '%d')\n", nms.types[1], type1); testFinishedFailure(); return; } /* DONE */ testFinishedSuccess(); } static void test_xmlSecX509NameRead_failure( const char * name, const char * str, xmlSecx509NameReplacements *replacements, int fail_callback ) { test_X509Name names; int ret; xmlSecAssert(name != NULL); testStart(name); memset(&names, 0, sizeof(names)); if (fail_callback != 0) { names.pos = -1; } ret = xmlSecX509NameRead(BAD_CAST str, replacements, test_xmlSecX509NameReadCallback, &names); if(ret >= 0) { testLog("Error: xmlSecX509NameRead expected to fail for '%s'\n", (str != NULL) ? str : "NULL"); testFinishedFailure(); return; } /* DONE */ testFinishedSuccess(); } static xmlSecx509NameReplacements test_X509NameReplacements[] = { { BAD_CAST "E", BAD_CAST "emailAddress"}, { NULL, NULL } }; int test_xmlSecX509NameRead(void) { /* start */ testGroupStart("xmlSecX509NameRead"); /* positive tests */ test_xmlSecX509NameRead_success("check empty string", "", NULL, 0, NULL, NULL, -1, NULL, NULL, -1); test_xmlSecX509NameRead_success("check one value", "Foo=Bar", NULL, 1, "Foo", "Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING, NULL, NULL, -1); test_xmlSecX509NameRead_success("check empty value", "Foo=", NULL, 1, "Foo", "", XMLSEC_X509_VALUE_TYPE_UF8_STRING, NULL, NULL, -1); test_xmlSecX509NameRead_success("check two values", "Foo=Bar,emailAddress=Value", NULL, 2, "Foo", "Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING, "emailAddress", "Value", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509NameRead_success("check two values with empty value", "Foo=,emailAddress=Value", NULL, 2, "Foo", "", XMLSEC_X509_VALUE_TYPE_UF8_STRING, "emailAddress", "Value", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509NameRead_success("check octet string", "Foo=Bar,emailAddress=#56616c7565", NULL, 2, "Foo", "Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING, "emailAddress", "Value", XMLSEC_X509_VALUE_TYPE_OCTET_STRING); test_xmlSecX509NameRead_success("check spaces", "Foo = Bar, emailAddress = Value", NULL, 2, "Foo", "Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING, "emailAddress", "Value", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509NameRead_success("check end comma", "Foo=Bar,emailAddress=Value,", NULL, 2, "Foo", "Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING, "emailAddress", "Value", XMLSEC_X509_VALUE_TYPE_UF8_STRING); test_xmlSecX509NameRead_success("check email address", "Foo=Bar,E=Value,", test_X509NameReplacements, 2, "Foo", "Bar", XMLSEC_X509_VALUE_TYPE_UF8_STRING, "emailAddress", "Value", XMLSEC_X509_VALUE_TYPE_UF8_STRING); /* negative tests */ test_xmlSecX509NameRead_failure("check NULL", NULL, NULL, 0); test_xmlSecX509NameRead_failure("check missing =", "Foo", NULL, 0); test_xmlSecX509NameRead_failure("check bad value", "Foo=#1Q", NULL, 0); test_xmlSecX509NameRead_failure("check missing name value pair", "Foo=Bar,,", NULL, 0); test_xmlSecX509NameRead_failure("check bad callback", "Foo=Bar", NULL, 1); /* done */ return (testGroupFinished()); } xmlsec-1.3.10/apps/unit_tests/xmlsec_unit_tests.c000066400000000000000000000167521516161755100221760ustar00rootroot00000000000000/** * XML Security Library (http://www.aleksey.com/xmlsec). * * Unit tests * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #include #include #include #include #if !defined(_MSC_VER) #include #endif /* defined(_MSC_VER) */ /* must be included before any other xmlsec header */ #include "xmlsec_unit_tests.h" #include "../src/x509_helpers.h" #if defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC) #include #endif /*defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC) */ /* per-test log buffer (defined after main; forward-declared here for use in main) */ static char * g_testLogBuffer; static size_t g_testLogBufferLen; static size_t g_testLogBufferCap; static void testXmlSecErrorsCallback(const char* file, int line, const char* func, const char* errorObject, const char* errorSubject, int reason, const char* msg); /* test group filter: if non-NULL, only the matching group runs */ static const char * g_testGroupFilter; static int g_testGroupSkip; #if defined(XMLSEC_WINDOWS) && defined(UNICODE) && defined(__MINGW32__) int wmain(int argc, wchar_t* argv[]); #endif /* defined(XMLSEC_WINDOWS) && defined(UNICODE) && defined(__MINGW32__) */ #if defined(XMLSEC_WINDOWS) && defined(UNICODE) int wmain(int argc, wchar_t *argv[]) { #else /* defined(XMLSEC_WINDOWS) && defined(UNICODE) */ int main(int argc, const char **argv) { #endif /* defined(XMLSEC_WINDOWS) && defined(UNICODE) */ int success = 1; int res = 1; #if defined(XMLSEC_WINDOWS) && defined(UNICODE) char testGroupFilterBuf[256] = { '\0' }; #endif /* defined(XMLSEC_WINDOWS) && defined(UNICODE) */ #if defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC) fprintf(stderr, "Enabling memory leaks detection\n"); _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif /* defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC) */ /* check command line params */ if((argc > 2) || (argv == NULL)) { fprintf(stderr, "Error: usage: xmlsec_unit_tests [test-group-name]\n"); goto done; } if(argc == 2) { #if defined(XMLSEC_WINDOWS) && defined(UNICODE) wcstombs_s(NULL, testGroupFilterBuf, sizeof(testGroupFilterBuf), argv[1], sizeof(testGroupFilterBuf) - 1); g_testGroupFilter = testGroupFilterBuf; #else /* defined(XMLSEC_WINDOWS) && defined(UNICODE) */ g_testGroupFilter = argv[1]; #endif /* defined(XMLSEC_WINDOWS) && defined(UNICODE) */ } xmlSecErrorsSetCallback(testXmlSecErrorsCallback); /* run tests */ fprintf(stdout, "=================== Checking xmlsec-core =================================\n"); if (test_base64() != 1) { success = 0; } if (test_transform_helpers() != 1) { success = 0; } if (test_xmlSecX509EscapedStringRead() != 1) { success = 0; } if (test_xmlSecX509AttrValueStringRead() != 1) { success = 0; } if (test_xmlSecX509NameRead() != 1) { success = 0; } if (test_xmltree() != 1) { success = 0; } if (test_templates() != 1) { success = 0; } if(success == 1) { /* sucecss! */ fprintf(stdout, "=================== Checking xmlsec-core: SUCCESS =================================\n"); res = 0; } else { fprintf(stdout, "=================== Checking xmlsec-core: FAILURE =================================\n"); res = 1; } done: #if defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC) _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); _CrtDumpMemoryLeaks(); #endif /* defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC) */ xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback); free(g_testLogBuffer); g_testLogBuffer = NULL; g_testGroupFilter = NULL; return(res); } static void testLogReset(void) { g_testLogBufferLen = 0; } static void testLogFlush(void) { if (g_testLogBufferLen > 0) { fwrite(g_testLogBuffer, 1, g_testLogBufferLen, stdout); fflush(stdout); } g_testLogBufferLen = 0; } void testLog(const char* fmt, ...) { char buf[8192]; va_list args; int len; char* newBuf; size_t newCap; if (fmt == NULL) return; va_start(args, fmt); len = vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); if (len <= 0) return; if ((size_t)len >= sizeof(buf)) { len = (int)(sizeof(buf) - 1); } if (g_testLogBufferLen + (size_t)len + 1 > g_testLogBufferCap) { newCap = g_testLogBufferLen + (size_t)len + 1 + 4096; newBuf = (char*)realloc(g_testLogBuffer, newCap); if (newBuf == NULL) return; g_testLogBuffer = newBuf; g_testLogBufferCap = newCap; } memcpy(g_testLogBuffer + g_testLogBufferLen, buf, (size_t)len); g_testLogBufferLen += (size_t)len; g_testLogBuffer[g_testLogBufferLen] = '\0'; } static void testXmlSecErrorsCallback(const char* file, int line, const char* func, const char* errorObject, const char* errorSubject, int reason, const char* msg) { testLog("xmlsec error: func=%s:file=%s:line=%d:obj=%s:subj=%s:error=%d:%s\n", (func != NULL) ? func : "unknown", (file != NULL) ? file : "unknown", line, (errorObject != NULL) ? errorObject : "unknown", (errorSubject != NULL) ? errorSubject : "unknown", reason, (msg != NULL) ? msg : ""); } static const char * testsGroupName = NULL; static const char * testsName = NULL; static int testsStarted = 0; static int testsFinishedSuccess = 0; static int testFinishedFailed = 0; void testGroupStart(const char * name) { xmlSecAssert(name != NULL); testsGroupName = name; testsStarted = 0; testsFinishedSuccess = 0; testFinishedFailed = 0; if((g_testGroupFilter != NULL) && (strcmp(g_testGroupFilter, name) != 0)) { g_testGroupSkip = 1; return; } g_testGroupSkip = 0; fprintf(stdout, "=== STARTED TESTS FOR '%s'\n", testsGroupName); } int testGroupFinished(void) { xmlSecAssert2(testsGroupName != NULL, 0); if(g_testGroupSkip) { g_testGroupSkip = 0; testsGroupName = NULL; return 1; } fprintf(stdout, "=== FINSIHED TESTS FOR '%s': TOTAL=%d, SUCCESS=%d, FAILURE=%d, NOT FIISHED=%d\n", testsGroupName, testsStarted, testsFinishedSuccess, testFinishedFailed, (testsStarted - (testsFinishedSuccess + testFinishedFailed)) ); testsGroupName = NULL; return testsStarted == testsFinishedSuccess ? 1 : 0; } void testStart(const char * name) { xmlSecAssert(name != NULL); if(g_testGroupSkip) { return; } testsName = name; testsStarted += 1; testLogReset(); testLog(" %s ...\n", testsName); fprintf(stdout, " %s ...\n", testsName); } void testFinishedSuccess(void) { if(g_testGroupSkip) { return; } fprintf(stdout, " %s OK\n", testsName); testLogReset(); testsFinishedSuccess += 1; testsName = NULL; } void testFinishedFailure(void) { if(g_testGroupSkip) { return; } fprintf(stdout, " %s FAILED\n", testsName); testLogFlush(); testFinishedFailed += 1; testsName = NULL; } xmlsec-1.3.10/apps/unit_tests/xmlsec_unit_tests.h000066400000000000000000000021401516161755100221650ustar00rootroot00000000000000/** * XMLSec library * * Unit tests * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #ifndef __XMLSEC_UNIT_TESTS_H__ #define __XMLSEC_UNIT_TESTS_H__ #define XMLSEC_PRIVATE 1 #include #include #include "../src/cast_helpers.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* helper functions */ void testGroupStart(const char * name); int testGroupFinished(void); void testStart(const char * name); void testFinishedSuccess(void); void testFinishedFailure(void); #ifdef __GNUC__ void testLog(const char* fmt, ...) __attribute__ ((format (printf, 1, 2))); #else /* __GNUC__ */ void testLog(const char* fmt, ...); #endif /* __GNUC__ */ /* tests */ int test_base64(void); int test_transform_helpers(void); int test_xmlSecX509EscapedStringRead(void); int test_xmlSecX509AttrValueStringRead(void); int test_xmlSecX509NameRead(void); int test_xmltree(void); int test_templates(void); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __XMLSEC_UNIT_TESTS_H__ */ xmlsec-1.3.10/apps/unit_tests/xmltree_unit_tests.c000066400000000000000000001217141516161755100223560ustar00rootroot00000000000000/** * XML Security Library (http://www.aleksey.com/xmlsec). * * xmltree unit tests * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #include #include #include /* must be included before any other xmlsec header */ #include "xmlsec_unit_tests.h" #include #include #include #define TEST_NS BAD_CAST "http://test.ns" /************************************************************************* * helpers *************************************************************************/ static xmlDocPtr xmltreeTestCreateDoc(const xmlChar* rootName, const xmlChar* rootNs) { xmlDocPtr doc; xmlNodePtr root; xmlNsPtr ns; doc = xmlNewDoc(BAD_CAST "1.0"); if(doc == NULL) { return(NULL); } root = xmlNewDocNode(doc, NULL, rootName, NULL); if(root == NULL) { xmlFreeDoc(doc); return(NULL); } xmlDocSetRootElement(doc, root); if(rootNs != NULL) { ns = xmlNewNs(root, rootNs, NULL); if(ns == NULL) { xmlFreeDoc(doc); return(NULL); } xmlSetNs(root, ns); } return(doc); } /************************************************************************* * xmlSecIsEmptyString *************************************************************************/ static void test_xmlSecIsEmptyString_empty(void) { testStart("xmlSecIsEmptyString: empty string"); if(xmlSecIsEmptyString(BAD_CAST "") != 1) { testLog("Error: empty string was not detected as empty\n"); testFinishedFailure(); return; } testFinishedSuccess(); } static void test_xmlSecIsEmptyString_whitespace_only(void) { testStart("xmlSecIsEmptyString: whitespace-only string"); if(xmlSecIsEmptyString(BAD_CAST " \t\n\r") != 1) { testLog("Error: whitespace-only string was not detected as empty\n"); testFinishedFailure(); return; } testFinishedSuccess(); } static void test_xmlSecIsEmptyString_nonempty(void) { testStart("xmlSecIsEmptyString: non-empty string"); if(xmlSecIsEmptyString(BAD_CAST "hello") != 0) { testLog("Error: non-empty string was detected as empty\n"); testFinishedFailure(); return; } testFinishedSuccess(); } static void test_xmlSecIsEmptyString_mixed_whitespace(void) { testStart("xmlSecIsEmptyString: string with embedded text"); if(xmlSecIsEmptyString(BAD_CAST " \t hello \t ") != 0) { testLog("Error: string with text was detected as empty\n"); testFinishedFailure(); return; } testFinishedSuccess(); } /************************************************************************* * xmlSecGetNodeContentAndTrim *************************************************************************/ static void test_xmlSecGetNodeContentAndTrim_plain(void) { xmlDocPtr doc; xmlNodePtr root; xmlChar* content; testStart("xmlSecGetNodeContentAndTrim: plain content"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST "hello"); content = xmlSecGetNodeContentAndTrim(root); if(content == NULL || xmlStrcmp(content, BAD_CAST "hello") != 0) { testLog("Error: expected 'hello', got '%s'\n", content ? (char*)content : "NULL"); xmlFree(content); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFree(content); xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecGetNodeContentAndTrim_leading_trailing_spaces(void) { xmlDocPtr doc; xmlNodePtr root; xmlChar* content; testStart("xmlSecGetNodeContentAndTrim: leading/trailing spaces trimmed"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST " hello world "); content = xmlSecGetNodeContentAndTrim(root); if(content == NULL || xmlStrcmp(content, BAD_CAST "hello world") != 0) { testLog("Error: expected 'hello world', got '%s'\n", content ? (char*)content : "NULL"); xmlFree(content); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFree(content); xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecGetNodeContentAndTrim_tabs_and_newlines(void) { xmlDocPtr doc; xmlNodePtr root; xmlChar* content; testStart("xmlSecGetNodeContentAndTrim: tabs and newlines trimmed"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST "\t\n value \n\t"); content = xmlSecGetNodeContentAndTrim(root); if(content == NULL || xmlStrcmp(content, BAD_CAST "value") != 0) { testLog("Error: expected 'value', got '%s'\n", content ? (char*)content : "NULL"); xmlFree(content); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFree(content); xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecGetNodeContentAndTrim_whitespace_only_becomes_empty(void) { xmlDocPtr doc; xmlNodePtr root; xmlChar* content; testStart("xmlSecGetNodeContentAndTrim: whitespace-only content returns empty string"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST " \t "); content = xmlSecGetNodeContentAndTrim(root); /* whitespace-only input → trimmed to empty string "" (not NULL) */ if(content == NULL || xmlStrcmp(content, BAD_CAST "") != 0) { testLog("Error: expected empty string, got '%s'\n", content ? (char*)content : "NULL"); xmlFree(content); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFree(content); xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecGetNodeContentAsSize *************************************************************************/ static void test_xmlSecGetNodeContentAsSize_valid(void) { xmlDocPtr doc; xmlNodePtr root; xmlSecSize val = 0; int ret; testStart("xmlSecGetNodeContentAsSize: valid number"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST "42"); ret = xmlSecGetNodeContentAsSize(root, 0, &val); if(ret < 0 || val != 42) { testLog("Error: expected val=42, got ret=%d val=%u\n", ret, (unsigned int)val); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecGetNodeContentAsSize_with_spaces(void) { xmlDocPtr doc; xmlNodePtr root; xmlSecSize val = 0; int ret; testStart("xmlSecGetNodeContentAsSize: number with surrounding spaces"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST " 128 "); ret = xmlSecGetNodeContentAsSize(root, 0, &val); if(ret < 0 || val != 128) { testLog("Error: expected val=128, got ret=%d val=%u\n", ret, (unsigned int)val); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecGetNodeContentAsSize_zero(void) { xmlDocPtr doc; xmlNodePtr root; xmlSecSize val = 99; int ret; testStart("xmlSecGetNodeContentAsSize: zero value"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST "0"); ret = xmlSecGetNodeContentAsSize(root, 99, &val); if(ret < 0 || val != 0) { testLog("Error: expected val=0, got ret=%d val=%u\n", ret, (unsigned int)val); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecGetNodeContentAsSize_negative_fails(void) { xmlDocPtr doc; xmlNodePtr root; xmlSecSize val = 0; int ret; testStart("xmlSecGetNodeContentAsSize: negative number fails"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST "-5"); ret = xmlSecGetNodeContentAsSize(root, 0, &val); if(ret >= 0) { testLog("Error: expected failure for negative number, got ret=%d\n", ret); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecGetNodeContentAsSize_nonnumeric_fails(void) { xmlDocPtr doc; xmlNodePtr root; xmlSecSize val = 0; int ret; testStart("xmlSecGetNodeContentAsSize: non-numeric content fails"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST "abc"); ret = xmlSecGetNodeContentAsSize(root, 0, &val); if(ret >= 0) { testLog("Error: expected failure for non-numeric content, got ret=%d\n", ret); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecGetNodeContentAsHex / xmlSecSetNodeContentAsHex *************************************************************************/ static void test_xmlSecNodeContentHex_roundtrip(void) { static const xmlSecByte data[] = { 0x00, 0x11, 0xAB, 0xCD, 0xEF, 0xFF }; xmlDocPtr doc; xmlNodePtr root; xmlSecBuffer buf; const xmlSecByte* bufData; xmlSecSize bufSize; int ret; testStart("xmlSecSetNodeContentAsHex/xmlSecGetNodeContentAsHex: roundtrip"); ret = xmlSecBufferInitialize(&buf, 64); if(ret < 0) { testLog("Error: failed to initialize buffer\n"); testFinishedFailure(); return; } doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); xmlSecBufferFinalize(&buf); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); ret = xmlSecSetNodeContentAsHex(root, data, sizeof(data)); if(ret < 0) { testLog("Error: xmlSecSetNodeContentAsHex failed\n"); xmlFreeDoc(doc); xmlSecBufferFinalize(&buf); testFinishedFailure(); return; } ret = xmlSecGetNodeContentAsHex(root, &buf); if(ret < 0) { testLog("Error: xmlSecGetNodeContentAsHex failed\n"); xmlFreeDoc(doc); xmlSecBufferFinalize(&buf); testFinishedFailure(); return; } bufData = xmlSecBufferGetData(&buf); bufSize = xmlSecBufferGetSize(&buf); if(bufSize != sizeof(data) || bufData == NULL || memcmp(bufData, data, sizeof(data)) != 0) { testLog("Error: hex roundtrip data mismatch (size=%u, expected=%u)\n", (unsigned int)bufSize, (unsigned int)sizeof(data)); xmlFreeDoc(doc); xmlSecBufferFinalize(&buf); testFinishedFailure(); return; } xmlFreeDoc(doc); xmlSecBufferFinalize(&buf); testFinishedSuccess(); } static void test_xmlSecSetNodeContentAsHex_encoding(void) { static const xmlSecByte data[] = { 0xDE, 0xAD, 0xBE, 0xEF }; static const char expected[] = "deadbeef"; xmlDocPtr doc; xmlNodePtr root; xmlChar* content; int ret; testStart("xmlSecSetNodeContentAsHex: correct lowercase hex encoding"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); ret = xmlSecSetNodeContentAsHex(root, data, sizeof(data)); if(ret < 0) { testLog("Error: xmlSecSetNodeContentAsHex failed\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } content = xmlNodeGetContent(root); if(content == NULL || xmlStrcmp(content, BAD_CAST expected) != 0) { testLog("Error: expected '%s', got '%s'\n", expected, content ? (char*)content : "NULL"); xmlFree(content); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFree(content); xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecSetNodeContentAsHex_empty(void) { xmlDocPtr doc; xmlNodePtr root; xmlChar* content; int ret; testStart("xmlSecSetNodeContentAsHex: empty data produces empty content"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); ret = xmlSecSetNodeContentAsHex(root, BAD_CAST "", 0); if(ret < 0) { testLog("Error: xmlSecSetNodeContentAsHex failed for empty data\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } content = xmlNodeGetContent(root); if(content == NULL || xmlStrcmp(content, BAD_CAST "") != 0) { testLog("Error: expected empty string, got '%s'\n", content ? (char*)content : "NULL"); xmlFree(content); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFree(content); xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecIsEmptyNode *************************************************************************/ static void test_xmlSecIsEmptyNode_no_children(void) { xmlDocPtr doc; xmlNodePtr root; int ret; testStart("xmlSecIsEmptyNode: no children"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); ret = xmlSecIsEmptyNode(root); if(ret != 1) { testLog("Error: expected empty (1), got %d\n", ret); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecIsEmptyNode_whitespace_text(void) { xmlDocPtr doc; xmlNodePtr root; int ret; testStart("xmlSecIsEmptyNode: whitespace-only text child"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST " \n\t "); ret = xmlSecIsEmptyNode(root); if(ret != 1) { testLog("Error: expected empty (1) for whitespace-only node, got %d\n", ret); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecIsEmptyNode_text_content(void) { xmlDocPtr doc; xmlNodePtr root; int ret; testStart("xmlSecIsEmptyNode: non-empty text content"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); xmlNodeSetContent(root, BAD_CAST "hello"); ret = xmlSecIsEmptyNode(root); if(ret != 0) { testLog("Error: expected non-empty (0), got %d\n", ret); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecIsEmptyNode_child_element(void) { xmlDocPtr doc; xmlNodePtr root; int ret; testStart("xmlSecIsEmptyNode: child element makes node non-empty"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); if(xmlNewChild(root, NULL, BAD_CAST "Child", NULL) == NULL) { testLog("Error: failed to add child element\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } ret = xmlSecIsEmptyNode(root); if(ret != 0) { testLog("Error: expected non-empty (0) for node with element child, got %d\n", ret); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecCreateTree *************************************************************************/ static void test_xmlSecCreateTree_with_ns(void) { xmlDocPtr doc; xmlNodePtr root; const xmlChar* nsHref; testStart("xmlSecCreateTree: creates tree with correct root name and namespace"); doc = xmlSecCreateTree(BAD_CAST "TestRoot", BAD_CAST "http://test.example.com/ns"); if(doc == NULL) { testLog("Error: xmlSecCreateTree returned NULL\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); if(root == NULL) { testLog("Error: no root element\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } if(xmlStrcmp(root->name, BAD_CAST "TestRoot") != 0) { testLog("Error: expected root name 'TestRoot', got '%s'\n", (char*)root->name); xmlFreeDoc(doc); testFinishedFailure(); return; } nsHref = xmlSecGetNodeNsHref(root); if(nsHref == NULL || xmlStrcmp(nsHref, BAD_CAST "http://test.example.com/ns") != 0) { testLog("Error: expected ns 'http://test.example.com/ns', got '%s'\n", nsHref ? (char*)nsHref : "NULL"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecCreateTree_null_ns(void) { xmlDocPtr doc; xmlNodePtr root; testStart("xmlSecCreateTree: creates tree with NULL namespace"); doc = xmlSecCreateTree(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: xmlSecCreateTree returned NULL\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); if(root == NULL || xmlStrcmp(root->name, BAD_CAST "Root") != 0) { testLog("Error: root element missing or wrong name\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecAddChild *************************************************************************/ static void test_xmlSecAddChild_name_and_ns(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child; const xmlChar* nsHref; testStart("xmlSecAddChild: child has correct name and namespace"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child = xmlSecAddChild(root, BAD_CAST "Child", BAD_CAST "http://ns.example.com"); if(child == NULL) { testLog("Error: xmlSecAddChild returned NULL\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } if(xmlStrcmp(child->name, BAD_CAST "Child") != 0) { testLog("Error: expected name 'Child', got '%s'\n", (char*)child->name); xmlFreeDoc(doc); testFinishedFailure(); return; } nsHref = xmlSecGetNodeNsHref(child); if(nsHref == NULL || xmlStrcmp(nsHref, BAD_CAST "http://ns.example.com") != 0) { testLog("Error: expected ns 'http://ns.example.com', got '%s'\n", nsHref ? (char*)nsHref : "NULL"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecAddChild_multiple_distinct(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child1, child2; testStart("xmlSecAddChild: two calls produce two distinct nodes"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child1 = xmlSecAddChild(root, BAD_CAST "First", BAD_CAST "http://ns.example.com"); child2 = xmlSecAddChild(root, BAD_CAST "Second", BAD_CAST "http://ns.example.com"); if(child1 == NULL || child2 == NULL || child1 == child2) { testLog("Error: expected two distinct children\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecCheckNodeName *************************************************************************/ static void test_xmlSecCheckNodeName_match(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child; testStart("xmlSecCheckNodeName: matching name and ns returns 1"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child = xmlSecAddChild(root, BAD_CAST "Target", TEST_NS); if(child == NULL) { testLog("Error: failed to add child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } if(xmlSecCheckNodeName(child, BAD_CAST "Target", TEST_NS) != 1) { testLog("Error: expected 1 for matching name and ns\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecCheckNodeName_wrong_name(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child; testStart("xmlSecCheckNodeName: wrong name returns 0"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child = xmlSecAddChild(root, BAD_CAST "Target", TEST_NS); if(child == NULL) { testLog("Error: failed to add child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } if(xmlSecCheckNodeName(child, BAD_CAST "Other", TEST_NS) != 0) { testLog("Error: expected 0 for wrong name\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecCheckNodeName_wrong_ns(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child; testStart("xmlSecCheckNodeName: wrong namespace returns 0"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child = xmlSecAddChild(root, BAD_CAST "Target", TEST_NS); if(child == NULL) { testLog("Error: failed to add child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } if(xmlSecCheckNodeName(child, BAD_CAST "Target", BAD_CAST "http://other.ns") != 0) { testLog("Error: expected 0 for wrong namespace\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecFindChild *************************************************************************/ static void test_xmlSecFindChild_found(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child, found; testStart("xmlSecFindChild: finds existing child"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child = xmlSecAddChild(root, BAD_CAST "Child", TEST_NS); if(child == NULL) { testLog("Error: failed to add child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecFindChild(root, BAD_CAST "Child", TEST_NS); if(found == NULL || found != child) { testLog("Error: xmlSecFindChild did not return the expected node\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecFindChild_not_found(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr found; testStart("xmlSecFindChild: returns NULL when child not found"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); found = xmlSecFindChild(root, BAD_CAST "Missing", TEST_NS); if(found != NULL) { testLog("Error: expected NULL for missing child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecFindChild_first_of_two(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child1, child2, found; testStart("xmlSecFindChild: returns first matching child when multiple exist"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child1 = xmlSecAddChild(root, BAD_CAST "Child", TEST_NS); child2 = xmlSecAddChild(root, BAD_CAST "Child", TEST_NS); if(child1 == NULL || child2 == NULL) { testLog("Error: failed to add children\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecFindChild(root, BAD_CAST "Child", TEST_NS); if(found != child1) { testLog("Error: expected first child to be returned\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecFindSibling *************************************************************************/ static void test_xmlSecFindSibling_finds_next(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child1, child2, found; testStart("xmlSecFindSibling: finds next sibling by name and ns"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child1 = xmlSecAddChild(root, BAD_CAST "First", TEST_NS); child2 = xmlSecAddChild(root, BAD_CAST "Second", TEST_NS); if(child1 == NULL || child2 == NULL) { testLog("Error: failed to add children\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecFindSibling(child1, BAD_CAST "Second", TEST_NS); if(found == NULL || found != child2) { testLog("Error: xmlSecFindSibling did not find second child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecFindSibling_matches_self(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child, found; testStart("xmlSecFindSibling: matches self if it satisfies criteria"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child = xmlSecAddChild(root, BAD_CAST "Only", TEST_NS); if(child == NULL) { testLog("Error: failed to add child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecFindSibling(child, BAD_CAST "Only", TEST_NS); if(found != child) { testLog("Error: expected self to be returned\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecFindParent *************************************************************************/ static void test_xmlSecFindParent_matches_self(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr found; testStart("xmlSecFindParent: returns self when cur matches"); doc = xmlSecCreateTree(BAD_CAST "Root", TEST_NS); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); found = xmlSecFindParent(root, BAD_CAST "Root", TEST_NS); if(found != root) { testLog("Error: expected self, got different node\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecFindParent_finds_ancestor(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr middle, leaf; xmlNodePtr found; testStart("xmlSecFindParent: finds ancestor by walking up tree"); doc = xmlSecCreateTree(BAD_CAST "Root", TEST_NS); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); middle = xmlSecAddChild(root, BAD_CAST "Middle", TEST_NS); leaf = xmlSecAddChild(middle, BAD_CAST "Leaf", TEST_NS); if(middle == NULL || leaf == NULL) { testLog("Error: failed to add nodes\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecFindParent(leaf, BAD_CAST "Root", TEST_NS); if(found != root) { testLog("Error: expected root ancestor\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecFindParent_not_found(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child; xmlNodePtr found; testStart("xmlSecFindParent: returns NULL when no match found"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child = xmlSecAddChild(root, BAD_CAST "Child", TEST_NS); if(child == NULL) { testLog("Error: failed to add child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecFindParent(child, BAD_CAST "Missing", TEST_NS); if(found != NULL) { testLog("Error: expected NULL for non-existent ancestor\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecFindNode *************************************************************************/ static void test_xmlSecFindNode_direct_child(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr child, found; testStart("xmlSecFindNode: finds direct child"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); child = xmlSecAddChild(root, BAD_CAST "Target", TEST_NS); if(child == NULL) { testLog("Error: failed to add child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecFindNode(root, BAD_CAST "Target", TEST_NS); if(found != child) { testLog("Error: xmlSecFindNode did not find direct child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecFindNode_nested_child(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr parent, target, found; testStart("xmlSecFindNode: finds deeply nested node"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); parent = xmlSecAddChild(root, BAD_CAST "Parent", TEST_NS); target = xmlSecAddChild(parent, BAD_CAST "DeepNode", TEST_NS); if(parent == NULL || target == NULL) { testLog("Error: failed to add nodes\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecFindNode(root, BAD_CAST "DeepNode", TEST_NS); if(found != target) { testLog("Error: xmlSecFindNode did not find nested node\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecFindNode_not_found(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr found; testStart("xmlSecFindNode: returns NULL when node not found"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); found = xmlSecFindNode(root, BAD_CAST "Missing", TEST_NS); if(found != NULL) { testLog("Error: expected NULL\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * xmlSecGetNextElementNode *************************************************************************/ static void test_xmlSecGetNextElementNode_already_element(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr elem, found; testStart("xmlSecGetNextElementNode: returns self when already an element"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); elem = xmlSecAddChild(root, BAD_CAST "Elem", TEST_NS); if(elem == NULL) { testLog("Error: failed to add child\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecGetNextElementNode(elem); if(found != elem) { testLog("Error: expected same element node, got different node\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecGetNextElementNode_skips_text(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr textNode, elemNode, found; testStart("xmlSecGetNextElementNode: skips text node to find element"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); /* build: sometext */ textNode = xmlNewText(BAD_CAST "some text"); if(textNode == NULL) { testLog("Error: failed to create text node\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlAddChild(root, textNode); elemNode = xmlNewChild(root, NULL, BAD_CAST "Elem", NULL); if(elemNode == NULL) { testLog("Error: failed to add element node\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } found = xmlSecGetNextElementNode(textNode); if(found != elemNode) { testLog("Error: expected element node after text, got unexpected node\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } static void test_xmlSecGetNextElementNode_no_elements(void) { xmlDocPtr doc; xmlNodePtr root; xmlNodePtr textNode, found; testStart("xmlSecGetNextElementNode: returns NULL when no element follows"); doc = xmltreeTestCreateDoc(BAD_CAST "Root", NULL); if(doc == NULL) { testLog("Error: failed to create doc\n"); testFinishedFailure(); return; } root = xmlDocGetRootElement(doc); textNode = xmlNewText(BAD_CAST "only text"); if(textNode == NULL) { testLog("Error: failed to create text node\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlAddChild(root, textNode); found = xmlSecGetNextElementNode(textNode); if(found != NULL) { testLog("Error: expected NULL when no element follows text\n"); xmlFreeDoc(doc); testFinishedFailure(); return; } xmlFreeDoc(doc); testFinishedSuccess(); } /************************************************************************* * exported entry point *************************************************************************/ int test_xmltree(void) { int success = 1; testGroupStart("xmlSecIsEmptyString"); test_xmlSecIsEmptyString_empty(); test_xmlSecIsEmptyString_whitespace_only(); test_xmlSecIsEmptyString_nonempty(); test_xmlSecIsEmptyString_mixed_whitespace(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecGetNodeContentAndTrim"); test_xmlSecGetNodeContentAndTrim_plain(); test_xmlSecGetNodeContentAndTrim_leading_trailing_spaces(); test_xmlSecGetNodeContentAndTrim_tabs_and_newlines(); test_xmlSecGetNodeContentAndTrim_whitespace_only_becomes_empty(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecGetNodeContentAsSize"); test_xmlSecGetNodeContentAsSize_valid(); test_xmlSecGetNodeContentAsSize_with_spaces(); test_xmlSecGetNodeContentAsSize_zero(); test_xmlSecGetNodeContentAsSize_negative_fails(); test_xmlSecGetNodeContentAsSize_nonnumeric_fails(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecNodeContentHex"); test_xmlSecNodeContentHex_roundtrip(); test_xmlSecSetNodeContentAsHex_encoding(); test_xmlSecSetNodeContentAsHex_empty(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecIsEmptyNode"); test_xmlSecIsEmptyNode_no_children(); test_xmlSecIsEmptyNode_whitespace_text(); test_xmlSecIsEmptyNode_text_content(); test_xmlSecIsEmptyNode_child_element(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecCreateTree"); test_xmlSecCreateTree_with_ns(); test_xmlSecCreateTree_null_ns(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecAddChild"); test_xmlSecAddChild_name_and_ns(); test_xmlSecAddChild_multiple_distinct(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecCheckNodeName"); test_xmlSecCheckNodeName_match(); test_xmlSecCheckNodeName_wrong_name(); test_xmlSecCheckNodeName_wrong_ns(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecFindChild"); test_xmlSecFindChild_found(); test_xmlSecFindChild_not_found(); test_xmlSecFindChild_first_of_two(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecFindSibling"); test_xmlSecFindSibling_finds_next(); test_xmlSecFindSibling_matches_self(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecFindParent"); test_xmlSecFindParent_matches_self(); test_xmlSecFindParent_finds_ancestor(); test_xmlSecFindParent_not_found(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecFindNode"); test_xmlSecFindNode_direct_child(); test_xmlSecFindNode_nested_child(); test_xmlSecFindNode_not_found(); if(testGroupFinished() != 1) { success = 0; } testGroupStart("xmlSecGetNextElementNode"); test_xmlSecGetNextElementNode_already_element(); test_xmlSecGetNextElementNode_skips_text(); test_xmlSecGetNextElementNode_no_elements(); if(testGroupFinished() != 1) { success = 0; } return(success); } xmlsec-1.3.10/apps/xmlsec.c000066400000000000000000004001331516161755100155020ustar00rootroot00000000000000/** * XML Security Library (http://www.aleksey.com/xmlsec). * * Command line utility. * * See Copyright for the status of this software. * * Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved. */ #include #include #include #if !defined(_MSC_VER) #include #endif /* defined(_MSC_VER) */ #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf #endif /* defined(_MSC_VER) && _MSC_VER < 1900 */ #include #include #include #include #include #include #ifndef XMLSEC_NO_XSLT #include #include #include #include #include #include #endif /* XMLSEC_NO_XSLT */ #include #include #include #include #include #include #include #include #include #include #include #include #include "crypto.h" #include "cmdline.h" #if defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC) #include #endif /*defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC) */ static const char copyright[] = "Written by Aleksey Sanin .\n\n" "Copyright (C) 2002-2024 Aleksey Sanin . All Rights Reserved.\n" "This is free software: see the source for copying information.\n"; static const char bugs[] = "Report bugs to http://www.aleksey.com/xmlsec/bugs.html\n"; static const char helpCommands1[] = "Usage: xmlsec [] []\n" "\n" "xmlsec is a command line tool for signing, verifying, encrypting and\n" "decrypting XML documents. The allowed values are:\n" " --help " "\tdisplay this help information and exit\n" " --help-all " "\tdisplay help information for all commands/options and exit\n" " --help-" "\tdisplay help information for command and exit\n" " --version " "\tprint version information and exit\n" " --keys " "\tkeys XML file manipulation\n"; static const char helpCommands2[] = #ifndef XMLSEC_NO_XMLDSIG " --sign " "\tsign data and output XML document\n" " --verify " "\tverify signed document\n" #endif /* XMLSEC_NO_XMLDSIG */ #ifndef XMLSEC_NO_XMLENC " --encrypt " "\tencrypt data and output XML document\n" " --decrypt " "\tdecrypt data from XML document\n" #endif /* XMLSEC_NO_XMLENC */ ; static const char helpVersion[] = "Usage: xmlsec version\n" "Prints version information and exits\n"; static const char helpKeys[] = "Usage: xmlsec keys [] \n" "Creates a new XML keys file \n"; static const char helpSign[] = "Usage: xmlsec sign [] \n" "Calculates XML Digital Signature using template file \n"; static const char helpVerify[] = "Usage: xmlsec verify [] \n" "Verifies XML Digital Signature in the \n"; static const char helpEncrypt[] = "Usage: xmlsec encrypt [] \n" "Encrypts data and creates XML Encryption using template file \n"; static const char helpDecrypt[] = "Usage: xmlsec decrypt [] \n" "Decrypts XML Encryption data in the \n"; static const char helpListKeyData[] = "Usage: xmlsec list-key-data\n" "Prints the list of known key data klasses\n"; static const char helpCheckKeyData[] = "Usage: xmlsec check-key-data [ ... ]\n" "Checks the given key-data against the list of known key-data klasses\n"; static const char helpListTransforms[] = "Usage: xmlsec list-transforms\n" "Prints the list of known transform klasses\n"; static const char helpCheckTransforms[] = "Usage: xmlsec check-transforms [ ... ]\n" "Checks the given transforms against the list of known transform klasses\n"; #define xmlSecAppCmdLineTopicGeneral 0x0001 #define xmlSecAppCmdLineTopicDSigCommon 0x0002 #define xmlSecAppCmdLineTopicDSigSign 0x0004 #define xmlSecAppCmdLineTopicDSigVerify 0x0008 #define xmlSecAppCmdLineTopicEncCommon 0x0010 #define xmlSecAppCmdLineTopicEncEncrypt 0x0020 #define xmlSecAppCmdLineTopicEncDecrypt 0x0040 /* #define UNUSED 0x0080 */ #define xmlSecAppCmdLineTopicKeysMngr 0x1000 #define xmlSecAppCmdLineTopicX509Certs 0x2000 #define xmlSecAppCmdLineTopicVersion 0x4000 #define xmlSecAppCmdLineTopicCryptoConfig 0x8000 #define xmlSecAppCmdLineTopicAll 0xFFFF /**************************************************************** * * General configuration params * ***************************************************************/ static xmlSecAppCmdLineParam helpParam = { xmlSecAppCmdLineTopicGeneral, "--help", "-h", "--help" "\n\tprint help information about the command", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam cryptoParam = { xmlSecAppCmdLineTopicCryptoConfig, "--crypto", NULL, "--crypto " "\n\tthe name of the crypto engine to use from the following" "\n\tlist: openssl, mscrypto, nss, gnutls, gcrypt (if no crypto engine is" "\n\tspecified then the default one is used)", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam cryptoConfigParam = { xmlSecAppCmdLineTopicCryptoConfig, "--crypto-config", NULL, "--crypto-config " "\n\tpath to crypto engine configuration", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam repeatParam = { xmlSecAppCmdLineTopicCryptoConfig, "--repeat", "-r", "--repeat " "\n\trepeat the operation times", xmlSecAppCmdLineParamTypeNumber, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam base64LineSizeParam = { xmlSecAppCmdLineTopicCryptoConfig, "--base64-line-size", NULL, "--base64-line-size " "\n\tsets the max line size for base64 encodings to ", xmlSecAppCmdLineParamTypeNumber, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam transformBinChunkSizeParam = { xmlSecAppCmdLineTopicCryptoConfig, "--transform-binary-chunk-size", NULL, "--transform-binary-chunk-size " "\n\tsets the transforms binary processing chunk size to ; " "\n\tincreasing chunk size might improve performance at the expense" "\n\tof increased memory usage", xmlSecAppCmdLineParamTypeNumber, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam verboseParam = { xmlSecAppCmdLineTopicGeneral, "--verbose", NULL, "--verbose" "\n\tprint detailed error messages", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam printCryptoErrorsParam = { xmlSecAppCmdLineTopicGeneral, "--print-crypto-library-errors", NULL, "--print-crypto-library-errors" "\n\tprint errors from crypto library (OpenSSL only)", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; /**************************************************************** * * Keys Manager params * ***************************************************************/ static xmlSecAppCmdLineParam genKeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--gen-key", "-g", "--gen-key[:] -" "\n\tgenerate new key of bits size," "\n\tset the key name to and add the result to keys" "\n\tmanager (for example, \"--gen:MyKeyName rsa-1024\" generates" "\n\ta new 1024 bits RSA key and sets it's name to \"MyKeyName\")", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam keysFileParam = { xmlSecAppCmdLineTopicKeysMngr, "--keys-file", "-k", "--keys-file " "\n\tload keys from XML file", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam privkeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--privkey-pem", "--privkey", "--privkey-pem[:] [,[,[...]]]" "\n\tload private key from PEM file and certificates" "\n\tthat verify this key", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam privkeyDerParam = { xmlSecAppCmdLineTopicKeysMngr, "--privkey-der", NULL, "--privkey-der[:] [,[,[...]]]" "\n\tload private key from DER file and certificates" "\n\tthat verify this key", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam pkcs8PemParam = { xmlSecAppCmdLineTopicKeysMngr, "--pkcs8-pem", "--privkey-p8-pem", "--pkcs8-pem[:] [,[,[...]]]" "\n\tload private key from PKCS8 PEM file and PEM certificates" "\n\tthat verify this key", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam pkcs8DerParam = { xmlSecAppCmdLineTopicKeysMngr, "--pkcs8-der", "--privkey-p8-der", "--pkcs8-der[:] [,[,[...]]]" "\n\tload private key from PKCS8 DER file and DER certificates" "\n\tthat verify this key", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; /* openssl specific privkey options */ static xmlSecAppCmdLineParam privkeyOpensslStoreParam = { xmlSecAppCmdLineTopicKeysMngr, "--privkey-openssl-store", NULL, "--privkey-openssl-store[:] " "\n\tload private key and certs through OpenSSL ossl_store interface (e.g. from HSM)", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam privkeyOpensslEngineParam = { xmlSecAppCmdLineTopicKeysMngr, "--privkey-openssl-engine", NULL, "--privkey-openssl-engine[:] ;[,[,[...]]]" "\n\tload private key by OpenSSL ENGINE interface; specify the name of engine" "\n\t(like with -engine params), the key specs (like with -inkey or -key params)" "\n\tand optionally certificates that verify this key", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam pubkeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--pubkey-pem", "--pubkey", "--pubkey-pem[:] " "\n\tload public key from PEM file", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam pubkeyDerParam = { xmlSecAppCmdLineTopicKeysMngr, "--pubkey-der", NULL, "--pubkey-der[:] " "\n\tload public key from DER file", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; /* openssl specific pubkey options */ static xmlSecAppCmdLineParam pubkeyOpensslStoreParam = { xmlSecAppCmdLineTopicKeysMngr, "--pubkey-openssl-store", NULL, "--pubkey-openssl-store[:] " "\n\tload pubkey key and certs through OpenSSL ossl_store interface (e.g. from HSM)", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam pubkeyOpensslEngineParam = { xmlSecAppCmdLineTopicKeysMngr, "--pubkey-openssl-engine", NULL, "--pubkey-openssl-engine[:] ;[,[,[...]]]" "\n\tload public key by OpenSSL ENGINE interface; specify the name of engine" "\n\t(like with -engine params), the key specs (like with -inkey or -key params)" "\n\tand optionally certificates that verify this key", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; #ifndef XMLSEC_NO_AES static xmlSecAppCmdLineParam aesKeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--aes-key", "--aeskey", "--aes-key[:] " "\n\tload AES key from binary file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; #endif /* XMLSEC_NO_AES */ #ifndef XMLSEC_NO_CAMELLIA static xmlSecAppCmdLineParam camelliaKeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--camellia-key", "--camelliakey", "--camellia-key[:] " "\n\tload Camellia key from binary file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; #endif /* XMLSEC_NO_CAMELLIA */ #ifndef XMLSEC_NO_CHACHA20 static xmlSecAppCmdLineParam chacha20KeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--chacha20-key", "--chacha20key", "--chacha20-key[:] " "\n\tload ChaCha20 key from binary file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; #endif /* XMLSEC_NO_CHACHA20 */ #ifndef XMLSEC_NO_CONCATKDF static xmlSecAppCmdLineParam concatKdfKeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--concatkdfkey", "--concatkdf-key", "--concatkdf-key[:] " "\n\tload ConcatKDF key from binary file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; #endif /* XMLSEC_NO_CONCATKDF */ #ifndef XMLSEC_NO_DES static xmlSecAppCmdLineParam desKeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--des-key", "--deskey", "--des-key[:] " "\n\tload DES key from binary file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; #endif /* XMLSEC_NO_DES */ #ifndef XMLSEC_NO_HMAC static xmlSecAppCmdLineParam hmacKeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--hmac-key", "--hmackey", "--hmac-key[:] " "\n\tload HMAC key from binary file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam hmacMinOutputLenParam = { xmlSecAppCmdLineTopicKeysMngr, "--hmac-min-out-len", NULL, "--hmac-min-out-len " "\n\tsets minimum HMAC output length to ", xmlSecAppCmdLineParamTypeNumber, xmlSecAppCmdLineParamFlagParamNameValue, NULL }; #endif /* XMLSEC_NO_HMAC */ #ifndef XMLSEC_NO_PBKDF2 static xmlSecAppCmdLineParam pbkdf2KeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--pbkdf2key", "--pbkdf2-key", "--pbkdf2-key[:] " "\n\tload Pbkdf2 key from binary file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; #endif /* XMLSEC_NO_PBKDF2 */ #ifndef XMLSEC_NO_HKDF static xmlSecAppCmdLineParam hkdfKeyParam = { xmlSecAppCmdLineTopicKeysMngr, "--hkdfkey", "--hkdf-key", "--hkdf-key[:] " "\n\tload HKDF key (IKM) from binary file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; #endif /* XMLSEC_NO_HKDF */ static xmlSecAppCmdLineParam pwdParam = { xmlSecAppCmdLineTopicKeysMngr, "--pwd", NULL, "--pwd " "\n\tthe password to use for reading keys and certs", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam enabledKeyDataParam = { xmlSecAppCmdLineTopicKeysMngr, "--enabled-key-data", NULL, "--enabled-key-data " "\n\tcomma-separated list of key-data types to enable." "\n\tExample:" "\n\t rsa,key-value,x509 -> populates and keeps " "\n\t when and placeholders" "\n\t are present in the template." "\n\tUse \"--list-key-data\" to view full list of registered key data klasses." "\n\tBy default, all registered key data are enabled.", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam enabledRetrievalMethodUrisParam = { xmlSecAppCmdLineTopicKeysMngr, "--enabled-retrieval-method-uris", NULL, "--enabled-retrieval-method-uris " "\n\tcomma separated list of of the following values:" "\n\t\"empty\", \"same-doc\", \"local\",\"remote\" to restrict possible URI" "\n\tattribute values for the element.", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam enabledKeyInfoReferenceUrisParam = { xmlSecAppCmdLineTopicKeysMngr, "--enabled-key-info-reference-uris", NULL, "--enabled-key-info-reference-uris " "\n\tcomma separated list of of the following values:" "\n\t\"empty\", \"same-doc\", \"local\",\"remote\" to restrict possible URI" "\n\tattribute values for the element.", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam laxKeySearchParam = { xmlSecAppCmdLineTopicKeysMngr, "--lax-key-search", NULL, "--lax-key-search" "\n\tenable lax key search (e.g. by key type like \"rsa\") vs default strict key search" "\n\tmode using only information from node (e.g. key name)", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam verifyKeysParam = { xmlSecAppCmdLineTopicKeysMngr, "--verify-keys", NULL, "--verify-keys" "\n\tforce verification of public/private keys loaded from the command: keys are required" "\n\tto have a key certificate that will be verified against the certificates in the key store", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam verifyCrlsParam = { xmlSecAppCmdLineTopicX509Certs, "--verify-crls", NULL, "--verify-crls" "\n\tforce verification of loaded CRLs: CRLs are required to have a valid signature" "\n\tfrom an issuer certificate in the trusted or untrusted certificate store, and" "\n\tmust be within their validity period (thisUpdate/nextUpdate)", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; /**************************************************************** * * Common params * ***************************************************************/ static xmlSecAppCmdLineParam sessionKeyParam = { xmlSecAppCmdLineTopicDSigSign | xmlSecAppCmdLineTopicEncEncrypt, "--session-key", NULL, "--session-key -" "\n\tgenerate new session key of bits size" "\n\t(for example, \"--session des-192\" generates a new 192 bits" "\n\tDES key for DES3 encryption)", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam outputParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--output", "-o", "--output " "\n\twrite result document to file ; the can" "\n\tbe a template and include '{inputfile}' which will be repaced" "\n\twith the input filename", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam nodeIdParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--node-id", NULL, "--node-id " "\n\tset the operation start point to the node with given ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam nodeNameParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--node-name", NULL, "--node-name [:]" "\n\tset the operation start point to the first node" "\n\twith given and URI", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam nodeXPathParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--node-xpath", NULL, "--node-xpath " "\n\tset the operation start point to the first node" "\n\tselected by the specified XPath expression", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam dtdFileParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--dtd-file", NULL, "--dtd-file " "\n\tload the specified file as the DTD", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam printDebugParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--print-debug", NULL, "--print-debug" "\n\tprint debug information to stdout", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam printXmlDebugParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--print-xml-debug", NULL, "--print-xml-debug" "\n\tprint debug information to stdout in xml format", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam idAttrParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--id-attr", NULL, "--id-attr[:] [:]" "\n\tadds attributes (default value \"id\") from all nodes" "\n\twith and namespace to the list of" "\n\tknown ID attributes; this is a hack and if you can use DTD or schema" "\n\tto declare ID attributes instead (see \"--dtd-file\" option)", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam addIdAttrParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--add-id-attr", NULL, "--add-id-attr " "\n\tadds attribute to all nodes in the document;" "\n\tthis is a hack and if you can use DTD or schema to declare ID attributes" "\n\tinstead (see \"--dtd-file\" option)", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam xxeParam = { xmlSecAppCmdLineTopicAll, "--xxe", NULL, "--xxe" "\n\tenable External Entity resolution." "\n\tWARNING: this may allow the reading of arbitrary files and URLs," "\n\tcontrolled by the input XML document. Use with caution!", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam urlMapParam = { xmlSecAppCmdLineTopicDSigCommon | xmlSecAppCmdLineTopicEncCommon, "--url-map", NULL, "--url-map: " "\n\tmaps a given to the given for loading external resources", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; /**************************************************************** * * Common dsig params * ***************************************************************/ #ifndef XMLSEC_NO_XMLDSIG static xmlSecAppCmdLineParam ignoreManifestsParam = { xmlSecAppCmdLineTopicDSigCommon, "--ignore-manifests", NULL, "--ignore-manifests" "\n\tdo not process elements", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam storeReferencesParam = { xmlSecAppCmdLineTopicDSigCommon, "--store-references", NULL, "--store-references" "\n\tstore and print the result of element processing" "\n\tjust before calculating digest", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam storeSignaturesParam = { xmlSecAppCmdLineTopicDSigCommon, "--store-signatures", NULL, "--store-signatures" "\n\tstore and print the result of processing" "\n\tjust before calculating signature", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam enabledRefUrisParam = { xmlSecAppCmdLineTopicDSigCommon, "--enabled-reference-uris", NULL, "--enabled-reference-uris " "\n\tcomma separated list of of the following values:" "\n\t\"empty\", \"same-doc\", \"local\",\"remote\" to restrict possible URI" "\n\tattribute values for the element", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam enableVisa3DHackParam = { xmlSecAppCmdLineTopicDSigCommon, "--enable-visa3d-hack", NULL, "--enable-visa3d-hack" "\n\tenables Visa3D protocol specific hack for URI attributes processing" "\n\twhen we are trying not to use XPath/XPointer engine; this is a hack" "\n\tand I don't know what else might be broken in your application when" "\n\tyou use it (also check \"--id-attr\" option because you might need it)", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam enableAsn1SignaturesHackParam = { xmlSecAppCmdLineTopicDSigCommon, "--enable-asn1-signatures-hack", NULL, "--enable-asn1-signatures-hack" "\n\tenables support for ASN1 signature values generated by some XMLDsig" "\n\timplementations.", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; #endif /* XMLSEC_NO_XMLDSIG */ /**************************************************************** * * Enc params * ***************************************************************/ #ifndef XMLSEC_NO_XMLENC static xmlSecAppCmdLineParam enabledCipherRefUrisParam = { xmlSecAppCmdLineTopicEncCommon, "--enabled-cipher-reference-uris", NULL, "--enabled-cipher-reference-uris " "\n\tcomma separated list of of the following values:" "\n\t\"empty\", \"same-doc\", \"local\",\"remote\" to restrict possible URI" "\n\tattribute values for the element", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam binaryDataParam = { xmlSecAppCmdLineTopicEncEncrypt, "--binary-data", "--binary", "--binary-data " "\n\tbinary to encrypt", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam xmlDataParam = { xmlSecAppCmdLineTopicEncEncrypt, "--xml-data", NULL, "--xml-data " "\n\tXML to encrypt", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; #endif /* XMLSEC_NO_XMLENC */ /**************************************************************** * * X509 params * ***************************************************************/ #ifndef XMLSEC_NO_X509 static xmlSecAppCmdLineParam pkcs12Param = { xmlSecAppCmdLineTopicKeysMngr, "--pkcs12", NULL, "--pkcs12[:] " "\n\tload load private key from pkcs12 file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam pkcs12PersistParam = { xmlSecAppCmdLineTopicKeysMngr, "--pkcs12-persist", NULL, "--pkcs12-persist" "\n\tpersist loaded private key", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL }; static xmlSecAppCmdLineParam pubkeyCertParam = { xmlSecAppCmdLineTopicKeysMngr, "--pubkey-cert-pem", "--pubkey-cert", "--pubkey-cert-pem[:] " "\n\tload public key from PEM cert file", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam pubkeyCertDerParam = { xmlSecAppCmdLineTopicKeysMngr, "--pubkey-cert-der", NULL, "--pubkey-cert-der[:] " "\n\tload public key from DER cert file", xmlSecAppCmdLineParamTypeStringList, xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam trustedParam = { xmlSecAppCmdLineTopicX509Certs, "--trusted-pem", "--trusted", "--trusted-pem " "\n\tload trusted (root) certificate from PEM file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam trustedDerParam = { xmlSecAppCmdLineTopicX509Certs, "--trusted-der", NULL, "--trusted-der " "\n\tload trusted (root) certificate from DER file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam untrustedParam = { xmlSecAppCmdLineTopicX509Certs, "--untrusted-pem", "--untrusted", "--untrusted-pem " "\n\tload untrusted certificate from PEM file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam untrustedDerParam = { xmlSecAppCmdLineTopicX509Certs, "--untrusted-der", NULL, "--untrusted-der " "\n\tload untrusted certificate from DER file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam crlPemParam = { xmlSecAppCmdLineTopicX509Certs, "--crl-pem", "--crl", "--crl-pem " "\n\tload CRLs from PEM file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam crlDerParam = { xmlSecAppCmdLineTopicX509Certs, "--crl-der", NULL, "--crl-der " "\n\tload CRLs from DER file ", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagMultipleValues, NULL }; static xmlSecAppCmdLineParam verificationTimeParam = { xmlSecAppCmdLineTopicX509Certs, "--verification-time", NULL, "--verification-time