-
Notifications
You must be signed in to change notification settings - Fork 47
/
libdigidocpp.dox
1761 lines (1379 loc) · 107 KB
/
libdigidocpp.dox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*! @mainpage
Libdigidocpp is the C++ library offering creating, signing and verification of digitally signed documents, according to <a href="http://www.etsi.org/deliver/etsi_en/319100_319199/31913201/01.01.01_60/en_31913201v010101p.pdf">XAdES</a> and <a href="http://www.etsi.org/deliver/etsi_en/319100_319199/31916201/01.01.01_60/en_31916201v010101p.pdf">ASiC</a> standards.
Development of the library can be monitored in GitHub environment: <a href="https://github.com/open-eid/libdigidocpp">https://github.com/open-eid/libdigidocpp</a>
Additional documentation about the library can be found from GitHub wiki section, see https://github.com/open-eid/libdigidocpp/wiki
*/
/*! \page manual Libdigidocpp Programmer's Guide
\section introduction Introduction
Libdigidocpp is the C++ library for creating applications handling digital signatures, their creation and verification. The digitally signed files are created in "DigiDoc format" (with .asice file extension), compliant to XML Advanced Electronic Signatures (\ref XAdES), technical standard published by European Telecommunication Standards Institute (ETSI).
Additionally the libdigidocpp library can be used to read and verify the digitally timestamped containers (using .asics file extension) with a single datafile. There is possible to validate \ref ASiC (\ref CAdES), \ref PDF and \ref DDOC formats with \ref SiVa service.
Development of the library can be monitored in GitHub environment: <a href="https://github.com/open-eid/libdigidocpp">https://github.com/open-eid/libdigidocpp</a>.
\subsection about About DigiDoc
Libdigidocpp library forms a part of the wider DigiDoc system framework which offers a full-scale architecture for digital signature and documents, consisting of software libraries (C++ and Java), SiVa service and end-user applications such as DigiDoc4 according to the following figure:
\image html digidoc_framework.svg "DigiDoc framework"
It is easy to integrate DigiDoc components into existing applications in order to allow for creation, handling, forwarding and verification of digital signatures. All applications share common digitally signed file formats.
\subsection format Format of digitally signed file
Actively used digitally signed file formats in DigiDoc system are:
- ASiC-E - default format for files in Libdigidocpp library, described in \ref ASiC "The ETSI standard ETSI EN 319 162-1";
- BDOC 2.1 - legacy format, described in \ref BDOC "BDOC2.1:2013", The library implements only read-only support for the format;
- ASiC-S - timestamped container, described in \ref ASiC "The ETSI standard ETSI EN 319 162-1". The library implements only read-only support for the format.
The following chapters provides an overview of ASiC-E (XAdES) digitally signed file format which is the preferred format for creating signed documents in Libdigidocpp library.
\subsubsection container ASiC-E (XAdES) container format
The ETSI standard \ref ASiC "EN 319 162-1" called Associated Signature Containers (ASiC) defines format of container for encapsulation of signed files and signatures with extra information. The container type used in case of ASiC-E documents is Associated Signature Extended form. In the container \ref XAdES "XAdES EN 319 132-1" (XML Advanced Electronic Signatures) format signatures are used.
ASiC-E container is a ZIP file consisting of the following objects:
- a file named "mimetype", containing only the following value: application/vnd.etsi.asic-e+zip
- data files in original format.
- META-INF subdirectory, consisting of:
- manifest.xml – a file containing list of all files in the container. The list does not contain the "mimetype" file and files in META-INF subdirectory.
- signatures*.xml – one file for each signature, ‘*’ in the file’s name denotes the sequence number of a signature (counting starts from zero). The signatures*.xml file also incorporates certificates, validity confirmation and meta-data about the signer.
When ASiC-E container is signed then all files in the container are signed, except of the mimetype file and files in META-INF subdirectory.
Original files (which were signed) along with the signature(s), timestamp(s), validation confirmation(s) and certificates are encapsulated within the container. As a result, it is possible to verify signature validity without any additional external information – the verifier should trust the issuer of signer’s certificate, TS Authority and the OCSP responder’s certificate.
\image html asic.svg "ASiC-E container's contents"
\subsubsection profiles Legacy BDOC signature profiles
The format of the BDOC 2.1 digitally signed file is based on ETSI \ref XAdES "XAdES TS 101 903" standard. The XAdES standard defines formats for advanced electronic signatures that remain valid over long periods of time. The ETSI standard \ref XAdES "TS 103 171" "XAdES Baseline Profile" further profiles the XAdES signature by putting limitations on choices.
BDOC 2.1 specification defines two profiles of qualified BDOC signatures: BDOC with time-mark and BDOC with time-stamp. Both of the profiles offer long-term validation possibility by incorporating the necessary validation data in the signature. Both of the profiles are compliant to XAdES LT-Level requirements.
\paragraph BDOC-TM BDOC signature with time-mark
The BDOC signature with time-mark is based XAdES-EPES signature (Explicit Policy based Electronic Signature, see \ref XAdES "XAdES").
In order to offer long time validation, it is necessary to obtain proof of validity of the signer’s X.509 digital certificate issued by a certificate authority (CA) at the time of signature creation. In case of BDOC with time-marks (TM profile), the proof is obtained with a single OCSP response that has a specific "nonce" field’s value (i.e. the time-mark).
The hash of the created signature (the <SignatureValue> element’s contents) is sent within the OCSP request’s and received back within the response’s "nonce" field. The OCSP request’s and response’s "nonce" field is a DER-encoding of the following ASN.1 data structure:
\code{.cpp}
TBSDocumentDigest ::= SEQUENCE {
algorithm AlgorithmIdentifier,
digest OCTET STRING
}
\endcode
The element digest is a hash value of the binary value of the <SignatureValue> element’s contents, element algorithm determines the used hash algorithm as defined in \ref RFC5280 "RFC 5280" clause 4.1.1.2.
<b>The time-mark provides proof of the following:</b>
1. The signature value existed at a certain point of time (issuance time of the OCSP confirmation) – the verifier can calculate the hash of the signature and check its conformance to the OCSP response’s "nonce" field.
2. The signer’s certificate was valid (provided that the OCSP response is positive and does indeed confirm the certificate’s validity) at a certain point of time
It is important to notice that additional time-stamps are not necessary as time of signing and time of obtaining validity information is indicated in the OCSP response (i.e. the time-mark).
<b>NB!</b> The issuance time (producedAt field’s value) of the OCSP response (the time-mark) is regarded as the time of signature creation.
To achieve long-time validity of digital signatures, a secure log system is employed within the model. All OCSP responses and changes in certificate validity are securely logged to preserve digital signature validity even after private key compromise of CA or OCSP responder.
\image html security.svg "Security model of time-marking mechanism"
\paragraph BDOC-TS BDOC signature with time-stamp
The BDOC signature with time-stamp is based on XAdES-BES signature (Basic Electronic Signature, see \ref XAdES).
In order to offer long time validation, it is necessary to obtaining proof of validity of the signer’s X.509 digital certificate issued by a certificate authority (CA) at the time of signature creation.
In case of BDOC with time-stamp (TS profile), the proof is provided as follows:
1. RFC3161 compliant time-stamp is obtained from a time-stamping service. The hash of the created signature (<SignatureValue> element block) is sent to the time-stamping server. The server’s response contains a time-stamp token with the same hash value that can later be used to validate that the time-stamp was indeed issued for the respective signature. The time-stamp token received from the server is added to the signature providing a proof from a trusted source that the signature value existed at a certain point of time.
2. RFC 6960 compliant OCSP confirmation is obtained from an OCSP service. The OCSP response received from the server is used as a trusted source to confirm that the signer’s certificate was valid at a certain point of time (producedAt field’s value in the OCSP response).
3. The verifier must check the time-stamp token’s and OCSP confirmation’s time difference. If the difference is acceptable then it can stated that the signer’s certificate was valid at the time of signature creation.
<b>NB!</b> The issuance time (getTime field’s value) of the time-stamp token (received with the response from time-stamping server) is regarded as the time of signature creation.
\subsubsection asics ASiC-S container format
In addition to the Associated Signature Extended form (ASiC-E) the \ref ASiC "ETSI standard TS 102 918" defines a Simple form which is used for encapsulating a single datafile and signature or time-stamp token associated with it.
ASiC-S container is a ZIP file consisting of the following objects:
- an optional file named "mimetype", containing only the following value: application/vnd.etsi.asic-s+zip
- data object (file) in original format.
- META-INF subdirectory with one of the following files:
- signatures.p7s
- signatures.xml
- timestamp.tst
The libdigidocpp library supports only containers with time-stamp token (container includes META-INF/timestamp.tst). The time-stamp token is a binary representation of TimeStampToken as defined in RFC 3161. The time-stamp is obtained from a time-stamping service; it is calculated over the entire binary content of the data object.
Since both the original file and time-stamp are included in the container, it is possible to verify that the timestamped file existed at a certain point of time.
The library can be used only for reading the content of the container and validating that the time-stamp was indeed issued for the data object included in the container.
\section releasenotes Release Notes
\include RELEASE-NOTES.md
\section overview Overview
\subsection References References and additional resources
<table><tr><td>\anchor BDOC BDOC2.1:2013</td><td>
BDOC – Format for Digital Signatures. Version 2.1:2013
https://www.skidsolutions.eu/repository/bdoc-spec21.pdf<br />
Other releases:<br />
https://www.skidsolutions.eu/repository/bdoc-spec20.pdf<br />
https://www.skidsolutions.eu/repository/bdoc-spec212.pdf<br />
https://www.id.ee/wp-content/uploads/2020/08/bdoc-spec21-est.pdf<br />
https://www.id.ee/wp-content/uploads/2020/01/bdoc-spec212-est.pdf
</td></tr><tr><td>\anchor DDOC DigiDoc format</td><td>
DigiDoc file format
https://www.id.ee/wp-content/uploads/2020/08/digidoc_format_1.3.pdf
</td></tr><tr><td>\anchor XML-DSIG XML-DSIG</td><td>
IETF RFC 3275: "XML-Signature Syntax and Processing"
http://www.ietf.org/rfc/rfc3275.txt
</td></tr><tr><td>\anchor XML-DSIG-1-1 XML-DSIG 1.1</td><td>
XML Signature Syntax and Processing. Version 1.1
http://www.w3.org/TR/xmldsig-core1/
</td></tr><tr><td>\anchor XAdES XAdES</td><td>
ETSI EN 319 132-1 V1.3.1 (2024-07) - Building blocks and XAdES baseline signatures<br />
ETSI TS 101 903 V1.4.2 (2010-12) – XML Advanced Electronic Signatures<br />
ETSI TS 103 171 V2.1.1 (2012-03) - XAdES Baseline Profile
https://www.etsi.org/deliver/etsi_en/319100_319199/31913201/01.03.01_60/en_31913201v010301p.pdf<br />
http://www.etsi.org/deliver/etsi_ts/101900_101999/101903/01.04.02_60/ts_101903v010402p.pdf<br />
http://www.etsi.org/deliver/etsi_ts/103100_103199/103171/02.01.01_60/ts_103171v020101p.pdf
</td></tr><tr><td>\anchor XAdES-Validation XAdES Validation</td><td>
ETSI TS 102 853 V1.1.2 (2012-10) – Signature validation procedures and policies
http://www.etsi.org/deliver/etsi_ts/102800_102899/102853/01.01.02_60/ts_102853v010102p.pdf
</td></tr><tr><td>\anchor CAdES CAdES EN</td><td>
ETSI EN 319 122-1 V1.2.1 (2021-10) - Building blocks and CAdES baseline signatures
https://www.etsi.org/deliver/etsi_en/319100_319199/31912201/01.02.01_60/en_31912201v010201p.pdf
</td></tr><tr><td>\anchor ZIP PKWARE ZIP</td><td>
ZIP File Format Specification
http://www.pkware.com/documents/casestudies/APPNOTE.TXT
</td></tr><tr><td>\anchor OpenDocument OpenDocument</td><td>
OASIS "Open Document Format for Office Applications. Version 1.2 Part 3: Packages"
http://docs.oasis-open.org/office/v1.2/cs01/OpenDocument-v1.2-cs01-part3.html#__RefHeading__752803_826425813<br />
Other versions:<br />
http://docs.oasis-open.org/office/v1.0/OpenDocument-v1.0-os.pdf
</td></tr><tr><td>\anchor ASiC ASiC</td><td>
ETSI EN 319 162-1 V1.1.1 (2016-04) - Associated Signature Containers<br />
ETSI TS 102 918 V1.3.1 (2013-06) - Associated Signature Containers<br />
ETSI TS 103 174 V2.1.1 (2012-03) - ASiC Baseline Profile
http://www.etsi.org/deliver/etsi_en/319100_319199/31916201/01.01.01_60/en_31916201v010101p.pdf<br />
http://www.etsi.org/deliver/etsi_ts/102900_102999/102918/01.03.01_60/ts_102918v010301p.pdf<br />
http://www.etsi.org/deliver/etsi_ts/103100_103199/103174/02.02.01_60/ts_103174v020201p.pdf
</td></tr><tr><td>\anchor PDF PDF (\anchor PAdES PAdES)</td><td>
ETSI EN 319 142-1 V1.1.1 (2016-04) - PAdES digital signatures
https://www.etsi.org/deliver/etsi_en/319100_319199/31914201/01.01.01_60/en_31914201v010101p.pdf<br />
</td></tr><tr><td>\anchor RFC6960 RFC6960</td><td>
X.509 Internet Public Key Infrastructure Online Certificate Status Protocol – OCSP
http://tools.ietf.org/html/rfc6960
</td></tr><tr><td>\anchor RFC3161 RFC3161</td><td>
Internet X.509 Public Key Infrastructure Time-Stamp protocol
http://tools.ietf.org/html/rfc3161
</td></tr><tr><td>\anchor RFC5280 RFC5280</td><td>
Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
http://tools.ietf.org/html/rfc5280
</td></tr><tr><td>\anchor TSL Trusted Lists</td><td>
ETSI TS 119 612 V2.2.1 (2016-04)
https://www.etsi.org/deliver/etsi_ts/119600_119699/119612/02.02.01_60/ts_119612v020201p.pdf
</td></tr><tr><td>\anchor SiVa SiVa</td><td>
Digital signature validation web service that provides SOAP and JSON API to validate files
http://open-eid.github.io/SiVa/
</td></tr><tr><td>\anchor rel-notes Release notes</td><td>
Libdigidocpp library’s release notes
</td></tr><tr><td>\anchor nat-cert ETSI TS 102 280 (V1.1.1)</td><td>
X.509 V3 Certificate Profile for Certificates Issued to Natural Persons
http://www.etsi.org/deliver/etsi_ts/102200_102299/102280/01.01.01_60/ts_102280v010101p.pdf
</td></tr><tr><td>\anchor DD-libs DigiDoc libraries</td><td>
https://www.id.ee/en/rubriik/digidoc-libraries/
</td></tr><tr><td>\anchor openeid-github ID-software GitHub project</td><td>
https://github.com/open-eid
</td></tr><tr><td>\anchor cpp-github Libdigidocpp GitHub project</td><td>
https://github.com/open-eid/libdigidocpp
</td></tr></table>
\subsection Terms Terms and acronyms
<table><tr><td>ASiC</td><td>
Associated Signature Containers
</td></tr><tr><td>ASiC-E</td><td>
Extended Associated Signature Containers. A type of ASiC container.
</td></tr><tr><td>ASiC-S</td><td>
Associated Signature Container Simple form. A type of ASiC container.
</td></tr><tr><td>BDOC 2.1 (.bdoc)</td><td>
Term is used to denote a digitally signed file format which is a profile of XAdES and follows container packaging rules based on OpenDocument and ASiC standards. The document format has been defined in \ref BDOC "BDOC2.1:2013", an overview is provided in chapter \ref format of the current document.
</td></tr><tr><td>CRL</td><td>
Certificate Revocation List, a list of certificates (or more specifically, a list of serial numbers for certificates) that have been revoked, and therefore should not be relied upon.
</td></tr><tr><td>DIGIDOC-XML (.ddoc)</td><td>
The term is used to denote a DigiDoc document format that is based on the XAdES standard and is a profile of that standard. The current version is 1.3 which has been described in \ref DDOC "DigiDoc format".
</td></tr><tr><td>ECDSA</td><td>
Elliptic Curve Digital Signature Algorithm. Digital Signature Algorithm (DSA) which uses elliptic curve cryptography. Used as an alternative to RSA algorithm.
</td></tr><tr><td>OCSP</td><td>
Online Certificate Status Protocol, an Internet protocol used for obtaining the revocation status of an X.509 digital certificate
</td></tr><tr><td>OCSP Responder</td><td>
OCSP Server, maintains a store of CA-published CRLs and an up-to-date list of valid and invalid certificates. After the OCSP responder receives a validation request (typically an HTTP or HTTPS transmission), the OCSP responder either validates the status of the certificate using its own authentication database or calls upon the OCSP responder that originally issued the certificate to validate the request. After formulating a response, the OCSP responder returns the signed response, and the original certificate is either approved or rejected, based on whether or not the OCSP responder validates the certificate.
</td></tr><tr><td>PAdES (.pdf)</td><td>
Term is used to denote a digitally signed PDF file format which is based on \ref PAdES standards.
</td></tr><tr><td>SK</td><td>
SK ID Solutions AS. Certificate Authority in Estonia
</td></tr><tr><td>time-mark</td><td>
Mechanism used for adding certificate validity and signing time information with the signature.
The information is provided with a special OCSP confirmation (also referred to as time-mark) - hash value of the binary value of the signature (along with hash algorithm identifier in case of BDOC 2.1 document format) must be present in the "nonce" field of the OCSP confirmation. In this case, signature creation time is the issuance time of the OCSP confirmation (producedAt value in the confirmation), additional time-stamp service is not required. The respective signature profile is TM profile (supported in case of DIGIDOC-XML 1.3 and BDOC 2.1 document formats).
</td></tr><tr><td>time-stamp</td><td>
Mechanism used for adding certificate validity and signing time information with the signature. The certificate validity information is added to the signature with an OCSP confirmation; the signing time information is added with a time-stamp token retrieved form a time-stamping service. In this case, signature creation time is the issuance time (genTime value in the time-stamp) of the time-stamp token. The respective signature profile is TS profile.
</td></tr><tr><td>archive time-stamp</td><td>
Mechanism used for providing long term validity of a XAdES signature. The signature and validation data values are time-stamped. The respective signature profile is TSA profile.
</td></tr><tr><td>TSA</td><td>
Time-Stamping Authority. Time-stamping service provider.
</td></tr><tr><td>TSL</td><td>
Trust Service status List. Signed list that provides information about the status and the status history of the trust services (including certification, OCSP confirmation and time-stamping services). Used as a trust anchor in case of signature creation and validation to check the trustworthiness of the certificates that are included in the signature. See also \ref TSL "Trusted Lists"
</td></tr><tr><td>X.509</td><td>
an ITU-T standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI) which specifies standard formats for public key certificates, certificate revocation lists, attribute certificates, and a certification path validation algorithm
</td></tr><tr><td>XAdES</td><td>
XML Advanced Electronic Signatures, a set of extensions to XML-DSIG recommendation making it suitable for advanced electronic signature. Specifies precise profiles of XML-DSIG for use with advanced electronic signature in the meaning of European Union Directive 1999/93/EC.
</td></tr><tr><td>XML-DSIG</td><td>
a general framework for digitally signing documents, defines an XML syntax for digital signatures and is defined in the W3C recommendation XML Signature Syntax and Processing
</td></tr></table>
\subsection Supported Supported functional properties
Libdigidocpp is a library of C++ classes offering the functionality of handling digitally signed files in supported DigiDoc formats. The following functions are implemented:
- creating containers in supported DigiDoc formats and adding data files;
- creating digital signatures using smart cards or other supported cryptographic tokens;
- adding time marks and validity confirmations to digital signatures using OCSP and time-stamping protocols;
- validating the digital signatures;
- using trust service status lists (TSL) as trust anchors for certificate validation;
- extracting data files from a container;
- removing signatures and data files from a container.
The following table gives overview of functional features that are supported with Libdigidocpp.
<table>
<tr>
<th>Feature</th>
<th>Supported values</th>
</tr>
<tr>
<td>DigiDoc document format</td>
<td>
- ASiC-E - the main document format to be used.
\note BDOC 1.0 file format is not supported (more info can be found from https://www.id.ee/en/article/digidoc-container-format-life-cycle-2/).
</td>
</tr>
<tr><td>Signature profile</td>
<td>Signature profiles are based on the profiles defined by XAdES (\ref XAdES "XAdES").
- time-stamp (TS) - signature profile in case of which the certificate validity information is added to the signature with an OCSP confirmation; the signing time information is added with a time-stamp token (see also \ref RFC6960 "RFC6960") retrieved from a time-stamping service. In this case, signature creation time is regarded as the issuance time of the time-stamp token (genTime value in the time-stamp).
- time-mark (TM) - certificate validity and signing time information is added to the signature with a time-mark - a special OCSP confirmation in case of which the hash value of the binary value of the signature (along with hash algorithm identifier in case of BDOC 2.1 document format) must be present in the "nonce" field of the OCSP confirmation. In this case, signature creation time is regarded as the issuance time of the OCSP confirmation (producedAt value in the confirmation), additional time-stamp token is not required.
- archive time-stamp (LTA) - the signature and all the accompanying validation data is time-stamped in order to provide long term validity. The profile is supported only in case of BDOC 2.1 document format, the "ArchiveTimeStamp" element is added to the time-stamp or time-mark signature (see also \ref BDOC "BDOC2.1:2013").
</td>
</tr>
<tr><td>Trust anchors</td>
<td>Information of trusted CA certificates (trust anchors) is used to validate the trustworthiness of certificates used in the signature. The signer certificate's CA, OCSP responder certificate and time-stamping service's certificate (in case of TS signature profile) must be trusted. Trusted certificates' information is obtained from TSL list (Trust Service status list), the trusted certificates' list is retrieved from a signed TSL list that provides information about the status and the status history of the trust services (including certification, OCSP confirmation and time-stamping services). The European Commission's TSL list is used, more information of which can be found from https://ec.europa.eu/information_society/policy/esignature/trusted-list/. For the TSL specification document, see also \ref TSL "Trusted Lists". For more information about the TSL implementation and configuration possibilities in Libdigidocpp library, see \ref TSL-overview and \ref CA-settings.
</td>
</tr>
<tr><td>Signature creation module</td>
<td>
- PKCS#11 – in Linux and macOS environments, the default module for singing with smart card (e.g. Estonian ID card or any other smartcard provided that you have the external native PKCS#11 driver for it).
- Windows CryptoAPI – the default module for signing with smart card in Windows environment. By default, a dialog window is opened for the user to choose the signing certificate and enter PIN code.
</td>
<tr>
<td>Cryptographic token type</td>
<td>
- Smart card, e.g. Estonian ID card. Supported signature creation modules are PKCS#11 and Windows CryptoAPI.
\note Usage of USB cryptostick (Aladdin eToken with Digital Stamp certificate (https://www.skidsolutions.eu/en/services/Digital-stamp)) has been tested indirectly with Libdigidocpp - testing has been carried out via DigiDoc desktop application which uses Libdigidocpp as a base layer.
</td>
</tr>
<tr><td>Public-key algorithm</td>
<td>
- RSA
- ECDSA
</td>
</tr>
</table>
\subsection Component Component model
The figure below describes the architecture of software and hardware components that are used when creating signatures with Libdigidocpp library.
\image html components.svg "Components used in Libdigidocpp implementation when signing with smart card"
<table>
<tr><th>Component</th><th>Description</th></tr>
<tr><td>PKCS#11</td><td>Widely adopted platform-independent API to cryptographic tokens (HSMs, smart cards and USB tokens), a standard management module of the cryptographic token and its certificates</td></tr>
<tr><td>CryptoAPI</td><td>Microsoft Cryptography API. Programming API for implementing cryptographic functions in Windows environment.</td></tr>
<tr><td>PC/SC</td><td>Standard communication interface between the computer and the smart card, a cross-platform API for accessing smart card readers</td></tr>
<tr><td>IFDHandler</td><td>Interface Device Handler for CCID readers</td></tr>
<tr><td>CCID</td><td>USB driver for Chip/Smart Card Interface Devices </td></tr>
<tr><td>Reader</td><td>Device used for communication with a smart card</td></tr>
</table>
\subsection Dependencies Dependencies
\subsubsection libraries Software libraries
Libdigidocpp library depends on the software libraries listed below.
<table>
<tr><th>Base Component</th><th>Required/optional</th><th>Description</th></tr>
<tr><td>OpenSSL</td><td>required</td><td>Used for validating certificates and digest values.</td></tr>
<tr><td>libxml2</td><td>required</td><td>Used for validating the documents according to XML Schema, reading and writing XML.</td></tr>
<tr><td>xmlsec</td><td>required</td><td>Used for handling signature related components.</td></tr>
<tr><td>ZLIB</td><td>required</td><td>Used when compressing and extracting ASiC files in ZIP format.</td></tr>
<tr><td>Minizip</td><td>required</td><td>Used when creating and opening ZIP container for ASiC file. If the component is not found from system then bundled version with source code is used. Forms a part of ZLIB component.</td></tr>
<tr><td>PKCS11</td><td>optional</td><td>Used for searching for default PKCS#11 driver in the system so that its path could be registered in configuration entries.</td></tr>
<tr><td>Doxygen</td><td>optional</td><td>Used for generating API documentation from source code.</td></tr>
<tr><td>SWIG</td><td>optional</td><td>Used for creating C# and Java bindings.</td></tr>
</table>
\subsubsection Schemas XML Schemas
Several XML schemas are used when creating digitally signed documents in ASiC file format and validating their structure. The schemas are included in etc/schema/ subdirectory of the Libdigidocpp distribution package, their description is given in the table below.
\note Some modifications have been made to some of the schemas. Differences in comparison with the original schemas are listed in section \ref schema-modification of the current document.
<table>
<tr><th>Schema file</th><th>Description</th>
</tr><tr><td>OpenDocument_manifest.xsd</td><td>OASIS OpenDocument v1.2 (\ref OpenDocument "OpenDocument")
Defines the structure of META-INF/manifest.xml file in ASiC container.
https://docs.oasis-open.org/office/v1.2/csd06/OpenDocument-v1.2-csd06-manifest-schema.rng
</td></tr><tr><td>OpenDocument_dsig.xsd</td><td>OASIS OpenDocument v1.2 (\ref OpenDocument "OpenDocument")
Defines the structure of META-INF/signature.xml file in ADOC container.
https://docs.oasis-open.org/office/v1.2/csd06/OpenDocument-v1.2-csd06-dsig-schema.rng
</td></tr><tr><td>en_31916201v010101.xsd</td><td>Associated Signature Containers (\ref ASiC "ASiC")
Defines the format of container for encapsulating the signed documents, signatures and additional information. http://www.etsi.org/deliver/etsi_ts/102900_102999/102918/01.02.01_60/
</td></tr><tr><td>xmldsig-core-schema.xsd</td><td>XML Signature Core Schema Instance (\ref XML-DSIG "XML-DSIG")
Defines XML syntax for digital signatures.
http://www.w3.org/TR/2008/REC-xmldsig-core-20080610/xmldsig-core-schema.xsd
</td></tr><tr><td>XAdES01903v132-201601.xsd</td><td>XML Advanced Electronic Signatures (\ref XAdES "XAdES EN")
Defines a set of extensions to XML-DSIG making it suitable for advanced electronic signature.
http://uri.etsi.org/01903/v1.3.2/XAdES01903v132-201601.xsd
</tr><tr><td>XAdES01903v141-201601.xsd</td><td>Defines XML syntax for additional elements of XAdES signatures that were added with version 1.4.1 of the (\ref XAdES "XAdES EN") standard. Needed for implementing archive time-stamp support in the future.
http://uri.etsi.org/01903/v1.4.1/XAdES01903v141-201601.xsd
</td></tr><tr><td>ts_119612v020201_201601xsd.xsd<br />ts_119612v020101_additionaltypes_xsd.xsd<br />ts_119612v020101_sie_xsd.xsd</td><td>Defines the format of Trust Service status Lists (\ref TSL) that contain information about trusted CA, OCSP and TSA certificates.
</td></tr><tr><td>conf.xsd</td><td>Configuration properties’ schema. Defines the Libdigidocpp configuration file’s digidocpp.conf structure (see also \ref conf).
</td></tr>
</table>
The following figure describes dependencies between the abovementioned schemas (direction of the arrow indicates the direction of dependency).
\image html schemas.svg "Dependencies between XML Schemas"
\paragraph schema-modification XML schema modifications
The following section describes modifications that have been made to XML schemas used in Libdigidocpp. The library uses several XML schemas when creating digitally signed documents and validating their structure. The schemas are included in etc/schema/ subdirectory of the Libdigidocpp distribution package, their description has been provided in section \ref Schemas.
Modifications are marked between xml comment tags.
<b>Schema en_31916201v010101.xsd</b>
1) The schema’s location has been altered so that the imported schema file is looked up from the local file system.
\code{.xml}
<xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>
<!-- originally "http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd" -->
\endcode
2) Additional schema’s location imports has been added so that the imported schema file is looked up from the local file system.
\code{.xml}
<xsd:import namespace="http://uri.etsi.org/01903/v1.3.2#" schemaLocation="XAdES01903v132-201601.xsd"/>
<xsd:import namespace="http://uri.etsi.org/01903/v1.4.1#" schemaLocation="XAdES01903v141-201601.xsd"/>
\endcode
<b>Schema xmldsig-core-schema.xsd</b>
1) The XMLSchema.dtd reference has been commented out due to implementation issues (otherwise a warning message would be produced).
\code{.xml}
<!--
<!DOCTYPE schema
PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd"
[
<!ATTLIST schema
xmlns:ds CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#">
<!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'>
<!ENTITY % p ''>
<!ENTITY % s ''>
]>
-->
\endcode
2) The initial integer data type used in the original schema is converted into long data type when generating C++ source code from the current schema. However, as the SK issued certificates’ serial numbers are too long to fit into long type variable then the data type has been changed to string.
\code{.xml}
<complexType name="X509IssuerSerialType">
<sequence>
<element name="X509IssuerName" type="string"/>
<element name="X509SerialNumber" type="string"/> <!-- originally type="integer" -->
</sequence>
</complexType>
\endcode
<b>Schema XAdES01903v132-201601.xsd</b>
1) The schema’s location has been modified so that the file is looked up from the local file system.
\code{.xml}
<xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>
<!-- originally "http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd" -->
\endcode
2) The "type" attribute has been added, otherwise a warning message would be produced.
\code{.xml}
<xsd:complexType name="SignaturePolicyIdentifierType">
<xsd:choice>
<xsd:element name="SignaturePolicyId" type="SignaturePolicyIdType"/>
<xsd:element name="SignaturePolicyImplied" type="AnyType"/> <!-- added type="AnyType" -->
</xsd:choice>
</xsd:complexType>
\endcode
3) The "type" attribute has been added, otherwise a warning message would be produced.
\code{.xml}
<xsd:complexType name="CommitmentTypeIndicationType">
<xsd:sequence>
<xsd:element name="CommitmentTypeId" type="ObjectIdentifierType"/>
<xsd:choice>
<xsd:element name="ObjectReference" type="xsd:anyURI"
maxOccurs="unbounded"/>
<xsd:element name="AllSignedDataObjects" type="AnyType"/> <!-- added type="AnyType" -->
</xsd:choice>
<xsd:element name="CommitmentTypeQualifiers"
type="CommitmentTypeQualifiersListType" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
\endcode
4) Change child elements of type SignedSignaturePropertiesType from "xsd:sequence" to "xsd:all" in order to allow the child elements to be listed in any order.
\code{.xml}
<xsd:complexType name="SignedSignaturePropertiesType">
<xsd:all>
<xsd:element ref="SigningTime" minOccurs="0"/>
<xsd:element ref="SigningCertificate" minOccurs="0"/>
<xsd:element ref="SigningCertificateV2" minOccurs="0"/>
<xsd:element ref="SignaturePolicyIdentifier" minOccurs="0"/>
<xsd:element ref="SignatureProductionPlace" minOccurs="0"/>
<xsd:element ref="SignatureProductionPlaceV2" minOccurs="0"/>
<xsd:element ref="SignerRole" minOccurs="0"/>
<xsd:element ref="SignerRoleV2" minOccurs="0"/>
<xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</xsd:all>
<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
</xsd:complexType>
\endcode
5) Change child elements of type SignatureProductionPlaceType from "xsd:sequence" to "xsd:all" in order to allow the child elements to be listed in any order.
\code{.xml}
<xsd:complexType name="SignatureProductionPlaceType">
<xsd:all>
<xsd:element name="City" type="xsd:string" minOccurs="0"/>
<xsd:element name="StateOrProvince" type="xsd:string" minOccurs="0"/>
<xsd:element name="PostalCode" type="xsd:string" minOccurs="0"/>
<xsd:element name="CountryName" type="xsd:string" minOccurs="0"/>
</xsd:all>
</xsd:complexType>
\endcode
<b>Schema XAdES01903v141-201601.xsd</b>
1) The schema's location has been modified so that the file is looked up from the local file system.
\code{.xml}
<xsd:import namespace="http://uri.etsi.org/01903/v1.3.2#" schemaLocation="XAdES01903v132-201601.xsd"/>
<!-- originally "http://uri.etsi.org/01903/v1.3.2/XAdES01903v132-201601.xsd" -->
\endcode
<b>Schema ts_119612v020201_201601xsd.xsd</b>
1) The schemas' locations have been modified so that the file is looked up from the local file system.
\code{.xml}
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
<!-- originally "http://www.w3.org/2001/xml.xsd" -->
<xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>
<!-- originally "http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd" -->
\endcode
\section conf Configuring Libdigidocpp
\tableofcontents
\subsection loading Loading configuration settings
Libdigidocpp uses XML configuration file named digidocpp.conf. Configuration file's structure is defined with XML schema "conf.xsd" - the file is included in etc/schema/ subdirectory of Libdigidocpp package. For a sample configuration file, see \ref sample-conf.
It is possible to use two types of configuration files: global and user's file. Global file can be used to determine system-wide settings that cannot be altered by a user's file – it can be done separately for each parameter in the file by setting the parameter's "lock" attribute value to "true". User's file can be used to determine user-specific parameter values.
It is possible to use only one configuration file (either global or user's file) or two files in parallel. In the latter case, the matching user file's parameter entries overwrite global file's entries, if the respective parameter is not defined as locked in the global file.
By default, the configuration file's settings are loaded during the library's initialization – Libdigidocpp looks for global and user configuration files from their default locations depending on the environment:
- in case of Windows environment:
- the global configuration file is looked up from the directory where digidocpp.dll library file is located. If the directory doesn't contain /schema subdirectory then the configuration file is looked up from the current working directory.
- user configuration file is looked up from the system directory containing application data for the current user: \%APPDATA%\\digidocpp\\digidocpp.conf
- in case of macOS:
- the global configuration file is looked up from a location in the file system: digidocpp.framework/Resources/digidocpp.conf
- user configuration file is looked up from $HOME/.digidocpp/digidocpp.conf
- in case of Linux environment:
- the global configuration file is looked up from a location in the file system: /etc/digidocpp/digidocpp.conf
- user configuration file is looked up from $HOME/.digidocpp/digidocpp.conf
It is also possible to load global configuration file from a non-default location. In this case, call out the configuration file's initialization method before initializing the library:
\code{.cpp}
// Initialize global configuration settings from a non-default location
digidoc::Conf::init(new digidoc::XmlConf("<file-path-and-name>"));
// then initialize the library
digidoc::initialize();
\endcode
Local configuration settings can also be set or modified during runtime by calling out the respective set methods of XmlConf class.
The digidoc::XMLConf class must be used in order to access all the configuration methods that are available.
\subsection parameters Configuration parameters
Configuration file's elements and their attribute names are defined in conf.xsd file.
Below is a description of the configuration file's parameters. The attribute "lock", when set to "true" can optionally be used to determine parameter values which should not be overwritten by another configuration file (e.g. when using global and user's configuration files in parallel; see also the previous section for more information).
\subsubsection logging-settings Logging settings
<table>
<tr>
<th>Parameter name</th>
<th>Comments</th>
</tr>
<tr>
<td>log.file</td>
<td>Location of the log file where the logging output is written, e.g.
/tmp/digidocpp.log or C:\\Temp\\digidocpp.log
If left unspecified then the logging output is written to standard output stream.
</td>
</tr>
<tr>
<td>log.level</td>
<td>Used for controlling the level of detail of the logging output messages, higher number value indicates higher level of detail. Possible values are:
1 – error messages,
2 – warning messages,
3 – info messages,
4 – debug messages.
</td>
</tr>
</table>
\subsubsection TS-settings Time-stamping service settings
<table>
<tr>
<th>Parameter name</th>
<th>Comments</th>
</tr>
<tr>
<td>ts.url</td>
<td>Specifies the URL of the time-stamping service that is used during signature creation, needed only in case of TS signature profile. By default, the RIA's time-stamping service is used by the library (https://eid-dd.ria.ee/ts)
</td>
</tr>
</table>
\note For testing purposes, the SK's test time-stamping service can be used. The service is available at http://demo.sk.ee/tsa/ additional information can be found at https://www.id.ee/en/article/trust-services-timestamping-service/.
\subsubsection VerifyService-settings Signature Verify Service settings
<table>
<tr>
<th>Parameter name</th>
<th>Comments</th>
</tr>
<tr>
<td>verify.serivceUri</td>
<td>Specifies the URL of the signature-verify service that is used during signature validation. By default, the RIA's signature-verify service is used by the library (https://siva.eesti.ee/V3/validate)
</td>
</tr>
</table>
\subsubsection pkcs11-settings PKCS#11 settings
<table>
<tr>
<th>Parameter name</th>
<th>Comments</th>
</tr>
<tr>
<td>pkcs11.driver.path</td>
<td>PKCS#11 driver library to be used when communicating with the smart card.
With Estonian ID cards for example, the following PKCS#11 libraries are used:
opensc-pkcs11.so (used in Linux environment)
opensc-pkcs11.dll (used in Windows environment)
</td>
</tr>
</table>
\subsubsection CA-settings Trust anchor/TSL settings
Information of trusted CA certificates (trust anchors) is used to validate the trustworthiness of certificates used in the signature during signing and signature validation processes. The signer certificate's CA, OCSP responder certificate and time-stamping service's certificate (also referred to as time-stamping authority, TSA) must be trusted.
Libdigidocpp library uses Trust Service Status List (TSL) as a source of trust anchor information (see also \ref TSL-overview and \ref TSL "TSL standard" for more information). A TSL list is a signed XML file that contains data of trusted CA certificates, OCSP responder service and time-stamping service certificates. Note that since v3.10, only TSL lists' based trust anchors are supported by the library.
By default, the trusted certificates' information is obtained from European Commission's official TSL list (https://ec.europa.eu/tools/lotl/eu-lotl.xml). The default TSL behaviour can be changed by altering the configuration parameters listed below.
\note - The TSL URL and TSL signing certificate values are not configurable via the digidocpp.conf configuration file. The default values are fixed in source code and can be accessed via methods digidoc::Conf::TSLCerts() and digidoc::Conf::TSLUrl(). The library's user has to create a subclass and override the methods in order to define other values. See also \ref initialization.
\note - When using digidoc-tool utility program then it is possible to specify necessary TSL parameters on the command line. See also \ref utility.
\note - For information about using test TSL lists with Libdigidocpp library, please refer to https://github.com/open-eid/libdigidocpp/wiki/Using-test-TSL-lists
<table>
<tr>
<th>Parameter name</th>
<th>Comments</th>
</tr>
<tr>
<td>tsl.autoupdate</td>
<td>Determines if TSL validity is checked during every initialization of the library and if new TSL lists are downloaded if the existing list is expired. By default, the automatic update functionality is enabled and can be disabled by setting the parameter's value to "false". Note that when setting the parameter to "false" then you should copy the necessary TSL files to the "tsl.cache" location manually.</td>
</tr>
<tr>
<td>tsl.cache</td>
<td>Directory in the file system where the TSL lists are saved and read in by the library. Set this parameter with your own value to change the default directories:
- in Windows environment: \%APPDATA%\\digidocpp\\tsl,
- in Linux ja OSX environments: $HOME/.digidocpp/tsl
</td>
</tr>
<tr>
<td>tsl.onlineDigest</td>
<td>Additional feature to optimize TSL updating process. By default, the value is "true", meaning that during each initialization of the library, it is checked if there is a newer TSL list published, even if the existing TSL list is not yet expired.
The check is based on the TSL list's HTTP HEAD request ETag field or SHA-256 digest value.
- HTTP HEAD request is made to TSL's URL to get remote ETag and if the value doesn't correspond with the existing local TSL's ETag value then a newer version of the TSL list is downloaded. Otherwise, the existing TSL is used.
- SHA-256 digest that is (optionally) published online by the TSL's owner/manager. The URL of the digest matches the TSL's URL, but extension .sha2 is used instead of .xml. If the digest can be read and the value doesn't correspond with the existing local TSL's SHA-256 digest then a newer version of the TSL list is downloaded. Otherwise, the existing TSL is used.</td>
</tr>
<tr>
<td>tsl.timeOut</td>
<td>TSL downloading timeout for each TSL list. The default value is 10 seconds.</td>
</tr>
</table>
\subsubsection proxy-settings HTTP proxy settings
<table>
<tr>
<th>Parameter name</th>
<th>Comments</th>
</tr>
<tr>
<td>proxy.host</td>
<td>Specifies the proxy hostname, e.g. proxy.example.net</td>
</tr>
<tr>
<td>proxy.port</td>
<td>Specifies the proxy port, e.g. 8080</td>
</tr>
<tr>
<td>proxy.user</td>
<td>Specifies the proxy username.</td>
</tr>
<tr>
<td>proxy.pass</td>
<td>Specifies the proxy password.</td>
</tr>
<tr>
<td>proxy.tunnelSSL</td>
<td>May be used to enable downloading TSL-s in case of HTTPS connections and proxy. If enabled, the library tries to download use the proxy tunnel also for the HTTPS session. </td>
</tr>
<tr>
<td>proxy.forceSSL</td>
<td>May be used to enable downloading TSL-s in case of HTTPS connections and proxy. If enabled then the library tries to pass by the proxy connection in case of HTTPS sessions. </td>
</tr>
</table>
\subsubsection digest-settings Digest type settings
<table>
<tr>
<th>Parameter name</th>
<th>Comments</th>
</tr>
<tr>
<td>signer.signatureDigestUri</td>
<td>Specifies the digest algorithm that is used when calculating the hash that is being signed. By default, the SHA-256 algorithm (with URI http://www.w3.org/2001/04/xmlenc#sha256) is used</td>
</tr>
<tr>
<td>signer.digestUri</td>
<td>Specifies the digest algorithm that is used for calculating all the hash values in the signature. By default, the SHA-256 algorithm is used</td>
</tr>
</table>
\subsubsection ocspresponder-settings OCSP responder settings
The default OCSP responder that the library uses for retrieving the OCSP confirmation during signature creation depends on the signer's certificate chain.
In case of no issuer is configured AIA extension is used for OCSP responder settings
You change the default behaviour in the configuration file with the following parameter.
<table>
<tr>
<th>Parameter name</th>
<th>Comments</th>
</tr>
<tr>
<td>ocsp issuer</td>
<td>The "issuer" parameter's name stands for the signer certificate issuer's Common Name (CN) value, e.g. ESTEID-SK 2015. The element's value specifies OCSP responder server's URL address that is used for certificates issued from the respective CA chain.
</td>
</tr>
</table>
\subsection sample-conf Sample configuration file
\includelineno src/digidocpp.conf
\section usage Using Libdigidocpp API
\tableofcontents
Note that Libdigidocpp uses internal memory buffers in case of all the operations, so that intermediary data is not written to temporary files on the disk. Also, the data files to be added to a DigiDoc container can be read from a data stream and later extracted from the container to a stream so that the data can be kept in memory.
\subsection initialization Initialization
Libdigidocpp's initialization method conducts the following operations:
1. initializes dependent libraries (see also \ref libraries)
2. loads configuration settings from default configuration files
3. initializes trust anchors: initializes TSL lists. See \ref TSL-init for more information about the TSL initialization process.
If you would like to use non-default configuration settings then call out the configuration file's initialization before initializing the library, for example:
\code{.cpp}
// Optionally initialize global configuration file to use non-default settings
digidoc::Conf::init(new digidoc::XmlConf("<file-path-and-name>"));
// Initialize the library
digidoc::initialize();
\endcode
The digidoc::XmlConf class must be used in order to access all the configuration methods that are available.
\note If you would like to use different configuration values that are fixed as constants in the digidoc::Conf configuration class then it is possible to extend the class and override the values that need to be reset.
\subsection creating Creating and signing a DigiDoc document (local signing)
\subsubsection containercreate Creating a DigiDoc container
Create a new container object and specify the DigiDoc document's type, for example:
\code{.cpp}
auto doc = digidoc::Container::createPtr("<output-file's-path>"); // create new container
\endcode
Container class is used to incorporate the data of a DigiDoc document.
\subsubsection adddatafile Adding data files
Data files can be added to a DigiDoc container in two alternative ways:
1. adding the data from an input stream (i.e. the data file contents can be read from internal memory buffer):
\code{.cpp}
std::unique_ptr<std::istream> is = ...;
void digidoc::Container::addDataFile(std::move(is), // input stream
const std::string &fileName, // file name that is written to the container
const std::string &mediaType); // mime type of the data file
\endcode
2. adding the data by reading the it from file system
\code{.cpp}
void digidoc::Container::addDataFile(const std::string &path, //data file's name and path in file system
const std::string &mediaType); // mime type of the data file
\endcode
Parameter mediaType in the methods above stands for a MIME type of the data file, for example "text/plain" or "application/msword". Value "application/octet-stream" is used by default.
Calling out any of the methods listed above shall create a new DataFile object and add it to the DigiDoc container's data file collection.
Note that in order to add a data file to a container, the container has to be unsigned and there shouldn't be an existing data file with the same name in the container. If a container is signed then it is possible to add data files to it only after the signatures are removed.
\warning - It is important to pay attention that the data file's mime type value in manifest.xml file and in signatures*.xml file's <DataObjectFormat><MimeType> element are the same, otherwise the signature is invalid! In case of the ordinary signature creation process, the library sets the correct value automatically. However, if you create a ASiC-E container with Libdigidocpp library and want to add signatures*.xml file that you have received from another source then make sure that the data files' mime-type values in manifest-xml file and in signatures*.xml file are the same.
\warning - Data file’s mime-type value must be formatted as specified in RFC2045, section 5.1 (https://tools.ietf.org/html/rfc2045#section-5.1), i.e. the "type" and "subtype" values must be separated with a forward slash character.
\warning - It is recommended not to use special characters in the data file’s name, i.e. it is suggested to only use the characters that are categorized as "unreserved" according to RFC3986 (http://tools.ietf.org/html/rfc3986).
\note By default, it is recommended to use data file mime-type value "application/octet-stream" for all file types.
\subsubsection API-add-sign Adding signatures
It is possible to add a signature to a container only if it contains at least one data file, multiple signatures can be added to a single container. The signer's certificate and PIN code to access the private signature key are required during signing.
\note Libdigidocpp library uses TSL lists (Trust Service Status list) to obtain information about trusted certificates during signature creation process. See also \ref TSL-overview "TSL overview", \ref TSL "TSL standard" and \ref CA-settings "Configuring TSL settings".
Signing can be done by using PKCS#11 module for accessing the signature token. PKCS#11 module is the default module for singing with smart card (e.g. Estonian ID card or any other smart card provided that you have the external native language PKCS#11 driver for it). See also \ref pkcs11-settings.
\code{.cpp}
digidoc::PKCS11Signer *signer = new digidoc::PKCS11Signer("<PKCS11-driver-path>");
// optionally specify PKCS#11 driver's location. If left unspecified then location is
// looked up from configuration file's parameter "pkcs11.driver.path".
std::string pin = "<pin-code>"; //PIN2 in case of Estonian ID cards
signer->setPin(pin);
\endcode
If you would like to add PIN insertion dialog window for the signer to enter the PIN code then you can write a new class which extends the PKCS11Signer class, overwrite the std::string pin(const X509Cert &cert) method and write your own PIN dialog implementation code there.
\paragraph API-sign-profile Optionally specify the signature profile
The supported signature profiles are (see also \ref Supported, under "Signature profiles"):
- "time-stamp" (TS) - signature profile in case of which the certificate validity information is added to the signature with an OCSP confirmation (retrieved from OCSP server); the signing time information is added with a time-stamp token (retrieved from a time-stamping service). Signature creation time is the issuance time of the time-stamp token (value of the getTime field in the token).
If the signature profile value is not specified then then a "time-stamp" profile is used by default.
Set the profile value as follows:
\code{.cpp}
std::string profile = "time-stamp"; // or "time-stamp-archive"
signer->setProfile(profile);
\endcode
\paragraph API-sign-data Optionally specify additional signer's data
Signature production place and signer role are optional signed meta-data about the signature. If left unspecified then the respective elements in the signatures*.xml file are created with no contents.
\code{.cpp}
std::string city, state, postalCode, country;
std::vector<std::string> roles;
signer->setSignatureProductionPlace(city, state, postalCode, country); // location where the signature is created
signer->setSignerRoles(roles); // role(s) of the signer
\endcode
\paragraph API-signature-hash Optionally specify signature digest method
By default, the hash that is being signed is calculated with SHA-256 algorithm.
You can also use a different digest algorithm for calculating the hash that is signed (this does not affect calculating other hash values). For that, use the digidoc::Signer::setMethod(const std::string &method) method.
\paragraph API-sign-create Create the signature
The signing method also adds validation data from external services (OCSP and time-stamping servers). Note that the OCSP responder and time-stamping server settings (in case of TS profile) should be configured before calling out the following method (see also \ref initialization and \ref parameters). By default, the RIA's time-stamping service https://eid-dd.ria.ee/ts is used.
Container holds the Signature object reference and there is no need cleanup memory.
\code{.cpp}
Signature *signature = doc->sign(signer);
\endcode
\paragraph validatesig Validating the created signatures
After the signature has been added to the container, it should be validated before writing the signed container to an output file. For validating the signature, do as follows:
\code{.cpp}
signature->validate();
\endcode
The validation method above validates the signed data files', signer certificate's and OCSP confirmation's correspondence to the signature value. Note that the validation method above does not validate other signatures which may belong to the same container.
\note See also \ref validate about more information for validating existing signatures and signature containers.
\paragraph savesig Save container changes
After the signature has been added and validated, container changes should be saved (\ref containeropen):
\code{.cpp}
doc->save();
\endcode
\subsection websigning Creating and signing a DigiDoc document (external signing, e.g. in browser)
External signing (two-step signing) can be used in case of signing in web applications, where the signature value is calculated externally, via a browser plug-in or extension.
In order to conduct web signing with Libdigidocpp library, do as follows:
Container holds the Signature object reference and there is no need cleanup memory.
1. In Container class, prepare signature XML structure:
\code{.cpp}
Signature *signature = doc->prepareSignature(signer);
\endcode
2. In Signature class, get the hash to be signed in browser:
\code{.cpp}
std::vector<unsigned char> dataToSign = signature->dataToSign();
std::vector<unsigned char> signatureMethod = signature->signatureMethod();
std::string id = signature->id();
\endcode
ID can be used when container is saved with digidoc::Container::save and later reloaded to locate signature object.
3. Sign the hash in browser (e.g. use the <a href="https://github.com/open-eid/hwcrypto.js">hwcrypto.js library</a>)
4. Add RSA or ECDSA signature value to the signature XML structure:
When container was stored on disk before reload container with digidoc::Container::open and use digidoc::Container::signatures() to enumerate signatures to locate correct object with previosly selected ID.
\code{.cpp}
std::vector<unsigned char> signatureValue = ...;
signature->setSignatureValue(signatureValue);
\endcode
5. Add time-stamp and OCSP data to Signature object, according to the signature's profile (see also section \ref API-sign-profile for more information):
\code{.cpp}
signature->extendSignatureProfile(signer);
\endcode
6. Write the document to output, as specified in section \ref containeropen
\subsection containeropen Reading and writing DigiDoc documents
In order to read an existing DigiDoc file from the file system, do as follows:
\code{.cpp}
auto doc = digidoc::Container::openPtr("<input-file's-path>");
\endcode
The method above reads in the DigiDoc file from the specified location in file system and creates the respective Container object representing the document's data. The file's structure is also validated during its parsing according to the corresponding standards.
Write a DigiDoc file (represented with a Container object) to file system with the following method:
\code{.cpp}
digidoc::Container::save("<output-file's-path>");
\endcode
\note In case of read-only formats (e.g. ASiC-S documents), the save will throw a digidoc::Exception.
\subsection validate Validating signature containers and signatures
Validation of a signed DigiDoc document consists of three main steps:
1. Call out the main validation method of the library. If there are multiple validation errors then get the errors list.
2. Check for additional errors/warnings (separate implementation);
3. Determine the validation status of the document (according to the returned error codes and validation status priorities).
\subsubsection main-method Using the main validation method
You can validate a signature and its validation data - OCSP confirmation and time-stamp (in case of TS profile) - with method:
\code{.cpp}
void digidoc::Signature::validate();
\endcode
If an exception is thrown from the validation method then the signature can be either <b>INVALID</b> or <b>VALID WITH WARNINGS</b>; otherwise the signature is VALID. Before determining the final validation status, additional errors must be checked, as described in the following chapters.
If an exception is thrown then its causes can be retrieved with the following method:
\code{.cpp}
std::vector<digidoc::Exception> digidoc::Exception::causes();
\endcode
\subsubsection additional Checking for additional errors/warnings
There is a validation case that is not checked in the default validation method of the library, instead, separate method for checking this specific situation has to be implemented by the library’s user. In Libdigidocpp library, checking for an old file format must be done separately.
The following subchapter describes how this check can be implemented. After checking for old signature format errors/warnings, collect all of the error codes and continue with determining the validation status as described in the next chapter. It is possible to check the source code of digidoc-tool or DigiDoc desktop application, accessible from https://github.com/open-eid/DigiDoc4-Client.
\subsubsection validation-status Determining the validation status
After validating the signed DigiDoc document, the validation result must be determined by the library's user. Final validation result must be one of the possible validation statuses that are described in the table below, the status must be chosen according to its priority.
The validation status priorities have to be applied in two cases:
1. <b>Returning a validation result of a single signature:</b><br>
If there are more than one validation errors that occur when validating a single signature in DigiDoc container then the overall status of the signature should be chosen according to the status priorities.
2. <b>Returning a validation result of the whole DigiDoc container:</b><br>
If there are more than one signatures in a DigiDoc container and the signatures have different validation statuses or validation of the container structure returns a different status then the overall status of the DigiDoc file should be chosen according to the status priorities.
<b>NB! User of the library has to determine the validation status according to the error code that is returned by the library's validation method.</b>
<table>
<tr>
<th>Priority</th>
<th>Status</th>
<th>Error code</th>
<th>Description</th>
</tr>
<tr>
<td>1</td>
<td>INDETERMINATE/UNKNOWN</td>
<td><b>10</b> CertificateIssuerMissing (signer's certificate is unknown)<br/>
<b>6</b> CertificateUnknown (OCSP responder certificate is unknown)</td>
<td>Validation process determines that one or more of the certificates included in the document are unknown or not trusted, i.e. the certificates have been issued by an unknown Certificate Authority (the CA
has not been added to trusted list). Notes:
- The file and signature(s) are not legally valid.