@@ -59,12 +59,14 @@ static auto base64_decode(string_view data) {
5959 0x29 , 0x2A , 0x2B , 0x2C , 0x2D , 0x2E , 0x2F , 0x30 , 0x31 , 0x32 , 0x33 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64
6060 };
6161
62- auto out = make_unique<stringstream>();
62+ string buf;
63+ buf.reserve (base64_enc_size (data.size ()));
64+ auto out = make_unique<stringstream>(std::move (buf));
6365 int value = 0 ;
6466 int bits = -8 ;
6567 for (auto c: data)
6668 {
67- if (c == ' \r ' || c == ' \n ' || c == ' ' )
69+ if (c == ' \r ' || c == ' \n ' || c == ' ' || static_cast < uint8_t >(c) > 128 )
6870 continue ;
6971 uint8_t check = T[c];
7072 if (check == 0x64 )
@@ -83,8 +85,8 @@ static auto base64_decode(string_view data) {
8385class SiVaContainer ::Private
8486{
8587public:
86- string path, mediaType ;
87- unique_ptr<istream> ddoc ;
88+ std::filesystem:: path path ;
89+ string mediaType ;
8890 vector<DataFile*> dataFiles;
8991 vector<Signature*> signatures;
9092};
@@ -109,26 +111,32 @@ void SignatureSiVa::validate(const string &policy) const
109111 static const set<string_view> QES = { " QESIG" , " QES" , " QESEAL" ,
110112 " ADESEAL_QC" , " ADESEAL" }; // Special treamtent for E-Seals
111113 Exception e (EXCEPTION_PARAMS (" Signature validation" ));
112- for (const Exception &exception: _exceptions)
113- e.addCause (exception);
114- if (!Exception::hasWarningIgnore (Exception::SignatureDigestWeak) &&
115- Digest::isWeakDigest (_signatureMethod))
116- {
117- Exception ex (EXCEPTION_PARAMS (" Signature digest weak" ));
118- ex.setCode (Exception::SignatureDigestWeak);
119- e.addCause (ex);
120- }
121- if (_indication == " TOTAL-PASSED" )
122- {
123- if (QES.count (_signatureLevel) || _signatureLevel.empty () || policy == POLv1)
114+ try {
115+ for (const Exception &exception: _exceptions)
116+ e.addCause (exception);
117+ if (!Exception::hasWarningIgnore (Exception::SignatureDigestWeak) &&
118+ Digest::isWeakDigest (_signatureMethod))
119+ {
120+ Exception ex (EXCEPTION_PARAMS (" Signature digest weak" ));
121+ ex.setCode (Exception::SignatureDigestWeak);
122+ e.addCause (ex);
123+ }
124+ if (_indication == " TOTAL-PASSED" )
124125 {
125- if (!e.causes ().empty ())
126- throw e;
127- return ;
126+ if (QES.contains (_signatureLevel) || _signatureLevel.empty () || policy == POLv1)
127+ {
128+ if (!e.causes ().empty ())
129+ throw e;
130+ return ;
131+ }
132+ Exception ex (EXCEPTION_PARAMS (" Signing certificate does not meet Qualification requirements" ));
133+ ex.setCode (Exception::CertificateIssuerMissing);
134+ e.addCause (ex);
128135 }
129- Exception ex (EXCEPTION_PARAMS (" Signing certificate does not meet Qualification requirements" ));
130- ex.setCode (Exception::CertificateIssuerMissing);
136+ } catch (const Exception &ex) {
131137 e.addCause (ex);
138+ } catch (...) {
139+ EXCEPTION_ADD (e, " Failed to validate signature" );
132140 }
133141 if (!e.causes ().empty ())
134142 throw e;
@@ -139,14 +147,13 @@ SiVaContainer::SiVaContainer(const string &path, ContainerOpenCB *cb, bool useHa
139147 : d(make_unique<Private>())
140148{
141149 DEBUG (" SiVaContainer::SiVaContainer(%s, %d)" , path.c_str (), useHashCode);
142- unique_ptr<istream> ifs = make_unique<ifstream>(File::encodeName ( d->path = path), ifstream::binary);
150+ unique_ptr<istream> ifs = make_unique<ifstream>(d->path = File::encodeName ( path), ifstream::binary);
143151 auto fileName = File::fileName (path);
144152 istream *is = ifs.get ();
145153 if (File::fileExtension (path, {" ddoc" }))
146154 {
147155 d->mediaType = " application/x-ddoc" ;
148- d->ddoc = std::move (ifs);
149- ifs = parseDDoc (useHashCode);
156+ ifs = parseDDoc (ifs, useHashCode);
150157 is = ifs.get ();
151158 }
152159 else if (File::fileExtension (path, {" pdf" }))
@@ -156,7 +163,6 @@ SiVaContainer::SiVaContainer(const string &path, ContainerOpenCB *cb, bool useHa
156163 }
157164 else if (File::fileExtension (path, {" asice" , " sce" , " asics" , " scs" }))
158165 {
159- static const string_view metaInf = " META-INF/" ;
160166 ZipSerialize z (path, false );
161167 vector<string> list = z.list ();
162168 if (list.front () != " mimetype" )
@@ -165,17 +171,17 @@ SiVaContainer::SiVaContainer(const string &path, ContainerOpenCB *cb, bool useHa
165171 d->mediaType != ASiContainer::MIMETYPE_ASIC_E && d->mediaType != ASiContainer::MIMETYPE_ASIC_S)
166172 THROW (" Unknown file" );
167173 if (none_of (list.cbegin (), list.cend (), [](const string &file) {
168- return file.rfind (metaInf, 0 ) == 0 && util::File::fileExtension (file, {" p7s" });
174+ return file.starts_with ( " META-INF/ " ) && util::File::fileExtension (file, {" p7s" });
169175 }))
170176 THROW (" Unknown file" );
171177
172178 for (const string &file: list)
173179 {
174- if (file == " mimetype" || file.rfind (metaInf, 0 ) == 0 )
180+ if (file == " mimetype" || file.starts_with ( " META-INF/ " ) )
175181 continue ;
176182 if (const auto directory = File::directory (file);
177183 directory.empty () || directory == " /" || directory == " ./" )
178- d->dataFiles .push_back (new DataFilePrivate (make_unique<stringstream>(z. extract <stringstream>(file)) , file, " application/octet-stream" ));
184+ d->dataFiles .push_back (new DataFilePrivate (z , file, " application/octet-stream" ));
179185 }
180186 }
181187 else
@@ -339,11 +345,11 @@ unique_ptr<Container> SiVaContainer::openInternal(const string &path, ContainerO
339345 }
340346}
341347
342- unique_ptr<istream> SiVaContainer::parseDDoc (bool useHashCode)
348+ unique_ptr<istream> SiVaContainer::parseDDoc (const unique_ptr<istream> &ddoc, bool useHashCode)
343349{
344350 try
345351 {
346- auto doc = XMLDocument::openStream (*d-> ddoc , {}, true );
352+ auto doc = XMLDocument::openStream (*ddoc, {}, true );
347353 for (auto dataFile = doc/" DataFile" ; dataFile; dataFile++)
348354 {
349355 auto contentType = dataFile[" ContentType" ];
@@ -401,16 +407,13 @@ void SiVaContainer::removeSignature(unsigned int /*index*/)
401407
402408void SiVaContainer::save (const string &path)
403409{
404- string to = path.empty () ? d->path : path;
405- if (d->ddoc )
406- {
407- d->ddoc ->clear ();
408- d->ddoc ->seekg (0 );
409- if (ofstream out{File::encodeName (to), ofstream::binary})
410- out << d->ddoc ->rdbuf ();
411- }
412- else
413- d->dataFiles [0 ]->saveAs (to);
410+ if (d->path .empty () || path.empty ())
411+ return ; // This is readonly container
412+ auto dest = File::encodeName (path);
413+ if (std::error_code ec;
414+ !std::filesystem::copy_file (d->path , dest, ec))
415+ THROW (" Failed to save container" );
416+ d->path = std::move (dest);
414417}
415418
416419Signature *SiVaContainer::sign (Signer * /* signer*/ )
0 commit comments