Skip to content

Commit

Permalink
Validate CAdES signature in SiVa service
Browse files Browse the repository at this point in the history
IB-6671

Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Aug 30, 2023
1 parent c9d4ca7 commit 089486b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/ASiContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ namespace digidoc
void removeSignature(unsigned int id) override;
std::vector<Signature*> signatures() const override;

static std::string readMimetype(std::istream &is);

protected:
ASiContainer(const std::string &mimetype);

Expand All @@ -72,8 +74,6 @@ namespace digidoc
ZipSerialize::Properties zproperty(const std::string &file) const;
void zproperty(const std::string &file, ZipSerialize::Properties &&prop);

static std::string readMimetype(std::istream &path);

private:
DISABLE_COPY(ASiContainer);

Expand Down
52 changes: 42 additions & 10 deletions src/SiVaContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@

#include "SiVaContainer.h"

#include "ASiContainer.h"
#include "Conf.h"
#include "DataFile_p.h"
#include "Signature.h"
#include "crypto/Connect.h"
#include "crypto/Digest.h"
#include "util/File.h"
#include "util/log.h"
#include "util/ZipSerialize.h"
#include "xml/xml.hxx"
#include "xml/SecureDOMParser.h"

Expand Down Expand Up @@ -142,27 +144,59 @@ void SignatureSiVa::validate(const string &policy) const
}


SiVaContainer::SiVaContainer(const string &path, const string &ext, bool useHashCode)
SiVaContainer::SiVaContainer(const string &path, bool useHashCode)
: d(make_unique<Private>())
{
string ext = File::fileExtension(path);
DEBUG("SiVaContainer::SiVaContainer(%s, %s, %d)", path.c_str(), ext.c_str(), useHashCode);
unique_ptr<istream> ifs = make_unique<ifstream>(File::encodeName(d->path = path), ifstream::binary);
auto fileName = File::fileName(path);
istream *is = ifs.get();
static const array asic {"asice", "sce", "asics", "scs"};
if(ext == "ddoc")
{
d->mediaType = "application/x-ddoc";
d->ddoc = move(ifs);
ifs = parseDDoc(useHashCode);
is = ifs.get();
}
else
else if(ext == "pdf")
{
d->mediaType = "application/pdf";
d->dataFiles.push_back(new DataFilePrivate(move(ifs), fileName, "application/pdf"));
}
else if(find(asic.cbegin(), asic.cend(), ext) != asic.cend())
{
ZipSerialize z(path, false);
vector<string> list = z.list();
if(list.empty() || list.front() != "mimetype")
THROW("Missing mimetype");
stringstream data;
z.extract(list.front(), data);
if(d->mediaType = ASiContainer::readMimetype(data);
d->mediaType != ASiContainer::MIMETYPE_ASIC_E && d->mediaType != ASiContainer::MIMETYPE_ASIC_S)
THROW("Unknown file");
if(none_of(list.cbegin(), list.cend(), [](const string &file) { return file.find("p7s") != string::npos; }))
THROW("Unknown file");

static const string metaInf = "META-INF/";
for(const string &file: list)
{
if(file == "mimetype" || file.substr(0, metaInf.size()) == metaInf)
continue;
const auto directory = File::directory(file);
if(directory.empty() || directory == "/" || directory == "./")
{
auto data = make_unique<stringstream>();
z.extract(file, *data);
d->dataFiles.push_back(new DataFilePrivate(move(data), file, "application/octet-stream"));
}
}
}
else
THROW("Unknown file");

array<XMLByte, 48*100> buf{};
array<XMLByte, 4800> buf{};
string b64;
is->clear();
is->seekg(0);
Expand Down Expand Up @@ -314,15 +348,13 @@ vector<DataFile *> SiVaContainer::dataFiles() const

unique_ptr<Container> SiVaContainer::openInternal(const string &path)
{
static const array supported {"pdf", "ddoc"};
string ext = File::fileExtension(path);
if(find(supported.cbegin(), supported.cend(), ext) == supported.cend())
return {};
try {
return unique_ptr<Container>(new SiVaContainer(path, ext, true));
return unique_ptr<Container>(new SiVaContainer(path, true));
} catch(const Exception &e) {
if(e.msg().find("Bad digest for DataFile") == 0)
return unique_ptr<Container>(new SiVaContainer(path, ext, false));
return unique_ptr<Container>(new SiVaContainer(path, false));
if(e.msg() == "Unknown file")
return {};
throw;
}
}
Expand All @@ -337,7 +369,7 @@ unique_ptr<istream> SiVaContainer::parseDDoc(bool useHashCode)
DOMNodeList *nodeList = dom->getElementsByTagName(cpXMLCh(u"DataFile"));
for(XMLSize_t i = 0; i < nodeList->getLength(); ++i)
{
DOMElement *item = static_cast<DOMElement*>(nodeList->item(i));
auto *item = static_cast<DOMElement*>(nodeList->item(i));
if(!item)
continue;

Expand Down
2 changes: 1 addition & 1 deletion src/SiVaContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class SiVaContainer final: public Container
static std::unique_ptr<Container> openInternal(const std::string &path);

private:
SiVaContainer(const std::string &path, const std::string &ext, bool useHashCode);
SiVaContainer(const std::string &path, bool useHashCode);
DISABLE_COPY(SiVaContainer);

std::unique_ptr<std::istream> parseDDoc(bool useHashCode);
Expand Down

0 comments on commit 089486b

Please sign in to comment.