For a project, XML files are dynamically generated. After a while, these XML files need to be signed using the XAdES-T protocol. The signature must be included in the XML file.
To do that, I generate a Timestamp Query (TSQ) from the XML file. It is created based on the SHA256 hash of the XML file. After that, I send the TSQ to FreeTSA (Timestamp Authority). The response consists of two elements:
- Response string (string / base64 encoded)
- Response time (integer / unix time)
Now here comes the hard part. The signature must be included in the XML using dsig:Signature
. Based on the W3 documentation:
- The SignatureTimeStamp encapsulates the time-stamp over the ds:SignatureValue element.
- The SignatureTimeStamp element contains a single HashDataInfo element that refers to the ds:SignatureValue element of the [XMLDSIG] signature. That is, the input for the timestamp hash computation is the ds:SignatureValue XML element.
I tried the following XML:
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference>
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue></ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
MIIFUDADAgEAMIIFRwYJKoZIhvcNAQcCoIIFODCCBTQCAQMxDzANBglghkgBZQMEAgMFADCCAY4GCyqGSIb3DQEJEAEEoIIBfQSCAXkwggF1AgEBBgQqAwQBMDEwDQYJYIZIAWUDBAIBBQAEIHY4mbyU5g4mM3CRUjMSjILz19kk0jYmuoZSCI6hnXQqAgQAzfxZGA8yMDIxMDgyNTExMzcwN1oBAf8CCHdmnjv+m4i4oIIBEaSCAQ0wggEJMREwDwYDVQQKEwhGcmVlIFRTQTEMMAoGA1UECxMDVFNBMXYwdAYDVQQNE21UaGlzIGNlcnRpZmljYXRlIGRpZ2l0YWxseSBzaWducyBkb2N1bWVudHMgYW5kIHRpbWUgc3RhbXAgcmVxdWVzdHMgbWFkZSB1c2luZyB0aGUgZnJlZXRzYS5vcmcgb25saW5lIHNlcnZpY2VzMRgwFgYDVQQDEw93d3cuZnJlZXRzYS5vcmcxIjAgBgkqhkiG9w0BCQEWE2J1c2lsZXphc0BnbWFpbC5jb20xEjAQBgNVBAcTCVd1ZXJ6YnVyZzELMAkGA1UEBhMCREUxDzANBgNVBAgTBkJheWVybjGCA4owggOGAgEBMIGjMIGVMREwDwYDVQQKEwhGcmVlIFRTQTEQMA4GA1UECxMHUm9vdCBDQTEYMBYGA1UEAxMPd3d3LmZyZWV0c2Eub3JnMSIwIAYJKoZIhvcNAQkBFhNidXNpbGV6YXNAZ21haWwuY29tMRIwEAYDVQQHEwlXdWVyemJ1cmcxDzANBgNVBAgTBkJheWVybjELMAkGA1UEBhMCREUCCQDB6YYWDajpgjANBglghkgBZQMEAgMFAKCBuDAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIxMDgyNTExMzcwN1owKwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQUkW2j2GDsyoLjS8WdF5Pn6WiHXxQwTwYJKoZIhvcNAQkEMUIEQOATishRq9feRvKy8q5CwPKviUzDLCEu81s7MeGTCrx/mQtcOaGfuSpLefXVXOq1ckfsaxlvY5aZQkW3uaKTDkcwDQYJKoZIhvcNAQEBBQAEggIAjjHuobwvxwLKdnvRO6YAOWm0JuJ3AU5wXlgZUwYw9hMkQmGyXz+ky2+WvMa4k9OQji+zX4G9xGXzxQg7qLNYkMd+Cfd86eSMqLoTJEatijgDUwdxq0u5JbWUq8RpTjAQFm4mswzg3sbEvsU1y58LJPKRZ0WekKTbBAFjCm4FyH17aWiPh1JS96Tm1on+xhWaoMXJNAyLbguLrQB2TsNQFL19y2wjqCOuomfm4bN/jyeSazmvVH+l8ye1A5xejXx2Lv81w7W1zbrSi7v1/ywnq3utKeMdcqKgLC99jN0ErQkBIhCuP4JvGO5mW/CgQPb+qBWISPgAOBLaYi72204+zl0pTZdpKKNLJaMr6gJFkDIF+ZHmieE5yR9aiQ7SWYYLdEcq5tC8yZjgFJxxyEdxXpBqyp3PkMciBTEeUyRfBlnnP1O+Oe8unqLceGrH/1H4WniDJUXZvra/jLx3T3IdknGn1swHdNMrLETK2vPd646wZfsKTSOqjbzi5ljrS03FsElhxujcrwjGLOs1l/EyAIM0an1lroHnu5n2MH5KLMvPJqjLIqn0jEsxXk8JU+kpqUpcTaTKq24VbvqYO/WeyfD1t2t9ExhPgxAaBf6lm9R7AdbxpWJTl0rP4h3YMq/h5z2U2TYAYXQ3aiXQZR0VvUJbPI22thftdhsNDC0v+fU=
</ds:SignatureValue>
</ds:Signature>
But the status (according to this website) is always "invalid".
What is the correct way to append the Timestamp Response to an XML file?
The best solution in PHP to work with Xades documents is: https://github.com/bseddon/xml-signer
I have signed a xml with LTA and timestamping. It´s very easy and well documented!
Thanks to @bseddon!