20
20
#include " ASiC_S.h"
21
21
22
22
#include " SignatureTST.h"
23
- #include " crypto/Digest .h"
23
+ #include " SignatureXAdES_LTA .h"
24
24
#include " util/File.h"
25
25
#include " util/log.h"
26
26
#include " util/ZipSerialize.h"
27
27
28
28
#include < algorithm>
29
- #include < fstream>
30
29
#include < sstream>
31
30
32
31
using namespace digidoc ;
@@ -37,37 +36,58 @@ using namespace std;
37
36
* Initialize ASiCS container.
38
37
*/
39
38
ASiC_S::ASiC_S (): ASiContainer(MIMETYPE_ASIC_S)
40
- {
41
- }
39
+ {}
42
40
43
41
/* *
44
42
* Opens ASiC-S container from a file
45
43
*/
46
44
ASiC_S::ASiC_S (const string &path): ASiContainer(MIMETYPE_ASIC_S)
47
45
{
48
- auto z = load (path, false , {MIMETYPE_ASIC_S});
49
- loadContainer (*z);
50
- }
46
+ auto z = load (path, false , {mediaType ()});
47
+ static const string_view metaInf = " META-INF/" ;
51
48
52
- void ASiC_S::save (const string & /* path*/ )
53
- {
54
- THROW (" Not implemented." );
55
- }
49
+ for (const string &file: z->list ())
50
+ {
51
+ if (file == " mimetype" ||
52
+ (metaInf.size () < file.size () && file.compare (0 , metaInf.size (), metaInf) == 0 ))
53
+ {
54
+ if (file == " META-INF/timestamp.tst" )
55
+ {
56
+ if (!signatures ().empty ())
57
+ THROW (" Can not add signature to ASiC-S container which already contains a signature." );
58
+ stringstream data;
59
+ z->extract (file, data);
60
+ addSignature (make_unique<SignatureTST>(data, this ));
61
+ }
62
+ if (file == " META-INF/signatures.xml" )
63
+ {
64
+ if (!signatures ().empty ())
65
+ THROW (" Can not add signature to ASiC-S container which already contains a signature." );
66
+ stringstream data;
67
+ z->extract (file, data);
68
+ addSignature (make_unique<SignatureXAdES_LTA>(data, this , true ));
69
+ }
70
+ continue ;
71
+ }
56
72
57
- void ASiC_S::addDataFile (const string &path, const string &mediaType)
58
- {
59
- if (!dataFiles ().empty ())
60
- THROW (" Can not add document to ASiC-S container which already contains a document." );
61
-
62
- ASiContainer::addDataFile (path, mediaType);
73
+ const auto directory = File::directory (file);
74
+ if (directory.empty () || directory == " /" || directory == " ./" )
75
+ {
76
+ if (!dataFiles ().empty ())
77
+ THROW (" Can not add document to ASiC-S container which already contains a document." );
78
+ addDataFile (dataStream (file, *z), file, " application/octet-stream" );
79
+ }
80
+ }
81
+
82
+ if (dataFiles ().empty ())
83
+ THROW (" ASiC-S container does not contain any data objects." );
84
+ if (signatures ().empty ())
85
+ THROW (" ASiC-S container does not contain any signatures." );
63
86
}
64
87
65
- void ASiC_S::addDataFile (unique_ptr<istream> is, const string &fileName, const string &mediaType )
88
+ void ASiC_S::save ( const string & /* path */ )
66
89
{
67
- if (!dataFiles ().empty ())
68
- THROW (" Can not add document to ASiC-S container which already contains a document." );
69
-
70
- ASiContainer::addDataFile (move (is), fileName, mediaType);
90
+ THROW (" Not implemented." );
71
91
}
72
92
73
93
unique_ptr<Container> ASiC_S::createInternal (const string & /* path*/ )
@@ -83,57 +103,11 @@ void ASiC_S::addAdESSignature(istream & /*signature*/)
83
103
unique_ptr<Container> ASiC_S::openInternal (const string &path)
84
104
{
85
105
if (!isContainerSimpleFormat (path))
86
- return nullptr ;
106
+ return {} ;
87
107
DEBUG (" ASiC_S::openInternal(%s)" , path.c_str ());
88
108
return unique_ptr<Container>(new ASiC_S (path));
89
109
}
90
110
91
- void ASiC_S::extractTimestamp (const ZipSerialize &z)
92
- {
93
- addSignature (make_unique<SignatureTST>(dataStream (" META-INF/timestamp.tst" , z), this ));
94
- }
95
-
96
- /* *
97
- * Load container (datafile and timestamp).
98
- *
99
- * @param z Zip stream.
100
- * @param list List of files contained in the container.
101
- * @throws IOException exception is thrown if the manifest.xml file parsing failed.
102
- * @throws ContainerException
103
- */
104
- void ASiC_S::loadContainer (const ZipSerialize &z)
105
- {
106
- DEBUG (" ASiC_S::loadFileAndTimestamp()" );
107
- const string metaInf = " META-INF/" ;
108
- const vector<string> &list = z.list ();
109
- int files = 0 ;
110
-
111
- for (const string &file: list)
112
- {
113
- if (file == " mimetype" ||
114
- file.substr (0 , metaInf.size ()) == metaInf)
115
- continue ;
116
-
117
- const auto directory = File::directory (file);
118
- if (directory.empty () || directory == " /" || directory == " ./" )
119
- {
120
- if (files > 0 )
121
- {
122
- THROW (" ASiC-S container contains more than one data objects." );
123
- }
124
- ASiContainer::addDataFile (dataStream (file, z), file, " application/octet-stream" );
125
- files++;
126
- }
127
- }
128
-
129
- if (files == 0 )
130
- {
131
- THROW (" ASiC-S container does not contain any data objects." );
132
- }
133
-
134
- extractTimestamp (z);
135
- }
136
-
137
111
Signature* ASiC_S::prepareSignature (Signer * /* signer*/ )
138
112
{
139
113
THROW (" Not implemented." );
@@ -144,31 +118,6 @@ Signature *ASiC_S::sign(Signer * /*signer*/)
144
118
THROW (" Not implemented." );
145
119
}
146
120
147
-
148
- bool ASiC_S::isTimestampedASiC_S (const vector<string> &list)
149
- {
150
- DEBUG (" isTimestampedASiC_S()" );
151
- bool isASiCS = false ;
152
-
153
- auto dataFiles = 0 ;
154
- auto hasTimestamp = false ;
155
-
156
- // container has only one file in root folder and has a timestamp
157
- for (const string &file: list)
158
- {
159
- const auto directory = File::directory (file);
160
- if (directory.empty () || directory == " /" || directory == " ./" )
161
- dataFiles++;
162
- if (file == " META-INF/timestamp.tst" )
163
- hasTimestamp = true ;
164
- }
165
-
166
- isASiCS = hasTimestamp && (dataFiles == 1 );
167
-
168
- DEBUG (" ASiCS Container: %s" , isASiCS ? " yes" : " no" );
169
- return isASiCS;
170
- }
171
-
172
121
/* *
173
122
* Detect ASiC format based on file extentions, mimetype or zip contents.<br/>
174
123
* Container format is simple (ASiC-S) or extended (ASiC-E).
@@ -185,26 +134,16 @@ bool ASiC_S::isContainerSimpleFormat(const string &path)
185
134
return false ;
186
135
if (extension == ASICS_EXTENSION || extension == ASICS_EXTENSION_ABBR)
187
136
return true ;
188
-
189
137
DEBUG (" Check if ASiC/zip containter" );
190
138
try
191
139
{
192
140
ZipSerialize z (path, false );
193
141
vector<string> list = z.list ();
194
- if (find (list.begin (), list.end (), " mimetype" ) != list.end ())
195
- {
196
- stringstream iss;
197
- z.extract (" mimetype" , iss);
198
- if (readMimetype (iss) == MIMETYPE_ASIC_S)
199
- return true ;
200
- }
201
- if (isTimestampedASiC_S (list))
202
- return true ;
142
+ return !list.empty () && list.front () == " mimetype" && readMimetype (z) == MIMETYPE_ASIC_S;
203
143
}
204
144
catch (const Exception &)
205
145
{
206
146
// Ignore the exception: not ASiC/zip document
207
147
}
208
-
209
148
return false ;
210
149
}
0 commit comments