Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ jobs:
fedora:
name: Build on Fedora ${{ matrix.container }}
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.container == 'rawhide' }}
container: fedora:${{ matrix.container }}
strategy:
matrix:
Expand Down Expand Up @@ -231,11 +232,14 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Cache vcpkg
- name: Cache vcpkg and WiX
uses: actions/cache@v5
with:
path: ${{ github.workspace }}/vcpkg_cache
key: vcpkg-${{ matrix.toolset }}-${{ matrix.platform }}-${{ hashFiles('vcpkg.json') }}
path: |
${{ github.workspace }}/vcpkg_cache
~/.dotnet/tools
~/.wix
key: vcpkg-${{ matrix.toolset }}-${{ matrix.platform }}-${{ hashFiles('vcpkg.json') }}-wix-7.0.0
- name: Setup winget
if: matrix.toolset == '143'
shell: powershell
Expand Down Expand Up @@ -269,7 +273,8 @@ jobs:
-swig $swig `
-doxygen "C:/Program files/doxygen/bin/doxygen.exe" `
-boost `
-python ${{ github.workspace }}/python
-python ${{ github.workspace }}/python `
-acceptWixEULA
- name: Archive artifacts
uses: actions/upload-artifact@v7
with:
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ endif()
if(POLICY CMP0177)
cmake_policy(SET CMP0177 NEW)
endif()
project(libdigidocpp VERSION 4.5.1
project(libdigidocpp VERSION 4.6.0
DESCRIPTION "C++ library for digital signatures and validation of digitally signed documents"
HOMEPAGE_URL https://github.com/open-eid/libdigidocpp
)
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,19 @@

6. Alternative to steps 4. and 5. -

powershell -ExecutionPolicy ByPass -File build.ps1
powershell -ExecutionPolicy ByPass -File build.ps1 -acceptWixEULA

WiX 7 requires accepting its
[Open Source Maintenance Fee EULA](https://docs.firegiant.com/wix/osmf/).
Pass `-acceptWixEULA` only after reviewing the terms. The acceptance is stored
for the current user, so the switch can be omitted from subsequent builds.

Optional build.ps1 parameters:

-swig C:/swigwin-4.4.1/swig.exe
-doxygen "C:/Program files/doxygen/bin/doxygen.exe"
-boost
-acceptWixEULA

The build script builds executables and installation media for given
platform (Debug and Release with debug symbols)
Expand Down
2 changes: 1 addition & 1 deletion RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Libdigidocpp library [4.5.0](https://github.com/open-eid/libdigidocpp/releases/t
- Harden XML, ZIP, network, and file handling
(#731, #732, #734, #736, #738, #743)
- Other fixes, optimizations, and documentation updates
(#727, #733, #753, #755)
(#727, #733, #753, #755, #757)

[Full Changelog](https://github.com/open-eid/libdigidocpp/compare/v4.4.0...v4.5.0)

Expand Down
13 changes: 9 additions & 4 deletions build.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#powershell -ExecutionPolicy ByPass -File build.ps1
param(
[string]$libdigidocpp = $PSScriptRoot,
[string]$platform = $env:PLATFORM,
[string]$platform = $(if ($null -eq $env:PLATFORM) {"x64"} else {$env:PLATFORM}),
[string]$build_number = $(if ($null -eq $env:BUILD_NUMBER) {"0"} else {$env:BUILD_NUMBER}),
[string]$msiversion = (Select-String -Path "$libdigidocpp/CMakeLists.txt" -Pattern 'project\(\w+ VERSION (\S+)').Matches[0].Groups[1].Value + ".$build_number",
[string]$msi_name = "libdigidocpp-$msiversion$env:VER_SUFFIX.$platform.msi",
Expand All @@ -16,7 +16,8 @@ param(
[string]$doxygen = $null,
[switch]$boost = $false,
[string]$sign = $null,
[string]$python = $null
[string]$python = $null,
[switch]$acceptWixEULA = $false
)

$ErrorActionPreference = "Stop"
Expand All @@ -25,10 +26,14 @@ Try {
& wix > $null
}
Catch {
& dotnet tool install -g --version 6.0.2 wix
& wix extension add -g WixToolset.UI.wixext/6.0.2
& dotnet tool install -g --version 7.0.0 wix
}

if($acceptWixEULA) {
& wix eula accept wix7
}
& wix extension add -g WixToolset.UI.wixext/7.0.0

if(!(Test-Path -Path $vcpkg)) {
$vcpkg = "$libdigidocpp\vcpkg"
& $git clone https://github.com/microsoft/vcpkg $vcpkg
Expand Down
2 changes: 0 additions & 2 deletions libdigidocpp.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
<?define VCVER = "145" ?>
<?elseif $(env.VisualStudioVersion) = "17.0" ?>
<?define VCVER = "143" ?>
<?elseif $(env.VisualStudioVersion) = "16.0" ?>
<?define VCVER = "142" ?>
<?endif?>

<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
Expand Down
76 changes: 63 additions & 13 deletions src/ASiC_S.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

#include "ASiC_S.h"

#include "DataFile_p.h"
#include "Exception.h"
#include "SiVaContainer.h"
#include "SignatureTST.h"
#include "SignatureXAdES_LTA.h"
#include "crypto/Signer.h"
Expand All @@ -33,7 +36,7 @@ using namespace std;
/**
* Initialize ASiCS container.
*/
ASiC_S::ASiC_S(const string &path, bool create)
ASiC_S::ASiC_S(const string &path, bool create, ContainerOpenCB *cb)
: ASiContainer(path, MIMETYPE_ASIC_S)
{
if(create)
Expand All @@ -49,14 +52,14 @@ ASiC_S::ASiC_S(const string &path, bool create)
foundTimestamp = true;
if(file == "META-INF/ASiCArchiveManifest.xml")
{
if(!signatures().empty())
if(!containerSignatures().empty())
THROW("Can not add signature to ASiC-S container which already contains a signature.");
addSignature(make_unique<SignatureTST>(true, z, this));
foundManifest = true;
}
else if(file == "META-INF/signatures.xml")
{
if(!signatures().empty())
if(!containerSignatures().empty())
THROW("Can not add signature to ASiC-S container which already contains a signature.");
auto signatures = make_shared<Signatures>(XMLDocument::open(z.read(file)), mediaType());
for(auto s = signatures->signature(); s; s++)
Expand All @@ -67,31 +70,78 @@ ASiC_S::ASiC_S(const string &path, bool create)
else if(const auto directory = File::directory(file);
!directory.empty() && directory != "/" && directory != "./")
THROW("Subfolders are not supported %s", directory.c_str());
else if(!dataFiles().empty())
else if(!containerDataFiles().empty())
THROW("Can not add document to ASiC-S container which already contains a document.");
else
addDataFilePrivate(z, file, "application/octet-stream");
}
if(foundTimestamp && !foundManifest)
{
if(!signatures().empty())
if(!containerSignatures().empty())
THROW("Can not add signature to ASiC-S container which already contains a signature.");
addSignature(make_unique<SignatureTST>(false, z, this));
}

if(dataFiles().empty())
if(containerDataFiles().empty())
THROW("ASiC-S container does not contain any data objects.");
if(signatures().empty())
if(containerSignatures().empty())
THROW("ASiC-S container does not contain any signatures.");

const auto documents = containerDataFiles();
const auto containerSigs = containerSignatures();
if(!cb || documents.size() != 1 || containerSigs.size() != 1 ||
containerSigs.front()->profile() != ASIC_TST_PROFILE ||
!File::fileExtension(documents.front()->fileName(), {"ddoc"}))
return;

try
{
auto *ddoc = static_cast<DataFilePrivate*>(documents.front());
enclosedDDoc = SiVaContainer::openDDoc(*ddoc->m_is, ddoc->fileName(), cb);
}
catch(...) {}
}

void ASiC_S::addDataFileChecks(string_view fileName, const string &mediaType)
{
ASiContainer::addDataFileChecks(fileName, mediaType);
if(!dataFiles().empty())
if(!containerDataFiles().empty())
THROW("Can not add document to ASiC-S container which already contains a document.");
}

vector<DataFile*> ASiC_S::containerDataFiles() const
{
return ASiContainer::dataFiles();
}

vector<DataFile*> ASiC_S::dataFiles() const
{
return enclosedDDoc ? enclosedDDoc->dataFiles() : containerDataFiles();
}

vector<Signature*> ASiC_S::containerSignatures() const
{
return ASiContainer::signatures();
}

void ASiC_S::removeSignature(unsigned int id)
{
if(enclosedDDoc)
THROW("Can not remove signatures from an ASiC-S container with an enclosed DDoc.");
ASiContainer::removeSignature(id);
}

vector<Signature*> ASiC_S::signatures() const
{
auto result = containerSignatures();
if(enclosedDDoc)
{
auto enclosed = enclosedDDoc->signatures();
result.insert(result.end(), enclosed.begin(), enclosed.end());
}
return result;
}

unique_ptr<Container> ASiC_S::createInternal(const string &path)
{
if(!util::File::fileExtension(path, {"asics", "scs"}))
Expand All @@ -107,18 +157,18 @@ void ASiC_S::addAdESSignature(istream & /*signature*/)

void ASiC_S::canSave()
{
if(auto list = signatures(); !list.empty() && list.front()->profile() != ASIC_TST_PROFILE)
if(auto list = containerSignatures(); !list.empty() && list.front()->profile() != ASIC_TST_PROFILE)
THROW("ASiC-S container supports only saving TimeStampToken signatures.");
}

unique_ptr<Container> ASiC_S::openInternal(const string &path, ContainerOpenCB * /*cb*/)
unique_ptr<Container> ASiC_S::openInternal(const string &path, ContainerOpenCB *cb)
{
DEBUG("ASiC_S::openInternal(%s)", path.c_str());
try
{
if(util::File::fileExtension(path, {"asice", "sce", "bdoc"}))
return {};
return unique_ptr<Container>(new ASiC_S(path, false));
return unique_ptr<Container>(new ASiC_S(path, false, cb));
}
catch(const Exception &)
{
Expand All @@ -137,15 +187,15 @@ void ASiC_S::save(const ZipSerialize &s)
if(const auto &prop = zproperty("META-INF/manifest.xml");
prop.size && !createManifest().save(s.addFile("META-INF/manifest.xml", prop), true))
THROW("Failed to create manifest XML");
for(Signature *sig: signatures())
for(Signature *sig: containerSignatures())
static_cast<SignatureTST*>(sig)->save(s);
}

Signature *ASiC_S::sign(Signer *signer)
{
if(signer->profile() != ASIC_TST_PROFILE)
THROW("ASiC-S container supports only TimeStampToken signing.");
if(!signatures().empty())
if(!containerSignatures().empty())
THROW("ASiC-S container supports only one TimeStampToken signature.");
return addSignature(make_unique<SignatureTST>(this, signer));
}
9 changes: 8 additions & 1 deletion src/ASiC_S.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,27 @@ namespace digidoc
static constexpr std::string_view ASIC_TST_PROFILE = "TimeStampToken";

void addAdESSignature(std::istream &sigdata) override;
std::vector<DataFile*> dataFiles() const override;
Signature* prepareSignature(Signer *signer) override;
void removeSignature(unsigned int id) override;
std::vector<Signature*> signatures() const override;
Signature* sign(Signer* signer) override;

static std::unique_ptr<Container> createInternal(const std::string &path);
static std::unique_ptr<Container> openInternal(const std::string &path, ContainerOpenCB *cb);

private:
ASiC_S(const std::string &path, bool create);
ASiC_S(const std::string &path, bool create, ContainerOpenCB *cb = nullptr);
DISABLE_COPY(ASiC_S);

void addDataFileChecks(std::string_view path, const std::string &mediaType) override;
void canSave() final;
std::vector<DataFile*> containerDataFiles() const;
std::vector<Signature*> containerSignatures() const;
void save(const ZipSerialize &s) final;

std::unique_ptr<Container> enclosedDDoc;

friend class SignatureTST;
};
}
6 changes: 3 additions & 3 deletions src/ASiContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ XMLDocument ASiContainer::createManifest() const
file.setProperty("media-type", mime, MANIFEST_NS);
};
add("/", mediaType());
for(const DataFile *file: dataFiles())
for(const DataFile *file: d->documents)
add(file->fileName(), file->mediaType());
return doc;
}
Expand Down Expand Up @@ -265,7 +265,7 @@ void ASiContainer::deleteSignature(Signature* s)

void ASiContainer::save(const string &path)
{
if(dataFiles().empty())
if(d->documents.empty())
THROW("Can not save, container is empty.");
canSave();
if(!path.empty())
Expand All @@ -274,7 +274,7 @@ void ASiContainer::save(const string &path)
s.addFile("mimetype", zproperty("mimetype"), false)(mediaType());

array<char,10240> buf{};
for(const DataFile *file: dataFiles())
for(const DataFile *file: d->documents)
{
auto f = s.addFile(file->fileName(), zproperty(file->fileName()));
const auto &is = static_cast<const DataFilePrivate*>(file)->m_is;
Expand Down
10 changes: 7 additions & 3 deletions src/Container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,11 @@ unique_ptr<Container> Container::createPtr(const std::string &path)
std::unique_ptr<Container> Container::extendContainerValidity(Container &doc, Signer *signer, size_t &extendedCount) try
{
extendedCount = 0;
if(doc.signatures().empty())
auto signatures = doc.signatures();
if(doc.mediaType() == ASiContainer::MIMETYPE_ASIC_S &&
!signatures.empty() && signatures.front()->profile() == ASiC_S::ASIC_TST_PROFILE)
signatures.resize(1);
if(signatures.empty())
THROW("Container does not contain signatures");

if(doc.mediaType() == ASiContainer::MIMETYPE_ASIC_S ||
Expand All @@ -354,7 +358,7 @@ std::unique_ptr<Container> Container::extendContainerValidity(Container &doc, Si
bool extendInPlace = true;
size_t tCount = 0;
size_t eeCount = 0;
for(Signature *s: doc.signatures())
for(Signature *s: signatures)
{
auto signingCert = s->signingCertificate();
if(signingCert.subjectName("C") != "EE" ||
Expand Down Expand Up @@ -431,7 +435,7 @@ std::unique_ptr<Container> Container::extendContainerValidity(Container &doc, Si

if(extendInPlace)
{
for(Signature *s: doc.signatures())
for(Signature *s: signatures)
{
if(auto cert = s->signingCertificate();
cert.subjectName("C") != "EE" ||
Expand Down
Loading