Skip to content

Commit

Permalink
Support multiple signatures in single XML
Browse files Browse the repository at this point in the history
IB-7602

Signed-off-by: Raul Metsma <raul@metsma.ee>
  • Loading branch information
metsma committed Sep 20, 2023
1 parent 95c7c68 commit e8d88c7
Show file tree
Hide file tree
Showing 14 changed files with 236 additions and 195 deletions.
27 changes: 16 additions & 11 deletions src/ASiC_E.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

#include <xercesc/util/OutOfMemoryException.hpp>

#include <fstream>
#include <set>

using namespace digidoc;
Expand Down Expand Up @@ -110,16 +109,18 @@ void ASiC_E::save(const string &path)
s.addFile("META-INF/manifest.xml", manifest, zproperty("META-INF/manifest.xml"));

for(const DataFile *file: dataFiles())
s.addFile(file->fileName(), *(static_cast<const DataFilePrivate*>(file)->m_is.get()), zproperty(file->fileName()));
s.addFile(file->fileName(), *(static_cast<const DataFilePrivate*>(file)->m_is), zproperty(file->fileName()));

std::set<Signatures*> saved;
unsigned int i = 0;
for(Signature *iter: signatures())
{
string file = Log::format("META-INF/signatures%u.xml", i++);
SignatureXAdES_B *signature = static_cast<SignatureXAdES_B*>(iter);

auto *signature = static_cast<SignatureXAdES_B*>(iter);
if(!saved.insert(signature->signatures.get()).second)
continue;
stringstream ofs;
signature->saveToXml(ofs);
signature->signatures->save(ofs);
s.addFile(file, ofs, zproperty(file));
}
}
Expand All @@ -138,7 +139,7 @@ unique_ptr<Container> ASiC_E::createInternal(const string &path)
* @param sigdata signature, which is added to the container.
* @throws Exception throws exception if there are no documents in container.
*/
void ASiC_E::addAdESSignature(istream &sigdata)
void ASiC_E::addAdESSignature(istream &data)
{
if(dataFiles().empty())
THROW("No documents in container, can not add signature.");
Expand All @@ -147,7 +148,9 @@ void ASiC_E::addAdESSignature(istream &sigdata)

try
{
addSignature(make_unique<SignatureXAdES_LTA>(sigdata, this));
auto signatures = make_shared<Signatures>(data, this);
for(size_t i = 0, count = signatures->count(); i < count; ++i)
addSignature(make_unique<SignatureXAdES_LTA>(signatures, i, this));
}
catch(const Exception &e)
{
Expand Down Expand Up @@ -218,7 +221,7 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z)
DEBUG("ASiC_E::readManifest()");

const vector<string> &list = z.list();
size_t mcount = size_t(count(list.cbegin(), list.cend(), "META-INF/manifest.xml"));
auto mcount = size_t(count(list.cbegin(), list.cend(), "META-INF/manifest.xml"));
if(mcount < 1)
THROW("Manifest file is missing");
if(mcount > 1)
Expand Down Expand Up @@ -254,7 +257,7 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z)
if(file.full_path().back() == '/') // Skip Directory entries
continue;

size_t fcount = size_t(count(list.cbegin(), list.cend(), file.full_path()));
auto fcount = size_t(count(list.cbegin(), list.cend(), file.full_path()));
if(fcount < 1)
THROW("File described in manifest '%s' does not exist in container.", file.full_path().c_str());
if(fcount > 1)
Expand Down Expand Up @@ -287,7 +290,9 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z)
{
stringstream data;
z.extract(file, data);
addSignature(make_unique<SignatureXAdES_LTA>(data, this, true));
auto signatures = make_shared<Signatures>(data, this);
for(size_t i = 0, count = signatures->count(); i < count; ++i)
addSignature(make_unique<SignatureXAdES_LTA>(signatures, i, this));
}
catch(const Exception &e)
{
Expand Down Expand Up @@ -354,7 +359,7 @@ Signature* ASiC_E::prepareSignature(Signer *signer)

Signature *ASiC_E::sign(Signer* signer)
{
SignatureXAdES_LTA *s = static_cast<SignatureXAdES_LTA*>(prepareSignature(signer));
auto *s = static_cast<SignatureXAdES_LTA*>(prepareSignature(signer));
try
{
s->setSignatureValue(signer->sign(s->signatureMethod(), s->dataToSign()));
Expand Down
2 changes: 1 addition & 1 deletion src/ASiC_E.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace digidoc
void save(const std::string &path = {}) final;
std::vector<DataFile*> metaFiles() const;

void addAdESSignature(std::istream &sigdata) final;
void addAdESSignature(std::istream &data) final;
Signature* prepareSignature(Signer *signer) final;
Signature* sign(Signer* signer) final;

Expand Down
4 changes: 3 additions & 1 deletion src/ASiC_S.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ ASiC_S::ASiC_S(const string &path): ASiContainer(MIMETYPE_ASIC_S)
THROW("Can not add signature to ASiC-S container which already contains a signature.");
stringstream data;
z->extract(file, data);
addSignature(make_unique<SignatureXAdES_LTA>(data, this, true));
auto signatures = make_shared<Signatures>(data, this);
for(size_t i = 0, count = signatures->count(); i < count; ++i)
addSignature(make_unique<SignatureXAdES_LTA>(signatures, i, this));
}
continue;
}
Expand Down
8 changes: 4 additions & 4 deletions src/SiVaContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,14 @@ SiVaContainer::SiVaContainer(const string &path, const string &ext, bool useHash
if(ext == "ddoc")
{
d->mediaType = "application/x-ddoc";
d->ddoc = move(ifs);
d->ddoc = std::move(ifs);
ifs = parseDDoc(useHashCode);
is = ifs.get();
}
else
{
d->mediaType = "application/pdf";
d->dataFiles.push_back(new DataFilePrivate(move(ifs), fileName, "application/pdf"));
d->dataFiles.push_back(new DataFilePrivate(std::move(ifs), fileName, "application/pdf"));
}

array<XMLByte, 48*100> buf{};
Expand All @@ -182,7 +182,7 @@ SiVaContainer::SiVaContainer(const string &path, const string &ext, bool useHash

string req = json({
{"filename", fileName},
{"document", move(b64)},
{"document", std::move(b64)},
{"signaturePolicy", "POLv4"}
}).dump();
Connect::Result r = Connect(CONF(verifyServiceUri), "POST", 0, CONF(verifyServiceCerts)).exec({
Expand Down Expand Up @@ -357,7 +357,7 @@ unique_ptr<istream> SiVaContainer::parseDDoc(bool useHashCode)
if(!useHashCode)
continue;
Digest calc(URI_SHA1);
SecureDOMParser::calcDigestOnNode(&calc, "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", dom.get(), item);
SecureDOMParser::calcDigestOnNode(&calc, "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", item);
vector<unsigned char> digest = calc.result();
XMLSize_t size = 0;
if(XMLByte *out = Base64::encode(digest.data(), XMLSize_t(digest.size()), &size))
Expand Down
Loading

0 comments on commit e8d88c7

Please sign in to comment.