Author SHA1 Message Date
artur 89644fe864 Merge pull request 'validate parents only once' (#17) from parentvelidationfix into main
Validate Trusted Timestamps Actions Demo / Validate (push) Failing after 21s
Reviewed-on: #17
Reviewed-by: phil <phil@jankaritech.eu>
2026-10-06 03:50:52 +00:00
Artur Neumann 68f212e4eb -----TIMESTAMP COMMIT-----
Validate Trusted Timestamps Actions Demo / Validate (push) Failing after 35s
Version: 1

Algorithm: sha1

Preimage: version:1,parent:445aa5635e92b8c59ded23a64fa918c1b99c3cb6,tree:730a434e4669a744319b7a1be82600f2f6527dff

Digest: 1fded0cb46bb8a98a8c0caa983433aa68c53d777

Timestamp: https://freetsa.org/tsr
 Info: Timestamp generated with GitTrustedTimestamps by Mabulous GmbH

 Version: 1
 Policy OID: tsa_policy1
 Hash Algorithm: sha1
 Message data:
     0000 - 1f de d0 cb 46 bb 8a 98-a8 c0 ca a9 83 43 3a a6   ....F........C:.
     0010 - 8c 53 d7 77                                       .S.w
 Serial number: 0x08E74F50
 Time stamp: Oct  5 11:10:54 2026 GMT
 Accuracy: unspecified
 Ordering: yes
 Nonce: 0x4D5A89D51BFCACB2
 TSA: DirName:/O=Free TSA/OU=TSA/description=This certificate digitally signs documents and time stamp requests made using the freetsa.org online services/CN=www.freetsa.org/emailAddress=busilezas@mailbox.org/L=Wuerzburg/C=DE/ST=Bayern
 Extensions:

 -----BEGIN RFC3161 TOKEN-----
 MIIDmgYJKoZIhvcNAQcCoIIDizCCA4cCAQMxDzANBglghkgBZQMEAgMFADCCAYAG
 CyqGSIb3DQEJEAEEoIIBbwSCAWswggFnAgEBBgQqAwQBMCEwCQYFKw4DAhoFAAQU
 H97Qy0a7ipiowMqpg0M6poxT13cCBAjnT1AYDzIwMjYxMDA1MTExMDU0WgEB/wII
 TVqJ1Rv8rLKgggETpIIBDzCCAQsxETAPBgNVBAoMCEZyZWUgVFNBMQwwCgYDVQQL
 DANUU0ExdjB0BgNVBA0MbVRoaXMgY2VydGlmaWNhdGUgZGlnaXRhbGx5IHNpZ25z
 IGRvY3VtZW50cyBhbmQgdGltZSBzdGFtcCByZXF1ZXN0cyBtYWRlIHVzaW5nIHRo
 ZSBmcmVldHNhLm9yZyBvbmxpbmUgc2VydmljZXMxGDAWBgNVBAMMD3d3dy5mcmVl
 dHNhLm9yZzEkMCIGCSqGSIb3DQEJARYVYnVzaWxlemFzQG1haWxib3gub3JnMRIw
 EAYDVQQHDAlXdWVyemJ1cmcxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCYXllcm4x
 ggHrMIIB5wIBATCBozCBlTERMA8GA1UEChMIRnJlZSBUU0ExEDAOBgNVBAsTB1Jv
 b3QgQ0ExGDAWBgNVBAMTD3d3dy5mcmVldHNhLm9yZzEiMCAGCSqGSIb3DQEJARYT
 YnVzaWxlemFzQGdtYWlsLmNvbTESMBAGA1UEBxMJV3VlcnpidXJnMQ8wDQYDVQQI
 EwZCYXllcm4xCzAJBgNVBAYTAkRFAgkAwumGFg2o6c0wDQYJYIZIAWUDBAIDBQCg
 gbgwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0y
 NjEwMDUxMTEwNTRaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFEgf1TxTTThBgMAo
 ZRmgNvmIVEdmME8GCSqGSIb3DQEJBDFCBEBG0bsumWx4aAhDPq20FxF67dOeiYGC
 TIpZBegL71ESdUuATcTUifp2DKI6t7PrNXMqz9uBpTIVdAM7KEiEkJgEMAoGCCqG
 SM49BAMEBGYwZAIwBJ8acnp7Etx2XQqeqjwRahviSVCPkNblLhqguw0g5FO2fNcy
 1j6HgKlqABSnK8tnAjAHDnTE2Ah1MalOTVT3ouiUzz0FYjBgesMRDFVd60nJqFF5
 lif2ROtMq8z3EgtWUuc=
 -----END RFC3161 TOKEN-----

Timestamp: https://tsa.cesnet.cz:3162/tsa
 Info: Timestamp generated with GitTrustedTimestamps by Mabulous GmbH

 Version: 1
 Policy OID: 1.3.6.1.4.1.22408.1.2.3.45
 Hash Algorithm: sha1
 Message data:
     0000 - 1f de d0 cb 46 bb 8a 98-a8 c0 ca a9 83 43 3a a6   ....F........C:.
     0010 - 8c 53 d7 77                                       .S.w
 Serial number: 0x6529662E3123923F
 Time stamp: Oct  5 11:10:55 2026 GMT
 Accuracy: unspecified seconds, unspecified millis, 0x01 micros
 Ordering: no
 Nonce: 0x1DF8C5B4F4FDF820
 TSA: DirName:/DC=cz/DC=cesnet-ca/O=CESNET/CN=tsa.cesnet.cz
 Extensions:

 -----BEGIN RFC3161 TOKEN-----
 MIIE3wYJKoZIhvcNAQcCoIIE0DCCBMwCAQMxDTALBglghkgBZQMEAgEwgdIGCyqG
 SIb3DQEJEAEEoIHCBIG/MIG8AgEBBgwrBgEEAYGvCAECAy0wITAJBgUrDgMCGgUA
 BBQf3tDLRruKmKjAyqmDQzqmjFPXdwIIZSlmLjEjkj8YDzIwMjYxMDA1MTExMDU1
 WjADgQEBAggd+MW09P34IKBcpFowWDESMBAGCgmSJomT8ixkARkWAmN6MRkwFwYK
 CZImiZPyLGQBGRYJY2VzbmV0LWNhMQ8wDQYDVQQKDAZDRVNORVQxFjAUBgNVBAMM
 DXRzYS5jZXNuZXQuY3oxggPhMIID3QIBATBsMGAxEjAQBgoJkiaJk/IsZAEZFgJj
 ejEZMBcGCgmSJomT8ixkARkWCWNlc25ldC1jYTESMBAGA1UECgwJQ0VTTkVUIENB
 MRswGQYDVQQDDBJQZXJzb25hbCBTaWduaW5nIDICCEypBoHUTnzHMAsGCWCGSAFl
 AwQCAaCCAUgwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJ
 BTEPFw0yNjEwMDUxMTEwNTVaMCsGCSqGSIb3DQEJNDEeMBwwCwYJYIZIAWUDBAIB
 oQ0GCSqGSIb3DQEBCwUAMC8GCSqGSIb3DQEJBDEiBCCDC9TqS/Uj2H2rw8+vrzUm
 lUb58YaALnJ4CDupZFBWHDCBrQYLKoZIhvcNAQkQAi8xgZ0wgZowgZcwgZQEIBw7
 ejf9btxySQfEE6VM0v+1ie7OnOWwYr0R52233q21MHAwZKRiMGAxEjAQBgoJkiaJ
 k/IsZAEZFgJjejEZMBcGCgmSJomT8ixkARkWCWNlc25ldC1jYTESMBAGA1UECgwJ
 Q0VTTkVUIENBMRswGQYDVQQDDBJQZXJzb25hbCBTaWduaW5nIDICCEypBoHUTnzH
 MA0GCSqGSIb3DQEBCwUABIICAIV7Gi1LUpdINBc9qBruLWx1ZKOSyFca0bD26nwA
 4HHBXU+23RERQMd80O8wpbUnVSzWiiA4Ohj1os23K/tZjo2kU5JDw7GSTh5RvzO/
 J7yPHjqYEc05kuVd4Na7XrYPS9W1jg5anfSfqvxKIuqZrkPObrBI8E7UGrW/6B1m
 6gQ2BJepE8Um0MdD4e5AspoHQ/yBY0bf7FmjRs/+dMHi4Rtex06CqjuecfgPlpzm
 TgpAVufArN7wKH2AwFdDUmI6SPrWIPdKsu7gsvzgUBf2nvacyq+wXJz3b1bWlZJl
 Yy61ItnZui0MuU3w2jg4HINQAW6uCDeQdzxJM8ihnURmi50eloFPGE9wS4nftykV
 bd0CxSTSJZXWRAOGQcq9vy08eUums9vp0f+ZYgLwVewgFQ9dBTJ5gBH3IbtKInSl
 TAPqgMdyvHGrSnaRQgGPxnHWORMiO/iwCDxy7xWxxVLzWz8BDlFx+fyOJ+ZeKNaI
 ew1dbuXaoTw7+COAYRVN4mLAoqZdTpCVLhB/pK3DSksf5goa0xiXEWqGvfl4gK+U
 LoAVj4WhOaPvuoKPcNG/dgQOkNlEbwQdzXnqo7re0dtHwEDGtQ9YSkmKFZVtd/90
 n+eMbzTz9qO9srxXinukXNQeed0i0GO3AZd3xKTGCUBxynyXB9Aq/vFSm6YQ7KTF
 WQ+T
 -----END RFC3161 TOKEN-----
2026-10-05 16:55:55 +05:45
Artur Neumann 445aa5635e validate parent chain only once 2026-10-05 16:54:27 +05:45
artur 2dd8923dc4 Merge pull request 'Only download CRL once' (#16) from onlyDownloadOnce into main
Validate Trusted Timestamps Actions Demo / Validate (push) Failing after 2m3s
Reviewed-on: #16
Reviewed-by: phil <phil@jankaritech.eu>
2026-10-05 10:14:53 +00:00
Artur Neumann 5f23cdf799 -----TIMESTAMP COMMIT-----
Validate Trusted Timestamps Actions Demo / Validate (push) Failing after 2m3s
Version: 1

Algorithm: sha1

Preimage: version:1,parent:57f0bbaf9cc7a23e3ab5d90c0ef07023b04fec01,tree:2b5a78ee16c9971858b50fa9c1980547b6e12e1c

Digest: 1a61e4c004239cc24021c21fd8819ede7a99af42

Timestamp: https://freetsa.org/tsr
 Info: Timestamp generated with GitTrustedTimestamps by Mabulous GmbH

 Version: 1
 Policy OID: tsa_policy1
 Hash Algorithm: sha1
 Message data:
     0000 - 1a 61 e4 c0 04 23 9c c2-40 21 c2 1f d8 81 9e de   .a...#..@!......
     0010 - 7a 99 af 42                                       z..B
 Serial number: 0x08E5B7C9
 Time stamp: Oct  5 08:37:23 2026 GMT
 Accuracy: unspecified
 Ordering: yes
 Nonce: 0x0E315C2FE4EA80F9
 TSA: DirName:/O=Free TSA/OU=TSA/description=This certificate digitally signs documents and time stamp requests made using the freetsa.org online services/CN=www.freetsa.org/emailAddress=busilezas@mailbox.org/L=Wuerzburg/C=DE/ST=Bayern
 Extensions:

 -----BEGIN RFC3161 TOKEN-----
 MIIDnAYJKoZIhvcNAQcCoIIDjTCCA4kCAQMxDzANBglghkgBZQMEAgMFADCCAYAG
 CyqGSIb3DQEJEAEEoIIBbwSCAWswggFnAgEBBgQqAwQBMCEwCQYFKw4DAhoFAAQU
 GmHkwAQjnMJAIcIf2IGe3nqZr0ICBAjlt8kYDzIwMjYxMDA1MDgzNzIzWgEB/wII
 DjFcL+TqgPmgggETpIIBDzCCAQsxETAPBgNVBAoMCEZyZWUgVFNBMQwwCgYDVQQL
 DANUU0ExdjB0BgNVBA0MbVRoaXMgY2VydGlmaWNhdGUgZGlnaXRhbGx5IHNpZ25z
 IGRvY3VtZW50cyBhbmQgdGltZSBzdGFtcCByZXF1ZXN0cyBtYWRlIHVzaW5nIHRo
 ZSBmcmVldHNhLm9yZyBvbmxpbmUgc2VydmljZXMxGDAWBgNVBAMMD3d3dy5mcmVl
 dHNhLm9yZzEkMCIGCSqGSIb3DQEJARYVYnVzaWxlemFzQG1haWxib3gub3JnMRIw
 EAYDVQQHDAlXdWVyemJ1cmcxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCYXllcm4x
 ggHtMIIB6QIBATCBozCBlTERMA8GA1UEChMIRnJlZSBUU0ExEDAOBgNVBAsTB1Jv
 b3QgQ0ExGDAWBgNVBAMTD3d3dy5mcmVldHNhLm9yZzEiMCAGCSqGSIb3DQEJARYT
 YnVzaWxlemFzQGdtYWlsLmNvbTESMBAGA1UEBxMJV3VlcnpidXJnMQ8wDQYDVQQI
 EwZCYXllcm4xCzAJBgNVBAYTAkRFAgkAwumGFg2o6c0wDQYJYIZIAWUDBAIDBQCg
 gbgwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0y
 NjEwMDUwODM3MjNaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFEgf1TxTTThBgMAo
 ZRmgNvmIVEdmME8GCSqGSIb3DQEJBDFCBECf9I+nx4VlcqIy9yo351cgn9aYh9w5
 qwFKtKlX6UqdX3HTNQDvyDbPBp2tRR7SVPmVDsGU5ED8bcO+4cxkipdYMAoGCCqG
 SM49BAMEBGgwZgIxAMLRgNn06QwRYwsFZkVR0zTYSE0xd6gvVRzQGJ3eNcrQxAmM
 X95TrGap0km2Uu9gFQIxAOqKuugEg5vZlaOx1p9C28uenIwXwZRUiz9TAq0L4QgM
 1pXUxv4/6tDVS2gEj7zjDw==
 -----END RFC3161 TOKEN-----

Timestamp: https://tsa.cesnet.cz:3162/tsa
 Info: Timestamp generated with GitTrustedTimestamps by Mabulous GmbH

 Version: 1
 Policy OID: 1.3.6.1.4.1.22408.1.2.3.45
 Hash Algorithm: sha1
 Message data:
     0000 - 1a 61 e4 c0 04 23 9c c2-40 21 c2 1f d8 81 9e de   .a...#..@!......
     0010 - 7a 99 af 42                                       z..B
 Serial number: 0x33D6B37621938998
 Time stamp: Oct  5 08:37:23 2026 GMT
 Accuracy: unspecified seconds, unspecified millis, 0x01 micros
 Ordering: no
 Nonce: 0xBA2582D629B00792
 TSA: DirName:/DC=cz/DC=cesnet-ca/O=CESNET/CN=tsa.cesnet.cz
 Extensions:

 -----BEGIN RFC3161 TOKEN-----
 MIIE4AYJKoZIhvcNAQcCoIIE0TCCBM0CAQMxDTALBglghkgBZQMEAgEwgdMGCyqG
 SIb3DQEJEAEEoIHDBIHAMIG9AgEBBgwrBgEEAYGvCAECAy0wITAJBgUrDgMCGgUA
 BBQaYeTABCOcwkAhwh/YgZ7eepmvQgIIM9azdiGTiZgYDzIwMjYxMDA1MDgzNzIz
 WjADgQEBAgkAuiWC1imwB5KgXKRaMFgxEjAQBgoJkiaJk/IsZAEZFgJjejEZMBcG
 CgmSJomT8ixkARkWCWNlc25ldC1jYTEPMA0GA1UECgwGQ0VTTkVUMRYwFAYDVQQD
 DA10c2EuY2VzbmV0LmN6MYID4TCCA90CAQEwbDBgMRIwEAYKCZImiZPyLGQBGRYC
 Y3oxGTAXBgoJkiaJk/IsZAEZFgljZXNuZXQtY2ExEjAQBgNVBAoMCUNFU05FVCBD
 QTEbMBkGA1UEAwwSUGVyc29uYWwgU2lnbmluZyAyAghMqQaB1E58xzALBglghkgB
 ZQMEAgGgggFIMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0B
 CQUxDxcNMjYxMDA1MDgzNzIzWjArBgkqhkiG9w0BCTQxHjAcMAsGCWCGSAFlAwQC
 AaENBgkqhkiG9w0BAQsFADAvBgkqhkiG9w0BCQQxIgQgIayddINSKud8vTX/7XOJ
 CTmt+HiaFJoHv190ivahK74wga0GCyqGSIb3DQEJEAIvMYGdMIGaMIGXMIGUBCAc
 O3o3/W7cckkHxBOlTNL/tYnuzpzlsGK9Eedtt96ttTBwMGSkYjBgMRIwEAYKCZIm
 iZPyLGQBGRYCY3oxGTAXBgoJkiaJk/IsZAEZFgljZXNuZXQtY2ExEjAQBgNVBAoM
 CUNFU05FVCBDQTEbMBkGA1UEAwwSUGVyc29uYWwgU2lnbmluZyAyAghMqQaB1E58
 xzANBgkqhkiG9w0BAQsFAASCAgAZIycR0GVwXJoE8w+JEl0FnCQd33IpAnA5FpTn
 SBmbRNvBVfl160uq9RDJULqp6xC2reeZTydjI/5JtuoUV6RJ5LVZj93fUf2FaZP9
 kJpcJxOJVHzreJUY6HJ4Oat/8kxkz4+JjZHlJc/aGBtXINxfwFLxOZSTHplRtVeG
 CbJP3JanrhdJa6TXbp6V1qYSJauNFWxL7HmeDmLzxwCaPdBdJOhpjkHLvy0kiYxj
 GfDlax+/A6hsnr/kxmi+C1KHmtOQU3Tmv/G9ndCegnxHaM4YPoxFMF2NGPFfpS0U
 Y+8MkJ6FV2nmcHQhvt76zQWb1WQYt6/T05YPadKzS/aYx6tHD+ZB1HRQJrHkKC1O
 QYqLZVr27Ry4Ls8oGmz/1cJfXFN/oHrgg7tG2ynveNepWzxy7O5wfIigI+V4UM5C
 3VXwvHq2FDg6LdNkxEF/ZokdsZQt1e/ayALYpWl6p7XfoWik3N18Nrj9uqFqntKB
 iufHfgIV/0A6sAotf17q5jhNgHXikg9QAxSjG40ZoaveuSvBUbCMYdFnSn0S/E7Y
 5AO+NVqxJVq58Dvh3eqdxJxRTYeXZfn++dqAwYj4uf3ejuUXQZQGuDEq9mjodxo8
 A2imEWPYDFDha6VwPirKX3PVnCxIJJjmyzikT57EHBkJiYvfTJIr2wXkOqzYyQwp
 JIPByA==
 -----END RFC3161 TOKEN-----
2026-10-05 14:22:24 +05:45
Artur Neumann 57f0bbaf9c only dowload CRL once 2026-10-05 14:20:39 +05:45
artur 308f0471b6 Merge pull request 'fix: spelling of remaining PARENT_COMMIT_HASH uses' (#14) from fix-PARENT_COMMIT_HASH into main
Validate Trusted Timestamps Actions Demo / Validate (push) Failing after 2m4s
Reviewed-on: #14
Reviewed-by: Artur Neumann <artur@jankaritech.eu>
2026-10-02 09:25:53 +00:00
Phillip Davis 8dbd2f0dec fix: spelling of remaining PARENT_COMMIT_HASH uses
Validate Trusted Timestamps Actions Demo / Validate (push) Failing after 2m3s
Signed-off-by: Phillip Davis <phil@jankaritech.com>
2026-10-02 18:13:35 +09:30
artur 0638d65c72 Merge pull request 'chore: fix typos' (#13) from fix-typos-20261002 into main
Validate Trusted Timestamps Actions Demo / Validate (push) Failing after 2m3s
Reviewed-on: #13
Reviewed-by: Artur Neumann <artur@jankaritech.eu>
2026-10-02 04:12:49 +00:00
Phillip Davis e9864318a0 chore: fix typos
Validate Trusted Timestamps Actions Demo / Validate (push) Failing after 2m3s
Signed-off-by: Phillip Davis <phil@jankaritech.com>
2026-10-02 12:39:47 +09:30
artur 093d283977 Merge pull request 'feature: validate commits in reverse date-time order when MAX_COMMITS_TO_CHECK is used' (#12) from date-order into main
Validate Trusted Timestamps Actions Demo / Validate (push) Successful in 54m17s
Reviewed-on: #12
Reviewed-by: Artur Neumann <artur@jankaritech.eu>
2025-06-04 03:16:25 +00:00
Phil Davis d48097695b feature: validate commits in reverse date-time order when MAX_COMMITS_TO_CHECK is used
Validate Trusted Timestamps Actions Demo / Validate (push) Successful in 28m9s
This ensures that the most recent commits are the ones that are validated.
2025-06-03 17:21:42 +05:45
phil 1622c1244f Merge pull request 'fix: stop correctly when MAX_COMMITS_TO_CHECK is reached' (#10) from respect-MAX_COMMITS_TO_CHECK into main
Validate Trusted Timestamps Actions Demo / Validate (push) Successful in 22m53s
Reviewed-on: #10
Reviewed-by: Artur Neumann <artur@jankaritech.eu>
2025-06-02 11:40:09 +00:00
Phil Davis f712aa0822 chore: adjust comment about MAX_COMMITS_TO_CHECK
Validate Trusted Timestamps Actions Demo / Validate (push) Successful in 14m39s
2025-06-02 15:32:48 +05:45
Phil Davis 8aba6e98d1 fix: stop correctly when MAX_COMMITS_TO_CHECK is reached
Validate Trusted Timestamps Actions Demo / Validate (push) Successful in 11m40s
2025-06-02 14:32:23 +05:45
phil 31e44f9b70 Merge pull request 'feature: limit the number of commits to be validated' (#9) from limit-num-commits-validated into main
Validate Trusted Timestamps Actions Demo / Validate (push) Successful in 14m5s
Reviewed-on: #9
Reviewed-by: Artur Neumann <artur@jankaritech.eu>
2025-06-02 04:10:47 +00:00
Phil Davis 4437b66f67 feature: default to checking all commits
Validate Trusted Timestamps Actions Demo / Validate (push) Successful in 13m47s
2025-05-29 09:55:57 +05:45
Phil Davis aabd314dde feature: limit the number of commits to be validated
Validate Trusted Timestamps Actions Demo / Validate (push) Successful in 49s
Signed-off-by: Phil Davis <phil@jankaritech.com>
2025-05-28 10:56:06 +05:45
artur ac5e6a6a89 Merge pull request 'only validate each commit once' (#7) from validate-each-commit-once-only into main
Validate Trusted Timestamps Actions Demo / Validate (push) Successful in 2m59s
Reviewed-on: #7
Reviewed-by: Artur Neumann <artur@jankaritech.eu>
2025-03-19 03:55:52 +00:00
12 changed files with 823 additions and 2347 deletions

No files matched your search

@@ -0,0 +1,95 @@
subject=DC=cz, DC=cesnet-ca, O=CESNET, CN=tsa.cesnet.cz
issuer=DC=cz, DC=cesnet-ca, O=CESNET CA, CN=Personal Signing 2
-----BEGIN CERTIFICATE-----
MIIFLjCCBBagAwIBAgIITKkGgdROfMcwDQYJKoZIhvcNAQELBQAwYDESMBAGCgmS
JomT8ixkARkWAmN6MRkwFwYKCZImiZPyLGQBGRYJY2VzbmV0LWNhMRIwEAYDVQQK
DAlDRVNORVQgQ0ExGzAZBgNVBAMMElBlcnNvbmFsIFNpZ25pbmcgMjAeFw0yNTAz
MDUxMjAzMDVaFw0yODA0MjAwOTIwNDhaMFgxEjAQBgoJkiaJk/IsZAEZFgJjejEZ
MBcGCgmSJomT8ixkARkWCWNlc25ldC1jYTEPMA0GA1UECgwGQ0VTTkVUMRYwFAYD
VQQDDA10c2EuY2VzbmV0LmN6MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEAsGge0kedZML8Mm59LjfUgr5QMBOGFoSzbrQe5YR0t43p3ILiS6DcnCm/n8cv
rX3eKkOPVmeDCQ/Snp+K6SBiWaKgzaAL/L6nuQdh7KoDzQO7+SdSa+q5HTghzca2
CxUKuP+EUnE88apvI901lvW2lo/Vw0k4opcO4CClHTzhsdiLjxaFFnTBwMdv0juf
3VmR6mVjLtgt8QIRoWNaUGPJ7uFk2MFZYmVB32JZu+whlW6p1gaxGSFpzK+mWcst
uL1zME5B2sKCbzN2/Ozx2dAAs+aARdPgCGcIu6AtWL82YUun5UFWzjafSwwH5PD2
Q5ozcTsGDHGRlt8dYXbTes2u7sIb8gwtT3RyHqwgxyPPUbWpTQg8wvxHubdSNlFQ
0FRNfnN5t5VPQ78f2s7i8uT5s8j1LIrlccTDQ0/taipElSDzlm6AFCAhrRbCgTUx
CphRJ/IQgcF140iAgWm3rqst9gcNOkn3je2DNsRJ9IoCfN/ydDleWXjGhbfFYkjm
wRjTQh1P8khrv/o3HPr0M9wNA0vzQMtcQgUywxvKWaUCC/SClHz03qOq1/2YWnNn
u+RCGGfXPmgiar63XUm4qUSGiRWsrkhKdX5TzRb08YgdewMQDlqounJSJ9pZwF8U
zyZ3nM/ifJs8tlgvrUUprco6PpqLiloctYdQbfNpWI5Sli8CAwEAAaOB8zCB8DAM
BgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFMEeu6Q/DhPfgZu+TGKy2bq+1ba7MEkG
A1UdEQRCMECCDnRzYTEuY2VzbmV0LmN6gg50c2EyLmNlc25ldC5jeoIOdHNhMy5j
ZXNuZXQuY3qCDnRzYTQuY2VzbmV0LmN6MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMI
MD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwuY2VzbmV0LWNhLmN6L1BlcnNv
bmFsU2lnbmluZzIuY3JsMB0GA1UdDgQWBBSYPaL5La3Ol0VRsc4tA2boji4mNTAN
BgkqhkiG9w0BAQsFAAOCAQEAFr8D9GjYwkeuY3oEj+kaJX7XCRK8SCmkKuhp6sWM
xsJRVyXUWhht9OCecW79mEUUkK79DuAwpGdKsOeqILamjmR6bm0Pc9WhQOySVIm/
54vB1dNWMmCL84xfheXIZI58sbWuUH7vSlBQJGADsyOEonZsBYPYnk4AwR0uM8Go
Mrr0Y618u5FKT8GKT7ZajykGeRzhc83g4iDZU72GsCX0N7R2jhGhK1SfGegv/tSn
3+2mvYbthcYV+745stxeae1HXiRrpnfUpkroqjpEHAcp+v+T8mGtrQTh+NVLd82W
zMwqSaiOYCpKc0lBzV4fSTP7Cpbfsx6xOyYPfxcu8/LlcA==
-----END CERTIFICATE-----
subject=DC=cz, DC=cesnet-ca, O=CESNET CA, CN=Personal Signing 2
issuer=DC=cz, DC=cesnet-ca, O=CESNET CA, CN=CESNET CA Root
-----BEGIN CERTIFICATE-----
MIIETTCCAzWgAwIBAgIHAPTqVoKaNDANBgkqhkiG9w0BAQsFADBcMRIwEAYKCZIm
iZPyLGQBGRYCY3oxGTAXBgoJkiaJk/IsZAEZFgljZXNuZXQtY2ExEjAQBgNVBAoT
CUNFU05FVCBDQTEXMBUGA1UEAxMOQ0VTTkVUIENBIFJvb3QwHhcNMTgwNDE4MDky
MDQ4WhcNMjgwNDIwMDkyMDQ4WjBgMRIwEAYKCZImiZPyLGQBGRYCY3oxGTAXBgoJ
kiaJk/IsZAEZFgljZXNuZXQtY2ExEjAQBgNVBAoMCUNFU05FVCBDQTEbMBkGA1UE
AwwSUGVyc29uYWwgU2lnbmluZyAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEApKhbabfUBLMtC10PXFQe+hJI4wpJFNkYt3HRud0rZKmRqlcpPJvc4PLr
9kEjXS+CP6Ut0UUkDvl686Mi7PsdxYFgDCfj0P694UA2SsGvBShL0vlZVkH19YFJ
tyY1imP3B94r57+umqKEEr9qxu9nwToS8AB6Ead4zBPMSnHZvyFPuD9Lsc/WhcUb
HnUvZN9jrrV4D6AjyvaBFPPcDVLjgiGoEE50PVMHPT5ZHpwTBTpBgL3zjE5fmxI4
HU7aD0orO0pg0kmZrQa98bnnVb7Wp9HhYHc9tPhLMhi9UdTBb9zwQCaezJ0gnS5K
iEAT5ZCYRUYlg82R07Z8k8UnHjczYQIDAQABo4IBDjCCAQowDwYDVR0TAQH/BAUw
AwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFMEeu6Q/DhPfgZu+TGKy2bq+1ba7
MB8GA1UdIwQYMBaAFJ5BMOPD1U6Mg46jPMl/o20TXYQlMG0GCCsGAQUFBwEBBGEw
XzAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AuY2VzbmV0LWNhLmN6LzA2BggrBgEF
BQcwAoYqaHR0cDovL2NydC5jZXNuZXQtY2EuY3ovQ0VTTkVUX0NBX1Jvb3QuY3J0
MDsGA1UdHwQ0MDIwMKAuoCyGKmh0dHA6Ly9jcmwuY2VzbmV0LWNhLmN6L0NFU05F
VF9DQV9Sb290LmNybDANBgkqhkiG9w0BAQsFAAOCAQEApoIA2/rStoUKnWC+qz3P
AZLtDiyuUqs4i4Lb18loxE67QdP9nDZEzwHrB9Cr4oxN9cTutdUiwDIBQKuLx3tH
r7TyuwcIYhHlW0+Ih+yUeyXEJlvSfR29M7SXY2axw4TWv4qOT2LKlFGxFqZx4OwN
aVMUDSFVr3E5J4doIB2u/pLd+LH1QdsUXF1VhIa+Is/HMhC2JvmdnFqOCypdQrSA
Ski6L8GRONF4SwzXg/glOQaw0QR69CjrYcogne1d/3Mxwr45MVkPwMJXscPKiRam
SSTj7AJpyic0xbFBwGu+T7BP0NujkY/CW96UoELgcPsKoTAg7j6BhrWsjrfEaqtu
7Q==
-----END CERTIFICATE-----
subject=DC=cz, DC=cesnet-ca, O=CESNET CA, CN=CESNET CA Root
issuer=DC=cz, DC=cesnet-ca, O=CESNET CA, CN=CESNET CA Root
-----BEGIN CERTIFICATE-----
MIIEDTCCAvWgAwIBAgIJAIf3+gBzaRRPMA0GCSqGSIb3DQEBBQUAMFwxEjAQBgoJ
kiaJk/IsZAEZFgJjejEZMBcGCgmSJomT8ixkARkWCWNlc25ldC1jYTESMBAGA1UE
ChMJQ0VTTkVUIENBMRcwFQYDVQQDEw5DRVNORVQgQ0EgUm9vdDAeFw0wOTAyMjQx
MzE2MDJaFw0yOTAyMjQxMzE2MDJaMFwxEjAQBgoJkiaJk/IsZAEZFgJjejEZMBcG
CgmSJomT8ixkARkWCWNlc25ldC1jYTESMBAGA1UEChMJQ0VTTkVUIENBMRcwFQYD
VQQDEw5DRVNORVQgQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAPeL9R8QFCBHw/PlWt2wBnx0cCSiNAhlI7HInrzGmtHK/9MJQJpmcoToq91R
Y+hdo7sVddNqbz3F+oeiKavz3wpdCZJtaPI8Sv44OlCtnxeuw0LkSAAfG3maue7X
I4jFqCU7/NxcoursXHDMCRLqeKHkast0b4i7d1KOdoc6hMNVaVc1UY/wyimM+Pbh
XRW4+iwnmJXlIqCumWaVKF0b1F0WK2LV5TRonsoFNPdVHBU795ObAXRsXWfiKwNK
CX85l3AO37UN1wbQ7UvCzE88jYOanRxL1AKezCa1ca8AohqbqoVVtrRPUTMrlXG3
JOBfRaG0+LPXxHwQ9zCjvV/9kFcCAwEAAaOB0TCBzjAdBgNVHQ4EFgQUnkEw48PV
ToyDjqM8yX+jbRNdhCUwgY4GA1UdIwSBhjCBg4AUnkEw48PVToyDjqM8yX+jbRNd
hCWhYKReMFwxEjAQBgoJkiaJk/IsZAEZFgJjejEZMBcGCgmSJomT8ixkARkWCWNl
c25ldC1jYTESMBAGA1UEChMJQ0VTTkVUIENBMRcwFQYDVQQDEw5DRVNORVQgQ0Eg
Um9vdIIJAIf3+gBzaRRPMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMA0G
CSqGSIb3DQEBBQUAA4IBAQB+vy9hAwzjgjYTnTwfxK03Ze/07GnmulUxUIPOagHJ
vGQojnjN3BGnMoXNhQrhhCy1BfKt88sweN/ELkeOsgthbQ24lX7YdgPEPSwY2iIB
E0NWxG87+z5hmfo+M69Q9WS8b5aSd4v5pSzT4+s6UW2lsddbdpnI4OwEEVdmj4e1
w0trIAfPsFSKx5jMvC0KzoO04fSAjxTj2bn4orRVWlVGUYmQm/Gq0w//f84zox/g
/XjE+kQ+eFOpNeeJC2Tpl04BByskoOw4LybIZ6iSdrUjoLgrK3R1geXo86Sx8QWE
VVWM2+1UCVV3AMhYwQUbgasrEPkZ79od6exSUb+ZTpWc
-----END CERTIFICATE-----
@@ -0,0 +1,92 @@
subject=O=Free TSA, OU=TSA, description=This certificate digitally signs documents and time stamp requests made using the freetsa.org online services, CN=www.freetsa.org, emailAddress=busilezas@mailbox.org, L=Wuerzburg, C=DE, ST=Bayern
issuer=O=Free TSA, OU=Root CA, CN=www.freetsa.org, emailAddress=busilezas@gmail.com, L=Wuerzburg, ST=Bayern, C=DE
-----BEGIN CERTIFICATE-----
MIIGYDCCBEigAwIBAgIJAMLphhYNqOnNMA0GCSqGSIb3DQEBDQUAMIGVMREwDwYD
VQQKEwhGcmVlIFRTQTEQMA4GA1UECxMHUm9vdCBDQTEYMBYGA1UEAxMPd3d3LmZy
ZWV0c2Eub3JnMSIwIAYJKoZIhvcNAQkBFhNidXNpbGV6YXNAZ21haWwuY29tMRIw
EAYDVQQHEwlXdWVyemJ1cmcxDzANBgNVBAgTBkJheWVybjELMAkGA1UEBhMCREUw
HhcNMjYwMjE1MTk0NDIyWhcNNDAwMjAyMTk0NDIyWjCCAQsxETAPBgNVBAoMCEZy
ZWUgVFNBMQwwCgYDVQQLDANUU0ExdjB0BgNVBA0MbVRoaXMgY2VydGlmaWNhdGUg
ZGlnaXRhbGx5IHNpZ25zIGRvY3VtZW50cyBhbmQgdGltZSBzdGFtcCByZXF1ZXN0
cyBtYWRlIHVzaW5nIHRoZSBmcmVldHNhLm9yZyBvbmxpbmUgc2VydmljZXMxGDAW
BgNVBAMMD3d3dy5mcmVldHNhLm9yZzEkMCIGCSqGSIb3DQEJARYVYnVzaWxlemFz
QG1haWxib3gub3JnMRIwEAYDVQQHDAlXdWVyemJ1cmcxCzAJBgNVBAYTAkRFMQ8w
DQYDVQQIDAZCYXllcm4wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASiFeGhstbLhxix
0o4UAumNSwHUUlOe3DBvs8fYs580wADW59oqGSCx15bp61TSmXkwLm1JW48XnbLL
izP6ZtjcvshV3H9uz2bS53sgDXhg1wLbIhAtraC+fHCytHeuVaujggHmMIIB4jAJ
BgNVHRMEAjAAMB0GA1UdDgQWBBQVwL0m69RdgtFdkyYxL+9wsotGXjAfBgNVHSME
GDAWgBT6VQ2MNGZRQ0z357OnbJWveuaklzALBgNVHQ8EBAMCBsAwFgYDVR0lAQH/
BAwwCgYIKwYBBQUHAwgwbAYIKwYBBQUHAQEEYDBeMDMGCCsGAQUFBzAChidodHRw
Oi8vd3d3LmZyZWV0c2Eub3JnL2ZpbGVzL2NhY2VydC5wZW0wJwYIKwYBBQUHMAGG
G2h0dHA6Ly93d3cuZnJlZXRzYS5vcmc6MjU2MDA3BgNVHR8EMDAuMCygKqAohiZo
dHRwOi8vd3d3LmZyZWV0c2Eub3JnL2NybC9yb290X2NhLmNybDCByAYDVR0gBIHA
MIG9MIG6BgMrBQgwgbIwMwYIKwYBBQUHAgEWJ2h0dHA6Ly93d3cuZnJlZXRzYS5v
cmcvZnJlZXRzYV9jcHMuaHRtbDAyBggrBgEFBQcCARYmaHR0cDovL3d3dy5mcmVl
dHNhLm9yZy9mcmVldHNhX2Nwcy5wZGYwRwYIKwYBBQUHAgIwOxo5RnJlZVRTQSB0
cnVzdGVkIHRpbWVzdGFtcGluZyBTb2Z0d2FyZSBhcyBhIFNlcnZpY2UgKFNhYVMp
MA0GCSqGSIb3DQEBDQUAA4ICAQBrMVS/YfnfMr0ziZnesBUOrDNRrNNgt3IgMNDw
Nhwl6oKWHVIhlYnM/5boljfbpZTAbqvxHI3ztT0/swxQOqTat5qBJRAY/VH1n/T4
M9uDjSuu3qfh0ZH5PL9ENqoVW44i5NT/znQev2MGXOAHwz9kZwwzz9MFX6hbGhBq
Wa+nlAqb7Y72KFzj33m1OVHxV2Wl4YD9f91bZTFpUEGW4Ktbkmxpf/iGIPaf4WHp
oBW/O6EzofMKYlz4yXyEBh0wRRVyXltLrj+MFHqhe+PsMBllq/dCaO4W/F+AuHEl
u7aUYWMASelphWAJiUsNMr5HAoeCSSgilqf1CSoWC+k6e4334Fym+Iy4csMex+PG
4rSdqXJVQ+AWEdRajSPKh7yDfpNkdnO6yqQJ/tSd11XQ5cL0M9jWuCD1zHlgA+u+
R2cry3yo23jD7qTGLhZqUvXCyWigH30/Q/RXjjDwrc4DJiQ+gRY0FhdTYqlvgMBP
r4LcJKnNksivdj+kbz7bVSbrBAzRiazK9l841/5XMtP9BvD0hKCpQFvP9PSgCC8E
QnKqgSe26FSJBaAQcA5TnK8NF4jkbElBxf/zyh7P3IjHso35jtgUWD1/itg9BJWb
YUwJ4tfILpB2F0wbk1GcZDCDZoyW3Xf3trApz/Zd93gF3joc9Hh9RFveKRzWQ7dd
Ut3egQ==
-----END CERTIFICATE-----
subject=O=Free TSA, OU=Root CA, CN=www.freetsa.org, emailAddress=busilezas@gmail.com, L=Wuerzburg, ST=Bayern, C=DE
issuer=O=Free TSA, OU=Root CA, CN=www.freetsa.org, emailAddress=busilezas@gmail.com, L=Wuerzburg, ST=Bayern, C=DE
-----BEGIN CERTIFICATE-----
MIIH/zCCBeegAwIBAgIJAMHphhYNqOmAMA0GCSqGSIb3DQEBDQUAMIGVMREwDwYD
VQQKEwhGcmVlIFRTQTEQMA4GA1UECxMHUm9vdCBDQTEYMBYGA1UEAxMPd3d3LmZy
ZWV0c2Eub3JnMSIwIAYJKoZIhvcNAQkBFhNidXNpbGV6YXNAZ21haWwuY29tMRIw
EAYDVQQHEwlXdWVyemJ1cmcxDzANBgNVBAgTBkJheWVybjELMAkGA1UEBhMCREUw
HhcNMTYwMzEzMDE1MjEzWhcNNDEwMzA3MDE1MjEzWjCBlTERMA8GA1UEChMIRnJl
ZSBUU0ExEDAOBgNVBAsTB1Jvb3QgQ0ExGDAWBgNVBAMTD3d3dy5mcmVldHNhLm9y
ZzEiMCAGCSqGSIb3DQEJARYTYnVzaWxlemFzQGdtYWlsLmNvbTESMBAGA1UEBxMJ
V3VlcnpidXJnMQ8wDQYDVQQIEwZCYXllcm4xCzAJBgNVBAYTAkRFMIICIjANBgkq
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtgKODjAy8REQ2WTNqUudAnjhlCrpE6ql
mQfNppeTmVvZrH4zutn+NwTaHAGpjSGv4/WRpZ1wZ3BRZ5mPUBZyLgq0YrIfQ5Fx
0s/MRZPzc1r3lKWrMR9sAQx4mN4z11xFEO529L0dFJjPF9MD8Gpd2feWzGyptlel
b+PqT+++fOa2oY0+NaMM7l/xcNHPOaMz0/2olk0i22hbKeVhvokPCqhFhzsuhKsm
q4Of/o+t6dI7sx5h0nPMm4gGSRhfq+z6BTRgCrqQG2FOLoVFgt6iIm/BnNffUr7V
DYd3zZmIwFOj/H3DKHoGik/xK3E82YA2ZulVOFRW/zj4ApjPa5OFbpIkd0pmzxzd
EcL479hSA9dFiyVmSxPtY5ze1P+BE9bMU1PScpRzw8MHFXxyKqW13Qv7LWw4sbk3
SciB7GACbQiVGzgkvXG6y85HOuvWNvC5GLSiyP9GlPB0V68tbxz4JVTRdw/Xn/XT
FNzRBM3cq8lBOAVt/PAX5+uFcv1S9wFE8YjaBfWCP1jdBil+c4e+0tdywT2oJmYB
BF/kEt1wmGwMmHunNEuQNzh1FtJY54hbUfiWi38mASE7xMtMhfj/C4SvapiDN837
gYaPfs8x3KZxbX7C3YAsFnJinlwAUss1fdKar8Q/YVs7H/nU4c4Ixxxz4f67fcVq
M2ITKentbCMCAwEAAaOCAk4wggJKMAwGA1UdEwQFMAMBAf8wDgYDVR0PAQH/BAQD
AgHGMB0GA1UdDgQWBBT6VQ2MNGZRQ0z357OnbJWveuaklzCBygYDVR0jBIHCMIG/
gBT6VQ2MNGZRQ0z357OnbJWveuakl6GBm6SBmDCBlTERMA8GA1UEChMIRnJlZSBU
U0ExEDAOBgNVBAsTB1Jvb3QgQ0ExGDAWBgNVBAMTD3d3dy5mcmVldHNhLm9yZzEi
MCAGCSqGSIb3DQEJARYTYnVzaWxlemFzQGdtYWlsLmNvbTESMBAGA1UEBxMJV3Vl
cnpidXJnMQ8wDQYDVQQIEwZCYXllcm4xCzAJBgNVBAYTAkRFggkAwemGFg2o6YAw
MwYDVR0fBCwwKjAooCagJIYiaHR0cDovL3d3dy5mcmVldHNhLm9yZy9yb290X2Nh
LmNybDCBzwYDVR0gBIHHMIHEMIHBBgorBgEEAYHyJAEBMIGyMDMGCCsGAQUFBwIB
FidodHRwOi8vd3d3LmZyZWV0c2Eub3JnL2ZyZWV0c2FfY3BzLmh0bWwwMgYIKwYB
BQUHAgEWJmh0dHA6Ly93d3cuZnJlZXRzYS5vcmcvZnJlZXRzYV9jcHMucGRmMEcG
CCsGAQUFBwICMDsaOUZyZWVUU0EgdHJ1c3RlZCB0aW1lc3RhbXBpbmcgU29mdHdh
cmUgYXMgYSBTZXJ2aWNlIChTYWFTKTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUH
MAGGG2h0dHA6Ly93d3cuZnJlZXRzYS5vcmc6MjU2MDANBgkqhkiG9w0BAQ0FAAOC
AgEAaK9+v5OFYu9M6ztYC+L69sw1omdyli89lZAfpWMMh9CRmJhM6KBqM/ipwoLt
nxyxGsbCPhcQjuTvzm+ylN6VwTMmIlVyVSLKYZcdSjt/eCUN+41K7sD7GVmxZBAF
ILnBDmTGJmLkrU0KuuIpj8lI/E6Z6NnmuP2+RAQSHsfBQi6sssnXMo4HOW5gtPO7
gDrUpVXID++1P4XndkoKn7Svw5n0zS9fv1hxBcYIHPPQUze2u30bAQt0n0iIyRLz
aWuhtpAtd7ffwEbASgzB7E+NGF4tpV37e8KiA2xiGSRqT5ndu28fgpOY87gD3ArZ
DctZvvTCfHdAS5kEO3gnGGeZEVLDmfEsv8TGJa3AljVa5E40IQDsUXpQLi8G+UC4
1DWZu8EVT4rnYaCw1VX7ShOR1PNCCvjb8S8tfdudd9zhU3gEB0rxdeTy1tVbNLXW
99y90xcwr1ZIDUwM/xQ/noO8FRhm0LoPC73Ef+J4ZBdrvWwauF3zJe33d4ibxEcb
8/pz5WzFkeixYM2nsHhqHsBKw7JPouKNXRnl5IAE1eFmqDyC7G/VT7OF669xM6hb
Ut5G21JE4cNK6NNucS+fzg1JPX0+3VhsYZjj7D5uljRvQXrJ8iHgr/M6j2oLHvTA
I2MLdq2qjZFDOCXsxBxJpbmLGBx9ow6ZerlUxzws2AWv2pk=
-----END CERTIFICATE-----
@@ -0,0 +1,211 @@
-----BEGIN X509 CRL-----
MIIkQjCCIyoCAQEwDQYJKoZIhvcNAQELBQAwYDESMBAGCgmSJomT8ixkARkWAmN6
MRkwFwYKCZImiZPyLGQBGRYJY2VzbmV0LWNhMRIwEAYDVQQKDAlDRVNORVQgQ0Ex
GzAZBgNVBAMMElBlcnNvbmFsIFNpZ25pbmcgMhcNMjYxMDA1MDkwMDEzWhcNMjYx
MjA0MDkwMDEzWjCCImIwGQIIUsGyPiz/JusXDTI1MTExMDEyNDAwNVowGQIITw/A
FKF3fpkXDTI2MDIxNzEzMzkzN1owGQIIDwynQv3qEtIXDTI1MTExNjA4NTcwOFow
GQIIecxHchhWqskXDTI2MDQyMDEyNDUyOFowGQIIVV3tvLyh5L8XDTI2MDcyMzA3
NTcyNVowGQIIXRFf7C89RHYXDTI2MTAwMTA4MDI1MlowGQIIGujCnHtZ630XDTI2
MDkwMjA4MzQyMVowGQIIBUjiaT1N8mQXDTI2MDgyMTE1Mzg0MVowGQIIYDtCkH3s
XC0XDTI2MDgyMTExNTczMlowGQIIM7A6M+zGNH4XDTI2MDYzMDA4MjE1OVowGQII
OD5YngzPhcwXDTI2MDIxOTA5NDg1MVowGQIId+3XWY9sLioXDTI1MDkxNzA3NTgw
NVowGQIICIfH2gcNl5QXDTI2MDEyMDEyNTE1MVowGQIIJutbA2mO0VgXDTI1MTEy
NTExMzM1MVowGQIIDo0+U9ypOjgXDTI1MTExMzExNTE0M1owGQIIYEs5r1CnAogX
DTI2MDkwMjA3MzIyNlowGQIIJKXjMnO2IfgXDTI1MTAwMjE0NDUwMVowGQIIK+6H
vtR7eOIXDTI1MTEwMzA1MDA1MFowGQIIOlm7aT+bfZgXDTI2MDQyMTEzNDIzOFow
GQIIXZabGRIWI58XDTI1MTAyOTA4MzEzMVowGQIIKW7Gp7+sBHgXDTI2MDkxNTEx
MDEyMFowGQIITd0Jmbynr3kXDTI1MTExMjA5MDMxMFowGQIIAZVn3opWO9oXDTI2
MDIwNTE1NTIyOFowGQIIAVrqR/q/GakXDTI1MTEwMzExMTgxMVowGQIIJoRNmqNO
InIXDTI2MDYyNjEwMDY0NVowGQIIKxDaf+wXG/oXDTI2MDExNTA2NDMyOFowGQII
GmzSpNnbshUXDTI2MDEyMDE0MjAwMFowGQIIB4PmtchWAeIXDTI1MTEyNTEyMzQ0
N1owGQIIFksemuGYxUcXDTI1MTExMzA5NTk0OFowGQIIE9Ta5gXasz4XDTI2MDEy
OTExMzU0NFowGQIIcxsIctoQtkYXDTI1MTEyNDExMjYzM1owGQIIVX3z9Arb9KUX
DTI1MTAxNDIwMTcwM1owGQIIDAG1ASPrGPYXDTI1MTAwMjExMTYxMlowGQIIFAlQ
P6dnuUYXDTI2MDkyOTA4MTUzMFowGQIIamxYsWCOFVUXDTI2MDgxOTA4MTYyNlow
GQIIfFxX/VTma4sXDTI1MTExMjExMzE0MlowGQIILwVIP3J189sXDTI2MDUxMTEy
MjUwM1owGQIIIxs+jHqWkTQXDTI1MTExMTEzMzUxNlowGQIIVfTA3V4+7D0XDTI2
MDQwODEzMzA0NVowGQIIBCuxCs4JMC8XDTI1MTIwMTE0MzI1NlowGQIIOM4eYtuK
hJ8XDTI2MDkxODA2NTE0OFowGQIITABFkB6YQckXDTI2MDQwODA5MzQxNVowGQII
T1L/qHpUyVkXDTI1MTAxNzEzMzIzNlowGQIIGAg0gJNBFAYXDTI1MTIwMzEyMjgx
OVowGQIIFtVCvvIpkg0XDTI2MTAwMjA4NDEzMVowGQIId2VhmCxSlw8XDTI2MDMy
NjEwNTMwMVowGQIIB87gZ6S0Zp4XDTI2MDIxNzA2NDIyMlowGQIICYvp2aXNSFMX
DTI2MDcxMDEzNTUzMVowGQIIcVww7496D90XDTI2MDkyOTA3MzczOFowGQIIZf0W
Ch+RCEQXDTI2MDMwMjEzNTEzMVowGQIITTEZBUpL138XDTI2MTAwMTEwMDkxM1ow
GQIIZ9HgurBci7AXDTI2MDUxNjE3MDcyN1owGQIIa5JPqwwcEU4XDTI2MDczMDEw
NTA0NVowGQIIUctU95q4yk4XDTI2MDkyNTA5MzEwMFowGQIIaKMLNuq6/awXDTI1
MTIwOTE0NDc0OFowGQIIUKb9EfwiUTEXDTI2MDUxMzE0NTA0OVowGQIIFzQm2Skn
62oXDTI2MDkzMDA4MzQyOFowGQIIOOy45PStQmIXDTI1MTAyODA2MzQwNVowGQII
Hu6J5L24masXDTI1MTAwMTE3MDcyM1owGQIIG9ycdVMY5DoXDTI2MDIwOTE1MzAw
NlowGQIIe0FU8xTSe6UXDTI1MTEyNTEzMjUwNlowGQIIA4I0jOjTUDsXDTI2MDEx
NTE3NTczMlowGQIIY0LCGujlTHMXDTI1MTExNjA5NTM1OFowGQIId2lhU9WPDO4X
DTI2MDkwNDEzMTI0OFowGQIISVcZMqymLEsXDTI1MTIwMTEzNTgwOFowGQIIIpoY
6WcirmAXDTI2MDcyMDA5MzI0MFowGQIIaaNO/2t9rGYXDTI2MDEyMDEyNDMzMlow
GQIIT3neNOCak34XDTI1MTAwMjEwMTk0OVowGQIIR77EFOHtwf8XDTI2MDIyNTEy
NTIzNFowGQIIdZtvgrPtNp0XDTI2MDEzMDA3MzQ1N1owGQIIH5lkBrVvYt8XDTI1
MTAwMjEwMjI0NFowGQIIE4KD2RBnOYwXDTI2MDMwOTEyMTMyM1owGQIIOnfUn2uN
x80XDTI2MDkwOTExMzc1NFowGQIIAydQ4+9veGQXDTI2MDIwNDExNDMxN1owGQII
QU7JtncblbsXDTI2MDUyNjA4NTk0M1owGQIIB4tWeYrmRNkXDTI1MTIxNjEyMzgx
NVowGQIIMehdRmqnb04XDTI1MTEyNDA5NDEyMFowGQIIJvAhg2gMLD8XDTI1MTAw
MzE3MzExOFowGQIIc0zuTh9Y1H0XDTI2MDIxNjExMzYyOVowGQIII88pbZ4oYiMX
DTI1MTIxMDEyMjEwOFowGQIIEQUpmz/jbzoXDTI2MDQyOTIzNDAzOFowGQIIOQLB
tHDRqpAXDTI2MDkwODA4MDY1OVowGQIIUHcDwFGr/FgXDTI2MDgwMzE4NTIxNVow
GQIIa5Qzz2cMheYXDTI2MDYxMTA2NDM0NVowGQIIHlQxCgBSP1oXDTI2MDUyMDA1
MTgwNVowGQIIbKE+rocZexQXDTI1MTEwNDA3NTEyOVowGQIIf0uUc6eaVsAXDTI2
MDIwNjA4MTU1OVowGQIIY+eb3zFca1MXDTI2MDcxNzEzMTAyOFowGQIIE0bdhdft
AUIXDTI1MTEyNjA3MzgxOFowGQIIT2xxXPFZRbYXDTI2MDEyMDEzMzU0NVowGQII
UkplZOj2P2MXDTI2MDYxNjA5NDIwOVowGQIIYn42KDa3L/kXDTI2MDcxNjE0MDM1
M1owGQIIInNDh7IsXhcXDTI2MDQxNjExMDMxN1owGQIICKAO9LVSvaAXDTI2MDkx
NTA5NDc0OFowGQIIZO8YVuy97SQXDTI1MTAwMjExMTAyN1owGQIIJ+Z6wziRjJ4X
DTI1MTAwMjExMTYwN1owGQIIIEFHTk7F1gsXDTI1MTEyMDA5NTcyN1owGQIIPko+
m2Vy3McXDTI2MDYyOTA5MTI1NVowGQIIIDwyl8gVSMkXDTI1MTEyMTIwNDUxOVow
GQIISdcQIZXutooXDTI2MDQxMzEzNDEzM1owGQIIbuT4JiU8OFAXDTI1MTIwMjE1
MTQ1MFowGQIIY+4uKoNK84UXDTI1MTAxNjA3NTUyOVowGQIIZ0QawiA6/iYXDTI2
MDkyOTA4NTgwOFowGQIIOHuIUJusOhcXDTI2MDMyMDE2MDI1OVowGQIIcqGOXGrM
RdMXDTI2MDcwMzEyNDgxNFowGQIIPne+2s5z8S8XDTI2MDkyMjEzMzAyNVowGQII
eZiJN0CAcDsXDTI2MDEwNzA5MjA0N1owGQIINN3rroiSTEQXDTI2MDcxNTExNTcz
MlowGQIIfs/AxFNTT28XDTI2MDUxODA4MzEwOFowGQIIQzxcao59hcYXDTI1MTEw
MTA5MTU1MVowGQIIEH9H99BhDQYXDTI2MDYyNTE1MzE1OFowGQIIb8+2DdusVG8X
DTI1MTExMDEwMTAzNlowGQIIae9A8zz6b7sXDTI2MDQwMTA2Mjg1OVowGQIIINVu
DnOezS0XDTI2MDcyMzA3MzAzMlowGQIIFeYu/X8nbsMXDTI2MDkxMTA2Mjk0NFow
GQIIdESSq793u1gXDTI1MTEwMjEwNDEyOFowGQIIahLWmQxae+EXDTI2MDUyNzA2
MjExNlowGQIIZxPdOyDDMRkXDTI1MTEwNDA5MDMxMVowGQIIXVnUTY2XtIUXDTI1
MTEwNTE2MDczNVowGQIIQaWn/fkln5sXDTI2MDEyMDEzMzUwMFowGQIIMCCITuVM
XfQXDTI2MDYyOTExNTcxN1owGQIIAzQNKMYpOBsXDTI1MTAwNzEyMTAyNVowGQII
EfMNg6J5K3wXDTI2MDUxMTEyMDMyN1owGQIIIU/n2JF2+3MXDTI2MDUxODA2MDYx
NVowGQIIFQNENN9WUfMXDTI2MDQwNzE0MDAyMlowGQIIY9pnje/3WZAXDTI1MTAx
MDE1NTUyNlowGQIIcsA/9oSy8aMXDTI1MTEyNDA5MjI0MVowGQIIChL5tS0PkiwX
DTI2MDUwNTA3NTAyMVowGQIIUIgq5xBKhWIXDTI2MDEwNTA4NDcwMlowGQIIJPwR
OLdENO4XDTI2MDkwMzE0MDYyNVowGQIIdepPNvs6g98XDTI2MDkxNTA2NDkyOFow
GQIIfieK/LJt8AEXDTI1MTAyMTA4MjEzMVowGQIIVzBSR0ukBpwXDTI2MTAwMjA4
MjQ0MlowGQIIZ9YSiFi3cu4XDTI2MDcwODA5MTMyMlowGQIIHiaiVUPFDsEXDTI1
MTIxMDA5NDMzNlowGQIII1oP5Y8l2dQXDTI2MDcyMDE5MTEwNVowGQIIWvB++OKF
j10XDTI1MTExNjA5NTUzM1owGQIIL+WkH6xWigMXDTI1MTExMzA3Mzc1N1owGQII
V5PIi1ZKXToXDTI2MDgzMDEyMjY0NFowGQIIJBPSP3mmzdoXDTI2MDEyODEyMDU1
M1owGQIIBoDh/2IUwekXDTI1MTAwODEyMTg0OFowGQIIJm0LoJ/sROoXDTI1MTEw
NjEwNTcyMVowGQIIYk5Rp+sjneYXDTI1MTAxNTEwMjAxNlowGQIIFbGHEEin5gsX
DTI1MTAyMDEyNDMwNVowGQIINFxmpvf9uvcXDTI2MDgyODA3MTcxNFowGQIICHPV
WIGIzSAXDTI2MDIxMjE5MTcwNVowGQIIKgqZH/08S7YXDTI2MDYwODEyMzcxNVow
GQIIMdxioTVehjcXDTI2MDkyOTIwMDQ0MFowGQIIJhvqUPFve9oXDTI1MTIwODEw
NDIyNFowGQIIOoORuebTtoIXDTI2MDExNTA2Mzc1NlowGQIIQVFDkFsxixsXDTI1
MTAxNzEzMDMzOFowGQIIe6XyIg4kQvQXDTI1MTAwNjEyMDY1NVowGQIIR8l9MlTb
l8QXDTI2MDIwMzEwMTkwOVowGQIIQ1dbYpVf80YXDTI1MTEyNDEwNTg0MFowGQII
VQaTTVNaI0sXDTI2MDkwODEwMjY1M1owGQIIF0SXS58bT6MXDTI2MDQxMjA5MTg0
MVowGQIICewuBOmmrTkXDTI2MDYyNTE1MjUyNlowGQIIPwH9hRRTHGkXDTI2MDIy
MDA3Mjk0OFowGQIIYX8M+IhEwecXDTI2MDcxNzEzMDMzMFowGQIITnEpmqbAiVoX
DTI1MTEyNDA5MzgwNlowGQIIaXKrPZxiyzIXDTI1MTIwMjExNDI0MFowGQIISMLv
5/HdOaYXDTI2MDUxNDA5MjgxNlowGQIINUnpr0mtGf0XDTI2MDkyOTEyNDEwNVow
GQIIM/9DyAgpaW8XDTI2MDUyNjEwMjE1NFowGQIICMhXhunT/L4XDTI2MDMyMDA3
NDYxMVowGQIIAq0/Sx4VsaQXDTI1MTAxNzEzMDUzOFowGQIIKnAiiKgQxjIXDTI1
MTEyNjE5MjU0OFowGQIII5dyjkClMl8XDTI2MDQzMDA5MjEwMVowGQIIF+nqKLg9
46QXDTI1MTAwODEwNDM0OVowGQIISjEr35VqGuEXDTI2MDQwODEzMjUwN1owGQII
fAhULLqErhcXDTI2MDUyMDA1MTYwNVowGQIIO5Jo7pem3Q4XDTI1MTAxNDEwMDAz
OFowGQIICDq9lZHqOzEXDTI2MDYxNTA2MzUwNFowGQIIDCUOwLwkaUoXDTI1MTEy
NzEwMjc0NlowGQIIfKxiawqtmb0XDTI2MDUxMjEwNTIwM1owGQIIDhHgV0VpJrUX
DTI2MDkyMjE4NTc1MFowGQIIMpvCr17+/+sXDTI2MDMwMjA3MjkzOVowGQIIAju3
lBGAW5oXDTI2MDMwMzExMTgxM1owGQIIPIDp2Q+/X5UXDTI2MDkwOTA1MzAwMVow
GQIIXaQU/3tt8lsXDTI2MDQwODEzMjQxOFowGQIIN9p2LMvinVsXDTI2MDIxNzEy
MDgxNVowGQIIJqdWkZ/LQBwXDTI2MDkwNzE3NTY1MFowGQIIHsYIyInWvQ4XDTI2
MDQwNzA2MjExNFowGQIIIjIBiqzq3EEXDTI2MDgyODA3MDkzOFowGQIIS5AoYpCE
HlgXDTI2MDYyMjA2Mjg0NVowGQIIBFZEwHfAMfQXDTI1MTIyMjEzMDc0NVowGQII
H3WFAgIY0ccXDTI2MDYwMjA3MzIzMlowGQIICDrAXCb6Sk4XDTI1MTAwMjE5MjEy
MFowGQIICz3QKkLfm94XDTI2MDkwMTE2MzQ0MVowGQIIXaZvBFfd2o8XDTI2MDYw
NTA4NTI1M1owGQIIOBX2e14+XB8XDTI2MDMyNDA4MzEyMVowGQIICN+4q7Ids2wX
DTI2MDEyNzA4MDUxN1owGQIIF2P1MyHmx1AXDTI1MTAxNDEwMTE1MFowGQIIMYFq
igt7RGwXDTI2MDUwNTA3MzQzMFowGQIIOrdl8wsUC2QXDTI2MDYwNTA4NTMzOFow
GQIILFeZfAqZ8tcXDTI1MTAwMzE5Mjg1NVowGQIIT/BwMpYlRrUXDTI1MTEyODEx
MTkxMlowGQIIDA3wK+KyvLIXDTI1MTAyMzA5MTM0MVowGQIIe+f8p1lmFbYXDTI2
MDgwNDEwMTE0M1owGQIID0Dv1PcLdgYXDTI2MDEwNzEzNTEyNVowGQIIeJYpUVVf
eucXDTI2MDIxNjExMzQxMFowGQIIf+bc2kQd2E4XDTI2MDYyOTA5Mzg0MFowGQII
JkJ2C4Jc8MwXDTI2MDYxMTExNDMyM1owGQIIcVgdw0yfWVgXDTI2MDIxODEwMjYy
NVowGQIIDSPges7W4fYXDTI2MDQwODEzMzMzMFowGQIIJfSYiD+gEQ0XDTI1MTAx
NTE0MjMwNlowGQIIIFQYctIx5v0XDTI1MTAxMzE4MDU0MVowGQIILOysJ8mMgEkX
DTI2MDgyMTEzNDc1OVowGQIIFNXghew2E4kXDTI2MDkxNTEzMzA0MlowGQIIMXEi
FsZRp+gXDTI1MTEyMTExNDEzNlowGQIIJ/Ohmzp/1RAXDTI2MDUxMTExNTMzMVow
GQIIHqkOq3IIUjwXDTI1MTAxOTE4MjQxNFowGQIICC57uK53vpUXDTI2MDQzMDA3
MjEyOVowGQIIUriOiPI7brIXDTI2MDkwODEwMjY0M1owGQIIJj8YeRYbJ8sXDTI1
MTIwMTE1MTYyMlowGQIIUTnE3mjq0JAXDTI2MDMxMTE0MjkzOVowGQIIaWtEWdqP
oSUXDTI1MTAwNjEyMzkwN1owGQIIKRrO+Rdtz2wXDTI1MTEwNDA3NTQ1MVowGQII
aqVHEVweOioXDTI1MTIxOTE0MTUzN1owGQIIKvhJaikszZAXDTI1MTAyOTA5Mjc1
M1owGQIIWvHgJlsly3cXDTI2MDUyNzE2NDYyMVowGQIIeGn+quSTe/8XDTI2MDcw
MTA3NDU1OFowGQIIfJzwjfsA564XDTI2MDcwOTA3NDAyMFowGQIIDiNdsncdIucX
DTI2MDYyMjE2NTQxMVowGQIIO7Z51f5KA4EXDTI2MDIxODA3MDUyMlowGQIIJf7g
fEzNKGAXDTI2MDUyMTA2NTczOVowGQIIHWIQ1PKmJX8XDTI1MTEwMjEwNTU0NVow
GQIIbUPAx+hYs4YXDTI2MDYxOTEzNTkyMlowGQIIcxCrjzdNOrEXDTI2MDcxMzEy
MTA0OVowGQIIEaDZoqb9FwgXDTI2MDUwNjA1MzUwMlowGQIIHZvS79h/NjsXDTI1
MTIwMjExMjU0MVowGQIIF509TpI3YtYXDTI1MTAxNTExNTAwNlowGQIIT0fITGJb
2y4XDTI1MTIwMzIwMzEyMFowGQIIZdUz8joqRaUXDTI2MDUyNzE4NTU0MVowGQII
YqAK5gXV4HoXDTI2MDcwNjE0MDcyNlowGQIIc0Y8ScuuFnkXDTI2MTAwNTA3MDIw
NlowGQIId1PxAXNaNP4XDTI2MDczMTA2NTcyMFowGQIIWtOmzd6TtmcXDTI2MDky
OTEzMTk1MFowGQIIJZvXfQk735YXDTI2MDkwMjA4MjcyMVowGQIIUIOvDtJU1EsX
DTI1MTIxNTIwMDE1OVowGQIIEf94P9BJ9t0XDTI2MDUyOTE1MTczOVowGQIIKf4w
R6Zi7zoXDTI2MDUxODA2MTM1M1owGQIIWXZCBL6+pdQXDTI2MDkxNjEwNDMwNFow
GQIIGoqYNwadV1AXDTI2MDgwMzA3MTUxOFowGQIIXg/hSqYdW7MXDTI2MDcyNzE5
NDIyM1owGQIIAw3RjkFZXGQXDTI2MDgzMTEyMjEyNVowGQIIAoEHWCIBGMQXDTI1
MTExNjEwMzQxNVowGQIIHDecbnOolr4XDTI1MTAxMzE4MDYzMlowGQIIMenjZOib
oNYXDTI1MTAyMDEwNDU1OFowGQIIIofwKKiA7PkXDTI2MDcyMzE0MjkyMlowGQII
C5Zs+eVmybcXDTI1MTIwMzIwMzIwM1owGQIINDo7QIrWSasXDTI2MDEwNzE3Mjgz
M1owGQIIZTuIj/XyoSMXDTI1MTAwMzE3MzExMFowGQIICp+OZ42EQlQXDTI2MDUy
NTA4NTE0MVowGQIIEAgP/rBzX70XDTI2MDkwNzEyMzU1OFowGQIIO5FuhGQDXhIX
DTI2MDcyNzIxNDExNVowGQIIaG/atHNa4XwXDTI2MDgyNDA5MjQwNVowGQIIAz2Y
JX4o2/cXDTI1MTAxNzEzMDQyNlowGQIIQ7Lm/pDJi6oXDTI2MDQyMjAwMzMzOFow
GQIITsttM/M7Wm0XDTI1MTEyMjAyMjg1MFowGQIIYaLHAWjfw6UXDTI1MTEyNzA4
NTMzNVowGQIIJQQmG3y7XQkXDTI1MTEwNzEzMjIzOFowGQIIPfNRQmx8pQMXDTI1
MTEwNjIxNDI0OFowGQIIDwU7bDEsDTwXDTI2MDYxNTEwMjIzNlowGQIIcHmCzh6K
LBcXDTI2MDcxMDA4MDAyOFowGQIIAjbty4b3dC0XDTI1MTIxNzIyMzIzN1owGQII
GIJhCvC8vyAXDTI2MDEyMDEzMzgxNlowGQIIDHBUM+MTvYoXDTI2MDIxNjExMzky
OFowGQIIfWUVsXT6Hg0XDTI1MTEyNzA5MjczOFowGQIIRPDVeldIuaoXDTI1MTAy
MzE2NTYxOFowGQIINz1uhwu5YJUXDTI1MTExMTA3NTEwM1owGQIIEJ3rriTZkb8X
DTI2MDYxMTA2MzUzMVowGQIIBTznbZIbRlMXDTI2MDIxNjExMjYzOVowGQIIPagq
2PjakYwXDTI2MDkxNTA2NTEwNFowGQIIa+FgHerm4OUXDTI1MTEwNTE2MDU1M1ow
GQIISN+7oBf9vewXDTI2MDcyMzE1MzUzM1owGQIIXLX1jnsLE3UXDTI2MDMyNDE2
MTc0OVowGQIIMr7rejBNLDIXDTI1MTExOTIxNDMzM1owGQIIDz3I6d3bGUMXDTI2
MDQwNzA3MjIzN1owGQIIcTuYpxJBFB4XDTI2MDYxODEwMjEwM1owGQIIBMHU2Ko9
BFkXDTI1MTIwMTEzMzQxMFowGQIICC27XX0Wt8kXDTI2MDIxNjExMzgyM1owGQII
B4uz1azIUP8XDTI2MDYyMjExNTIwM1owGQIILJPWhJFnnoMXDTI2MDEyMDEzMTI1
NVowGQIIfKXkjacqUUsXDTI2MDExMjIyMTQwNFowGQIIWPS4HpRvqbAXDTI1MTEy
NjA3NTczOFowGQIIPC3/T3HH1wsXDTI1MTAyOTE0MjcwOVowGQIIMUiNWSoAQQUX
DTI1MTEwNDE1MjEzNFowGQIIOYgtJBa781EXDTI1MTIxNTIwMTkwNVowGQIIOJ1q
lfI0LHEXDTI2MDgwNzA4NTUxM1owGQIIXXq99FZW1LQXDTI2MDkwMjA4MzMyM1ow
GQIIKWMCH/ST5o4XDTI1MTAxOTE5MzYzMlowGQIIJEAhg56jt3UXDTI2MDYyODEy
MDM0OFowGQIIAXqYKxpnuQkXDTI2MDUyNjA3MDk1OVowGQIIVFgu3Mkb1u4XDTI2
MDQwOTEzNDEwNFowGQIIXqV+TMawcKYXDTI2MDYyOTE1NDI0M1owGQIIVYQxxZkv
1QYXDTI2MDkwNjE4NTY0N1owGQIIBd5VPxN4OBoXDTI2MDIyNDE0NTExNFowGQII
RLeFdPjDIXsXDTI2MDkxODA2NTIwNFowGQIIEOGGPdufvEYXDTI1MTEyMTA3MDkw
MVowGQIIRXwBTXN2qCUXDTI1MTAyMDA2NDM0MlowGQIIZH4V1WQhVZ4XDTI2MDEy
ODEyMDcyN1owGQIISaIxfVkLyZwXDTI2MDYxMTEzNTg0M1owGQIIC+vrr179GvQX
DTI2MDMwMjEzMTYyN1owGQIIHcooYDhiwg8XDTI2MDcwODEyMzc1NFowGQIIXPgO
1HmiSpkXDTI2MDQyNDEyMjY1MlowGQIIY4R7/Ekn5icXDTI1MTEwNTEyMTUyNVow
GQIIH5v/d93xrRsXDTI1MTAyMDEwMzAzNFowGQIIelGp2TRbOuEXDTI2MDkxODEx
MDkzOVowGQIIWKSvQc1n8QYXDTI2MDgwMzA3MDc1N1owGQIITbE23PsSk5sXDTI2
MDExOTE0NDExMFowGQIIBiqRK3nPFz4XDTI1MTEwNDE0MjY1NFowGQIIL7k5jXdS
OZkXDTI2MDUxOTA5NDY1NVowGQIISwRIoQccT5gXDTI1MTAwMTEzMTk1NFowGQII
O+0td/KaNkMXDTI2MDQxNTExMDEwNlowGQIIdhWgkhkuiycXDTI2MDUyNTA5NTkz
MlowGQIIKraDl0ZldrQXDTI1MTAwODEyMjQ0OFowGQIIJxE9bkjeCksXDTI2MDYx
NTEyMTM1OFowGQIIFva6DRqvZlcXDTI2MDYyMjEzNTUzOVowGQIIdG7nw0wvSPYX
DTI1MTEyNzA4NTYyNlowGQIIN1mH3g49lsgXDTI2MDUyNjEzNDg0M1owGQIIWOLd
x6gv2JIXDTI2MDEwNTA3MzU1MVowGQIIKXVDQs5LNZcXDTI2MDkxMDA4MTExOVow
GQIIIgd6b+1OVBoXDTI2MDQyOTEzMTYyNlowGQIIYADlz2qkbywXDTI1MTEwNTE1
MDg0NVowGQIIaW/7YSEuYiMXDTI2MDgyMDExNTQzNFqgMDAuMB8GA1UdIwQYMBaA
FMEeu6Q/DhPfgZu+TGKy2bq+1ba7MAsGA1UdFAQEAgIkADANBgkqhkiG9w0BAQsF
AAOCAQEAJ939YsIiiypiNUwsRAcbVyVvy1lVjr6or+uEPqNpPdaXvjdpVD4fm/In
YExEOKSwDfida2HR/RijCTcWEUos+Hw83RAFi8KiPm4GZUmgW0aQ+DHpqX/AFpFl
ytDRakmEneVMmAzAUcNtn2NY0mbsPGmhyAV6Cjp6cqKapPuZEV53hMm9X3Ev64LR
O+UvI/wyUONgSPBRe2yaWFLxmBCTUYzJuoErER0Im9OPqPLe/8JcNjtgjxiN9XFU
fEEkeGxEkRfItI1vBuLsepN5M3fSRPjikBIKkv7J0rPNeqAEj4N+BH0E8EWC3uwX
l9pPDi563TDD9Flu2Je87xghdsMVfw==
-----END X509 CRL-----
-----BEGIN X509 CRL-----
MIICSTCCATECAQEwDQYJKoZIhvcNAQELBQAwXDESMBAGCgmSJomT8ixkARkWAmN6
MRkwFwYKCZImiZPyLGQBGRYJY2VzbmV0LWNhMRIwEAYDVQQKEwlDRVNORVQgQ0Ex
FzAVBgNVBAMTDkNFU05FVCBDQSBSb290Fw0yNjAzMTExMTAyMTNaFw0yNzAzMTIx
MTAyMTNaoIGgMIGdMIGOBgNVHSMEgYYwgYOAFJ5BMOPD1U6Mg46jPMl/o20TXYQl
oWCkXjBcMRIwEAYKCZImiZPyLGQBGRYCY3oxGTAXBgoJkiaJk/IsZAEZFgljZXNu
ZXQtY2ExEjAQBgNVBAoTCUNFU05FVCBDQTEXMBUGA1UEAxMOQ0VTTkVUIENBIFJv
b3SCCQCH9/oAc2kUTzAKBgNVHRQEAwIBGjANBgkqhkiG9w0BAQsFAAOCAQEAllsy
RAg1qH/efzMXW4ZE1+1lB8GOVayA/ZoqJrXg6eTy0aruW64V/V7MDCAfdTPOlUHE
s1NkgBgJYMeXWHd8tkTAiJv+50wbHwsJECr0a2KZ5WBmdOYzhWQHaM1AWGYPtGoj
uU53UL0JOoHi/Gm4tlHfGSneWbmQmBDzrN/C/lZ+QTxY7ZJK02uLfbco60ktVoYA
N7g8SghtlzwwICsM06N6QjWo0OK61HVWhDBWeyByEK9fk5ewGIEgV3wJhwZeLJT0
7e2iOwIwo8+SNc77FS+aaFOU+Fgd89r1MCnuy9/sWKc9Rpmm4cSd11dLZhlRXGfR
GXKb2wujaj8Ha0iRGQ==
-----END X509 CRL-----
@@ -0,0 +1,18 @@
-----BEGIN X509 CRL-----
MIIC8DCB2QIBATANBgkqhkiG9w0BAQ0FADCBlTERMA8GA1UEChMIRnJlZSBUU0Ex
EDAOBgNVBAsTB1Jvb3QgQ0ExGDAWBgNVBAMTD3d3dy5mcmVldHNhLm9yZzEiMCAG
CSqGSIb3DQEJARYTYnVzaWxlemFzQGdtYWlsLmNvbTESMBAGA1UEBxMJV3Vlcnpi
dXJnMQ8wDQYDVQQIEwZCYXllcm4xCzAJBgNVBAYTAkRFFw0yNjA5MTgxMDMwNTVa
Fw0yNzA5MTgxMDMwNTVaoA8wDTALBgNVHRQEBAICEAAwDQYJKoZIhvcNAQENBQAD
ggIBABHK9i209Jx6iSu0+YIgeZLo1X0I8CLw5pnWopQIwd40PBbjLqvY3KjFUj8b
AAHzYqrmVDFvBA4VXJB+uzf7L8JeveipwHCnoGERwczEI4gNWyYENeUW9hATDrr6
BsIrueXmgqDZjhAW0impc8vaPxLLtNWJIGnl2KR5aaYqKyWqdlR9zBzvp6qNAPJN
xTxLHA833ddFq8LVXdYk87ACQEymof/wxBF9aTA/qYyEptFIAWgeRcoWxigA+2IB
MjVfGGB2dop5Oo9xe6ZUu6wOJmJS+nMEDvyzMeoGLU9QtEZOo+W6cF4/+si1DH0B
VwU2JgHOc7VKZwOWE9mlOrL9+b/1IHSghg7RsQ3+HE0Puo/PGDAKjJcOa6TOvhSo
eRMnOTV/axmFsv3/tvrsymVJ/phoYoHZaXkaoGugNwDzVMTTVx6dSpbd/n8JFDCh
KbOs0aNB1ZBnWMw5HwUxV+dGXjyZOib+M0W2SdMGrXycxG70M7Vg/ZWYjQboE6Sp
o1hjUCONq3QdU3L5luy9vUatp6cgSj58w20CQRkaibW5S/8fjfYCsePG7hRHO5ht
YX5UU8n61kkgq5n8w3VF9G3khCEmiK+0/5YXDmwQ71UM0OZkYaKBgaQt8+HC2X12
dUGrgUfytqHQtKTZsKbhpRSGC1oj1TGIyENG9lh7307RsARx
-----END X509 CRL-----
File diff suppressed because it is too large. Load diff
@@ -2,17 +2,17 @@
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
-----END X509 CRL----- -----END X509 CRL-----
@@ -1,18 +1,46 @@
-----BEGIN X509 CRL----- -----BEGIN X509 CRL-----
MIIC5jCCAc4CAQEwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNV MIIDVjCCAj4CAQEwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNV
BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G
A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQRcN A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQRcN
MjUwMjEyMDUyMjQ1WhcNMjUwMjE5MDUyMjQ1WjCB9TAhAhAL2v0LKRQzmpYSZqw1 MjYxMDA0MjMwMDExWhcNMjYxMDExMjMwMDExWjCB9TAhAhAL2v0LKRQzmpYSZqw1
OkdEFw0xNjEwMjQxNzQyNDlaMCECEAH40oMtKRkZcbNQw9u8pQAXDTE2MTExMTE1 OkdEFw0xNjEwMjQxNzQyNDlaMCECEAH40oMtKRkZcbNQw9u8pQAXDTE2MTExMTE1
MjEzNFowIQIQClKwbEb16yWgi9U/3Ht4hhcNMTgwOTAzMTIxMTQyWjAhAhAFlx7K MjEzNFowIQIQClKwbEb16yWgi9U/3Ht4hhcNMTgwOTAzMTIxMTQyWjAhAhAFlx7K
SlmJinvPTLfjd5doFw0xOTA5MzAwODE2MjRaMCECEAxFkEkmQLBOlEh/jEwCeJAX SlmJinvPTLfjd5doFw0xOTA5MzAwODE2MjRaMCECEAxFkEkmQLBOlEh/jEwCeJAX
DTIxMDIwOTIyMzk0MlowIQIQBMvnUVSd49EL7YN0yV7iRBcNMjEwMjA5MjMyMzM3 DTIxMDIwOTIyMzk0MlowIQIQBMvnUVSd49EL7YN0yV7iRBcNMjEwMjA5MjMyMzM3
WjAhAhALmUrhw5aLANVesgZ0jpseFw0yMTAyMDkyMzI0MjNaoDAwLjAfBgNVHSME WjAhAhALmUrhw5aLANVesgZ0jpseFw0yMTAyMDkyMzI0MjNaoIGfMIGcMB8GA1Ud
GDAWgBT0tuEgHf4prtLkYaWyoiWyyBc1bjALBgNVHRQEBAICDO8wDQYJKoZIhvcN IwQYMBaAFPS24SAd/imu0uRhpbKiJbLIFzVuMAsGA1UdFAQEAgIPRjBsBgNVHRwB
AQELBQADggEBALr4VopJYkMfQ97HiyqytcWRY/vgyU/LxOwlH0/1DBSeeObQB0Nj Af8EYjBgoF6gXIYsaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl
uF7vcF2bhbpnxba7gvzOPryudwtbqquf2cl3CJG6MC2D8Nk1XzntDnpxCjVSfsAr ZC10cy5jcmyGLGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQt
158zAWPevyiuj3yzFz04mYALt/ZmOJMTF0vyKN8cg5bwfLu3itV6b6vhpuloIhRc dHMuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAXHlmJHU53c/CpqMKhcL+30p2c+ma2
Hmsbgr3BtCVHkf4vJWq/qKDEMcOhSrJ6wxGCzVyphenewSIbVcogj19cRZDFPWOC H8is0oPrXjXHPbKpbWuNQaD2/OPsS2wWhrYbFJ/PYB70TXca/+I8NKM+pYADPhbF
3sAy/GY3Rz0qK30tDvNbE1uum8gy5ijXFmepJ/lEetRCvrIsxTsXJOj0tqVZfIIQ x3ZdiOF7iSxAuR/7SjRhLFlSF9IrSsCMEh+jCPJDFPsxOi1aVpyu1pHsxHeDMZ/4
E1YWUZ57TiBBrdS+dTgmRxkN/zaAfYVAIck= XC8kwWgWqu4A9UWezT1w3xLd+OzLkOY6UMg8SjL1875x9JJbgBpv5F6t2itY7FHx
2afHEC9t9Ak3jY3ocymoPtDOk7urJCD8NkQZ5PEQ8hH1/TiHEkAMV2LIpnpPf+Zp
AZodHfxORZNwySgGRfJabS5rtrBG2nvd9/H+Y6d7TjG5ASbD6hefa3OY
-----END X509 CRL-----
-----BEGIN X509 CRL-----
MIIEYjCCA0oCAQEwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVVMxFTATBgNV
BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIG
A1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBFw0yNjEwMDEyMzQ3MjBa
Fw0yNjEwMjIyMzQ3MjBaMIICfTAvAhAHOSbHsl+5YpAf8d9FUCGIFw0yNDA4MTMx
OTE4NTZaMAwwCgYDVR0VBAMKAQQwLwIQBxVWH+V/ML4XiYkjwzpEUBcNMjYwOTE4
MDAyMzI1WjAMMAoGA1UdFQQDCgEEMC8CEAw218hurWfj9/gddWDyLVMXDTE4MTAw
OTE1MDAxN1owDDAKBgNVHRUEAwoBBTAvAhAGgvsfgXd2pXmRLD7ZEO/xFw0yMDA4
MTIxMjMzMDlaMAwwCgYDVR0VBAMKAQUwLwIQC3hRTN/GgFLrRHzkC8KklhcNMjIx
MDEzMDk1ODA3WjAMMAoGA1UdFQQDCgEFMC8CEAsqhekMa2Uu2MCOV/mEbMQXDTIy
MTAxMzEwMDAzNFowDDAKBgNVHRUEAwoBBTAvAhAC8dXyHqirKBCgl3AVPcLQFw0y
MjEwMTMxMDAzMTFaMAwwCgYDVR0VBAMKAQUwLwIQCkE6FgBN+nIkANMmgOQkiRcN
MTgxMDI1MTYxMDMyWjAMMAoGA1UdFQQDCgEFMC8CEAI8e/7WGY6RbeXQQciaPSUX
DTE4MTAyNTE2MDkzM1owDDAKBgNVHRUEAwoBBTAvAhAOn6HUxFmz0BodonYrg1Cc
Fw0yMjEwMTMxMDA1MTlaMAwwCgYDVR0VBAMKAQUwLwIQBkoduoMprQURTuDY6pi+
fBcNMjAwNzIxMjAwMDAwWjAMMAoGA1UdFQQDCgEFMC8CEAER6Rdjkvpnl9JRx+xh
VCoXDTIwMTIyODE1MzY0MlowDDAKBgNVHRUEAwoBBTAvAhAMVaXo089Ps1nwCyty
L+75Fw0yMjEwMTMxMDEzMDJaMAwwCgYDVR0VBAMKAQWgMDAuMB8GA1UdIwQYMBaA
FEXroq/0ksuCMS1Ri6enIZ3zbcgPMAsGA1UdFAQEAgIDXDANBgkqhkiG9w0BAQsF
AAOCAQEAbp95b7N5u7stn7jSth9LbqIP0i2OeBZETdcWnfcG+ck99Mjm0eYMMjmt
SaWIcTGTfK9rQ6xwgMG3yVKEOPjPq2XQ5mQlXj4isuCzp3KmVCUxs9du12QlSHJ5
ObqWzprVjhZuYUyozh07ohuU4YLZHmRByZeih+TlRqzt5A+bQqCDZ+aLCvat/Clg
zlSAAF1dCRniukekB5JtSc6h6YfdPXZC0vCqMi/CyxQEo83hfN1dVOEBos96zek4
5wu0cTk8Cq1isfCBFOMxulcXLzYH7HZ3fC24hLrM8ijpNZjLjuUBC5euozDU4M0T
sDO7suNrXqSB8DKcPYfUy0caMml+oQ==
-----END X509 CRL----- -----END X509 CRL-----
+12 -12
View File
@@ -13,19 +13,19 @@ By using this post-commit hook in a repository and thereby adding secure timesta
These hooks were written for git 2.30 and newer (they may or may not work with older versions of git). If you do not use Git Bash, you need bash-4.3 or newer. These hooks were written for git 2.30 and newer (they may or may not work with older versions of git). If you do not use Git Bash, you need bash-4.3 or newer.
0. (optional, but recommended) If you're ceating a new repository, it is strongly recommended to use SHA256 hashes (git uses SHA1 by default at the time of writing) by initializing the repository using `git init --object-format=sha256` (Note: If you want to use a public hosting server such as github for your repository, you should check whether they already support SHA256 repositories). For more information, see https://git-scm.com/docs/hash-function-transition/ 0. (optional, but recommended) If you're creating a new repository, it is strongly recommended to use SHA256 hashes (git uses SHA1 by default at the time of writing) by initializing the repository using `git init --object-format=sha256` (Note: If you want to use a public hosting server such as GitHub for your repository, you should check whether they already support SHA256 repositories). For more information, see https://git-scm.com/docs/hash-function-transition/
1. Copy the four bash scripts in the [hooks](hooks/) folder of this project into the .git/hooks folder of the project you want to timestamp. 1. Copy the four bash scripts in the [hooks](hooks/) folder of this project into the .git/hooks folder of the project you want to timestamp.
2. Configure the TSA url you want to use (in this example https://freetsa.org/tsr) using 2. Configure the TSA url you want to use (in this example https://freetsa.org/tsr) using
`git config --local timestamping.tsa0.url https://freetsa.org/tsr` `git config --local timestamping.tsa0.url https://freetsa.org/tsr`
3. You must declare that you trust this TSA by copying the root certificate of that TSA's trust chain into the .git/hooks/trustanchors folder (create it if it doesn't exist yet). The certificate MUST be in PEM format and the filename MUST be "subject_hash.0" where`subject_hash` is what openssl returns for the `--subject_hash` argument for x509 cetificates (https://www.openssl.org/docs/man1.1.1/man1/x509.html). 3. You must declare that you trust this TSA by copying the root certificate of that TSA's trust chain into the .git/hooks/trustanchors folder (create it if it doesn't exist yet). The certificate MUST be in PEM format and the filename MUST be "subject_hash.0" where`subject_hash` is what openssl returns for the `--subject_hash` argument for x509 certificates (https://www.openssl.org/docs/man1.1.1/man1/x509.html).
**For your convenience, there is the [hooks/trust.sh](hooks/trust.sh) script which will do this for you.** To use it, simply run `.git/hooks/trust.sh https://freetsa.org/tsr` from your Git-Bash and confirm adding the certificate (Note: The certificates stored in .git/hooks/trustanchors are ONLY used to validate timestamp tokens, no other trust is established). **For your convenience, there is the [hooks/trust.sh](hooks/trust.sh) script which will do this for you.** To use it, simply run `.git/hooks/trust.sh https://freetsa.org/tsr` from your Git-Bash and confirm adding the certificate (Note: The certificates stored in .git/hooks/trustanchors are ONLY used to validate timestamp tokens, no other trust is established).
4. (optional) If you want to use multiple TSAs, just set additional urls for tsa1, tsa2 and so on. Make sure that they are all defined consecutively, for example, if you have a url defined for tsa0 and for tsa2, but not for tsa1, then tsa2 will be ignored. Since timestamp tokens will become forever invalid should a TSA's private key leak, using at least two trusted TSAs is a good strategy to protect against this unlikely eventuality (see chapter 4. "Security Considerations" of RFC3161 specification). 4. (optional) If you want to use multiple TSAs, just set additional URLs for tsa1, tsa2 and so on. Make sure that they are all defined consecutively, for example, if you have a url defined for tsa0 and for tsa2, but not for tsa1, then tsa2 will be ignored. Since timestamp tokens will become forever invalid should a TSA's private key leak, using at least two trusted TSAs is a good strategy to protect against this unlikely eventuality (see chapter 4. "Security Considerations" of RFC3161 specification).
5. (optional) By default, a commit will fail if a timestamp token cannot be retrieved. If you want to make timestamping optional for a certain tsa, you can set 5. (optional) By default, a commit will fail if a timestamp token cannot be retrieved. If you want to make timestamping optional for a certain tsa, you can set
`git config --local --type=bool timestamping.tsa0.optional true`. `git config --local --type=bool timestamping.tsa0.optional true`.
If `optional` is set to true and a timestamping token cannot be retrieved, you will receive a warning but the commit will be created nevertheless. If `optional` is set to true and a timestamping token cannot be retrieved, you will receive a warning but the commit will be created nevertheless.
7. (optional) You might want to add this README.md and the [docs](docs/) folder of this repository to your repository as well, so that documentation of the timestamps is guaranteed to be available if the timestamps should be evaluated many years in the future. 7. (optional) You might want to add this README.md and the [docs](docs/) folder of this repository to your repository as well, so that documentation of the timestamps is guaranteed to be available if the timestamps should be evaluated many years in the future.
From now on, every `git commit` will automatically tigger an additional commit that securely timestamps it. From now on, every `git commit` will automatically trigger an additional commit that securely timestamps it.
# Implementation design # Implementation design
@@ -39,7 +39,7 @@ By embedding the timestamps in the commit history, they form a hash-chain and th
# Merkle-Tree layout # Merkle-Tree layout
The design leverages git's Merkle-Tree layout and embeds the timestmaps in the commit history, making them form a hash-chain that prevents later changes without being noticed: The design leverages git's Merkle-Tree layout and embeds the timestamps in the commit history, making them form a hash-chain that prevents later changes without being noticed:
![Merkle-Tree](./docs/schematic.png) ![Merkle-Tree](./docs/schematic.png)
@@ -59,7 +59,7 @@ Before writing this software, I evaluated alternatives available at the time of
This script allows to manually create timestamps for revisions and store them in git-notes. This was not sufficient for me since having timestamps stored in git-notes makes them "cryptographically dangling" in the sense that the timestamped repository does not depend on them (meaning that they can be "lost" without being noticed). This may be the preferred solution for someone who just wants to be *able* to prove the time the code was created if he so desires, without creating a repository which is *tamperproof* (and without the benefits discussed further down). Also, the script does not take CRLs into consideration for validation. This script allows to manually create timestamps for revisions and store them in git-notes. This was not sufficient for me since having timestamps stored in git-notes makes them "cryptographically dangling" in the sense that the timestamped repository does not depend on them (meaning that they can be "lost" without being noticed). This may be the preferred solution for someone who just wants to be *able* to prove the time the code was created if he so desires, without creating a repository which is *tamperproof* (and without the benefits discussed further down). Also, the script does not take CRLs into consideration for validation.
- GitLock (https://www.npmjs.com/package/gitlock): - GitLock (https://www.npmjs.com/package/gitlock):
GitLock adds timestamps as tags, which, like git-notes, also won't make the timestamped repository cryptographically depend on the timestamps themselves and thus offers the same advantages/disadvantages as the script above. It also creates a parallel SHA256 hierarchy (which isn't necessary anymore, since git now provides native SHA256 support) and depends on a Node.js application that must be installed and used manually. This solution may be preferred if the same conditions hold as with the first altenative and additionally SHA256 is required but a public git server which does not yet support native SHA256 commit hashes is used. GitLock adds timestamps as tags, which, like git-notes, also won't make the timestamped repository cryptographically depend on the timestamps themselves and thus offers the same advantages/disadvantages as the script above. It also creates a parallel SHA256 hierarchy (which isn't necessary anymore, since git now provides native SHA256 support) and depends on a Node.js application that must be installed and used manually. This solution may be preferred if the same conditions hold as with the first alternative and additionally SHA256 is required but a public git server which does not yet support native SHA256 commit hashes is used.
- There is [this](https://gitlab.cs.fau.de/CSG/git-rfc3161) fork of git: - There is [this](https://gitlab.cs.fau.de/CSG/git-rfc3161) fork of git:
The fork was created as part of a university project to add native support for RFC3161 tokens to git. There is a corresponding discussion in the archived git mailing list (http://git.661346.n2.nabble.com/Adding-RFC-3161-timestamps-to-git-tags-td7650116.html). Since it requires a custom build of git and wasn't adopted by the official repo, I did not further investigate this implementation. The fork was created as part of a university project to add native support for RFC3161 tokens to git. There is a corresponding discussion in the archived git mailing list (http://git.661346.n2.nabble.com/Adding-RFC-3161-timestamps-to-git-tags-td7650116.html). Since it requires a custom build of git and wasn't adopted by the official repo, I did not further investigate this implementation.
@@ -72,14 +72,14 @@ Zeitgitter seems to use a custom timestamping protocol and rely on developers cr
# How are timestamps added to commits # How are timestamps added to commits
For each commit that is being timestamped, an additional *timestamp commit* is created, for which the commit that is being timestamped is the direct parent. The digest hash that is contained in the timestamp token is a hash derived from the commit hash of that parent commit as well as the tree hash of this *timestamp commit*. Since git itself is implemented as a [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree), this hash hence depends on every bit of every commited file as well as the entire commit history, making it impossible to change anything without invalidating the timestamp. The timestamping token (one for each TSA for which a timestamp was retrieved from) is then added in PEM encoding (plus some info about the token in readable form) as a trailer to the commit message of the *timestamp commit*. Chosing this design to add the timestamps has several advantages: For each commit that is being timestamped, an additional *timestamp commit* is created, for which the commit that is being timestamped is the direct parent. The digest hash that is contained in the timestamp token is a hash derived from the commit hash of that parent commit as well as the tree hash of this *timestamp commit*. Since git itself is implemented as a [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree), this hash hence depends on every bit of every commited file as well as the entire commit history, making it impossible to change anything without invalidating the timestamp. The timestamping token (one for each TSA for which a timestamp was retrieved from) is then added in PEM encoding (plus some info about the token in readable form) as a trailer to the commit message of the *timestamp commit*. Choosing this design to add the timestamps has several advantages:
- The commit hash always depends on the entire data of that commit (including the pgp signature that commit is signed with) and its history, meaning that not a single bit of data being committed (or the history it depends on) could be changed without creating a completely different commit hash. - The commit hash always depends on the entire data of that commit (including the pgp signature that commit is signed with) and its history, meaning that not a single bit of data being committed (or the history it depends on) could be changed without creating a completely different commit hash.
- It is most likely the most forward-compatible option. If new commit headers or other commit data will be added to git in the future, they will most likely also be captured by the commit hash. - It is most likely the most forward-compatible option. If new commit headers or other commit data will be added to git in the future, they will most likely also be captured by the commit hash.
- By storing the tokens inside the commit message, which is hashed itself, rather than in git-notes or tags, subsequent commits will *seal* these timestamps, making it impossible to "lose" them, which gives the timestamping of the repository a *non-repudiation* property (https://en.wikipedia.org/wiki/Non-repudiation), meaning it will be impossible to "rewrite history" unnoticed. - By storing the tokens inside the commit message, which is hashed itself, rather than in git-notes or tags, subsequent commits will *seal* these timestamps, making it impossible to "lose" them, which gives the timestamping of the repository a *non-repudiation* property (https://en.wikipedia.org/wiki/Non-repudiation), meaning it will be impossible to "rewrite history" unnoticed.
- Since newer timestamps *seal* older timestamps (i.e. the older timestamps are part of what is being timestamped), this protects old timestamps from becoming invalid in some situations and can extend their validatability arbitrarily into the future (see Long Term Validation below). For example: Say in 2021 all commits are timestamped using a TSA that uses "certificateA" to sign its timestamps. Then in 2022 a TSA is used which uses "certificateB" to sign its timestamps. Then in 2023 the private key of "certificateA" leaks. Normally, if a TSA's private key leaks, all old timestamps become invalid and can't be trusted anymore (because the private key could be used to "backdate" data) - however, since in this case the timestamps of 2021, which are signed with the still trusted "certificateB" *sealed* the older timestamps, these old timestamps can still be considered valid, since they were provably created before the "certificateA" private key leaked. The same applies to old timestamps becoming invalid for example due to the algorithm used for them not being deemed secure anymore or if a CA stops issuing CRL data for the TSA certificate. - Since newer timestamps *seal* older timestamps (i.e. the older timestamps are part of what is being timestamped), this protects old timestamps from becoming invalid in some situations and can extend their validatability arbitrarily into the future (see Long Term Validation below). For example: Say in 2021 all commits are timestamped using a TSA that uses "certificateA" to sign its timestamps. Then in 2022 a TSA is used which uses "certificateB" to sign its timestamps. Then in 2023 the private key of "certificateA" leaks. Normally, if a TSA's private key leaks, all old timestamps become invalid and can't be trusted anymore (because the private key could be used to "backdate" data) - however, since in this case the timestamps of 2021, which are signed with the still trusted "certificateB" *sealed* the older timestamps, these old timestamps can still be considered valid, since they were provably created before the "certificateA" private key leaked. The same applies to old timestamps becoming invalid for example due to the algorithm used for them not being deemed secure anymore or if a CA stops issuing CRL data for the TSA certificate.
An altenative design that was considered but dismissed was to include the timestamps right into the commit message of the commit that is being timestamped (in order to keep the commit history more tidy), in a similar fashion as PGP signatures are added. PGP signatures do this by calculating the commit hash AS-IF the signature was not contained, then sign this hash and then add the signature into the commit header (thereby changing the hash). A similar approach could have been taken with the timestamps, but this would have two serious drawbacks: An alternative design that was considered but dismissed was to include the timestamps right into the commit message of the commit that is being timestamped (in order to keep the commit history more tidy), in a similar fashion as PGP signatures are added. PGP signatures do this by calculating the commit hash AS-IF the signature was not contained, then sign this hash and then add the signature into the commit header (thereby changing the hash). A similar approach could have been taken with the timestamps, but this would have two serious drawbacks:
1. Since PGP signatues are inserted natively AFTER the commit is generated, the timestamp token could therefore not timestamp the signature (instead, the signature would sign the timestamp, which is not useful). 1. Since PGP signatures are inserted natively AFTER the commit is generated, the timestamp token could therefore not timestamp the signature (instead, the signature would sign the timestamp, which is not useful).
2. Validation code would need to compute a commit hash AS-IF the timestamp-token was not contained, but also AS-IF any insertions happening AFTER timestamping were not present (at the time of writing, that's only PGP-Signatures. However, since future versions of git may include other additional headers in a similar fashion, this would break current timestamp validation code). 2. Validation code would need to compute a commit hash AS-IF the timestamp-token was not contained, but also AS-IF any insertions happening AFTER timestamping were not present (at the time of writing, that's only PGP-Signatures. However, since future versions of git may include other additional headers in a similar fashion, this would break current timestamp validation code).
For these reasons, adding timestamps right into the commit that is being timestamped was dismissed, for separate *timestamp commits* are much more likely to be forward compatible with anything git will add to the commit object in the future. For these reasons, adding timestamps right into the commit that is being timestamped was dismissed, for separate *timestamp commits* are much more likely to be forward compatible with anything git will add to the commit object in the future.
@@ -93,7 +93,7 @@ If a token does not pass these tests, it is not added and the commit is either a
This repository uses the post-commit hook itself, so if you check the commit history of this repository, you will see that each commit is followed by a -----TIMESTAMP COMMIT----- that contains one or more timestamp tokens. This repository uses the post-commit hook itself, so if you check the commit history of this repository, you will see that each commit is followed by a -----TIMESTAMP COMMIT----- that contains one or more timestamp tokens.
For example, [this](https://github.com/MrMabulous/GitTrustedTimestamps/commit/58ba3dbd480e3c07dbd14beca02092982f8e9492) *timestamp commit* timestamps [this](https://github.com/MrMabulous/GitTrustedTimestamps/commit/80034aeb7857a910f06429c3580635b4afa40cc0) regular commit, which is its direct parent. You can see that the "Digest" that is timestamped by the token is `d8f311290fb12fbd87c50014b75809150d125272=sha1(version:1,parent:80034aeb7857a910f06429c3580635b4afa40cc0,tree:50c7905ec6a07547e5bdeab38a810c2dc1c5ae44)`, whereas the tree hash and parent hash in the preimage correspond to the parent and tree of this *timestamp commit*. For example, [this](https://github.com/MrMabulous/GitTrustedTimestamps/commit/58ba3dbd480e3c07dbd14beca02092982f8e9492) *timestamp commit* timestamps [this](https://github.com/MrMabulous/GitTrustedTimestamps/commit/80034aeb7857a910f06429c3580635b4afa40cc0) regular commit, which is its direct parent. You can see that the "Digest" that is timestamped by the token is `d8f311290fb12fbd87c50014b75809150d125272=sha1(version:1,parent:80034aeb7857a910f06429c3580635b4afa40cc0,tree:50c7905ec6a07547e5bdeab38a810c2dc1c5ae44)`, whereas the tree hash and parent hash in the preimage correspond to the parent and tree of this *timestamp commit*.
Since github did not support sha256 hashes yet at the time this repository was created, the hashing algorithm used is sha1 (for a repository initialized with `git init --object-format=sha256` the hashing algorithm will be sha256 or other, once git adds support for further algorithms) Since GitHub did not support sha256 hashes yet at the time this repository was created, the hashing algorithm used is sha1 (for a repository initialized with `git init --object-format=sha256` the hashing algorithm will be sha256 or other, once git adds support for further algorithms)
# For how long are timestamps valid? # For how long are timestamps valid?
@@ -101,7 +101,7 @@ Generally, a RFC3161 timestamp can be trusted for as long as
- the private key of the signing certificate or a certificate in its trustchain did not get compromised and - the private key of the signing certificate or a certificate in its trustchain did not get compromised and
- the hashing algorithm used by the timestamp and the signature algorithm used by the signing certificate is still considered secure - the hashing algorithm used by the timestamp and the signature algorithm used by the signing certificate is still considered secure
To be sure of the first point, one must know the current revocation status of the signing certificate. This in turn means that once new CRLs for the certificate that signed the timestamp are not issued anymore, the timestamp shouldn not be trusted anymore, since timestamps could be forged if the private key of the signing certificate leaked. To be sure of the first point, one must know the current revocation status of the signing certificate. This in turn means that once new CRLs for the certificate that signed the timestamp are not issued anymore, the timestamp should not be trusted anymore, since timestamps could be forged if the private key of the signing certificate leaked.
However, if one has a copy of a historic CRL that shows the signature certificate to be valid, and which is timestamped by a timestamp that still can be trusted, then also the compromised timestamp can still be trusted. However, if one has a copy of a historic CRL that shows the signature certificate to be valid, and which is timestamped by a timestamp that still can be trusted, then also the compromised timestamp can still be trusted.
GitTrustedTimestamp enables this extension of the lifetime of timestamps by storing *Long Term Validation* data for previous timestamps with each new timestamp added. GitTrustedTimestamp enables this extension of the lifetime of timestamps by storing *Long Term Validation* data for previous timestamps with each new timestamp added.
@@ -128,7 +128,7 @@ This repository does come however with an [implementation](hooks/validate.sh) th
To perform these checks, the same trusted rootCAs from the `.git/hooks/trustanchors` folder are used. To perform these checks, the same trusted rootCAs from the `.git/hooks/trustanchors` folder are used.
No other checks are performed. In particular, a timestamp-token is considered valid beyond the expiration date of its signing certificate if it hasn't been revoked due to a reason other than those specified in chapter 4.1 of the RFC3161 specification. No other checks are performed. In particular, a timestamp-token is considered valid beyond the expiration date of its signing certificate if it hasn't been revoked due to a reason other than those specified in chapter 4.1 of the RFC3161 specification.
The curent implementation of the validate.sh script also does not consider whether the hashing algorithms used in the timestamp-token or the keylength of the signing certificate are still considered secure, as this depends on what the validating party considers secure. The current implementation of the validate.sh script also does not consider whether the hashing algorithms used in the timestamp-token or the key length of the signing certificate are still considered secure, as this depends on what the validating party considers secure.
The script exits with exit code 0 if all tests passed, and with exit code 1 otherwise. The script exits with exit code 0 if all tests passed, and with exit code 1 otherwise.
+4 -4
View File
@@ -147,8 +147,8 @@ retrieve_crl_for_most_recent_parent_timestamps() {
} }
#get hash of unstamped commit #get hash of unstamped commit
PEARENT_COMMIT_HASH=$(git rev-parse --verify HEAD) PARENT_COMMIT_HASH=$(git rev-parse --verify HEAD)
if ! retrieve_crl_for_most_recent_parent_timestamps "$PEARENT_COMMIT_HASH"; then if ! retrieve_crl_for_most_recent_parent_timestamps "$PARENT_COMMIT_HASH"; then
echo_error "ERROR: Failed to download CRLs for last timestamp commit." echo_error "ERROR: Failed to download CRLs for last timestamp commit."
exit 1 exit 1
fi fi
@@ -172,9 +172,9 @@ for ((i=0;; i++)); do
TREE_HASH=$(git write-tree) TREE_HASH=$(git write-tree)
declare PREIMAGE declare PREIMAGE
get_preimage_from_tree_and_parent "$TREE_HASH" "$PEARENT_COMMIT_HASH" PREIMAGE get_preimage_from_tree_and_parent "$TREE_HASH" "$PARENT_COMMIT_HASH" PREIMAGE
declare NEW_DIGEST_TO_TIMESTAMP declare NEW_DIGEST_TO_TIMESTAMP
compute_digest_from_tree_and_parent "$TREE_HASH" "$PEARENT_COMMIT_HASH" NEW_DIGEST_TO_TIMESTAMP compute_digest_from_tree_and_parent "$TREE_HASH" "$PARENT_COMMIT_HASH" NEW_DIGEST_TO_TIMESTAMP
if [ "$NEW_DIGEST_TO_TIMESTAMP" == "$DIGEST_TO_TIMESTAMP" ];then if [ "$NEW_DIGEST_TO_TIMESTAMP" == "$DIGEST_TO_TIMESTAMP" ];then
#no new LTV data added, no need to re-request token. #no new LTV data added, no need to re-request token.
break break
+26 -20
View File
@@ -17,22 +17,22 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# #
# The interactive user interfaces in modified source and object code versions # The interactive user interfaces in modified source and object code versions
# of this program must display Appropriate Legal Notices, as required under # of this program must display Appropriate Legal Notices, as required under
# Section 5 of the GNU Affero General Public License version 3. In accordance # Section 5 of the GNU Affero General Public License version 3. In accordance
# with Section 7(b) of the GNU Affero General Public License, you must retain # with Section 7(b) of the GNU Affero General Public License, you must retain
# the Info line in every timestamp that is created or manipulated using a # the Info line in every timestamp that is created or manipulated using a
# covered work. # covered work.
# #
# You can be released from the requirements of the license by purchasing # You can be released from the requirements of the license by purchasing
# a commercial license. Buying such a license is mandatory as soon as you # a commercial license. Buying such a license is mandatory as soon as you
# develop commercial activities involving this software without # develop commercial activities involving this software without
# disclosing the source code of your own applications. # disclosing the source code of your own applications.
# These activities include: offering paid services to customers as an ASP, # These activities include: offering paid services to customers as an ASP,
# providing data storage and archival services, shipping this software with a # providing data storage and archival services, shipping this software with a
# closed source product. # closed source product.
# #
# For more information, please contact Mabulous GmbH at this # For more information, please contact Mabulous GmbH at this
# address: info@mabulous.com # address: info@mabulous.com
# #
@@ -271,10 +271,10 @@ get_tsa_cert_id() {
# function to extract hashing algorithm used in the ESSCertID (always sha1) or ESSCertIDv2 # function to extract hashing algorithm used in the ESSCertID (always sha1) or ESSCertIDv2
# param1: path to token in DER encoding # param1: path to token in DER encoding
# param2: OUT variable, the hashing algorithm string # param2: OUT variable, the hashing algorithm string
get_cert_id_hash_agorithm() { get_cert_id_hash_algorithm() {
local TOKEN_FILE="$1" local TOKEN_FILE="$1"
local -n ALGO_NAME_OUT="$2" local -n ALGO_NAME_OUT="$2"
log "get_cert_id_hash_agorithm for $TOKEN_FILE" log "get_cert_id_hash_algorithm for $TOKEN_FILE"
#perform precondition checks #perform precondition checks
assert "[ ! -z $TOKEN_FILE ]" "Precondition: Path to token file must not be empty." assert "[ ! -z $TOKEN_FILE ]" "Precondition: Path to token file must not be empty."
@@ -401,7 +401,7 @@ request_token() {
# param2: the digest the token was requested for # param2: the digest the token was requested for
# param3: the tsa url from which the token was requested # param3: the tsa url from which the token was requested
# param4: the output file for the chain. It contains all certificates in order, with the first # param4: the output file for the chain. It contains all certificates in order, with the first
# one being the TSA cetificate and the last one the self-signed root certificate. # one being the TSA certificate and the last one the self-signed root certificate.
build_certificate_chain_for_token() { build_certificate_chain_for_token() {
local TOKEN_FILE="$1" local TOKEN_FILE="$1"
local DIGEST="$2" local DIGEST="$2"
@@ -417,18 +417,18 @@ build_certificate_chain_for_token() {
local DUMMY_TOKEN="$TMP_DIR"/dummy_token.tst local DUMMY_TOKEN="$TMP_DIR"/dummy_token.tst
local ALL_EXTRACTED_CERTS="$TMP_DIR"/extracted_certs.pem local ALL_EXTRACTED_CERTS="$TMP_DIR"/extracted_certs.pem
local CHAIN=() local CHAIN=()
#if the TSA uses multiple certificates to sign tokens it may take a few attempts to get one containint the proper signer #if the TSA uses multiple certificates to sign tokens it may take a few attempts to get one containing the proper signer
#TODO: allow to set maximum retry attempts #TODO: allow to set maximum retry attempts
local SIGNING_CERT_ID="" local SIGNING_CERT_ID=""
get_tsa_cert_id "$TOKEN_FILE" SIGNING_CERT_ID get_tsa_cert_id "$TOKEN_FILE" SIGNING_CERT_ID
local CERT_ID_HASH_ALGO="" local CERT_ID_HASH_ALGO=""
get_cert_id_hash_agorithm "$TOKEN_FILE" CERT_ID_HASH_ALGO get_cert_id_hash_algorithm "$TOKEN_FILE" CERT_ID_HASH_ALGO
local -i i local -i i
for i in {1..10} ;do for i in {1..10} ;do
#request dummy token. Use current commit digest #request dummy token. Use current commit digest
request_token "$TSA_URL" "$DIGEST" true "$DUMMY_TOKEN" request_token "$TSA_URL" "$DIGEST" true "$DUMMY_TOKEN"
#extract certifcates #extract certificates
openssl pkcs7 -inform DER -in "$DUMMY_TOKEN" -print_certs -outform PEM -out "$ALL_EXTRACTED_CERTS" &> "$OUT_STREAM" openssl pkcs7 -inform DER -in "$DUMMY_TOKEN" -print_certs -outform PEM -out "$ALL_EXTRACTED_CERTS" &> "$OUT_STREAM"
#remove files from previous runs #remove files from previous runs
@@ -440,7 +440,7 @@ build_certificate_chain_for_token() {
| awk '/-----BEGIN CERTIFICATE-----/ { i++; } /-----BEGIN CERTIFICATE-----/, /-----END CERTIFICATE-----/ \ | awk '/-----BEGIN CERTIFICATE-----/ { i++; } /-----BEGIN CERTIFICATE-----/, /-----END CERTIFICATE-----/ \
{ print > tmpdir i ".extracted.pem.cer" }' tmpdir="$TMP_DIR/" { print > tmpdir i ".extracted.pem.cer" }' tmpdir="$TMP_DIR/"
#find cetificate that signed token #find certificate that signed token
local EXTRACTED_CERT local EXTRACTED_CERT
while read EXTRACTED_CERT; do while read EXTRACTED_CERT; do
local CERT_ID=$(openssl x509 -inform PEM -in "$EXTRACTED_CERT" -outform DER | openssl dgst -"$CERT_ID_HASH_ALGO" -binary | xxd -p -c 256) local CERT_ID=$(openssl x509 -inform PEM -in "$EXTRACTED_CERT" -outform DER | openssl dgst -"$CERT_ID_HASH_ALGO" -binary | xxd -p -c 256)
@@ -453,7 +453,7 @@ build_certificate_chain_for_token() {
fi fi
done <<< $(ls "$TMP_DIR"/*.extracted.pem.cer) done <<< $(ls "$TMP_DIR"/*.extracted.pem.cer)
done done
if [ ${#CHAIN[@]} -eq 0 ]; then if [ ${#CHAIN[@]} -eq 0 ]; then
echo "Unable to download token that contains signing cert for this token:" echo "Unable to download token that contains signing cert for this token:"
openssl ts -reply -token_in -token_out -in "$TOKEN_FILE" -text openssl ts -reply -token_in -token_out -in "$TOKEN_FILE" -text
@@ -471,8 +471,8 @@ build_certificate_chain_for_token() {
continue 2 continue 2
fi fi
done <<< $(ls "$TMP_DIR"/*.extracted.pem.cer) done <<< $(ls "$TMP_DIR"/*.extracted.pem.cer)
fi fi
#otherwise try to find in trust store #otherwise try to find in trust store
if ls "$CA_PATH"/*.0 &> "$OUT_STREAM"; then if ls "$CA_PATH"/*.0 &> "$OUT_STREAM"; then
local TRUSTED_CERT local TRUSTED_CERT
@@ -483,7 +483,7 @@ build_certificate_chain_for_token() {
fi fi
done <<< $(ls "$CA_PATH"/*.0) done <<< $(ls "$CA_PATH"/*.0)
fi fi
#otherwise try to download #otherwise try to download
local URL=$(openssl x509 -inform PEM -noout -text -in "${CHAIN[-1]}" \ local URL=$(openssl x509 -inform PEM -noout -text -in "${CHAIN[-1]}" \
| awk '/Authority Information Access:/{f=1} f && /CA Issuers - URI:/ {print; exit}' \ | awk '/Authority Information Access:/{f=1} f && /CA Issuers - URI:/ {print; exit}' \
@@ -535,7 +535,7 @@ download_crls_for_chain() {
assert "[ -f $CERT_FILE ]" "Precondition: Certificate file $CERT_FILE must exist." assert "[ -f $CERT_FILE ]" "Precondition: Certificate file $CERT_FILE must exist."
echo -n > "$OUTPUT_FILE" echo -n > "$OUTPUT_FILE"
local CRL_TMP="$TMP_DIR"/crl_tmp.crl
#remove files from possible previous runs #remove files from possible previous runs
rm -f "$TMP_DIR"/*.extracted.pem.cer rm -f "$TMP_DIR"/*.extracted.pem.cer
#extract all contained certificates into separate files #extract all contained certificates into separate files
@@ -553,19 +553,25 @@ download_crls_for_chain() {
local URL=$(openssl x509 -inform PEM -in $EXTRACTED_CERT -text -noout \ local URL=$(openssl x509 -inform PEM -in $EXTRACTED_CERT -text -noout \
| awk '/CRL Distribution Points:/{f=1} f && /URI:/ {print; exit}' \ | awk '/CRL Distribution Points:/{f=1} f && /URI:/ {print; exit}' \
| sed 's/^.*URI://1') | sed 's/^.*URI://1')
if curl -L "$URL" --output "$CRL_TMP" &> "$OUT_STREAM"; then local CRL_TMP="$TMP_DIR"/crl_tmp.$(echo "$URL" | sha256sum -z | awk '{printf "%s",$1}').crl
local CURL_EXIT_CODE=0
if [ ! -f $CRL_TMP ]; then
curl -L "$URL" --output "$CRL_TMP" &> "$OUT_STREAM"
CURL_EXIT_CODE=$?
fi
if [ $CURL_EXIT_CODE -eq 0 ]; then
if openssl crl -in "$CRL_TMP" -inform DER -noout &> "$OUT_STREAM"; then if openssl crl -in "$CRL_TMP" -inform DER -noout &> "$OUT_STREAM"; then
openssl crl -in "$CRL_TMP" -inform DER >> "$OUTPUT_FILE" openssl crl -in "$CRL_TMP" -inform DER >> "$OUTPUT_FILE"
elif openssl crl -in "$CRL_TMP" -inform PEM -noout &> "$OUT_STREAM"; then elif openssl crl -in "$CRL_TMP" -inform PEM -noout &> "$OUT_STREAM"; then
openssl crl -in "$CRL_TMP" -inform PEM >> "$OUTPUT_FILE" openssl crl -in "$CRL_TMP" -inform PEM >> "$OUTPUT_FILE"
else else
echo "Unknown CRL file format for $URL" echo "Unknown CRL file format for $URL"
return 1 return 1
fi fi
else else
echo "Failed to download CRL from $URL" echo "Failed to download CRL from $URL"
return 1 return 1
fi fi
fi fi
done done
} }
@@ -625,4 +631,4 @@ verify_token_and_add_ltv_data() {
echo "Token from $TSA_URL could not be validated." echo "Token from $TSA_URL could not be validated."
return 1 return 1
fi fi
} }
+1 -1
View File
@@ -95,7 +95,7 @@ if [[ "$RESPONSE" =~ ^([yY][eE][sS]|[yY])$ ]]; then
echo '' >> "$TARGET_FILE" echo '' >> "$TARGET_FILE"
cat "$ROOT_CERT" >> "$TARGET_FILE" cat "$ROOT_CERT" >> "$TARGET_FILE"
echo '' >> "$TARGET_FILE" echo '' >> "$TARGET_FILE"
echo_warning "Added cetificate as $TARGET_FILE" echo_warning "Added certificate as $TARGET_FILE"
else else
echo_warning "Aborted." echo_warning "Aborted."
fi fi
+110 -11
View File
@@ -17,22 +17,22 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# #
# The interactive user interfaces in modified source and object code versions # The interactive user interfaces in modified source and object code versions
# of this program must display Appropriate Legal Notices, as required under # of this program must display Appropriate Legal Notices, as required under
# Section 5 of the GNU Affero General Public License version 3. In accordance # Section 5 of the GNU Affero General Public License version 3. In accordance
# with Section 7(b) of the GNU Affero General Public License, you must retain # with Section 7(b) of the GNU Affero General Public License, you must retain
# the Info line in every timestamp that is created or manipulated using a # the Info line in every timestamp that is created or manipulated using a
# covered work. # covered work.
# #
# You can be released from the requirements of the license by purchasing # You can be released from the requirements of the license by purchasing
# a commercial license. Buying such a license is mandatory as soon as you # a commercial license. Buying such a license is mandatory as soon as you
# develop commercial activities involving this software without # develop commercial activities involving this software without
# disclosing the source code of your own applications. # disclosing the source code of your own applications.
# These activities include: offering paid services to customers as an ASP, # These activities include: offering paid services to customers as an ASP,
# providing data storage and archival services, shipping this software with a # providing data storage and archival services, shipping this software with a
# closed source product. # closed source product.
# #
# For more information, please contact Mabulous GmbH at this # For more information, please contact Mabulous GmbH at this
# address: info@mabulous.com # address: info@mabulous.com
# #
@@ -42,7 +42,11 @@ if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/timestamping" . "$DIR/timestamping"
declare -i MINVERSION=$TIMESTAMPING_VERSION declare -i MINVERSION=$TIMESTAMPING_VERSION
declare -i MAX_COMMITS_TO_CHECK=0
declare -A PROCESSED_COMMIT declare -A PROCESSED_COMMIT
declare -A PROCESSED_PARENT
declare -A COMMITS
declare -A COMMIT_TIMES
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
KEY="$1" KEY="$1"
@@ -58,7 +62,17 @@ while [[ $# -gt 0 ]]; do
if [ $MINVERSION -gt $TIMESTAMPING_VERSION ]; then if [ $MINVERSION -gt $TIMESTAMPING_VERSION ]; then
echo_error "$KEY: this script only supports validating up to version $TIMESTAMPING_VERSION, but got $MINVERSION" echo_error "$KEY: this script only supports validating up to version $TIMESTAMPING_VERSION, but got $MINVERSION"
exit 1 exit 1
fi fi
shift # past argument
shift # past value
;;
-max|--maxcommits)
INTEGER_REGEX='^[0-9]+$'
if ! [[ "$2" =~ $INTEGER_REGEX ]]; then
echo_error "$KEY: expected positive integer"
exit 1
fi
MAX_COMMITS_TO_CHECK="$2"
shift # past argument shift # past argument
shift # past value shift # past value
;; ;;
@@ -284,7 +298,7 @@ validate_commit() {
if [ $NUM_VALID -gt 0 ]; then if [ $NUM_VALID -gt 0 ]; then
if [ $NUM_INVALID -gt 0 ]; then if [ $NUM_INVALID -gt 0 ]; then
echo_warning "Warning: While commit $COMMIT_HASH contains $NUM_VALID valid timestamp tokens and thus is considered proppely timestamped, it also contains $NUM_INVALID invalid timestamp tokens." echo_warning "Warning: While commit $COMMIT_HASH contains $NUM_VALID valid timestamp tokens and thus is considered properly timestamped, it also contains $NUM_INVALID invalid timestamp tokens."
fi fi
DATE_STRING=$(date -d @"$EARLIEST_VALID_UNIX_TIME") DATE_STRING=$(date -d @"$EARLIEST_VALID_UNIX_TIME")
echo_info "Commit $COMMIT_HASH, which timestamps commit $PARENT_HASH at $DATE_STRING, contains $NUM_VALID valid timestamp tokens." echo_info "Commit $COMMIT_HASH, which timestamps commit $PARENT_HASH at $DATE_STRING, contains $NUM_VALID valid timestamp tokens."
@@ -300,14 +314,29 @@ validate_commit() {
# param1: commit hash # param1: commit hash
# returns: 0 if the validation of the commit and all its ancestors succeeded # returns: 0 if the validation of the commit and all its ancestors succeeded
validate_commit_and_parents() { validate_commit_and_parents() {
# If MAX_COMMITS_TO_CHECK is zero (or a negative number) then that is understood as "infinity".
# So finish if we have reached the limit, and if the limit is not "infinity".
NUM_COMMITS_CHECKED=${#PROCESSED_COMMIT[@]}
if [[ ${NUM_COMMITS_CHECKED} -ge ${MAX_COMMITS_TO_CHECK} ]] && [[ ${MAX_COMMITS_TO_CHECK} -ge 1 ]]; then
# enough commits have already been checked, so return early
return 0;
fi
local COMMIT_HASH="$1" local COMMIT_HASH="$1"
log "validate_commit_and_parents for $COMMIT_HASH" log "validate_commit_and_parents for $COMMIT_HASH"
if [[ ${PROCESSED_PARENT[$COMMIT_HASH]} ]]; then
log "parents for $COMMIT_HASH have already been validated"
return 0;
else
PROCESSED_PARENT[$COMMIT_HASH]=1
fi
local ALL_PASSED=true local ALL_PASSED=true
if ! validate_commit "$COMMIT_HASH"; then if ! validate_commit "$COMMIT_HASH"; then
ALL_PASSED=false ALL_PASSED=false
fi fi
NUM_COMMITS_CHECKED=${#PROCESSED_COMMIT[@]}
local PARENTS=$(git cat-file -p "$COMMIT_HASH" | awk '/^$/{exit} /parent/ {print}' | sed 's/parent //') local PARENTS=$(git cat-file -p "$COMMIT_HASH" | awk '/^$/{exit} /parent/ {print}' | sed 's/parent //')
#iterate over all parents of commit #iterate over all parents of commit
if [ ! -z "$PARENTS" ]; then if [ ! -z "$PARENTS" ]; then
while read PARENT_HASH; do while read PARENT_HASH; do
@@ -316,6 +345,65 @@ validate_commit_and_parents() {
fi fi
done <<< $(printf "%s" "$PARENTS") done <<< $(printf "%s" "$PARENTS")
fi fi
if [ "$ALL_PASSED" = true ]; then
return 0
fi
return 1
}
# Recursive function to find all ancestors of commit
# param1: commit hash
# creates an array COMMITS, key is the commit hash, value is the commit time (Unix epoch seconds)
# the array contains all commits found in all paths from the passed-in commit hash back to the root commit of the repo
# the array is global so it can be accessed after the function returns
find_all_commits() {
local COMMIT_HASH="$1"
log "find_all_commits for $COMMIT_HASH"
# git show "ct" format returns the commit time as Unix epoch seconds
COMMIT_TIME=$(git show --no-patch --format=%ct "$COMMIT_HASH")
COMMITS[$COMMIT_HASH]="${COMMIT_TIME}"
local PARENTS=$(git cat-file -p "$COMMIT_HASH" | awk '/^$/{exit} /parent/ {print}' | sed 's/parent //')
# iterate over all parents of commit
if [ ! -z "$PARENTS" ]; then
while read PARENT_HASH; do
if [[ ${COMMITS[$PARENT_HASH]} ]]; then
log "commit $PARENT_HASH has already been processed"
else
find_all_commits "$PARENT_HASH"
fi
done <<< $(printf "%s" "$PARENTS")
fi
}
# Validate the commits in the COMMITS array, up to MAX_COMMITS_TO_CHECK
# returns: 0 if the validation of the commits succeeded
validate_commits() {
ALL_PASSED=true
# create an associative array with keys using the Unix epoch commit time and value the commit hash
# this array can be easily used to sort in (forward or reverse) order of time
for HASH in "${!COMMITS[@]}"; do
UNIX_EPOCH_TIME="${COMMITS[$HASH]}"
# two commits could have the exact same Unix epoch in seconds
# so make that unique by appending an "x" and the hash
UNIQUE_KEY="${UNIX_EPOCH_TIME}x${HASH}"
COMMIT_TIMES[$UNIQUE_KEY]="${HASH}"
done
# sort into reverse order
SORTED_KEYS=($(printf "%s\n" "${!COMMIT_TIMES[@]}" | sort -r))
# process the commits from latest time to oldest time
ALL_PASSED=true
for ENTRY in "${SORTED_KEYS[@]}"; do
COMMIT_HASH=${COMMIT_TIMES[${ENTRY}]}
log "${ENTRY} has value ${COMMIT_HASH}"
NUM_COMMITS_CHECKED=${#PROCESSED_COMMIT[@]}
if [[ ${NUM_COMMITS_CHECKED} -lt ${MAX_COMMITS_TO_CHECK} ]]; then
if ! validate_commit "$COMMIT_HASH"; then
ALL_PASSED=false
fi
fi
done
if [ "$ALL_PASSED" = true ]; then if [ "$ALL_PASSED" = true ]; then
return 0 return 0
fi fi
@@ -333,10 +421,21 @@ echo ""
echo_info "Validating timestamps. This may take a while..." echo_info "Validating timestamps. This may take a while..."
echo "" echo ""
if validate_commit_and_parents "$COMMIT_HASH"; then if [[ ${MAX_COMMITS_TO_CHECK} -ge 1 ]]; then
echo_success "Validation OK: All timestamped commits in the commit history of $COMMIT_HASH contain at least one valid timestamp." find_all_commits "$COMMIT_HASH"
exit 0 if validate_commits; then
echo_success "Validation OK: ${NUM_COMMITS_CHECKED} timestamped commits in the commit history of $COMMIT_HASH contain at least one valid timestamp."
exit 0
else
echo_error "Validation Failed: There are timestamped commits in the commit history of $COMMIT_HASH which do not contain any valid timestamps."
exit 1
fi
else else
echo_error "Validation Failed: There are timestamped commits in the commit history of $COMMIT_HASH which do not contain any valid timestamps." if validate_commit_and_parents "$COMMIT_HASH"; then
exit 1 echo_success "Validation OK: All timestamped commits in the commit history of $COMMIT_HASH contain at least one valid timestamp."
exit 0
else
echo_error "Validation Failed: There are timestamped commits in the commit history of $COMMIT_HASH which do not contain any valid timestamps."
exit 1
fi
fi fi