Skip to content

Commit 0cafa3f

Browse files
authored
Support multiple signatures in single XML (#545)
IB-7602 Signed-off-by: Raul Metsma <[email protected]>
1 parent fa4056d commit 0cafa3f

15 files changed

+244
-197
lines changed

src/ASiC_E.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333

3434
#include <xercesc/util/OutOfMemoryException.hpp>
3535

36-
#include <fstream>
3736
#include <set>
3837

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

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

114+
std::set<Signatures*> saved;
115115
unsigned int i = 0;
116116
for(Signature *iter: signatures())
117117
{
118118
string file = Log::format("META-INF/signatures%u.xml", i++);
119-
SignatureXAdES_B *signature = static_cast<SignatureXAdES_B*>(iter);
120-
119+
auto *signature = static_cast<SignatureXAdES_B*>(iter);
120+
if(!saved.insert(signature->signatures.get()).second)
121+
continue;
121122
stringstream ofs;
122-
signature->saveToXml(ofs);
123+
signature->signatures->save(ofs);
123124
s.addFile(file, ofs, zproperty(file));
124125
}
125126
}
@@ -138,7 +139,7 @@ unique_ptr<Container> ASiC_E::createInternal(const string &path)
138139
* @param sigdata signature, which is added to the container.
139140
* @throws Exception throws exception if there are no documents in container.
140141
*/
141-
void ASiC_E::addAdESSignature(istream &sigdata)
142+
void ASiC_E::addAdESSignature(istream &data)
142143
{
143144
if(dataFiles().empty())
144145
THROW("No documents in container, can not add signature.");
@@ -147,7 +148,9 @@ void ASiC_E::addAdESSignature(istream &sigdata)
147148

148149
try
149150
{
150-
addSignature(make_unique<SignatureXAdES_LTA>(sigdata, this));
151+
auto signatures = make_shared<Signatures>(data, this);
152+
for(size_t i = 0, count = signatures->count(); i < count; ++i)
153+
addSignature(make_unique<SignatureXAdES_LTA>(signatures, i, this));
151154
}
152155
catch(const Exception &e)
153156
{
@@ -218,7 +221,7 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z)
218221
DEBUG("ASiC_E::readManifest()");
219222

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

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

355360
Signature *ASiC_E::sign(Signer* signer)
356361
{
357-
SignatureXAdES_LTA *s = static_cast<SignatureXAdES_LTA*>(prepareSignature(signer));
362+
auto *s = static_cast<SignatureXAdES_LTA*>(prepareSignature(signer));
358363
try
359364
{
360365
s->setSignatureValue(signer->sign(s->signatureMethod(), s->dataToSign()));

src/ASiC_E.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace digidoc
4646
void save(const std::string &path = {}) final;
4747
std::vector<DataFile*> metaFiles() const;
4848

49-
void addAdESSignature(std::istream &sigdata) final;
49+
void addAdESSignature(std::istream &data) final;
5050
Signature* prepareSignature(Signer *signer) final;
5151
Signature* sign(Signer* signer) final;
5252

src/ASiC_S.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ ASiC_S::ASiC_S(const string &path): ASiContainer(MIMETYPE_ASIC_S)
6565
THROW("Can not add signature to ASiC-S container which already contains a signature.");
6666
stringstream data;
6767
z->extract(file, data);
68-
addSignature(make_unique<SignatureXAdES_LTA>(data, this, true));
68+
auto signatures = make_shared<Signatures>(data, this);
69+
for(size_t i = 0, count = signatures->count(); i < count; ++i)
70+
addSignature(make_unique<SignatureXAdES_LTA>(signatures, i, this));
6971
}
7072
continue;
7173
}

src/SiVaContainer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,14 @@ SiVaContainer::SiVaContainer(const string &path, const string &ext, bool useHash
152152
if(ext == "ddoc")
153153
{
154154
d->mediaType = "application/x-ddoc";
155-
d->ddoc = move(ifs);
155+
d->ddoc = std::move(ifs);
156156
ifs = parseDDoc(useHashCode);
157157
is = ifs.get();
158158
}
159159
else
160160
{
161161
d->mediaType = "application/pdf";
162-
d->dataFiles.push_back(new DataFilePrivate(move(ifs), fileName, "application/pdf"));
162+
d->dataFiles.push_back(new DataFilePrivate(std::move(ifs), fileName, "application/pdf"));
163163
}
164164

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

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

0 commit comments

Comments
 (0)