From e91f26ff3ea8bc48abd549462ac00e7cc5023131 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 21 Jul 2026 10:53:00 +0300 Subject: [PATCH] Update documentation Signed-off-by: Raul Metsma --- .github/workflows/build.yml | 25 +- README.md | 45 ++- RELEASE-NOTES.md | 15 + doc/images/asic.svg | 4 +- doc/images/components.svg | 2 +- doc/images/digidoc_framework.svg | 2 +- doc/images/schemas.svg | 2 +- doc/images/security.svg | 2 +- etc/Doxyfile.in | 89 +++++- examples/DigiDocCSharp/DigiDocCSharp.csproj | 6 +- examples/DigiDocCSharp/DigiDocCSharp.sln | 25 -- examples/DigiDocCSharp/README.md | 93 ++++-- examples/README.md | 2 +- examples/android/README.md | 9 +- examples/ios/README.md | 13 +- libdigidocpp.dox | 304 +++++++++++++----- src/ASiC_E.cpp | 9 +- src/ASiC_S.h | 6 +- src/CMakeLists.txt | 1 + src/DataFile.cpp | 4 + src/crypto/Digest.cpp | 5 +- src/crypto/OCSP.cpp | 4 +- src/crypto/X509Cert.cpp | 38 +-- src/crypto/X509Crypto.cpp | 8 +- src/digidoc-tool.1.cmake | 330 +++++++++++++++----- src/digidoc-tool.cpp | 13 +- 26 files changed, 753 insertions(+), 303 deletions(-) delete mode 100644 examples/DigiDocCSharp/DigiDocCSharp.sln diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b70a638b..d57e04371 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -277,25 +277,36 @@ jobs: path: ./*.msi pages: name: Deploy pages - if: github.repository == 'open-eid/libdigidocpp' && contains(github.ref, 'master') + if: github.repository == 'open-eid/libdigidocpp' && github.ref == 'refs/heads/master' + concurrency: + group: pages + cancel-in-progress: false + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-24.04 permissions: - contents: write + contents: read + pages: write + id-token: write steps: - name: Checkout uses: actions/checkout@v6 + - name: Setup Pages + uses: actions/configure-pages@v5 - name: Install dependencies run: sudo apt update -qq && sudo apt install --no-install-recommends -y doxygen ${UBUNTU_DEPS} - name: Build docs run: | cmake -B build -S . cmake --build build --target docs - - name: Deploy - uses: peaceiris/actions-gh-pages@v4 + - name: Upload artifact + uses: actions/upload-pages-artifact@v5 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./build/doc - force_orphan: true + path: ./build/doc + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5 coverity: name: Run Coverity tests if: github.repository == 'open-eid/libdigidocpp' && contains(github.ref, 'coverity_scan') diff --git a/README.md b/README.md index 98e1c1ab5..ab4ebf01c 100644 --- a/README.md +++ b/README.md @@ -31,17 +31,18 @@ git clone https://github.com/open-eid/libdigidocpp cd libdigidocpp -3. Configure +3. List the available CMake presets and configure the default build - cmake -B build -S . + cmake --list-presets + cmake --preset default 4. Build - cmake --build build + cmake --build build/default 5. Install - sudo cmake --build build --target install + sudo cmake --build build/default --target install 6. Execute @@ -53,7 +54,7 @@ * [XCode](https://itunes.apple.com/en/app/xcode/id497799835?mt=12) - For macOS/iOS development * [CMake](http://www.cmake.org) * [Homebrew](https://brew.sh) - * [vcpkg](https://vcpkg.io/) - For Android development (VCPKG_ROOT) + * [vcpkg](https://vcpkg.io/) - For iOS and Android development (`VCPKG_ROOT`) * [Android NDK](https://developer.android.com/ndk/downloads) - For Android development (ANDROID_NDK_ROOT) 2. Fetch the source @@ -61,9 +62,12 @@ git clone https://github.com/open-eid/libdigidocpp cd libdigidocpp -3. Prepare dependencies (available targets: macos, iphoneos, iphonesimulator) +3. Prepare macOS dependencies - sh prepare_osx_build_environment.sh macos all + sh prepare_osx_build_environment.sh all + + iOS and Android dependencies are managed by vcpkg instead. Set `VCPKG_ROOT` + for both platforms and `ANDROID_NDK_ROOT` for Android before configuring. 4. Install dependencies @@ -71,11 +75,14 @@ * doxygen - Optional, for API documentation * boost - Optional, for unittests - * swig - Optional, for C# and Java bindings + * swig - Optional, for C#, Java and Python bindings * openjdk - Optional, for Java bindings -5. Configure, build and install (available presets: macos, iphoneos, iphonessimulator, androidarm, androidarm64, androidx86_64) +5. List the available presets, then configure, build and install. Platform presets + include `macos`, `iphoneos`, `iphonesimulator`, `iphonecatalyst`, + `androidarm`, `androidarm64` and `androidx86_64`. + cmake --list-presets cmake --preset macos cmake --build --preset macos sudo cmake --build --preset macos --target install @@ -87,7 +94,7 @@ ### Windows 1. Install dependencies and necessary tools from - * [Visual Studio Community 2022](https://www.visualstudio.com/downloads/) + * [Visual Studio](https://www.visualstudio.com/downloads/) with a supported MSVC toolset (v143 or v145) * [CMake](http://www.cmake.org) * [vcpkg](https://vcpkg.io/) * [Swig](http://swig.org/download.html) - Optional, for C#, Python and Java bindings @@ -107,12 +114,12 @@ git clone https://github.com/open-eid/libdigidocpp cd libdigidocpp -4. Configure +4. Set the target platform and vcpkg location, then configure with the checked-in + Windows preset - cmake -DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake ` - -DVCPKG_TARGET_TRIPLET=x64-windows ` - -DVCPKG_MANIFEST_FEATURES=tests ` - -B build -S . + $env:PLATFORM = "x64" + $env:VCPKG_ROOT = "C:/src/vcpkg" + cmake --preset windows -DVCPKG_MANIFEST_FEATURES=tests Optional CMake parameters: @@ -122,9 +129,13 @@ After running the cmake build, digidoc_csharp.dll along with the C# source files will be created, more info at [examples/DigiDocCSharp/README.md](examples/DigiDocCSharp/README.md). + The preset uses a platform-specific build directory such as + `build/windows-x64`, keeping Windows builds separate from Linux, macOS and + other Windows architectures. + 5. Build - cmake --build build + cmake --build --preset windows --config RelWithDebInfo 6. Alternative to steps 4. and 5. - @@ -141,7 +152,7 @@ 7. Execute - build/src/digidoc-tool.exe + build/windows-x64/src/RelWithDebInfo/digidoc-tool.exe ### Examples [examples/README.md](examples/README.md) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index bc8f586ed..22edd9e8c 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,3 +1,18 @@ +Libdigidocpp library [4.5.0](https://github.com/open-eid/libdigidocpp/releases/tag/v4.5.0) release notes +-------------------------------------- +- Add `Container::extendContainerValidity` for adding archive timestamps to eligible ASiC-E and ASiC-S/TST containers, or wrapping a container in timestamped ASiC-S when in-place extension is unavailable + (#658) +- Update libraries and platform support + (#722, #726, #749) +- Improve signature and container compatibility + (#615, #728, #729, #730, #735, #751, #752, #754, #756) +- Harden XML, ZIP, network, and file handling + (#731, #732, #734, #736, #738, #743) +- Other fixes, optimizations, and documentation updates + (#727, #733, #753, #755) + +[Full Changelog](https://github.com/open-eid/libdigidocpp/compare/v4.4.0...v4.5.0) + Libdigidocpp library [4.4.0](https://github.com/open-eid/libdigidocpp/releases/tag/v4.4.0) release notes -------------------------------------- - Update libraries and platform support diff --git a/doc/images/asic.svg b/doc/images/asic.svg index 4c8ad01f7..af856df90 100644 --- a/doc/images/asic.svg +++ b/doc/images/asic.svg @@ -2,7 +2,7 @@ - + @@ -150,7 +150,7 @@ - BDOC 2.1 container (ASiC-E) + ASiC-E container diff --git a/doc/images/components.svg b/doc/images/components.svg index 5efd23e89..ef279272f 100644 --- a/doc/images/components.svg +++ b/doc/images/components.svg @@ -3,7 +3,7 @@ - + diff --git a/doc/images/digidoc_framework.svg b/doc/images/digidoc_framework.svg index fd2e0e5ab..ab7993d45 100644 --- a/doc/images/digidoc_framework.svg +++ b/doc/images/digidoc_framework.svg @@ -2,7 +2,7 @@ - + diff --git a/doc/images/schemas.svg b/doc/images/schemas.svg index 48a4c042b..175c13b69 100644 --- a/doc/images/schemas.svg +++ b/doc/images/schemas.svg @@ -3,7 +3,7 @@ - + diff --git a/doc/images/security.svg b/doc/images/security.svg index 328f09c8e..802dfe500 100644 --- a/doc/images/security.svg +++ b/doc/images/security.svg @@ -3,7 +3,7 @@ - + diff --git a/etc/Doxyfile.in b/etc/Doxyfile.in index c68de5942..accc5091c 100644 --- a/etc/Doxyfile.in +++ b/etc/Doxyfile.in @@ -1,4 +1,4 @@ -# Doxyfile 1.16.1 +# Doxyfile 1.17.0 # This file describes the settings to be used by the documentation system # Doxygen (www.doxygen.org) for a project. @@ -81,7 +81,7 @@ OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/doc/ # and will distribute the generated files over these directories. Enabling this # option can be useful when feeding Doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise cause -# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# performance problems for the file system. Adjust CREATE_SUBDIRS_LEVEL to # control the number of sub-directories. # The default value is: NO. @@ -802,7 +802,7 @@ GENERATE_REQUIREMENTS = YES # The REQ_TRACEABILITY_INFO tag controls if traceability information is shown on # the requirements page (only relevant when using \requirement comment blocks). -# The setting NO will disable the traceablility information altogether. The +# The setting NO will disable the traceability information altogether. The # setting UNSATISFIED_ONLY will show a list of requirements that are missing a # satisfies relation (through the command: \satisfies). Similarly the setting # UNVERIFIED_ONLY will show a list of requirements that are missing a verifies @@ -1140,8 +1140,7 @@ EXCLUDE_SYMBOLS = digidoc::*Private \ # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = @PROJECT_SOURCE_DIR@/ \ - @PROJECT_BINARY_DIR@/ +EXAMPLE_PATH = @PROJECT_SOURCE_DIR@/RELEASE-NOTES.md # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -1604,8 +1603,8 @@ DOCSET_PUBLISHER_NAME = Publisher # a.o. the download links, offline (the HTML help workshop was already many # years in maintenance mode). You can download the HTML help workshop from the # web archives at Installation executable (see: -# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo -# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# http://web.archive.org/web/20160201063255/https://download.microsoft.com/downl +# oad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by Doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1912,7 +1911,7 @@ MATHJAX_FORMAT = HTML-CSS # output directory using the MATHJAX_RELPATH option. For Mathjax version 2 the # destination directory should contain the MathJax.js script. For instance, if # the mathjax directory is located at the same level as the HTML output -# directory, then MATHJAX_RELPATH should be ../mathjax.s For Mathjax versions 3 +# directory, then MATHJAX_RELPATH should be ../mathjax. For Mathjax versions 3 # and 4 the destination directory should contain the tex-.js script # (where is either chtml or svg). The default value points to the # MathJax Content Delivery Network so you can quickly see the result without @@ -2618,6 +2617,19 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 +# The DOT_BATCH_SIZE specifies the number of dot graphs Doxygen is allowed to +# compile in a single invocation of dot. When set to 1 Doxygen will invoke dot +# for each graph separately, which can cause significant process creation +# overhead especially on systems with many CPU cores. Together with +# DOT_NUM_THREADS this setting can be used to optimise the dot processing speed +# for a particular system. Doxygen will try to give each thread a balanced batch +# of work. If the total number of graphs to process exceeds DOT_NUM_THREADS * +# DOT_BATCH_SIZE then additional batches will be created for dot to process. +# Minimum value: 1, maximum value: 1000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_BATCH_SIZE = 50 + # DOT_COMMON_ATTR is common attributes for nodes, edges and labels of # subgraphs. When you want a differently looking font in the dot files that # Doxygen generates you can specify fontname, fontcolor and fontsize attributes. @@ -2909,6 +2921,58 @@ PLANTUML_INCLUDE_PATH = PLANTUMLFILE_DIRS = +# When using Mermaid diagrams with CLI rendering, the MERMAID_PATH tag should be +# used to specify the directory where the mmdc (Mermaid CLI) executable can be +# found. If left blank, CLI-based rendering is disabled. For HTML output, +# client-side rendering via JavaScript is used by default and does not require +# mmdc. For LaTeX/PDF output, mmdc is required to pre-generate images. Doxygen +# will generate a warning when CLI rendering is needed but mmdc is not +# available. + +MERMAID_PATH = + +# When using Mermaid diagrams, the MERMAID_CONFIG_FILE tag can be used to +# specify a JSON configuration file for the Mermaid CLI tool (mmdc). This file +# can contain theme settings and other Mermaid configuration options. + +MERMAID_CONFIG_FILE = + +# The MERMAID_RENDER_MODE tag selects how Mermaid diagrams are rendered. +# Possible values are: AUTO (use client-side rendering for HTML and mmdc for +# LaTeX/PDF and other formats. If MERMAID_PATH is not set, non-HTML diagrams +# will produce a warning), CLI (use the mmdc tool to pre-generate images +# (requires Node.js and mermaid-js/mermaid-cli). Works for all output formats) +# and CLIENT_SIDE (embed mermaid.js in HTML output for client-side rendering. +# Does not require mmdc but only works for HTML output). +# The default value is: AUTO. + +MERMAID_RENDER_MODE = AUTO + +# The MERMAID_JS_URL tag specifies the URL to load mermaid.js from when using +# client-side rendering (MERMAID_RENDER_MODE is CLIENT_SIDE or AUTO). The +# default points to the latest Mermaid v11 release on the jsDelivr CDN. +# +# The default CDN URL requires internet access when viewing the generated +# documentation. For offline use, download mermaid.esm.min.mjs and set this to a +# relative path, or use MERMAID_RENDER_MODE=CLI to pre-generate images instead. +# Examples: +# - Latest v11 (default): +# 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs' +# - Pinned version: +# 'https://cdn.jsdelivr.net/npm/mermaid@11.3.0/dist/mermaid.esm.min.mjs' +# - Local copy: './mermaid.esm.min.mjs' (user must place file in HTML output +# directory) +# The default value is: +# https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs. + +MERMAID_JS_URL = https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs + +# The MERMAIDFILE_DIRS tag can be used to specify one or more directories that +# contain Mermaid files that are included in the documentation (see the +# \mermaidfile command). + +MERMAIDFILE_DIRS = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, Doxygen will truncate the graph, which is visualized @@ -2933,15 +2997,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) support -# this, this feature is disabled by default. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_MULTI_TARGETS = NO - # If the GENERATE_LEGEND tag is set to YES Doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. diff --git a/examples/DigiDocCSharp/DigiDocCSharp.csproj b/examples/DigiDocCSharp/DigiDocCSharp.csproj index 8a865fa9c..98bc95624 100644 --- a/examples/DigiDocCSharp/DigiDocCSharp.csproj +++ b/examples/DigiDocCSharp/DigiDocCSharp.csproj @@ -1,8 +1,8 @@  - net472 + net8.0 Exe - 0.6.0.0 + 0.6.0 Copyright © 2015 @@ -11,4 +11,4 @@ - \ No newline at end of file + diff --git a/examples/DigiDocCSharp/DigiDocCSharp.sln b/examples/DigiDocCSharp/DigiDocCSharp.sln deleted file mode 100644 index dca8f622b..000000000 --- a/examples/DigiDocCSharp/DigiDocCSharp.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.7.34009.444 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigiDocCSharp", "DigiDocCSharp.csproj", "{DDEE2029-EA2A-49D2-80CB-F0E2E396B005}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DDEE2029-EA2A-49D2-80CB-F0E2E396B005}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DDEE2029-EA2A-49D2-80CB-F0E2E396B005}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DDEE2029-EA2A-49D2-80CB-F0E2E396B005}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DDEE2029-EA2A-49D2-80CB-F0E2E396B005}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7D43E58D-0FD9-4023-A18F-D69EE6A229E1} - EndGlobalSection -EndGlobal diff --git a/examples/DigiDocCSharp/README.md b/examples/DigiDocCSharp/README.md index a121e1f51..c8bc3969b 100644 --- a/examples/DigiDocCSharp/README.md +++ b/examples/DigiDocCSharp/README.md @@ -1,27 +1,66 @@ -## C-SHARP -Uses [http://swig.org/](http://swig.org/) tools for generating bindings. - -## Setting up the sample C# application - -For compiling and running the DigiDocCSharp sample C# project, do as follows: - -1. Install the "libdigidocpp-3.14.4.msi" package or higher. The installation packages are available from https://github.com/open-eid/libdigidocpp/releases -2. Open the C# sample project from source\examples\DigiDocCSharp folder located in the installation directory -3. Add the C# source files files from include\digidocpp_csharp folder to the digidoc folder of the opened project (in Solution Explorer view, right click on the digidoc folder, choose Add->Existing item) -4. Build the solution, DigiDocCSharp.exe executable is created -4. Libdigidocpp library's binaries (in the x64 or x86 folder of the "libdigidocpp" package's installation directory) need to be accessible for running the DigiDocCSharp executable. You can either copy the DigiDocCSharp.exe to the x64 or x86 folder, depending on the platform or set the working directory of the project accordingly or add the binaries' folder to PATH variable. -5. Run the DigiDocCSharp.exe sample program with the commands described in the next section - -## Commands of the sample application Program.cs -* DigiDocCSharp.exe version -* DigiDocCSharp.exe help -* DigiDocCSharp.exe verify test.bdoc -* DigiDocCSharp.exe sign text.txt test.bdoc -* DigiDocCSharp.exe extract=0 test.bdoc - -## API -* [digidoc.initialize()](http://open-eid.github.io/libdigidocpp/namespacedigidoc.html#ada31d19121d7a6d98b04267f3ed8cc8f) -* [Container](http://open-eid.github.io/libdigidocpp/classdigidoc_1_1Container.html) -* [DataFile](http://open-eid.github.io/libdigidocpp/classdigidoc_1_1DataFile.html) -* [Signature](http://open-eid.github.io/libdigidocpp/classdigidoc_1_1Signature.html) -* [digidoc.terminate()](http://open-eid.github.io/libdigidocpp/namespacedigidoc.html#a121f0363627f62f3972ac4b445986598) +# C# example + +The C# bindings are generated with [SWIG](https://www.swig.org/) and work on +Windows, macOS and Linux. The example targets .NET 8. + +## Prerequisites + +Install the native build dependencies for your platform from the main +[build instructions](../../README.md), together with SWIG and the .NET 8 SDK or +newer. + +## Build the native wrapper + +On Linux, use the default preset: + + cmake --preset default + cmake --build build/default --target digidoc_csharp + +On macOS, use the macOS preset: + + cmake --preset macos + cmake --build --preset macos --target digidoc_csharp + +On Windows, use a Visual Studio tools PowerShell and the Windows preset: + + $env:PLATFORM = "x64" + $env:VCPKG_ROOT = "C:/src/vcpkg" + cmake --preset windows -DSWIG_EXECUTABLE=C:/swigwin/swig.exe + cmake --build --preset windows --config RelWithDebInfo --target digidoc_csharp + +The generated C# files are written to the `src/csharp` directory inside the +selected CMake build directory—for example, `build/default/src/csharp`, +`build/macos/src/csharp` or `build/windows-x64/src/csharp`. Copy or add those +`.cs` files to the example's `digidoc` folder, then build the managed project: + + dotnet build examples/DigiDocCSharp/DigiDocCSharp.csproj -c Release + +Before running the example, make the directory containing the native +libdigidocpp and SWIG wrapper libraries available to the platform loader: + +- Windows: add it to `PATH`. +- macOS: add it to `DYLD_LIBRARY_PATH`. +- Linux: add it to `LD_LIBRARY_PATH`. + +Use native libraries matching the process architecture and build configuration. +Installing libdigidocpp is an alternative to setting a build-tree loader path. + +## Example commands + +Use `DigiDocCSharp.exe` on Windows or `dotnet DigiDocCSharp.dll` on macOS and +Linux. For example: + + dotnet DigiDocCSharp.dll version + dotnet DigiDocCSharp.dll help + dotnet DigiDocCSharp.dll add text.txt unsigned.asice + dotnet DigiDocCSharp.dll verify signed.asice + dotnet DigiDocCSharp.dll extract 0 signed.asice + +Signing uses `WinSigner` on Windows. On macOS and Linux it uses `PKCS11Signer`, +so the PIN precedes the input file arguments: + + dotnet DigiDocCSharp.dll sign 12345 text.txt signed.asice + +The C# API mirrors the public libdigidocpp API. See the generated bindings and +the [libdigidocpp API documentation](https://open-eid.github.io/libdigidocpp/) +for the available classes and methods. diff --git a/examples/README.md b/examples/README.md index fe051e122..500543734 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,7 +2,7 @@ Contents of this folder is provided on as is terms, whithout support. -* [DigiDocCSharp](./DigiDocCSharp/README.md) - example project to use C# on Windows +* [DigiDocCSharp](./DigiDocCSharp/README.md) - example project for C# on Windows, macOS and Linux * [android](./android/README.md) - example project to use on Android platform * [ios](./ios/README.md) - example project to use on iOS platform * [java](./java/README.md) - example project to use with java diff --git a/examples/android/README.md b/examples/android/README.md index 7225a9049..000d2974b 100644 --- a/examples/android/README.md +++ b/examples/android/README.md @@ -2,7 +2,10 @@ ### macOS -1. Install dependencies see [README.md](../../README.md#macOS) -2. Build example and run +1. Install the dependencies listed in the main [README](../../README.md#macos). +2. Set `VCPKG_ROOT` and `ANDROID_NDK_ROOT`. The Gradle build invokes the + `androidarm` and `androidarm64` CMake presets and installs their outputs into + the example build directory automatically. +3. Build the example and install it on a connected device or emulator: - ./gradlew installDebug + ./gradlew installDebug diff --git a/examples/ios/README.md b/examples/ios/README.md index 9d4f1cbeb..7d078921c 100644 --- a/examples/ios/README.md +++ b/examples/ios/README.md @@ -2,11 +2,16 @@ ### macOS -1. Install dependencies see [README.md](../../README.md#macOS) -2. Build example and run on simulator +1. Install the dependencies listed in the main [README](../../README.md#macos). +2. Set `VCPKG_ROOT`. The Xcode build invokes the matching `iphoneos`, + `iphonesimulator` or `iphonecatalyst` CMake preset and builds libdigidocpp + automatically. +3. Build the example and run it on a simulator: xcodebuild -project libdigidocpp.xcodeproj -sdk iphonesimulator - Or open the Xcode project and run on a simulator or device directly. + Or open the Xcode project and run it on a simulator, device or Mac Catalyst + target directly. -AppDelegate.mm contains how to override digidoc::XmlConf to point right cache folder for TSL lists. +`AppDelegate.mm` shows how to override `digidoc::XmlConf` so TSL lists use an +application-writable cache directory. diff --git a/libdigidocpp.dox b/libdigidocpp.dox index 7bb2bc84b..703833ba0 100644 --- a/libdigidocpp.dox +++ b/libdigidocpp.dox @@ -1,6 +1,6 @@ /*! @mainpage -Libdigidocpp is the C++ library offering creating, signing and verification of digitally signed documents, according to XAdES and ASiC standards. +Libdigidocpp is a C++ library for creating, signing, and verifying digitally signed documents according to the XML Advanced Electronic Signatures (\ref XAdES "XAdES") and Associated Signature Containers (\ref ASiC "ASiC") standards. Development of the library can be monitored in GitHub environment: https://github.com/open-eid/libdigidocpp @@ -10,12 +10,15 @@ Additional documentation about the library can be found from GitHub wiki section /*! \page manual Libdigidocpp Programmer's Guide \section introduction Introduction -Libdigidocpp is the C++ library for creating applications handling digital signatures, their creation and verification. The digitally signed files are created in "DigiDoc format" (with .asice file extension), compliant to XML Advanced Electronic Signatures (\ref XAdES), technical standard published by European Telecommunication Standards Institute (ETSI). +Libdigidocpp is a C++ library for creating applications that create and verify digital signatures. Digitally signed files are created as Associated Signature Containers (\ref ASiC "ASiC"), using the .asice file extension and XML Advanced Electronic Signatures (\ref XAdES "XAdES") standardized by the European Telecommunications Standards Institute (ETSI). -Additionally the libdigidocpp library can be used to read and verify the digitally timestamped containers (using .asics file extension) with a single datafile. There is possible to validate \ref ASiC (\ref CAdES), \ref PDF and \ref DDOC formats with \ref SiVa service. +Additionally, the libdigidocpp library can create, save, read, validate, and extend digitally timestamped containers (using the .asics file extension) with a single data file and \ref RFC3161 "RFC 3161" time-stamp tokens. ASiC containers with \ref CAdES "CAdES" signatures, \ref PDF "PDF", and \ref DDOC "DDOC" files can be validated with the \ref SiVa service. Development of the library can be monitored in GitHub environment: https://github.com/open-eid/libdigidocpp. +\anchor releasenotes +Changes by version are listed on the separate \ref release_notes "Release Notes" page. + \subsection about About DigiDoc Libdigidocpp library forms a part of the wider DigiDoc system framework which offers a full-scale architecture for digital signature and documents, consisting of software libraries (C++ and Java), SiVa service and end-user applications such as DigiDoc4 according to the following figure: @@ -32,14 +35,14 @@ It is easy to integrate DigiDoc components into existing applications in order t Actively used digitally signed file formats in DigiDoc system are: - ASiC-E - default format for files in Libdigidocpp library, described in \ref ASiC "The ETSI standard ETSI EN 319 162-1"; - BDOC 2.1 - legacy format, described in \ref BDOC "BDOC2.1:2013", The library implements only read-only support for the format; -- ASiC-S - timestamped container, described in \ref ASiC "The ETSI standard ETSI EN 319 162-1". The library implements only read-only support for the format. +- ASiC-S - simple signature container, described in \ref ASiC "The ETSI standard ETSI EN 319 162-1". The library supports opening and validating containers with XAdES signatures. For containers with \ref RFC3161 "RFC 3161" time-stamp tokens, creating, saving, reading, validating, and archive-manifest time-stamp extension are supported. -The following chapters provides an overview of ASiC-E (XAdES) digitally signed file format which is the preferred format for creating signed documents in Libdigidocpp library. +The following chapters provide an overview of the ASiC-E (XAdES) digitally signed file format, which is the preferred format for creating signed documents with Libdigidocpp. \subsubsection container ASiC-E (XAdES) container format -The ETSI standard \ref ASiC "EN 319 162-1" called Associated Signature Containers (ASiC) defines format of container for encapsulation of signed files and signatures with extra information. The container type used in case of ASiC-E documents is Associated Signature Extended form. In the container \ref XAdES "XAdES EN 319 132-1" (XML Advanced Electronic Signatures) format signatures are used. +The ETSI standard \ref ASiC "EN 319 162-1" defines a container format for encapsulating signed files, signatures, and supporting information. ASiC-E documents use the Extended form and contain signatures conforming to \ref XAdES "XAdES EN 319 132-1". ASiC-E container is a ZIP file consisting of the following objects: - a file named "mimetype", containing only the following value: application/vnd.etsi.asic-e+zip @@ -85,7 +88,7 @@ The element digest is a hash value of the binary value of the <SignatureValue It is important to notice that additional time-stamps are not necessary as time of signing and time of obtaining validity information is indicated in the OCSP response (i.e. the time-mark). -NB! The issuance time (producedAt field’s value) of the OCSP response (the time-mark) is regarded as the time of signature creation. +\note The issuance time (producedAt field’s value) of the OCSP response (the time-mark) is regarded as the time of signature creation. To achieve long-time validity of digital signatures, a secure log system is employed within the model. All OCSP responses and changes in certificate validity are securely logged to preserve digital signature validity even after private key compromise of CA or OCSP responder. @@ -99,34 +102,29 @@ The BDOC signature with time-stamp is based on XAdES-BES signature (Basic Electr In order to offer long time validation, it is necessary to obtaining proof of validity of the signer’s X.509 digital certificate issued by a certificate authority (CA) at the time of signature creation. In case of BDOC with time-stamp (TS profile), the proof is provided as follows: -1. RFC3161 compliant time-stamp is obtained from a time-stamping service. The hash of the created signature (<SignatureValue> element block) is sent to the time-stamping server. The server’s response contains a time-stamp token with the same hash value that can later be used to validate that the time-stamp was indeed issued for the respective signature. The time-stamp token received from the server is added to the signature providing a proof from a trusted source that the signature value existed at a certain point of time. -2. RFC 6960 compliant OCSP confirmation is obtained from an OCSP service. The OCSP response received from the server is used as a trusted source to confirm that the signer’s certificate was valid at a certain point of time (producedAt field’s value in the OCSP response). +1. A time-stamp compliant with \ref RFC3161 "RFC 3161" is obtained from a time-stamping service. The hash of the created signature (<SignatureValue> element block) is sent to the time-stamping server. The server’s response contains a time-stamp token with the same hash value that can later be used to validate that the time-stamp was indeed issued for the respective signature. The time-stamp token received from the server is added to the signature providing a proof from a trusted source that the signature value existed at a certain point of time. +2. An \ref RFC6960 "RFC 6960" compliant OCSP confirmation is obtained from an OCSP service. The OCSP response received from the server is used as a trusted source to confirm that the signer’s certificate was valid at a certain point of time (producedAt field’s value in the OCSP response). 3. The verifier must check the time-stamp token’s and OCSP confirmation’s time difference. If the difference is acceptable then it can stated that the signer’s certificate was valid at the time of signature creation. -NB! The issuance time (getTime field’s value) of the time-stamp token (received with the response from time-stamping server) is regarded as the time of signature creation. +\note The \ref RFC3161 "RFC 3161 TSTInfo.genTime" field records when the TSA created the time-stamp token. This issuance time is regarded as the time of signature creation. \subsubsection asics ASiC-S container format -In addition to the Associated Signature Extended form (ASiC-E) the \ref ASiC "ETSI standard TS 102 918" defines a Simple form which is used for encapsulating a single datafile and signature or time-stamp token associated with it. +In addition to the Associated Signature Extended form (ASiC-E), the \ref ASiC "ETSI standard EN 319 162-1" defines a Simple form which is used for encapsulating a single data file and a signature or time-stamp token associated with it. -ASiC-S container is a ZIP file consisting of the following objects: +An ASiC-S container is a ZIP file consisting of the following objects: - an optional file named "mimetype", containing only the following value: application/vnd.etsi.asic-s+zip - data object (file) in original format. -- META-INF subdirectory with one of the following files: - - signatures.p7s - - signatures.xml - - timestamp.tst - -The libdigidocpp library supports only containers with time-stamp token (container includes META-INF/timestamp.tst). The time-stamp token is a binary representation of TimeStampToken as defined in RFC 3161. The time-stamp is obtained from a time-stamping service; it is calculated over the entire binary content of the data object. -Since both the original file and time-stamp are included in the container, it is possible to verify that the timestamped file existed at a certain point of time. - -The library can be used only for reading the content of the container and validating that the time-stamp was indeed issued for the data object included in the container. +- one signature form: + - META-INF/signatures.xml containing XAdES signatures; or + - META-INF/timestamp.tst containing the initial \ref RFC3161 "RFC 3161" time-stamp token. +- for the time-stamp-token form, optional META-INF/ASiCArchiveManifest*.xml and META-INF/timestamp*.tst files containing additional archive-manifest time-stamp layers. +Since version 3.17.0, libdigidocpp can open and locally validate ASiC-S containers containing XAdES signatures in META-INF/signatures.xml. This variant is read-only: creating, adding signatures to, and saving ASiC-S/XAdES containers are not supported. -\section releasenotes Release Notes - -\include RELEASE-NOTES.md - +The library also supports local creation and validation of ASiC-S containers with a time-stamp token (the container includes META-INF/timestamp.tst). The time-stamp token is a binary representation of TimeStampToken as defined in \ref RFC3161 "RFC 3161". The time-stamp is obtained from a time-stamping service and is calculated over the entire binary content of the data object. +Since both the original file and time-stamp are included in the container, it is possible to verify that the timestamped file existed at a certain point of time. +An existing time-stamp token can be extended by adding an ASiC archive manifest and a new time-stamp token. Each new layer protects the data object and the preceding time-stamp information. See \ref extend-validity for the high-level validity-extension workflow. \section overview Overview @@ -148,7 +146,7 @@ https://www.id.ee/wp-content/uploads/2020/08/digidoc_format_1.3.pdf \anchor XML-DSIG XML-DSIG IETF RFC 3275: "XML-Signature Syntax and Processing" -http://www.ietf.org/rfc/rfc3275.txt +https://www.rfc-editor.org/rfc/rfc3275.html \anchor XML-DSIG-1-1 XML-DSIG 1.1 XML Signature Syntax and Processing. Version 1.1 @@ -191,18 +189,64 @@ http://www.etsi.org/deliver/etsi_ts/103100_103199/103174/02.02.01_60/ts_103174v0 ETSI EN 319 142-1 V1.1.1 (2016-04) - PAdES digital signatures https://www.etsi.org/deliver/etsi_en/319100_319199/31914201/01.01.01_60/en_31914201v010101p.pdf
-\anchor RFC6960 RFC6960 -X.509 Internet Public Key Infrastructure Online Certificate Status Protocol – OCSP +\anchor RFC2045 RFC 2045 +Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies + +https://www.rfc-editor.org/rfc/rfc2045.html +\anchor RFC2253 RFC 2253 +Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names. Obsoleted by RFC 4514. + +https://www.rfc-editor.org/rfc/rfc2253.html +\anchor RFC4514 RFC 4514 +Lightweight Directory Access Protocol: String Representation of Distinguished Names + +https://www.rfc-editor.org/rfc/rfc4514.html +\anchor RFC3161 RFC 3161 +Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP) + +The TSTInfo genTime field records the UTC time at which the time-stamp token was created by the Time-Stamping Authority (TSA). + +https://www.rfc-editor.org/rfc/rfc3161.html +\anchor RFC3739 RFC 3739 +Internet X.509 Public Key Infrastructure: Qualified Certificates Profile + +https://www.rfc-editor.org/rfc/rfc3739.html +\anchor RFC3986 RFC 3986 +Uniform Resource Identifier (URI): Generic Syntax + +https://www.rfc-editor.org/rfc/rfc3986.html +\anchor RFC4051 RFC 4051 +Additional XML Security Uniform Resource Identifiers. Obsoleted by RFC 6931. + +https://www.rfc-editor.org/rfc/rfc4051.html +\anchor RFC6931 RFC 6931 +Additional XML Security Uniform Resource Identifiers. Obsoletes RFC 4051 and is obsoleted by RFC 9231. -http://tools.ietf.org/html/rfc6960 -\anchor RFC3161 RFC3161 -Internet X.509 Public Key Infrastructure Time-Stamp protocol +https://www.rfc-editor.org/rfc/rfc6931.html +\anchor RFC9231 RFC 9231 +Additional XML Security Uniform Resource Identifiers -http://tools.ietf.org/html/rfc3161 -\anchor RFC5280 RFC5280 +https://www.rfc-editor.org/rfc/rfc9231.html +\anchor RFC4519 RFC 4519 +Lightweight Directory Access Protocol: Schema for User Applications + +https://www.rfc-editor.org/rfc/rfc4519.html +\anchor RFC5035 RFC 5035 +Enhanced Security Services (ESS) Update: Adding CertID Algorithm Agility + +https://www.rfc-editor.org/rfc/rfc5035.html +\anchor RFC5280 RFC 5280 Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile -http://tools.ietf.org/html/rfc5280 +https://www.rfc-editor.org/rfc/rfc5280.html +\anchor RFC6960 RFC 6960 +X.509 Internet Public Key Infrastructure Online Certificate Status Protocol (OCSP) + +https://www.rfc-editor.org/rfc/rfc6960.html +\anchor RFC8954 RFC 8954 +Online Certificate Status Protocol (OCSP) Nonce Extension + +https://www.rfc-editor.org/rfc/rfc8954.html \anchor TSL Trusted Lists ETSI TS 119 612 V2.2.1 (2016-04) @@ -217,6 +261,18 @@ Libdigidocpp library’s release notes X.509 V3 Certificate Profile for Certificates Issued to Natural Persons http://www.etsi.org/deliver/etsi_ts/102200_102299/102280/01.01.01_60/ts_102280v010101p.pdf +\anchor QC-cert QC Certificate Profiles +ETSI EN 319 412-1 V1.7.1 – Certificate Profiles; Part 1: Overview and common data structures
+ETSI EN 319 412-5 V2.6.1 – Certificate Profiles; Part 5: QCStatements + +http://www.etsi.org/deliver/etsi_en/319400_319499/31941201/01.07.01_60/en_31941201v010701p.pdf
+http://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.06.01_60/en_31941205v020601p.pdf +\anchor QC-policy QC Certificate Policy +ETSI EN 319 411-2 V2.6.1 – Policy requirements for Trust Service Providers issuing EU qualified certificates
+ETSI TS 101 456 V1.4.3 (2007-05) – Policy requirements for certification authorities issuing qualified certificates + +http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.06.01_60/en_31941102v020601p.pdf
+http://www.etsi.org/deliver/etsi_ts/101400_101499/101456/01.04.03_60/ts_101456v010403p.pdf \anchor DD-libs DigiDoc libraries https://www.id.ee/en/rubriik/digidoc-libraries/ \anchor openeid-github ID-software GitHub project @@ -255,7 +311,7 @@ SK ID Solutions AS. Certificate Authority in Estonia Mechanism used for adding certificate validity and signing time information with the signature. The information is provided with a special OCSP confirmation (also referred to as time-mark) - hash value of the binary value of the signature (along with hash algorithm identifier in case of BDOC 2.1 document format) must be present in the "nonce" field of the OCSP confirmation. In this case, signature creation time is the issuance time of the OCSP confirmation (producedAt value in the confirmation), additional time-stamp service is not required. The respective signature profile is TM profile (supported in case of DIGIDOC-XML 1.3 and BDOC 2.1 document formats). time-stamp -Mechanism used for adding certificate validity and signing time information with the signature. The certificate validity information is added to the signature with an OCSP confirmation; the signing time information is added with a time-stamp token retrieved form a time-stamping service. In this case, signature creation time is the issuance time (genTime value in the time-stamp) of the time-stamp token. The respective signature profile is TS profile. +Mechanism used for adding certificate validity and signing time information with the signature. The certificate validity information is added to the signature with an OCSP confirmation; the signing time information is added with a time-stamp token retrieved form a time-stamping service. In this case, signature creation time is the issuance time (\ref RFC3161 "RFC 3161 TSTInfo.genTime") of the time-stamp token. The respective signature profile is TS profile. archive time-stamp Mechanism used for providing long term validity of a XAdES signature. The signature and validation data values are time-stamped. The respective signature profile is TSA profile. TSA @@ -293,15 +349,17 @@ The following table gives overview of functional features that are supported wit DigiDoc document format - ASiC-E - the main document format to be used. +- ASiC-S - a single-data-file container. Opening and validating XAdES signatures are supported; this variant is read-only. For \ref RFC3161 "RFC 3161" TimeStampToken containers, creation, saving, validation, and archive-manifest time-stamp extension are supported. +- BDOC 2.1 - legacy read-only compatibility. \note BDOC 1.0 file format is not supported (more info can be found from https://www.id.ee/en/article/digidoc-container-format-life-cycle-2/). Signature profile Signature profiles are based on the profiles defined by XAdES (\ref XAdES "XAdES"). -- time-stamp (TS) - signature profile in case of which the certificate validity information is added to the signature with an OCSP confirmation; the signing time information is added with a time-stamp token (see also \ref RFC6960 "RFC6960") retrieved from a time-stamping service. In this case, signature creation time is regarded as the issuance time of the time-stamp token (genTime value in the time-stamp). +- time-stamp (TS) - signature profile in case of which the certificate validity information is added to the signature with an \ref RFC6960 "RFC 6960" OCSP confirmation; the signing time information is added with an \ref RFC3161 "RFC 3161" time-stamp token retrieved from a time-stamping service. In this case, signature creation time is regarded as the issuance time of the time-stamp token (\ref RFC3161 "RFC 3161 TSTInfo.genTime"). - time-mark (TM) - certificate validity and signing time information is added to the signature with a time-mark - a special OCSP confirmation in case of which the hash value of the binary value of the signature (along with hash algorithm identifier in case of BDOC 2.1 document format) must be present in the "nonce" field of the OCSP confirmation. In this case, signature creation time is regarded as the issuance time of the OCSP confirmation (producedAt value in the confirmation), additional time-stamp token is not required. -- archive time-stamp (LTA) - the signature and all the accompanying validation data is time-stamped in order to provide long term validity. The profile is supported only in case of BDOC 2.1 document format, the "ArchiveTimeStamp" element is added to the time-stamp or time-mark signature (see also \ref BDOC "BDOC2.1:2013"). +- archive time-stamp (TSA/LTA) - the signature and its accompanying validation data are time-stamped to provide long-term validity. Eligible ASiC-E XAdES signatures receive an ArchiveTimeStamp element. ASiC-S TimeStampToken signatures are extended with an ASiC archive manifest and another \ref RFC3161 "RFC 3161" time-stamp token. Trust anchors @@ -317,7 +375,7 @@ The following table gives overview of functional features that are supported wit Cryptographic token type - Smart card, e.g. Estonian ID card. Supported signature creation modules are PKCS#11 and Windows CryptoAPI. -\note Usage of USB cryptostick (Aladdin eToken with Digital Stamp certificate (https://www.skidsolutions.eu/en/services/Digital-stamp)) has been tested indirectly with Libdigidocpp - testing has been carried out via DigiDoc desktop application which uses Libdigidocpp as a base layer. +\note Usage of SafeNet USB tokens with a Digital Stamp certificate (https://www.skidsolutions.eu/en/services/Digital-stamp) has been tested indirectly with Libdigidocpp through the DigiDoc desktop application, which uses Libdigidocpp as a base layer. Public-key algorithm @@ -358,7 +416,7 @@ Libdigidocpp library depends on the software libraries listed below. MiniziprequiredUsed when creating and opening ZIP container for ASiC file. If the component is not found from system then bundled version with source code is used. Forms a part of ZLIB component. PKCS11optionalUsed for searching for default PKCS#11 driver in the system so that its path could be registered in configuration entries. DoxygenoptionalUsed for generating API documentation from source code. -SWIGoptionalUsed for creating C# and Java bindings. +SWIGoptionalUsed for creating C#, Java, and Python bindings. @@ -384,7 +442,7 @@ http://www.w3.org/TR/2008/REC-xmldsig-core-20080610/xmldsig-core-schema.xsd XAdES01903v132-201601.xsdXML Advanced Electronic Signatures (\ref XAdES "XAdES EN") Defines a set of extensions to XML-DSIG making it suitable for advanced electronic signature. http://uri.etsi.org/01903/v1.3.2/XAdES01903v132-201601.xsd -XAdES01903v141-201601.xsdDefines XML syntax for additional elements of XAdES signatures that were added with version 1.4.1 of the (\ref XAdES "XAdES EN") standard. Needed for implementing archive time-stamp support in the future. +XAdES01903v141-201601.xsdDefines XML syntax for additional elements of XAdES signatures that were added with version 1.4.1 of the (\ref XAdES "XAdES EN") standard. Used for XAdES archive time-stamps, including the ArchiveTimeStamp element. http://uri.etsi.org/01903/v1.4.1/XAdES01903v141-201601.xsd ts_119612v020201_201601xsd.xsd
ts_119612v020101_additionaltypes_xsd.xsd
ts_119612v020101_sie_xsd.xsdDefines the format of Trust Service status Lists (\ref TSL) that contain information about trusted CA, OCSP and TSA certificates. conf.xsdConfiguration properties’ schema. Defines the Libdigidocpp configuration file’s digidocpp.conf structure (see also \ref conf). @@ -521,14 +579,14 @@ Modifications are marked between xml comment tags. \endcode -Schema ts_119612v020101_sie_xsd.xsd +Schema ts_119612v020101_sie_xsd.xsd
1) The schemas' locations have been modified so that the file is looked up from the local file system. \code{.xml} \endcode -Schema ts_119612v020101_additionaltypes_xsd.xsd +Schema ts_119612v020101_additionaltypes_xsd.xsd
1) The schemas' locations have been modified so that the file is looked up from the local file system. \code{.xml} @@ -654,9 +712,10 @@ Libdigidocpp library uses Trust Service Status List (TSL) as a source of trust a By default, the trusted certificates' information is obtained from European Commission's official TSL list (https://ec.europa.eu/tools/lotl/eu-lotl.xml). The default TSL behaviour can be changed by altering the configuration parameters listed below. -\note - The TSL URL and TSL signing certificate values are not configurable via the digidocpp.conf configuration file. The default values are fixed in source code and can be accessed via methods digidoc::Conf::TSLCerts() and digidoc::Conf::TSLUrl(). The library's user has to create a subclass and override the methods in order to define other values. See also \ref initialization. -\note - When using digidoc-tool utility program then it is possible to specify necessary TSL parameters on the command line. See also \ref utility. -\note - For information about using test TSL lists with Libdigidocpp library, please refer to https://github.com/open-eid/libdigidocpp/wiki/Using-test-TSL-lists +\note +- The TSL URL and TSL signing certificate values are not configurable via the digidocpp.conf configuration file. The default values are fixed in source code and can be accessed via methods digidoc::Conf::TSLCerts() and digidoc::Conf::TSLUrl(). The library's user has to create a subclass and override the methods in order to define other values. See also \ref initialization. +- When using digidoc-tool utility program then it is possible to specify necessary TSL parameters on the command line. See also \ref utility. +- For information about using test TSL lists with Libdigidocpp library, please refer to https://github.com/open-eid/libdigidocpp/wiki/Using-test-TSL-lists @@ -813,6 +872,23 @@ Create a new container object and specify the DigiDoc document's type, for examp Container class is used to incorporate the data of a DigiDoc document. +\subsubsection asics-create Creating and timestamping an ASiC-S container +Create an ASiC-S container by using an .asics or .scs output file name. An ASiC-S TimeStampToken container supports exactly one data file and one initial \ref RFC3161 "RFC 3161" time-stamp token. + +\code{.cpp} +auto doc = digidoc::Container::createPtr("timestamped-document.asics"); +doc->addDataFile("document.txt", "text/plain"); + +digidoc::Signer *signer = ...; +signer->setProfile("TimeStampToken"); // "time-stamp-token" is also accepted +digidoc::Signature *timestamp = doc->sign(signer); +timestamp->validate(); +doc->save(); +\endcode + +ASiC-S TimeStampToken creation uses the one-step digidoc::Container::sign method. External two-step signing with digidoc::Container::prepareSignature is not supported for this format. Additional archive-manifest time-stamp layers can be added with the workflow described in \ref extend-validity. + + \subsubsection adddatafile Adding data files @@ -834,16 +910,20 @@ Parameter mediaType in the methods above stands for a MIME type of the data file Calling out any of the methods listed above shall create a new DataFile object and add it to the DigiDoc container's data file collection. Note that in order to add a data file to a container, the container has to be unsigned and there shouldn't be an existing data file with the same name in the container. If a container is signed then it is possible to add data files to it only after the signatures are removed. +The stream overload's fileName is the name stored inside the container. It must be a single non-empty path component: ".", "..", forward slashes, and backslashes are rejected. The file-system overload accepts a source path and stores only its base name. When an existing ASiC-E container is opened, safe relative subdirectories separated by forward slashes are accepted, but absolute paths, backslashes, trailing slashes, and empty, ".", or ".." path segments are rejected. ASiC-S data files must be at the container root. + \warning - It is important to pay attention that the data file's mime type value in manifest.xml file and in signatures*.xml file's <DataObjectFormat><MimeType> element are the same, otherwise the signature is invalid! In case of the ordinary signature creation process, the library sets the correct value automatically. However, if you create a ASiC-E container with Libdigidocpp library and want to add signatures*.xml file that you have received from another source then make sure that the data files' mime-type values in manifest-xml file and in signatures*.xml file are the same. -\warning - Data file’s mime-type value must be formatted as specified in RFC2045, section 5.1 (https://tools.ietf.org/html/rfc2045#section-5.1), i.e. the "type" and "subtype" values must be separated with a forward slash character. +\warning - Data file’s mime-type value must be formatted as specified in \ref RFC2045 "RFC 2045", section 5.1, i.e. the "type" and "subtype" values must be separated with a forward slash character. -\warning - It is recommended not to use special characters in the data file’s name, i.e. it is suggested to only use the characters that are categorized as "unreserved" according to RFC3986 (http://tools.ietf.org/html/rfc3986). +\warning - It is recommended not to use special characters in the data file’s name, i.e. it is suggested to only use the characters that are categorized as "unreserved" according to \ref RFC3986 "RFC 3986". \note By default, it is recommended to use data file mime-type value "application/octet-stream" for all file types. +\note For resource-exhaustion protection, structural and other non-data ZIP entries, such as manifests and signature XML, are limited to 10 MiB when read into memory. HTTP service responses are also limited to 10 MiB after decompression. Data files use a separate streaming and temporary-file strategy and are not subject to the 10 MiB metadata limit. + \subsubsection API-add-sign Adding signatures @@ -866,7 +946,7 @@ If you would like to add PIN insertion dialog window for the signer to enter the \paragraph API-sign-profile Optionally specify the signature profile The supported signature profiles are (see also \ref Supported, under "Signature profiles"): -- "time-stamp" (TS) - signature profile in case of which the certificate validity information is added to the signature with an OCSP confirmation (retrieved from OCSP server); the signing time information is added with a time-stamp token (retrieved from a time-stamping service). Signature creation time is the issuance time of the time-stamp token (value of the getTime field in the token). +- "time-stamp" (TS) - signature profile in case of which the certificate validity information is added to the signature with an OCSP confirmation (retrieved from OCSP server); the signing time information is added with a time-stamp token (retrieved from a time-stamping service). Signature creation time is the issuance time recorded in the token's \ref RFC3161 "RFC 3161 TSTInfo.genTime" field. If the signature profile value is not specified then then a "time-stamp" profile is used by default. @@ -968,7 +1048,7 @@ Write a DigiDoc file (represented with a Container object) to file system with t digidoc::Container::save(""); \endcode -\note In case of read-only formats (e.g. ASiC-S documents), the save will throw a digidoc::Exception. +\note ASiC-S containers with TimeStampToken signatures can be saved. Saving a read-only format or an unsupported ASiC-S signature variant throws a digidoc::Exception. \subsection validate Validating signature containers and signatures Validation of a signed DigiDoc document consists of three main steps: @@ -1004,7 +1084,7 @@ If there are more than one validation errors that occur when validating a single 2. Returning a validation result of the whole DigiDoc container:
If there are more than one signatures in a DigiDoc container and the signatures have different validation statuses or validation of the container structure returns a different status then the overall status of the DigiDoc file should be chosen according to the status priorities. -NB! User of the library has to determine the validation status according to the error code that is returned by the library's validation method. +\note The user of the library has to determine the validation status according to the error code returned by the library's validation method.
@@ -1096,7 +1176,7 @@ It is recommended to use the validation status VALID WITH WARNINGS in case of th - \subsection Creating Creating and signing a document (local signing) -Command "create" can be used to create a new DigiDoc container, add data files, optionally some meta-info about the signer and sign the document. Documents can be created only in ASiC-E format. +Command "create" can be used to create a new DigiDoc container, add data files, optionally some meta-info about the signer and sign the document. The output extension selects ASiC-E (.asice or .sce) or ASiC-S (.asics or .scs). ASiC-S creation requires exactly one data file and the TimeStampToken signature profile. General form of the command is: \code{.txt} > digidoc-tool create --file= @@ -1271,11 +1383,11 @@ Available options: +\warning It is recommended not to use special characters in the data file’s name, i.e. it is suggested to only use the characters that are categorized as "unreserved" according to \ref RFC3986 "RFC 3986". +\warning Data file’s mime-type value must be formatted as specified in \ref RFC2045 "RFC 2045", section 5.1, i.e. the "type" and "subtype" values must be separated with a forward slash character.
Priority
16 ProducedATLateWarning BDOC 2.1 TS / ASiCThe difference between time-stamp issuance time (genTime value) and OCSP response's issuance time (producedAt value) exceeds 15 minutes but is less than 24 hours. + The difference between the time-stamp issuance time (\ref RFC3161 "RFC 3161 TSTInfo.genTime") and the OCSP response's issuance time (producedAt value) exceeds 15 minutes but is less than 24 hours. Suggested warning message: "Time-stamp and OCSP issuance time difference is over 15 minutes." @@ -1158,33 +1238,65 @@ Overview of validation activities is as follows: \note Libdigidocpp library uses TSL lists (Trust Service Status list) to obtain information about trusted certificates during signature validation process. See also \ref TSL-overview "TSL overview", \ref TSL "TSL standard" and \ref CA-settings "Configuring TSL settings". +For formats validated through SiVa, archive time-stamp information returned by the service is available through digidoc::Signature::ArchiveTimeStamps in the same way as locally validated archive time-stamps. + + +\subsection extend-validity Extending container validity +Since version 4.5.0, digidoc::Container::extendContainerValidity provides the high-level workflow for extending the validity evidence of a container. The method sets the required signer profile automatically and uses the following strategy: +- eligible ASiC-E LT-level signatures are extended in place with archive time-stamps; +- an ASiC-S TimeStampToken is extended in place with an ASiC archive manifest and a new time-stamp token; +- when in-place extension is unsuitable, the original container is embedded as the data file of a new timestamped ASiC-S container. + +Only signatures with an Estonian signing certificate are considered for in-place extension, and e-seal signatures are skipped. A container with no applicable Estonian signatures, or with only T-level signatures lacking OCSP validation data, cannot be extended by this workflow. + +\code{.cpp} +auto doc = digidoc::Container::openPtr("signed-document.asice"); +digidoc::Signer *signer = ...; +std::size_t extendedCount = 0; + +if(auto wrapped = digidoc::Container::extendContainerValidity(*doc, signer, extendedCount)) + doc = std::move(wrapped); // original container was wrapped in a new ASiC-S container +// Otherwise doc was extended in place and extendedCount contains the number +// of signatures that received new validity evidence. +doc->save(); +\endcode + +The returned unique pointer is empty when extension was performed in place. It contains the new ASiC-S container when wrapping was necessary; in that case extendedCount is zero. The caller must save the modified or newly returned container. + +The generated language bindings expose the same workflow with language-specific return values: +- C#: Container.extendContainerValidity(doc, signer, out ulong extendedCount) returns the wrapping container, or null for an in-place extension. +- Python: Container.extendContainerValidity(doc, signer) returns a tuple (wrapping_container_or_None, extended_count). +- Java: Container.extendContainerValidity(doc, signer) returns the wrapping container, or null for an in-place extension; the count is not exposed. + +In every binding, replace the original container with the returned container when the return value is not null/None, then save the resulting container. A null/None result means the original object was modified in place. + \subsection extracting Extracting data files A data file can be extracted from container and written to the specified location in the file system or to an output stream. 1. You can write the data file to a stream and keep it in memory: \code{.cpp} -void digidoc::DataFile::saveAs(std::ostream &os); +void digidoc::DataFile::saveAs(std::ostream &os) const; \endcode 2. The file can be written to file system with the following method: \code{.cpp} -void digidoc::DataFile::saveAs(const std::string &path); +void digidoc::DataFile::saveAs(const std::string &path) const; \endcode List of all the document’s data files can be retrieved with the following method: \code{.cpp} -std::vector digidoc::Container::dataFiles(); +std::vector digidoc::Container::dataFiles() const; \endcode For example, read in a DigiDoc document and write its data files to file system as follows: \code{.cpp} -digidoc::Container doc(""); // read in a document -for(const digidoc::DataFile &file: doc.dataFiles()){ // get the data files’ list +auto doc = digidoc::Container::openPtr(""); +for(const digidoc::DataFile *file: doc->dataFiles()) { try { - std::string dst = file.fileName(); // get the data file’s name - file.saveAs(dst); // save the data file to working directory + std::string dst = file->fileName(); + file->saveAs(dst); } catch(const digidoc::Exception &e) { - printf(" Document %s extraction: FAILED\n", file.fileName().c_str()); + printf(" Document %s extraction: FAILED\n", file->fileName().c_str()); } } \endcode @@ -1192,16 +1304,16 @@ for(const digidoc::DataFile &file: doc.dataFiles()){ // get the data files’ li \subsection removing Removing signatures and data files In order to remove a signature from DigiDoc document, use the following method: \code{.cpp} -void digidoc::Container::removeSignature(unsigned int id); +void digidoc::Container::removeSignature(unsigned int index); \endcode Data files can be removed from a container only after all of its signatures have been removed. Use the following method to remove a data file from DigiDoc container: \code{.cpp} -void digidoc::Container::removeDataFile(unsigned int id); +void digidoc::Container::removeDataFile(unsigned int index); \endcode -"Id" parameters of the abovementioned methods represent the signature’s and data file’s sequence numbers in the container. The identifiers are determined when a data file or signature is added to the container, counting starts from zero. -\note The functionality of modifying files in DigiDoc file format ASiC-S is not supported. +The index parameters of the methods above are the signature and data file sequence numbers in the container, starting from zero. +\note Directly modifying the data file or initial signature of an existing ASiC-S container is not supported. Adding archive-manifest time-stamp layers through digidoc::Container::extendContainerValidity is supported. \subsection shutting-down Shutting down the library @@ -1260,7 +1372,7 @@ File to log, empty to console
\-\-file= Required Data file(s) to be signed. The option can occur multiple times. -\warning It is recommended not to use special characters in the data file’s name, i.e. it is suggested to only use the characters that are categorized as "unreserved" according to RFC3986 (http://tools.ietf.org/html/rfc3986).
\-\-mime= Optional Specifies the data file's mime-type value. When used then must be written right after the "--file" parameter. If left unspecified then the default mime-type value "application/octet-stream" is used. -\warning Data file’s mime-type value must be formatted as specified in RFC2045, section 5.1 (https://tools.ietf.org/html/rfc2045#section-5.1), i.e. the "type" and "subtype" values must be separated with a forward slash character.
\-\-dontsign Optional Don't sign the newly created container.
@@ -1284,6 +1396,13 @@ Additional options for the "create" command are the same as for "sign" command ( Sample commands for creating and signing DigiDoc files: +\code{.txt} +Sample: creating an ASiC-S container with one data file and an RFC 3161 time-stamp token +> digidoc-tool create --file=file1.txt --mime=text/plain --profile=TimeStampToken timestamped-document.asics + +The profile alias time-stamp-token is also accepted. +\endcode + \code{.txt} Sample: creating new ASiC-E file, adding multiple data files and signing via PKCS#11 driver > digidoc-tool create --file=file1.txt --mime=text/plain --file=file2.pdf --mime=application/pdf --country=Estonia @@ -1381,7 +1500,7 @@ Input: \subsection Opening Opening document, validating signatures and extracting data files -Command "open" enables to read in an existing DigiDoc document, print out a list of its contents and validate signatures. By specifying the additional option --extractaAll, then the data files are extracted from the container and stored on the disk. All DigiDoc file formats are supported with this command (except of BDOC1.0). +Command "open" reads an existing document, prints its contents and validates its signatures. The --extractAll option extracts data files to disk. Supported ASiC-E, ASiC-S and legacy BDOC 2.1 variants are handled locally. PDF, legacy DDOC and ASiC containers with CAdES signatures are sent to the SiVa Online Service for validation; --offline disables that fallback, so those service-backed formats cannot be opened offline. BDOC 1.0 is not supported. General form of the command is: \code{.txt} > digidoc-tool open @@ -1393,12 +1512,6 @@ Available options: If set, then all of the input container’s data files are extracted and written to disk without validating signatures. If an output directory is not specified with the value of this parameter then the extracted files are written to the same directory where the input file is located. --validateOnExtract Optional If set, then validates container before extracting files. -\-\-policy=(POLv1,POLv2) Optional -Signature Validation Policy - -Default POLv2 - -http://open-eid.github.io/SiVa/siva/appendix/validation_policy/ \-\-offline Optional open container offline (eg. Don't send to SiVa) \-\-warnings= @@ -1531,7 +1644,7 @@ Output: \subsection Adding Adding signatures -Command "sign" enables adding signatures to existing DigiDoc containers. The command is supported with DigiDoc formats BDOC 2.1 and ASiC-E. +Command "sign" enables adding XAdES signatures to existing ASiC-E and legacy BDOC 2.1 containers. The same signing options are used by "create" to add the initial \ref RFC3161 "RFC 3161" TimeStampToken to a new ASiC-S container; an existing ASiC-S container cannot receive another ordinary signature. \code{.txt} > digidoc-tool sign \endcode @@ -1541,8 +1654,10 @@ Command "sign" enables adding signatures to existing DigiDoc containers. The com If PIN is not provided with this parameter value and (the default) PKCS#11 module is used for signing then the utility program asks for the user to insert PIN code to command line during the program’s execution time. \-\-profile= Optional Profile of the signature. Possible values are: -- TS - a time-stamp and OCSP confirmation will be added to the signature as validation data. -- TSA - a time-stamp and OCSP confirmation will be added to the signature as validation data. Additional time-stamp is added for notarize all certificate and revocation info. +- TS or time-stamp - a time-stamp and OCSP confirmation will be added to an XAdES signature as validation data. +- TSA or time-stamp-archive - a time-stamp and OCSP confirmation will be added to an XAdES signature as validation data, followed by an archive time-stamp over the certificate and revocation information. +- TimeStampToken or time-stamp-token - create the \ref RFC3161 "RFC 3161" token signature used by a new ASiC-S container. + \-\-XAdESEN Optional Use XAdES EN profile. \-\-city= Optional @@ -1567,8 +1682,10 @@ Used for testing purposes. With RSA keys RSA-PSS padding is used. Specifies the Option to change RSA Signature padding (RSA PKCS1.5). \-\-rsapss Optional Option to change RSA Signature padding (RSA PSS). -\-\-tsurl Optional +\-\-tsurl= Optional Option to change TS URL. +\-\-userAgent= Optional +Additional application information sent to the TSA or OCSP service. \-\-dontValidate Optional Don't validate container on signature creation. @@ -1620,6 +1737,30 @@ Input: \endcode +\subsection Extending Extending container validity +Command "extend" adds new validity evidence and saves the result. Without --signature, it calls the high-level digidoc::Container::extendContainerValidity workflow: eligible ASiC-E or ASiC-S signatures are extended in place, or the original container is wrapped in a new timestamped ASiC-S container when necessary. + +\code{.txt} +> digidoc-tool extend demo-container.asice +\endcode + +When one or more --signature options are specified, only those zero-based signature indexes are extended directly with digidoc::Signature::extendSignatureProfile. In this mode --profile selects the target profile and --dontValidate skips validation after each extension. + + + + + +
\-\-signature=Optional +Zero-based signature index to extend directly. The option can occur multiple times.
\-\-profile=Optional +Target profile for direct per-signature extension: TS, TSA, time-stamp or time-stamp-archive. The high-level workflow chooses the required profile automatically when --signature is omitted.
\-\-dontValidateOptional +Do not validate a directly extended signature after extension.
+ +\code{.txt} +Sample: directly extend signature 0 to the archive time-stamp profile +> digidoc-tool extend --signature=0 --profile=TSA demo-container.asice +\endcode + + \subsection Removing Removing signatures and data files Signatures and data files can be removed from a DigiDoc container with the command "remove". Note that it is possible to remove data files only from an unsigned container (i.e all signatures must be removed before removing data files). The command is supported with DigiDoc formats BDOC 2.1 and ASiC-E. General format of the command is: @@ -1759,8 +1900,8 @@ It is expected that either a time-mark or time-stamp and OCSP confirmation have 10. The data file’s MIME type that is used in case of Libdigidocpp’s utility program is always "application/octet-stream" for testing purposes. 11. The element’s Id attribute value is set to "S" during signature creation where sequence numbers are counted from zero. Other Id values that are used in the sub-elements of the element contain the signature’s Id value as a prefix. During verification, different Id attribute values are also supported but are not tested periodically. 12. signatures*.xml file's XML structure validation is done on the basis of XAdES XML Schema (\ref XAdES), however, there are additional checks to determine any unsupported elements that are allowed by the XAdES specification. The unsupported elements are CounterSignature, AttributeCertificateRefs, AttributeRevocationRefs, RefsOnlyTimeStamp, AttrAuthoritiesCertValues, AttributeRevocationValues, CommitmentTypeIndicationType, AllDataObjectsTimeStamp, IndividualDataObjectsTimeStampType. -13. Special characters in URI attribute values are handled according to RFC3986 (since v3.9 of the library): the characters are percent-encoded, except of unreserved characters and delimiters. Both percent-encoded and non-percent-encoded characters are supported during signature's validation. -14. When validating a BDOC-TS document then the difference between OCSP validity confirmation's production time (producedAt field) and time-stamp's production time (getTime field) is checked. An exception is thrown if the OCSP confirmation's time is earlier than time-stamp's time. If the OCSP confirmation's time is later than time-stamp's time by more than 15 minutes then a warning is returned. If the difference is more than 24 hours then exception is thrown. +13. Special characters in URI attribute values are handled according to \ref RFC3986 "RFC 3986" (since v3.9 of the library): the characters are percent-encoded, except of unreserved characters and delimiters. Both percent-encoded and non-percent-encoded characters are supported during signature's validation. +14. When validating a BDOC-TS document then the difference between the OCSP validity confirmation's production time (producedAt field) and the time-stamp token's creation time (\ref RFC3161 "RFC 3161 TSTInfo.genTime") is checked. An exception is thrown if the OCSP confirmation's time is earlier than the time-stamp's time. If the OCSP confirmation's time is later than the time-stamp's time by more than 15 minutes then a warning is returned. If the difference is more than 24 hours then an exception is thrown. 15. During signature creation, it is checked that the difference between the signer's computer time and the OCSP response's production time (producedAt value) would not exceed 15 minutes. If the difference exceeds 15 minutes then an exception is returned and signing is cancelled. \subsection cert-notes Certificate related notes @@ -1781,3 +1922,8 @@ It is expected that either a time-mark or time-stamp and OCSP confirmation have */ + +/*! \page release_notes Release Notes + +\include RELEASE-NOTES.md +*/ diff --git a/src/ASiC_E.cpp b/src/ASiC_E.cpp index 6b6f944fb..ace983e0b 100644 --- a/src/ASiC_E.cpp +++ b/src/ASiC_E.cpp @@ -56,6 +56,11 @@ ASiC_E::ASiC_E(const string &path, bool create) try if(create) return; auto z = load(true, {MIMETYPE_ASIC_E, MIMETYPE_ADOC}); + /** + * ETSI EN 319 162-1 V1.1.1 (2016-04) + * 5.3.3 Requirements for ASiC-E with XAdES signature, Table 5 + * META-INF/manifest.xml shall be present (cardinality 1) in ASiC-E XAdES baseline containers. + */ auto doc = XMLDocument::open(z.read("META-INF/manifest.xml"), {"manifest", MANIFEST_NS}); static const XMLSchema schema(File::path(Conf::instance()->xsdPath(), "OpenDocument_manifest_v1_2.xsd")); doc.validateSchema(schema); @@ -98,8 +103,8 @@ ASiC_E::ASiC_E(const string &path, bool create) try for(const string &file: z.list()) { /** - * http://www.etsi.org/deliver/etsi_ts/102900_102999/102918/01.03.01_60/ts_102918v010301p.pdf - * 6.2.2 Contents of Container + * ETSI EN 319 162-1 V1.1.1 (2016-04) + * 4.4.3.2 Contents of Container * 3) The root element of each "*signatures*.xml" content shall be either: */ if(file.starts_with("META-INF/") && file.contains("signatures") && file.ends_with(".xml")) diff --git a/src/ASiC_S.h b/src/ASiC_S.h index 1b7dd481f..bfccbe053 100644 --- a/src/ASiC_S.h +++ b/src/ASiC_S.h @@ -25,8 +25,10 @@ namespace digidoc { /** * Implements the ASiC-S specification of the timestamped digital document container. - * Container contains a single datafile object and one time assertion file. - * The signing (timestamping) and save operations are not supported. + * The container contains a single data file and either XAdES signatures or + * an RFC 3161 TimeStampToken. XAdES containers can be opened and validated, + * but are read-only. Creating, timestamping, saving, validating, and adding + * archive-manifest time-stamp layers are supported for TimeStampToken containers. */ class ASiC_S : public ASiContainer { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a617eed5c..5ee902147 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -168,6 +168,7 @@ if( BUILD_TOOLS ) target_link_options(digidoc-tool PRIVATE $<$: /MANIFEST:NO /MANIFEST:EMBED /MANIFESTINPUT:${CMAKE_CURRENT_SOURCE_DIR}/digidoc-tool.manifest> ) + string(TIMESTAMP BUILD_DATE "%Y-%m-%d" UTC) configure_file( digidoc-tool.1.cmake digidoc-tool.1 ) endif() diff --git a/src/DataFile.cpp b/src/DataFile.cpp index b2826d3b3..5cfe26672 100644 --- a/src/DataFile.cpp +++ b/src/DataFile.cpp @@ -86,6 +86,8 @@ using namespace std; DataFile::DataFile() = default; DataFile::~DataFile() = default; +/** @cond INTERNAL */ + struct DataFilePrivate::Private { optional size; }; @@ -187,3 +189,5 @@ void DataFilePrivate::saveAs(ostream &os) const m_is->seekg(0); os << m_is->rdbuf(); } + +/** @endcond */ diff --git a/src/crypto/Digest.cpp b/src/crypto/Digest.cpp index 60d216e31..f751993d0 100644 --- a/src/crypto/Digest.cpp +++ b/src/crypto/Digest.cpp @@ -105,8 +105,9 @@ bool Digest::isWeakDigest(string_view uri) * For available method URIs see: *
  • *
      W3C XML Encryption Syntax and Processing (10 December 2005) http://www.w3.org/TR/xmlenc-core/
    - *
      RFC 4051 https://www.ietf.org/rfc/rfc4051.txt
    - *
      RFC 6931 https://www.ietf.org/rfc/rfc6931.txt
    + *
      RFC 4051 https://www.rfc-editor.org/rfc/rfc4051.html
    + *
      RFC 6931 https://www.rfc-editor.org/rfc/rfc6931.html
    + *
      RFC 9231 https://www.rfc-editor.org/rfc/rfc9231.html
    *
  • * * @param uri digest method URI (e.g. 'http://www.w3.org/2000/09/xmldsig#sha1' for SHA1). diff --git a/src/crypto/OCSP.cpp b/src/crypto/OCSP.cpp index 0859b9a73..22c4a98e3 100644 --- a/src/crypto/OCSP.cpp +++ b/src/crypto/OCSP.cpp @@ -78,7 +78,9 @@ OCSP::OCSP(const X509Cert &cert, const X509Cert &issuer, const std::string &user if(!OCSP_request_add0_id(req.get(), certId)) THROW_OPENSSLEXCEPTION("Failed to add certificate ID to OCSP request."); - if(!OCSP_request_add1_nonce(req.get(), nullptr, 32)) // rfc8954: SIZE(1..32) + // RFC 8954: the OCSP nonce has SIZE(1..32). + // https://www.rfc-editor.org/rfc/rfc8954.html + if(!OCSP_request_add1_nonce(req.get(), nullptr, 32)) THROW_OPENSSLEXCEPTION("Failed to add NONCE to OCSP request."); Connect::Result result = Connect(url, "POST", 0, {}, userAgent, "1.0").exec({ diff --git a/src/crypto/X509Cert.cpp b/src/crypto/X509Cert.cpp index fa5b528e5..489089af6 100644 --- a/src/crypto/X509Cert.cpp +++ b/src/crypto/X509Cert.cpp @@ -142,57 +142,57 @@ DECLARE_ASN1_FUNCTIONS(QCStatements) */ /** - * https://www.ietf.org/rfc/rfc3739.txt - id-etsi-qcs-QcCompliance + * https://www.rfc-editor.org/rfc/rfc3739.html - id-etsi-qcs-QcCompliance * @since 3.13.0 */ const string X509Cert::QC_COMPLIANT = "0.4.0.1862.1.1"; /** - * https://www.ietf.org/rfc/rfc3739.txt - id-etsi-qcs-QcSSCD + * https://www.rfc-editor.org/rfc/rfc3739.html - id-etsi-qcs-QcSSCD * @since 3.13.0 */ const string X509Cert::QC_SSCD = "0.4.0.1862.1.4"; /** - * https://www.ietf.org/rfc/rfc3739.txt - id-etsi-qcs-QcPDS + * https://www.rfc-editor.org/rfc/rfc3739.html - id-etsi-qcs-QcPDS * @since 3.13.0 */ const string X509Cert::QC_QCP = "0.4.0.1862.1.5"; /** - * https://www.ietf.org/rfc/rfc3739.txt - id-etsi-qcs-QcType + * https://www.rfc-editor.org/rfc/rfc3739.html - id-etsi-qcs-QcType * @since 3.13.0 */ const string X509Cert::QC_QCT = "0.4.0.1862.1.6"; /** - * https://www.ietf.org/rfc/rfc3739.txt - id-qcs-pkixQCSyntax-v1 + * https://www.rfc-editor.org/rfc/rfc3739.html - id-qcs-pkixQCSyntax-v1 * @since 3.13.0 */ const string X509Cert::QC_SYNTAX1 = "1.3.6.1.5.5.7.11.1"; /** - * https://www.ietf.org/rfc/rfc3739.txt - id-qcs-pkixQCSyntax-v2 + * https://www.rfc-editor.org/rfc/rfc3739.html - id-qcs-pkixQCSyntax-v2 * @since 3.13.0 */ const string X509Cert::QC_SYNTAX2 = "1.3.6.1.5.5.7.11.2"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941201/01.01.01_60/en_31941201v010101p.pdf - id-etsi-qcs-semanticsId-natural + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941201/01.07.01_60/en_31941201v010701p.pdf - id-etsi-qcs-semanticsId-natural * @since 3.13.0 */ const string X509Cert::QCS_NATURAL = "0.4.0.194121.1.1"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941201/01.01.01_60/en_31941201v010101p.pdf - id-etsi-qcs-semanticsId-legal + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941201/01.07.01_60/en_31941201v010701p.pdf - id-etsi-qcs-semanticsId-legal * @since 3.13.0 */ const string X509Cert::QCS_LEGAL = "0.4.0.194121.1.2"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.01.01_60/en_31941205v020101p.pdf - id-etsi-qct-esign + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.06.01_60/en_31941205v020601p.pdf - id-etsi-qct-esign * @since 3.13.0 */ const string X509Cert::QCT_ESIGN = "0.4.0.1862.1.6.1"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.01.01_60/en_31941205v020101p.pdf - id-etsi-qct-eseal + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.06.01_60/en_31941205v020601p.pdf - id-etsi-qct-eseal * @since 3.13.0 */ const string X509Cert::QCT_ESEAL = "0.4.0.1862.1.6.2"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.01.01_60/en_31941205v020101p.pdf - id-etsi-qct-web + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.06.01_60/en_31941205v020601p.pdf - id-etsi-qct-web * @since 3.13.0 */ const string X509Cert::QCT_WEB = "0.4.0.1862.1.6.3"; @@ -207,27 +207,27 @@ const string X509Cert::QCP_PUBLIC_WITH_SSCD = "0.4.0.1456.1.1"; */ const string X509Cert::QCP_PUBLIC = "0.4.0.1456.1.2"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.01.01_60/en_31941102v020101p.pdf + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.06.01_60/en_31941102v020601p.pdf * @since 3.13.0 */ const string X509Cert::QCP_NATURAL = "0.4.0.194112.1.0"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.01.01_60/en_31941102v020101p.pdf + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.06.01_60/en_31941102v020601p.pdf * @since 3.13.0 */ const string X509Cert::QCP_LEGAL = "0.4.0.194112.1.1"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.01.01_60/en_31941102v020101p.pdf + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.06.01_60/en_31941102v020601p.pdf * @since 3.13.0 */ const string X509Cert::QCP_NATURAL_QSCD = "0.4.0.194112.1.2"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.01.01_60/en_31941102v020101p.pdf + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.06.01_60/en_31941102v020601p.pdf * @since 3.13.0 */ const string X509Cert::QCP_LEGAL_QSCD = "0.4.0.194112.1.3"; /** - * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.01.01_60/en_31941102v020101p.pdf + * http://www.etsi.org/deliver/etsi_en/319400_319499/31941102/02.06.01_60/en_31941102v020601p.pdf * @since 3.13.0 */ const string X509Cert::QCP_WEB = "0.4.0.194112.1.4"; @@ -356,7 +356,7 @@ string X509Cert::serial() const } /** - * Returns issuer name as an RFC 2253 string. + * Returns issuer name as an \ref RFC2253 "RFC 2253" string. * * @param obj If empty, returns the full issuer DN. If a short name (e.g., "CN", "O", "C") is provided, * returns only that component of the issuer name. @@ -411,7 +411,7 @@ vector X509Cert::certificatePolicies() const } /** - * Returns Qualified Certificate (QC) statements as defined in RFC 3739 and ETSI EN 319 412-5. + * Returns Qualified Certificate (QC) statements as defined in \ref RFC3739 "RFC 3739" and ETSI EN 319 412-5. * * @since 3.13.0 * @return Vector of OID strings representing QC statements. @@ -460,7 +460,7 @@ vector X509Cert::qcStatements() const } /** - * Returns subject name as an RFC 2253 string. + * Returns subject name as an \ref RFC2253 "RFC 2253" string. * * @param obj If empty, returns the full subject DN. If a short name (e.g., "CN", "SN", "GN") is provided, * returns only that component of the subject name. diff --git a/src/crypto/X509Crypto.cpp b/src/crypto/X509Crypto.cpp index 105e4160d..aa1b1424f 100644 --- a/src/crypto/X509Crypto.cpp +++ b/src/crypto/X509Crypto.cpp @@ -53,7 +53,8 @@ X509Crypto::X509Crypto(X509Cert cert) bool X509Crypto::compareIssuerToDer(const vector &data) const { - // DER-encoded instance of type IssuerSerial type defined in IETF RFC 5035 [17]. + // DER-encoded instance of type IssuerSerial defined in IETF RFC 5035: + // https://www.rfc-editor.org/rfc/rfc5035.html auto is = d2i(data); if(!is || sk_GENERAL_NAME_num(is->issuer) != 1) return false; @@ -67,7 +68,7 @@ bool X509Crypto::compareIssuerToDer(const vector &data) const /** * Check if X509Cert issuer is same as provided issuer name by * http://www.w3.org/TR/xmldsig-core/#dname-encrules which refers to - * http://www.ietf.org/rfc/rfc4514.txt + * https://www.rfc-editor.org/rfc/rfc4514.html * * String X.500 AttributeType * CN commonName (2.5.4.3) @@ -80,7 +81,8 @@ bool X509Crypto::compareIssuerToDer(const vector &data) const * DC domainComponent (0.9.2342.19200300.100.1.25) * UID userId (0.9.2342.19200300.100.1.1) * - * These attribute types are described in [RFC4519]. + * These attribute types are described in RFC 4519: + * https://www.rfc-editor.org/rfc/rfc4519.html * Implementations MAY recognize other DN string representations. * However, as there is no requirement that alternative DN string * representations be recognized (and, if so, how), implementations diff --git a/src/digidoc-tool.1.cmake b/src/digidoc-tool.1.cmake index 6eca6a05b..aba05ce00 100644 --- a/src/digidoc-tool.1.cmake +++ b/src/digidoc-tool.1.cmake @@ -1,84 +1,254 @@ .\" Manpage for digidoc-tool -.TH digidoc-tool 1 "${BUILD_DATE}" "${VERSION}" "digidoc-tool man page" +.TH DIGIDOC-TOOL 1 "${BUILD_DATE}" "${VERSION}" "User Commands" .SH NAME -digidoc-tool \- open/create/verify ASiC-E/ASiC-S/BDoc format files +digidoc-tool \- create, sign, open, validate, and extend ASiC containers .SH SYNOPSIS -digidoc-tool COMMAND [OPTIONS] FILE -.SH OPTIONS -Command create: - Example: digidoc-tool create --file=file1.txt --file=file2.txt demo-container.asice - Available options: - --file= - File(s) to be signed. The option can occur multiple times. - --mime= - Specifies the file's mime-type value. When used then must be written right - after the "-file" parameter. Default value is application/octet-stream - --dontsign - Don't sign the newly created container. - for additional options look sign command - -Command createBatch: - Example: digidoc-tool createBatch folder/content/to/sign - Available options: - for additional options look sign command - -Command open: - Example: digidoc-tool open container-file.asice - Available options: - --warnings=(ignore,warning,error) - warning handling (default warning) - --policy=(POLv1,POLv2) - Signature Validation Policy (default POLv2) - http://open-eid.github.io/SiVa/siva/appendix/validation_policy/ - --extractAll[=path] - extracts documents without validating signatures (to path when provided) - --validateOnExtract - validates container before extracting files - --offline - open container offline (eg. Don't send to SiVa) - -Command add: - Example: digidoc-tool add --file=file1.txt container-file.asice - Available options: - --file and --mime look create command for info - -Command remove: - Example: digidoc-tool remove --document=0 --document=1 --signature=1 container-file.asice - Available options: - --document= - documents to remove - --signature= - signatures to remove - -Command websign: - Example: digidoc-tool websign --cert=signer.crt demo-container.asice - Available options: - --cert= - signer token certificate - for additional options look sign command - -Command sign: - Example: digidoc-tool sign demo-container.asice - Available options: - --profile= - signature profile, TS, TSA, time-stamp, time-stamp-archive, TimeStampToken, time-stamp-token - --XAdESEN - use XAdES EN profile - --city= - city of production place - --street= - streetAddress of production place in XAdES EN profile - --state= - state of production place - --postalCode= - postalCode of production place - --country= - country of production place - --role= - option can occur multiple times. Signer role(s) - --pkcs11[=] - default is ${PKCS11_MODULE}. Path of PKCS11 driver. - --pkcs12= - pkcs12 signer certificate (use --pin for password) - --pin= - default asks pin from prompt - --sha(224,256,384,512) - set default digest method (default sha256) - --sigsha(224,256,384,512) - set default digest method (default sha256) - --sigpsssha(224,256,384,512) - set default digest method using RSA PSS (default sha256, same as --sigsha* with --rsapss) - --rsapkcs15 - Use RSA PKCS1.5 padding - --rsapss - Use RSA PSS padding - --tsurl - option to change TS URL (default http://demo.sk.ee/tsa) - --dontValidate - Don't validate container on signature creation - --userAgent - Additional info info that is sent to TSA or OCSP service - -Command extend: - Example: " << executable << " extend --signature=0 demo-container.asice - Available options: - --profile= - signature profile, TS, TSA, time-stamp, time-stamp-archive - --signature= - signature to extend - --dontValidate - Don't validate container on signature creation - -All commands: - --nocolor - Disable terminal colors - --loglevel=[0,1,2,3,4] - Log level 0 - none, 1 - error, 2 - warning, 3 - info, 4 - debug - --logfile= - File to log, empty to console +.B digidoc-tool +.I COMMAND +.RI [ OPTIONS ] +.I FILE +.SH DESCRIPTION +.B digidoc-tool +is a command-line utility for working with digital signature containers. +Supported ASiC-E, ASiC-S, and legacy BDOC 2.1 variants are handled locally. +PDF, legacy DDOC, and ASiC containers with CAdES signatures are validated +through the SiVa Online Service. The +.B \-\-offline +option disables this service fallback. +.PP +The interface is intended for testing and as an API usage example. Its +command-line compatibility is not guaranteed between releases. +.SH COMMANDS +.SS create +Create and normally sign a container. The output extension selects ASiC-E +(.asice or .sce) or ASiC-S (.asics or .scs). +.PP +An ASiC-S TimeStampToken container requires exactly one +.B \-\-file +and +.BR "\-\-profile=TimeStampToken" . +The profile alias +.B time-stamp-token +is also accepted. +.PP +Example: +.PP +.EX +digidoc-tool create --file=document.txt signed-document.asice +digidoc-tool create --file=document.txt --profile=TimeStampToken timestamped-document.asics +.EE +.TP +.BI \-\-file= path +Add a data file. This option may occur multiple times for ASiC-E. +.TP +.BI \-\-mime= type/subtype +Set the MIME type for the preceding +.B \-\-file +option. The default is application/octet-stream. +.TP +.B \-\-dontsign +Create the container without signing it. This is intended for ASiC-E. +.PP +The signing options described under +.B sign +are also accepted. +.SS createBatch +Create and sign a separate ASiC-E container for each regular file in a +directory. +.PP +Example: +.PP +.EX +digidoc-tool createBatch folder/content/to/sign +.EE +.SS open +Open a document, list its contents, and validate its signatures. +.PP +Example: +.PP +.EX +digidoc-tool open container-file.asice +.EE +.TP +.BR \-\-warnings= "ignore|warning|error" +Select how validation warnings affect output. The default is warning. +.TP +.BR \-\-extractAll [=directory] +Extract all data files without validating signatures. Without a directory, +files are written to the current directory. +.TP +.B \-\-validateOnExtract +Validate the container before extracting data files. +.TP +.B \-\-offline +Do not send unsupported local formats to SiVa. Service-backed formats cannot +be opened in this mode. +.SS add +Add data files to an unsigned ASiC-E container. The +.B \-\-file +and +.B \-\-mime +options have the same meaning as for +.BR create . +.PP +Example: +.PP +.EX +digidoc-tool add --file=file1.txt container-file.asice +.EE +.SS remove +Remove data files or signatures by their zero-based indexes. Data files can +only be removed after all signatures have been removed. +.PP +Example: +.PP +.EX +digidoc-tool remove --document=0 --signature=1 container-file.asice +.EE +.TP +.BI \-\-document= index +Data file to remove. This option may occur multiple times. +.TP +.BI \-\-signature= index +Signature to remove. This option may occur multiple times. +.SS websign +Create an ASiC-E container using external two-step XAdES signing. +.TP +.BI \-\-cert= file +PEM signer certificate. +.PP +The data-file and signing metadata options described under +.B create +and +.B sign +are also accepted. +.SS sign +Add an XAdES signature to an existing ASiC-E or legacy BDOC 2.1 container. +The signing options are also used by +.B create +to add the initial RFC 3161 TimeStampToken to a new ASiC-S container. An +existing ASiC-S container cannot receive another ordinary signature. +.PP +Example: +.PP +.EX +digidoc-tool sign --pkcs11 container-file.asice +.EE +.TP +.BI \-\-profile= profile +Signature profile. Accepted values are TS, TSA, time-stamp, +time-stamp-archive, TimeStampToken, and time-stamp-token. The TimeStampToken +profiles are used when creating ASiC-S. +.TP +.B \-\-XAdESEN +Use the XAdES EN profile. +.TP +.BI \-\-city= value +City of the signature production place. +.TP +.BI \-\-street= value +Street address of the signature production place for the XAdES EN profile. +.TP +.BI \-\-state= value +State or province of the signature production place. +.TP +.BI \-\-postalCode= value +Postal code of the signature production place. +.TP +.BI \-\-country= code +Two-character country code of the signature production place. +.TP +.BI \-\-role= value +Signer role. This option may occur multiple times. +.TP +.BR \-\-pkcs11 [=driver] +Use PKCS#11. If no driver is given, the configured default is +${PKCS11_MODULE}. +.TP +.BI \-\-pkcs12= file +Use a PKCS#12 software token. The +.B \-\-pin +value is used as its password. +.TP +.BI \-\-pin= value +PIN or PKCS#12 password. PKCS#11 prompts for a PIN when this is omitted. +.TP +.B \-\-cng +On Windows, use the Microsoft CNG signing API. +.TP +.B \-\-selectFirst +On Windows, select the first suitable certificate instead of showing a +selection dialog. +.TP +.BI \-\-thumbprint= hex +On Windows, select a certificate by its hexadecimal thumbprint. +.TP +.BR \-\-sha224 | \-\-sha256 | \-\-sha384 | \-\-sha512 +Select the data digest algorithm. The default is SHA-256. +.TP +.BR \-\-sigsha224 | \-\-sigsha256 | \-\-sigsha384 | \-\-sigsha512 +Select the signature digest algorithm. The default is SHA-256. +.TP +.BR \-\-sigpsssha224 | \-\-sigpsssha256 | \-\-sigpsssha384 | \-\-sigpsssha512 +Select the signature digest algorithm and RSA-PSS padding. +.TP +.B \-\-rsapkcs15 +Use RSA PKCS#1 v1.5 padding. +.TP +.B \-\-rsapss +Use RSA-PSS padding. +.TP +.BI \-\-tsurl= url +Override the configured time-stamping service URL. +.TP +.BI \-\-userAgent= value +Send additional application information to the TSA or OCSP service. +.TP +.B \-\-dontValidate +Do not validate the newly created signature. +.SS extend +Add new validity evidence and save the result. +.PP +Without +.BR \-\-signature , +the high-level validity-extension workflow chooses the required profile. It +extends eligible ASiC-E or ASiC-S signatures in place, or wraps the original +container in a new timestamped ASiC-S container when necessary. +.PP +With one or more +.B \-\-signature +options, only the selected signatures are extended directly. +.PP +Examples: +.PP +.EX +digidoc-tool extend container-file.asice +digidoc-tool extend --signature=0 --profile=TSA container-file.asice +.EE +.TP +.BI \-\-signature= index +Zero-based signature index to extend directly. This option may occur multiple +times. +.TP +.BI \-\-profile= profile +Direct extension profile: TS, TSA, time-stamp, or time-stamp-archive. This is +chosen automatically when +.B \-\-signature +is omitted. +.TP +.B \-\-dontValidate +Do not validate a directly extended signature after extension. +.SS version +Print the digidoc-tool and libdigidocpp versions. +.SH GLOBAL OPTIONS +.TP +.B \-\-nocolor +Disable terminal colors. +.TP +.BR \-\-loglevel= 0|1|2|3|4 +Set logging to none, error, warning, info, or debug respectively. +.TP +.BI \-\-logfile= file +Write logs to a file. An empty value writes logs to the console. .SH SEE ALSO -qdigidoc4(1) +.BR qdigidoc4 (1) diff --git a/src/digidoc-tool.cpp b/src/digidoc-tool.cpp index 698ff8430..2f1e8b5ad 100644 --- a/src/digidoc-tool.cpp +++ b/src/digidoc-tool.cpp @@ -346,7 +346,7 @@ static int printUsage(const char *executable) << " Available options:" << endl << " --file= - File(s) to be signed. The option can occur multiple times." << endl << " --mime= - Specifies the file's mime-type value. When used then must be written right " << endl - << " after the \"-file\" parameter. Default value is application/octet-stream" << endl + << " after the \"--file\" parameter. Default value is application/octet-stream" << endl << " --dontsign - Don't sign the newly created container." << endl << " for additional options look sign command" << endl << endl << " Command createBatch:" << endl @@ -398,15 +398,17 @@ static int printUsage(const char *executable) << " --sigpsssha(224,256,384,512) - set default digest method using RSA PSS (default sha256, same as --sigsha* with --rsapss)" << endl << " --rsapkcs15 - Use RSA PKCS1.5 padding" << endl << " --rsapss - Use RSA PSS padding" << endl - << " --tsurl - option to change TS URL (default " << CONF(TSUrl) << ")" << endl - << " --dontValidate - Don't validate container on signature creation" << endl << endl - << " --userAgent - Additional info info that is sent to TSA or OCSP service" << endl << endl + << " --tsurl= - option to change TS URL (default " << CONF(TSUrl) << ")" << endl + << " --dontValidate - Don't validate container on signature creation" << endl + << " --userAgent= - Additional application info sent to TSA or OCSP service" << endl << endl << " Command extend:" << endl << " Example: " << executable << " extend --signature=0 demo-container.asice" << endl << " Available options:" << endl << " --profile= - signature profile, TS, TSA, time-stamp, time-stamp-archive" << endl << " --signature= - signature to extend" << endl - << " --dontValidate - Don't validate container on signature creation" << endl << endl + << " --dontValidate - Don't validate a directly extended signature after extension" << endl << endl + << " Command version:" << endl + << " Prints digidoc-tool and libdigidocpp versions." << endl << endl << " All commands:" << endl << " --nocolor - Disable terminal colors" << endl << " --loglevel=[0,1,2,3,4] - Log level 0 - none, 1 - error, 2 - warning, 3 - info, 4 - debug" << endl @@ -457,6 +459,7 @@ ToolConfig::ToolConfig(int argc, char *argv[]) else if(value v{arg, "--postalCode="}) postalCode = v; else if(value v{arg, "--country="}) country = v; else if(value v{arg, "--role="}) roles.emplace_back(v); + else if(value v{arg, "--userAgent="}) userAgent = v; else if(arg == "--sha224") uri = URI_SHA224; else if(arg == "--sha256") uri = URI_SHA256; else if(arg == "--sha384") uri = URI_SHA384;