2929#include " DataFile_p.h"
3030#include " XMLDocument.h"
3131#include " crypto/Connect.h"
32+ #include " crypto/TS.h"
33+ #include " util/DateTime.h"
3234#include " util/File.h"
3335
3436#include " json.hpp"
@@ -41,47 +43,6 @@ using namespace digidoc::util;
4143using namespace std ;
4244using json = nlohmann::json;
4345
44- template <class T >
45- constexpr T base64_enc_size (T n) noexcept
46- {
47- return ((n + 2 ) / 3 ) << 2 ;
48- }
49-
50- static auto base64_decode (string_view data) {
51- static constexpr array<uint8_t , 128 > T{
52- 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 ,
53- 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 ,
54- 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x3E , 0x64 , 0x64 , 0x64 , 0x3F ,
55- 0x34 , 0x35 , 0x36 , 0x37 , 0x38 , 0x39 , 0x3A , 0x3B , 0x3C , 0x3D , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 ,
56- 0x64 , 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E ,
57- 0x0F , 0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 , 0x18 , 0x19 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64 ,
58- 0x64 , 0x1A , 0x1B , 0x1C , 0x1D , 0x1E , 0x1F , 0x20 , 0x21 , 0x22 , 0x23 , 0x24 , 0x25 , 0x26 , 0x27 , 0x28 ,
59- 0x29 , 0x2A , 0x2B , 0x2C , 0x2D , 0x2E , 0x2F , 0x30 , 0x31 , 0x32 , 0x33 , 0x64 , 0x64 , 0x64 , 0x64 , 0x64
60- };
61-
62- string buf;
63- buf.reserve (base64_enc_size (data.size ()));
64- auto out = make_unique<stringstream>(std::move (buf));
65- int value = 0 ;
66- int bits = -8 ;
67- for (auto c: data)
68- {
69- if (c == ' \r ' || c == ' \n ' || c == ' ' || static_cast <uint8_t >(c) > 128 )
70- continue ;
71- uint8_t check = T[c];
72- if (check == 0x64 )
73- break ;
74- value = (value << 6 ) + check;
75- if (bits += 6 ; bits < 0 )
76- continue ;
77- out->put (char ((value >> bits) & 0xFF ));
78- bits -= 8 ;
79- }
80- return out;
81- }
82-
83-
84-
8546class SiVaContainer ::Private
8647{
8748public:
@@ -197,7 +158,7 @@ SiVaContainer::SiVaContainer(const string &path, ContainerOpenCB *cb, bool useHa
197158 break ;
198159
199160 size_t pos = b64.size ();
200- b64.resize (b64.size () + base64_enc_size ( buf.size ()) );
161+ b64.resize (b64.size () + (( buf.size () + 2 ) / 3 ) * 4 );
201162 int size = EVP_EncodeBlock ((unsigned char *)&b64[pos], buf.data (), int (is->gcount ()));
202163 b64.resize (pos + size);
203164 }
@@ -255,6 +216,11 @@ SiVaContainer::SiVaContainer(const string &path, ContainerOpenCB *cb, bool useHa
255216 s->_postalCode = signatureProductionPlace.value <string>(" postalCode" , {});
256217 s->_country = signatureProductionPlace.value <string>(" countryName" , {});
257218 }
219+ for (const json &tsa: info.value <json>(" archiveTimeStamps" , {}))
220+ {
221+ TS ts (from_base64 (tsa.value <string_view>(" content" , {})));
222+ s->_archiveTimeStamps .push_back ({ts.cert (), util::date::to_string (ts.time ())});
223+ }
258224 }
259225 for (const json &certificate: signature.value <json>(" certificates" , {}))
260226 {
@@ -265,8 +231,8 @@ SiVaContainer::SiVaContainer(const string &path, ContainerOpenCB *cb, bool useHa
265231 s->_ocspCertificate = X509Cert (der, X509Cert::Der);
266232 if (certificate[" type" ] == " SIGNATURE_TIMESTAMP" )
267233 s->_tsCertificate = X509Cert (der, X509Cert::Der);
268- if (certificate[" type" ] == " ARCHIVE_TIMESTAMP" )
269- s->_tsaCertificate = X509Cert (der, X509Cert::Der);
234+ if (certificate[" type" ] == " ARCHIVE_TIMESTAMP" && s-> _archiveTimeStamps . empty () )
235+ s->_archiveTimeStamps . push_back ({ X509Cert (der, X509Cert::Der), {}} );
270236 }
271237 for (const json &error: signature.value <json>(" errors" , {}))
272238 {
@@ -353,7 +319,7 @@ unique_ptr<istream> SiVaContainer::parseDDoc(const unique_ptr<istream> &ddoc, bo
353319 THROW (" Currently supports only content types EMBEDDED_BASE64 for DDOC format" );
354320 if (contentType != " EMBEDDED_BASE64" )
355321 continue ;
356- d->dataFiles .push_back (new DataFilePrivate (base64_decode ( dataFile),
322+ d->dataFiles .push_back (new DataFilePrivate (make_unique<stringstream>(from_base64<string>( dataFile) ),
357323 string (dataFile[" Filename" ]),
358324 string (dataFile[" MimeType" ]),
359325 string (dataFile[" Id" ])));
0 commit comments