Skip to content

Commit

Permalink
Keep existing filenames
Browse files Browse the repository at this point in the history
IB-8168

Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Sep 18, 2024
1 parent 72437de commit 220e9b4
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 47 deletions.
65 changes: 36 additions & 29 deletions src/ASiC_E.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,19 @@ using namespace digidoc;
using namespace digidoc::util;
using namespace std;

const string_view ASiC_E::ASIC_TM_PROFILE = "time-mark";
const string_view ASiC_E::ASIC_TS_PROFILE = "time-stamp";
const string_view ASiC_E::ASIC_TSA_PROFILE = "time-stamp-archive";
const string_view ASiC_E::ASIC_TMA_PROFILE = "time-mark-archive";
constexpr string_view MANIFEST_NS {"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"};

class ASiC_E::Private
{
public:
string unique_name()
{
string file;
for(unsigned int i = 0; signatures.count(file = Log::format("META-INF/signatures%u.xml", i++)); );
return file;
}
vector<DataFile*> metadata;
map<string,Signatures*> signatures;
};

/**
Expand All @@ -58,7 +61,7 @@ ASiC_E::ASiC_E()
}

/**
* Opens BDOC container from a file
* Opens ASiC container from a file
*/
ASiC_E::ASiC_E(const string &path)
: ASiContainer(MIMETYPE_ASIC_E)
Expand Down Expand Up @@ -102,24 +105,28 @@ void ASiC_E::save(const string &path)
s.addFile("mimetype", mimetype, zproperty("mimetype"), ZipSerialize::DontCompress);

stringstream manifest;
createManifest(manifest);
if(!createManifest().save(manifest))
THROW("Failed to create manifest XML");
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), 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++);
auto *signature = static_cast<SignatureXAdES_B*>(iter);
if(!saved.insert(signature->signatures.get()).second)
auto *signatures = static_cast<SignatureXAdES_B*>(iter)->signatures.get();
if(!saved.insert(signatures).second)
continue;
auto name = find_if(d->signatures.cbegin(), d->signatures.cend(), [signatures](const auto &k){
return k.second == signatures;
});
if(name == d->signatures.cend())
THROW("Unkown signature object");
stringstream ofs;
if(!signature->signatures->save(ofs))
if(!signatures->save(ofs))
THROW("Failed to create signature XML file.");
s.addFile(file, ofs, zproperty(file));
s.addFile(name->first, ofs, zproperty(name->first));
}
}

Expand All @@ -143,12 +150,9 @@ void ASiC_E::addAdESSignature(istream &data)
THROW("No documents in container, can not add signature.");
if(mediaType() != MIMETYPE_ASIC_E)
THROW("'%s' format is not supported", mediaType().c_str());

