1919
2020#include " ASiC_S.h"
2121
22- #include " Conf.h"
2322#include " SignatureTST.h"
2423#include " SignatureXAdES_LTA.h"
2524#include " crypto/Signer.h"
@@ -33,18 +32,6 @@ using namespace digidoc;
3332using namespace digidoc ::util;
3433using namespace std ;
3534
36- struct ASiC_S ::Data {
37- std::string name, mime, data;
38-
39- Digest digest (Digest digest = {}) const
40- {
41- digest.update ((const unsigned char *)data.data (), data.size ());
42- return digest;
43- }
44- };
45-
46-
47-
4835/* *
4936 * Initialize ASiCS container.
5037 */
@@ -59,17 +46,19 @@ ASiC_S::ASiC_S(const string &path)
5946 : ASiContainer(MIMETYPE_ASIC_S )
6047{
6148 auto z = load (path, false , {mediaType ()});
49+ bool foundTimestamp = false ;
6250 for (const string &file: z.list ())
6351 {
6452 if (file == " mimetype" )
6553 continue ;
6654 if (file == " META-INF/timestamp.tst" )
55+ foundTimestamp = true ;
56+ if (file == " META-INF/ASiCArchiveManifest.xml" )
6757 {
6858 if (!signatures ().empty ())
6959 THROW (" Can not add signature to ASiC-S container which already contains a signature." );
70- string tst = z.extract <stringstream>(file).str ();
71- addSignature (make_unique<SignatureTST>(tst, this ));
72- metadata.push_back ({file, " application/vnd.etsi.timestamp-token" , std::move (tst)});
60+ addSignature (make_unique<SignatureTST>(true , z, this ));
61+ foundTimestamp = false ; // Manifest contains timestamp
7362 }
7463 else if (file == " META-INF/signatures.xml" )
7564 {
@@ -80,28 +69,6 @@ ASiC_S::ASiC_S(const string &path)
8069 for (auto s = signatures->signature (); s; s++)
8170 addSignature (make_unique<SignatureXAdES_LTA>(signatures, s, this ));
8271 }
83- else if (file == " META-INF/ASiCArchiveManifest.xml" )
84- {
85- function<void (const string &, string_view)> add = [this , &add, &z](const string &file, string_view mime) {
86- auto xml = z.extract <stringstream>(file);
87- XMLDocument doc = XMLDocument::openStream (xml, {" ASiCManifest" , ASIC_NS });
88- doc.validateSchema (util::File::path (Conf::instance ()->xsdPath (), " en_31916201v010101.xsd" ));
89-
90- for (auto ref = doc/" DataObjectReference" ; ref; ref++)
91- {
92- if (ref[" Rootfile" ] == " true" )
93- add (util::File::fromUriPath (ref[" URI" ]), ref[" MimeType" ]);
94- }
95-
96- auto ref = doc/" SigReference" ;
97- string uri = util::File::fromUriPath (ref[" URI" ]);
98- string tst = z.extract <stringstream>(uri).str ();
99- addSignature (make_unique<SignatureTST>(file, ::move (doc), tst, this ));
100- metadata.push_back ({file, string (mime), xml.str ()});
101- metadata.push_back ({uri, string (ref[" MimeType" ]), std::move (tst)});
102- };
103- add (file, " text/xml" );
104- }
10572 else if (starts_with (file, " META-INF/" ))
10673 continue ;
10774 else if (const auto directory = File::directory (file);
@@ -112,6 +79,12 @@ ASiC_S::ASiC_S(const string &path)
11279 else
11380 addDataFile (dataStream (file, z), file, " application/octet-stream" );
11481 }
82+ if (foundTimestamp)
83+ {
84+ if (!signatures ().empty ())
85+ THROW (" Can not add signature to ASiC-S container which already contains a signature." );
86+ addSignature (make_unique<SignatureTST>(false , z, this ));
87+ }
11588
11689 if (dataFiles ().empty ())
11790 THROW (" ASiC-S container does not contain any data objects." );
@@ -147,20 +120,20 @@ void ASiC_S::canSave()
147120 THROW (" ASiC-S container supports only saving TimeStampToken signatures." );
148121}
149122
150- Digest ASiC_S::fileDigest (const string &file, string_view method) const
151- {
152- if (auto i = find_if (metadata.cbegin (), metadata.cend (), [&file](const auto &d) { return d.name == file; });
153- i != metadata.cend ())
154- return i->digest (method);
155- THROW (" File not found %s." , file.c_str ());
156- }
157-
158123unique_ptr<Container> ASiC_S::openInternal (const string &path, ContainerOpenCB * /* cb*/ )
159124{
160- if (!isContainerSimpleFormat (path))
161- return {};
162125 DEBUG (" ASiC_S::openInternal(%s)" , path.c_str ());
163- return unique_ptr<Container>(new ASiC_S (path));
126+ try
127+ {
128+ if (util::File::fileExtension (path, {" asice" , " sce" , " bdoc" }))
129+ return {};
130+ return unique_ptr<Container>(new ASiC_S (path));
131+ }
132+ catch (const Exception &)
133+ {
134+ // Ignore the exception: not ASiC/zip document
135+ }
136+ return {};
164137}
165138
166139Signature* ASiC_S::prepareSignature (Signer * /* signer*/ )
@@ -170,10 +143,11 @@ Signature* ASiC_S::prepareSignature(Signer * /*signer*/)
170143
171144void ASiC_S::save (const ZipSerialize &s)
172145{
173- if (zproperty (" META-INF/manifest.xml" ).size && !createManifest ().save (s.addFile (" META-INF/manifest.xml" , zproperty (" META-INF/manifest.xml" )), true ))
146+ if (const auto &prop = zproperty (" META-INF/manifest.xml" );
147+ prop.size && !createManifest ().save (s.addFile (" META-INF/manifest.xml" , prop), true ))
174148 THROW (" Failed to create manifest XML" );
175- for (const auto &[name, mime, data]: metadata )
176- s. addFile (name, zproperty (name))(data );
149+ for (Signature *sig: signatures () )
150+ static_cast <SignatureTST*>(sig)-> save (s );
177151}
178152
179153Signature *ASiC_S::sign (Signer *signer)
@@ -184,31 +158,3 @@ Signature *ASiC_S::sign(Signer *signer)
184158 THROW (" ASiC-S container supports only one TimeStampToken signature." );
185159 return addSignature (make_unique<SignatureTST>(this , signer));
186160}
187-
188- /* *
189- * Detect ASiC format based on file extentions, mimetype or zip contents.<br/>
190- * Container format is simple (ASiC-S) or extended (ASiC-E).
191- *
192- * @param path Path of the container.
193- * @throws Exception
194- */
195- bool ASiC_S::isContainerSimpleFormat (const string &path)
196- {
197- DEBUG (" isContainerSimpleFormat(path = '%s')" , path.c_str ());
198- if (util::File::fileExtension (path, {" asice" , " sce" , " bdoc" }))
199- return false ;
200- if (util::File::fileExtension (path, {" asics" , " scs" }))
201- return true ;
202- DEBUG (" Check if ASiC/zip containter" );
203- try
204- {
205- ZipSerialize z (path, false );
206- vector<string> list = z.list ();
207- return list.front () == " mimetype" && readMimetype (z) == MIMETYPE_ASIC_S ;
208- }
209- catch (const Exception &)
210- {
211- // Ignore the exception: not ASiC/zip document
212- }
213- return false ;
214- }
0 commit comments