19
19
20
20
#include " ASiC_S.h"
21
21
22
- #include " Conf.h"
23
22
#include " SignatureTST.h"
24
23
#include " SignatureXAdES_LTA.h"
25
24
#include " crypto/Signer.h"
@@ -33,18 +32,6 @@ using namespace digidoc;
33
32
using namespace digidoc ::util;
34
33
using namespace std ;
35
34
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
-
48
35
/* *
49
36
* Initialize ASiCS container.
50
37
*/
@@ -59,17 +46,19 @@ ASiC_S::ASiC_S(const string &path)
59
46
: ASiContainer(MIMETYPE_ASIC_S)
60
47
{
61
48
auto z = load (path, false , {mediaType ()});
49
+ bool foundTimestamp = false ;
62
50
for (const string &file: z.list ())
63
51
{
64
52
if (file == " mimetype" )
65
53
continue ;
66
54
if (file == " META-INF/timestamp.tst" )
55
+ foundTimestamp = true ;
56
+ if (file == " META-INF/ASiCArchiveManifest.xml" )
67
57
{
68
58
if (!signatures ().empty ())
69
59
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
73
62
}
74
63
else if (file == " META-INF/signatures.xml" )
75
64
{
@@ -80,28 +69,6 @@ ASiC_S::ASiC_S(const string &path)
80
69
for (auto s = signatures->signature (); s; s++)
81
70
addSignature (make_unique<SignatureXAdES_LTA>(signatures, s, this ));
82
71
}
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
- }
105
72
else if (starts_with (file, " META-INF/" ))
106
73
continue ;
107
74
else if (const auto directory = File::directory (file);
@@ -112,6 +79,12 @@ ASiC_S::ASiC_S(const string &path)
112
79
else
113
80
addDataFile (dataStream (file, z), file, " application/octet-stream" );
114
81
}
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
+ }
115
88
116
89
if (dataFiles ().empty ())
117
90
THROW (" ASiC-S container does not contain any data objects." );
@@ -147,20 +120,20 @@ void ASiC_S::canSave()
147
120
THROW (" ASiC-S container supports only saving TimeStampToken signatures." );
148
121
}
149
122
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
-
158
123
unique_ptr<Container> ASiC_S::openInternal (const string &path, ContainerOpenCB * /* cb*/ )
159
124
{
160
- if (!isContainerSimpleFormat (path))
161
- return {};
162
125
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 {};
164
137
}
165
138
166
139
Signature* ASiC_S::prepareSignature (Signer * /* signer*/ )
@@ -170,10 +143,11 @@ Signature* ASiC_S::prepareSignature(Signer * /*signer*/)
170
143
171
144
void ASiC_S::save (const ZipSerialize &s)
172
145
{
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 ))
174
148
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 );
177
151
}
178
152
179
153
Signature *ASiC_S::sign (Signer *signer)
@@ -184,31 +158,3 @@ Signature *ASiC_S::sign(Signer *signer)
184
158
THROW (" ASiC-S container supports only one TimeStampToken signature." );
185
159
return addSignature (make_unique<SignatureTST>(this , signer));
186
160
}
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