try
{
auto signatures = make_shared<Signatures>(data, this);
for(auto s = signatures->signature(); s; s++)
addSignature(make_unique<SignatureXAdES_LTA>(signatures, s, this));
loadSignatures(data, d->unique_name());
}
catch(const Exception &e)
{
Expand All @@ -165,14 +169,10 @@ unique_ptr<Container> ASiC_E::openInternal(const string &path)
/**
* Creates BDoc container manifest file and returns its path.
*
* Note: If non-ascii characters are present in XML data, we depend on the LANG variable to be set properly
* (see iconv --list for the list of supported encoding values for libiconv).
*
*
* @return returns created manifest file path.
* @throws Exception exception is thrown if manifest file creation failed.
*/
void ASiC_E::createManifest(ostream &os)
XMLDocument ASiC_E::createManifest() const
{
DEBUG("ASiC_E::createManifest()");
auto doc = XMLDocument::create("manifest", MANIFEST_NS, "manifest");
Expand All @@ -185,8 +185,15 @@ void ASiC_E::createManifest(ostream &os)
add("/", mediaType());
for(const DataFile *file: dataFiles())
add(file->fileName(), file->mediaType());
if(!doc.save(os))
THROW("Failed to create manifest XML");
return doc;
}

void ASiC_E::loadSignatures(istream &data, const string &file)
{
auto signatures = make_shared<Signatures>(data, mediaType());
d->signatures.emplace(file, signatures.get());
for(auto s = signatures->signature(); s; s++)
addSignature(make_unique<SignatureXAdES_LTA>(signatures, s, this));
}

/**
Expand Down Expand Up @@ -214,11 +221,11 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z)
{
stringstream manifestdata;
z.extract("META-INF/manifest.xml", manifestdata);
auto doc = XMLDocument::openStream(manifestdata, {"manifest", MANIFEST_NS});
doc.validateSchema(File::path(Conf::instance()->xsdPath(), "OpenDocument_manifest_v1_2.xsd"));

set<string_view> manifestFiles;
bool mimeFound = false;
auto doc = XMLDocument::openStream(manifestdata, {"manifest", MANIFEST_NS});
doc.validateSchema(File::path(Conf::instance()->xsdPath(), "OpenDocument_manifest_v1_2.xsd"));
for(auto file = doc/"file-entry"; file; file++)
{
auto full_path = file[{"full-path", MANIFEST_NS}];
Expand Down Expand Up @@ -272,9 +279,7 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z)
{
stringstream data;
z.extract(file, data);
auto signatures = make_shared<Signatures>(data, this);
for(auto s = signatures->signature(); s; s++)
addSignature(make_unique<SignatureXAdES_LTA>(signatures, s, this));
loadSignatures(data, file);
}
catch(const Exception &e)
{
Expand Down Expand Up @@ -307,7 +312,9 @@ Signature* ASiC_E::prepareSignature(Signer *signer)
THROW("No documents in container, can not sign container.");
if(!signer)
THROW("Null pointer in ASiC_E::sign");
return addSignature(make_unique<SignatureXAdES_LTA>(newSignatureId(), this, signer));
auto signatures = make_shared<Signatures>();
d->signatures.emplace(d->unique_name(), signatures.get());
return addSignature(make_unique<SignatureXAdES_LTA>(signatures, newSignatureId(), this, signer));
}

Signature *ASiC_E::sign(Signer* signer)
Expand Down
12 changes: 7 additions & 5 deletions src/ASiC_E.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

namespace digidoc
{
struct XMLDocument;
class ZipSerialize;

/**
Expand All @@ -36,10 +37,10 @@ namespace digidoc
class ASiC_E final : public ASiContainer
{
public:
static const std::string_view ASIC_TM_PROFILE;
static const std::string_view ASIC_TS_PROFILE;
static const std::string_view ASIC_TMA_PROFILE;
static const std::string_view ASIC_TSA_PROFILE;
static constexpr std::string_view ASIC_TM_PROFILE = "time-mark";
static constexpr std::string_view ASIC_TS_PROFILE = "time-stamp";
static constexpr std::string_view ASIC_TMA_PROFILE = "time-mark-archive";
static constexpr std::string_view ASIC_TSA_PROFILE = "time-stamp-archive";

~ASiC_E() final;
void save(const std::string &path = {}) final;
Expand All @@ -56,7 +57,8 @@ namespace digidoc
ASiC_E();
ASiC_E(const std::string &path);
DISABLE_COPY(ASiC_E);
void createManifest(std::ostream &os);
XMLDocument createManifest() const;
void loadSignatures(std::istream &data, const std::string &file);
void parseManifestAndLoadFiles(const ZipSerialize &z);

class Private;
Expand Down
2 changes: 1 addition & 1 deletion src/ASiC_S.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ 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);
auto signatures = make_shared<Signatures>(data, this);
auto signatures = make_shared<Signatures>(data, mediaType());
for(auto s = signatures->signature(); s; s++)
addSignature(make_unique<SignatureXAdES_LTA>(signatures, s, this));
}
Expand Down
12 changes: 6 additions & 6 deletions src/SignatureXAdES_B.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ int initXmlSecCallback()
return is;
},
[](void *ctx, char *buf, int len) -> int {
auto *is = static_cast<std::istream*>(ctx);
auto *is = static_cast<istream*>(ctx);
is->read(buf, len);
return int(is->gcount());
},
Expand All @@ -207,7 +207,7 @@ Signatures::Signatures()
addNS(XADES_NS, "xades");
}

Signatures::Signatures(istream &data, ASiContainer *container)
Signatures::Signatures(istream &data, string_view mediaType)
: XMLDocument(openStream(data))
{
/* http://www.etsi.org/deliver/etsi_ts/102900_102999/102918/01.03.01_60/ts_102918v010301p.pdf
Expand All @@ -219,7 +219,7 @@ Signatures::Signatures(istream &data, ASiContainer *container)
* Case container is ADoc 1.0 then handle document-signatures root element
*/
try {
if(container->mediaType() == ASiC_E::MIMETYPE_ADOC && name() == "document-signatures" && ns() == OPENDOCUMENT_NS)
if(mediaType == ASiC_E::MIMETYPE_ADOC && name() == "document-signatures" && ns() == OPENDOCUMENT_NS)
validateSchema(File::path(Conf::instance()->xsdPath(), "OpenDocument_dsig.xsd"));
else
validateSchema(File::path(Conf::instance()->xsdPath(), "en_31916201v010101.xsd"));
Expand All @@ -234,8 +234,8 @@ Signatures::Signatures(istream &data, ASiContainer *container)
/**
* Creates an empty BDOC-BES signature with mandatory XML nodes.
*/
SignatureXAdES_B::SignatureXAdES_B(unsigned int id, ASiContainer *container, Signer *signer)
: signatures(make_shared<Signatures>())
SignatureXAdES_B::SignatureXAdES_B(const shared_ptr<Signatures> &signatures, unsigned int id, ASiContainer *container, Signer *signer)
: signatures(signatures)
, bdoc(container)
{
X509Cert c = signer->cert();
Expand Down Expand Up @@ -295,7 +295,7 @@ SignatureXAdES_B::SignatureXAdES_B(unsigned int id, ASiContainer *container, Sig
* @param bdoc BDOC container
* @throws SignatureException
*/
SignatureXAdES_B::SignatureXAdES_B(const std::shared_ptr<Signatures> &signatures, XMLNode s, ASiContainer *container)
SignatureXAdES_B::SignatureXAdES_B(const shared_ptr<Signatures> &signatures, XMLNode s, ASiContainer *container)
: signatures(signatures)
, signature(s)
, bdoc(container)
Expand Down
4 changes: 2 additions & 2 deletions src/SignatureXAdES_B.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace digidoc
{
public:
explicit Signatures();
Signatures(std::istream &data, ASiContainer *container);
Signatures(std::istream &data, std::string_view mediaType);

constexpr XMLNode signature() const noexcept
{
Expand All @@ -55,7 +55,7 @@ namespace digidoc
{

public:
SignatureXAdES_B(unsigned int id, ASiContainer *bdoc, Signer *signer);
SignatureXAdES_B(const std::shared_ptr<Signatures> &signatures, unsigned int id, ASiContainer *bdoc, Signer *signer);
SignatureXAdES_B(const std::shared_ptr<Signatures> &signatures, XMLNode s, ASiContainer *container);
~SignatureXAdES_B();

Expand Down
6 changes: 3 additions & 3 deletions src/SignatureXAdES_LT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@
using namespace digidoc;
using namespace std;

SignatureXAdES_LT::SignatureXAdES_LT(unsigned int id, ASiContainer *bdoc, Signer *signer)
: SignatureXAdES_T(id, bdoc, signer)
SignatureXAdES_LT::SignatureXAdES_LT(const shared_ptr<Signatures> &signatures, unsigned int id, ASiContainer *bdoc, Signer *signer)
: SignatureXAdES_T(signatures, id, bdoc, signer)
{}

SignatureXAdES_LT::SignatureXAdES_LT(const std::shared_ptr<Signatures> &signatures, XMLNode s, ASiContainer *container)
SignatureXAdES_LT::SignatureXAdES_LT(const shared_ptr<Signatures> &signatures, XMLNode s, ASiContainer *container)
: SignatureXAdES_T(signatures, s, container)
{
try {
Expand Down
2 changes: 1 addition & 1 deletion src/SignatureXAdES_LT.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class OCSP;
class SignatureXAdES_LT: public SignatureXAdES_T
{
public:
SignatureXAdES_LT(unsigned int id, ASiContainer *bdoc, Signer *signer);
SignatureXAdES_LT(const std::shared_ptr<Signatures> &signatures, unsigned int id, ASiContainer *bdoc, Signer *signer);
SignatureXAdES_LT(const std::shared_ptr<Signatures> &signatures, XMLNode s, ASiContainer *container);

std::string trustedSigningTime() const override;
Expand Down

0 comments on commit 220e9b4

Please sign in to comment.