Open lukehinds opened 3 years ago
I'm a little confused as to how you imagine that field would be used. If I were to generate a CSAF document, then sign that document, and put that signature as a value of a hypothetical signature
field then verifying that signature involves first stripping that field from the document and using the value to verify the modified document.
Normally, file signatures are provided in separate files so that the signature represents the state of the file in its complete form. You wouldn't expect to find the checksum of an ISO within the ISO itself, no? Maybe I'm just not understanding the ask here correctly :-)
@mprpic sorry, should have clarified. The signature would be generated by each value part of all key / values concatenated together and hashed and signed. So it is an attached signature, but not a signature of the entirety of the file itself (which is not possible as you rightly point out).
Thank you for the suggestion.
I agree that signing CSAF documents is important to accomplish the goal of integrity protection. Given that there are a lot of signature wrapping attacks and signatures may not always be produced within the same (online) tool (e.g. Secvisogram, I prefer detached signatures as suggested in https://github.com/oasis-tcs/csaf/issues/152#issuecomment-733804674:
All files shall have a cryptographic hash (e.g. SHA-512 or SHA-3) as well as an OpenPGP signature file which are provided under the same file name which is extended by the appropriate extension. Example: File names
Value of document/tracking/id: "Example Company - 2019-YH3234" File name of CSAF document: example_company_-_2019-yh3234.json File name of hash file: example_company_-_2019-yh3234.json.sha512 File name of signature file: example_company_-_2019-yh3234.json.asc
Is rekor able to handle detached signatures?
Is rekor able to handle detached signatures?
Yes, very much, both in fact. The below is the generic type:
https://github.com/sigstore/rekor/blob/main/tests/rekor.json
So this could easily become:
{
"kind": "CSAF",
"apiVersion": "0.0.1",
"spec": {
"signature": {
"format": "pgp",
"content": "iQHKBAABCAA0FiEEcgCUXG78adj6hGUJJrfBoJ04pHoFAl+86RwWHGxoaW5kc0Bwcm90b25tYWlsLmNvbQAKCRAmt8GgnTikejcHC/9yyGEPh2D+MnNR8I8w0sfWChc6pGAQoS6qk/sfC/9GvF4OC7RIy6OwLr/lxyEZbOP2ngYjh/s5KjKxhZyApwwg13LmcbazGnXc3E76J55LoTfwoRa9fupH/M6HI56VFKwnu+AbMNW1s+DM47r7i5nIN6IX9kMpDe3B9XTUULff/yNUv0XtXU+VAf8ndF1w117YVWxf8TnU/HWvX74URQPN+syuyqK/NO1H1KhBVTzcIYd5H6kJu300jgkDypyyqQpd/pJYVwfeY8fCOaeCpfIPjKQ/4enCsAeBgKsAwfIbor8WiE86KoANYqROaW7uqiN+VPadbWVeN6bMpRIdEq8+NKQGlepSCRqbkVg4VKGOPgB3h5WbY9U1O1FVDnXyt7kWdEPEZjBX+V4DawshvNe5LIyqH5hJ1QNAFd0UStqKQt8EUZ/gAtQiXSGbxM1ACoYL9HblKW5b+kj/onKghekFoCoAfhMwRRqR5g/TS/Pc2/ztwYTIuhpQQfMXziTm64g=",
"publicKey": {
"content":"LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgptUUdOQkYrY0lNMEJEQUNhOEc3UkQydjNtaXdNdHhWYVppM0pCVnVlVkFxSEtDNGVLb01TNUhNQ1JvK0haVlJBCjcwWG1zVHBYMVoxZ1pRdXVDMEdEWTI2aEJoZWpBcTNoeDJydjYvOHE5MEJ2V0dIOXRWZUdwTDFzYUltNTJnRVIKWHlWZ2d6NWtBQzBTNnZNbjdkcjJldEJrV1dQK09qMDVTMDJZWkJUWWd4cE9ieWVjVVNjcUtOVGpzbFpRQkgyZApTSHVrM28yWjdoTTQ5VTBsN3piV3c0b0lUK2xBUmNzYWpRVHdXamxpYVBEL0hSalQyblJPaEloaXRlZC93Z3l6CnlkSXE1ZTZzMThWTGNUNzVxV25yWlhOUFdGd2YyNVJYWTN1dGtXK0dXNW5RZU44MFEya1JFZ2t4RnM1QWQ1V1oKdkU3dDgvaHg1em1zbFo0dGZGNHNpM1FaZUlRQmFjWWJ3eE1QU0RmOW9GR3hkR0ZUODg5d0pMR2dXbXIxVGtQTQpjTjA2d3hBUkd0eE4wejYxRkpUaWpMV1JialczdW5JOWhjUWNVbE4vUSsxNm90SHBlS1ZnNG9XMDBDcnZXT0Q2CnFrTGNNRDQ5eVVEOGZTR0IrUkVuaUJhODlDOWtRVTRTS2Rnc0xML1ErSksrU3k5S21JRHJtMWE0RGZQMXBzZmUKTGphcnpzVlpmS1VIZndjQUVRRUFBYlFpVEhWclpTQklhVzVrY3lBOGJHaHBibVJ6UUhCeWIzUnZibTFoYVd3dQpZMjl0UG9rQjFBUVRBUWdBUGhZaEJISUFsRnh1L0duWStvUmxDU2Ezd2FDZE9LUjZCUUpmbkNETkFoc0RCUWtECndtY0FCUXNKQ0FjQ0JoVUtDUWdMQWdRV0FnTUJBaDRCQWhlQUFBb0pFQ2Ezd2FDZE9LUjZaMWtMLzFJSzB2ZGUKWlg1cjVTZWJOeFRJTlNBQXZZa3JLUnlKNWY3bE9NOWdMR0l1YzJGb05VbmpWUVQwcklHOTAxOWg0OHBDeTkxZgpYakREUk1ZOWd6RldXQ2dHblhoMWhXSTNNN0JKRjZZRTZ1NkRYR3N2dVVwR3JOZVpBRzZra2F6QXVBbm5WMGtDCjA4em9SckFaQ3ZscGFacnlkOGl0YityVitRS3A3QXcybEFJSDFlNmR3TTRSTEZqdmZrOExKWHhqSkFvUG13NmwKTHcxOGM3b1c2UkxPOVFYUThlTTZyMnZISHBtMFR1ZHZaeWFmTnVDMzJHRGxNWTR1MFYxRGI4THN5bVBzQWh1QQoySno0L0tQcTZ1S3dJdG1WSzRwbmRmRUR1NkQxVG9vRFlYaXB0WWFmZHZVMzNwVVF4d0hvZlRUZkU1elp3MlBlCmxIM25aZHNnSFhHUHhKTExNcU9wVzRDL2NNNlpRVmdZU3RWcjBudlU2NitRalF2c2tVWlIwNmRkRXpuQnBHSnMKdHBtajlBZS9HUlk4RU5uTjkvMkdmRXVydHozZEtOVVpvak15MTUzamNHMFUxenpoMTE1V0o3dDh3SEJ1NFM0cAowZ0UrUkFxeXRBY0laRGQyTlNOcno4VnI5RkU5eCtmYXQ5RVJsYm5kQUJFNWlWOHNLMCtGYW5Xd2dia0JqUVJmCm5DRE5BUXdBdEJvdGhmY1J6cjN4cjNQOXA3UUNNd0t1aW9udk1DbThXZ3dOUzRDcGhxbzVOT3IyaU1qa0xQMEoKb21nSkxWWDVOK2Jydjh5NEg4cllQd0tCMTZvL2hBOEliR2JwWXltM0ZjeWtUd2NiV2J0UFRMRXRkQ1VQTFlURApOQzVMR0pwZzNlODZZZlF0QU42L01uWnlZT21sRHgyV0d0dExkbXNBU0dWdXg2QVZKcUl2K3gwNlVLSkVtSzN0CmpsRVZLeWcxMlJFenllNUlUNnFFU0dwT3pvMllsV1VxSVR3L0FhUFEyWnhVYXh2WUZvVU9jd2djZG5Ia2dzaEkKT245aC9OSFVtUDMyV1F2cWtRTXVVYVBJTlJzQzgzS3ZUREdseWZTSFZGek1hNGhETWhFY1h6NGFjaW5kNVdUZQp6eUxnWmhPYjdjTmVDeDR4Y3J0UEI2VTdCUi9GVkx6TEJsQXp1emppRWhZd0pvM0FPTXFGb1I1bUFxaGx1dE5PCnNzeW9mYnFUZ0diU0xkamJYUC9hRXRnejJNVjluL29jMVNCOEhlWk8vMTdKeWduenJ1SUt5Ky9sT1dPenQralYKVkZwVnloMXVlOGxGN3ltS1I0dHNsK2lJVmJxblB2cE1oTE9JQnFYRm4yZ01Da0dvSkx5N09IbzJXQUVKR2x0MwpTd3BicmpqMUFCRUJBQUdKQWJ3RUdBRUlBQ1lXSVFSeUFKUmNidnhwMlBxRVpRa210OEdnblRpa2VnVUNYNXdnCnpRSWJEQVVKQThKbkFBQUtDUkFtdDhHZ25UaWtlaW5pREFDRUFma1pxLzRScDJhTkE0ZGJvSjdVRlhET2FSa1YKOU1Lb0VaRnFUTU5vdkRMNXhoTWxnbFBQdS9sK2RoVGd4ZGVKOUVWSG9lenRiODk2VS9wT3VCUnNuOVZ0VzRZLwpqZWlXN0V5TlhBZC9PcnZuRmJ4KzdpWExxdXBaSkpGVGkvajlSaFZZTnNtbDdzZWJUUGVCbkdEQTkxcWJDNHhICnBRVkRDdWp4NjlWeE81RTFMU29oQ00rTy81dkxCbThpMW8vbmJGbWJ5N1ZDeUtlUkRmaHRmOW5DODRxc0U5R3EKVTcvTFNpazliZnhNV2JwcTh5a250bVMzYTBzemM0YlZGcGV6QnBtTmIwQVZjQitUbTlnV21FemhpTHM2RktBTgpJbnFOdVh1Qkw5UENhYzcrbVUrYzJtQmdHT1JHZDFkWk8zUkM4OXpGM3hCQlluQ09lNWNBTUZsYzFYR3NsbHNJCmR6ZHJkWHZiTkJ6L2o3MXB1TjhvRlltL1hiVmNpZU8wVGZRaURjVHQ4S2lpUjlUQUQ5L1A1OTNSTWxMT0dTOHAKaHZKYmlGb1pmWEhjbHNaRkhtOERRUWE5NElad1RCOG00Z0JWME0yWFN2ZEhvMzBsc3FqdFphWmlTclJoNHJzaApuMTRwYkFhVGRhS0VQY3Z0dWZiVXVXMElqWWQya3BJVC90Zz0KPU9naHIKLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQo="
}
},
"data": {
"url": "https://example.com/csaf_2.0/json_schema.json",
"hash": {
"algorithm": "sha256",
"value": "45c7b11fcbf07dec1694adecd8c5b85770a12a6c8dfdcf2580a2db0c47c31779"
}
}
}
}
So the above entry would be the digest of the csaf file and the public key / signature. The url is only used to retreive the file, this can also be sourced locally / inline (base64 encoded) as well and uploaded . This signing would be validated before entry is allowed (so we have some form of non-repudation). At a later point, someone could then perform an inclusion proof to make sure the entry is present or rekor could act as a tamper resistant audit system.
GPG is used for the above, but its very worth while considering x509.
GPG is used for the above, but its very worth while considering x509.
IMHO: As CSAF is related to the CERT/PSIRT/security researcher community it is more likely that they will accept GPG than x509.
Anyway, wouldn't we need for x509 a full (public) PKI?
GPG is used for the above, but its very worth while considering x509.
IMHO: As CSAF is related to the CERT/PSIRT/security researcher community it is more likely that they will accept GPG than x509.
Anyway, wouldn't we need for x509 a full (public) PKI?
agree, that makes sense. As long as the users public key is well known (one of the short falls of GPG is web-of-trust / in person signing and the post covid world).
Good point @lukehinds ! Although, I also agree with @tschmidtb51 , most PSIRT teams, security researchers, and coordination centers currently use GPG. The web-of-trust is also another concern. However, this may also highlight the use case of https://securitytxt.org/ and references to GPG/openPGP keys, etc...
https://securitytxt.org looks good, and nice to see any moves to progress matters. storing these things on a non tamper proof medium such as a website can be problematic though (thinking of the linux mint attack where the digests got swapped out on the hacked site).
Nit: @lukehinds I assume that
GPG is used for the above, but its very worth while considering x509.
was intended to say PGP
?
I still am a bit confused as what exactly should be signed.
The signature would be generated by each value part of all key / values concatenated together and hashed and signed
That reads to me like one of many overlapping conventions out in the wild - because canonical JSON is not here (yet) ...
Some implementations host insert order (de)serializations others are still not able to combine key structure storage with insert order conservation.
... and reading "[...]like blockchain, without the large electricity bills." makes me š for today - but no worries, tomorrow is another day.
Whether PGP or X.509, users can decide to trust one or more PKIs, webs of trust, TOFU, or verify individual keys manually... we won't solve that problem here, but should pick a functional signing mechanism and probably one of PGP or X.509. The trust model is beyond our control.
My expertise being limited to 30 minutes of searching: Are JOSE/JWS/etc something that exists and we can use?
https://jose.readthedocs.io/en/latest/ https://www.iana.org/assignments/jose/jose.xhtml
Maybe this is not widely used/adopted?
I still am a bit confused as what exactly should be signed.
The signature would be generated by each value part of all key / values concatenated together and hashed and signed
That reads to me like one of many overlapping conventions out in the wild - because canonical JSON is not here (yet) ...
Some implementations host insert order (de)serializations others are still not able to combine key structure storage with insert order conservation.
... and reading "[...]like blockchain, without the large electricity bills." makes me š for today - but no worries, tomorrow is another day.
It's very simple and hardly out in the wild. Consider the manifest as an envelope , there is a body section (which contains the sbom) and the body is the section that is signed. TUF does this with its root role : https://raw.githubusercontent.com/theupdateframework/tuf/develop/tests/repository_data/repository/metadata/root.json
This then solves the whole issue of where to stick detached sigs and how to map them to that which they sign.
I was about to say that a detached PGP signature of a JSON text file is OK and might be a simple enough starting point... but at least one concern is (trailing) spaces, tabs, etc. Simple PGP can tell you if you got the exactly the same file, but not if you got the same data with whitespace differences.
It's very simple and hardly out in the wild. Consider the manifest as an envelope , there is a body section (which contains the sbom) and the body is the section that is signed. TUF does this with its root role : https://raw.githubusercontent.com/theupdateframework/tuf/develop/tests/repository_data/repository/metadata/root.json
This then solves the whole issue of where to stick detached sigs and how to map them to that which they sign.
We could probably put that on the roadmap for discussions for later versions of CSAF.
For CSAF 2.0, I guess it is the easiest to use what the people are already familiar with. In terms of signatures in the vulnerability disclosure field that is PGP... There are tools out there to create and check those signature and they are well understood. We don't have to provide anything new - it can be used "out-of-the-box" with known tools. Hopefully, this aids in adoption of the standard.
I was about to say that a detached PGP signature of a JSON text file is OK and might be a simple enough starting point...
I agree here. A detached PGP signature is a simple starting point. By using this you can easily create a human-readable website (just by rendering the JSON data as e.g. Secvisogram does in its Preview tab) without having to decode base64 on the fly.
but at least one concern is (trailing) spaces, tabs, etc. Simple PGP can tell you if you got the exactly the same file, but not if you got the same data with whitespace differences.
To solve this problem, we need a defined (and well-understood) way of generating a canonical JSON. However, this introduces the possibility for a lot of attacks. E.g. a malicious JSON might have keyword multiple times - what is then checked for the signature might not be the same as the business logic uses...
Therefore, I suggest to use the easy solution (for now)...
Honest good intentioned view:
If you start off with PGP you're quickly going to hit it's limits and then the pain of a migration plan stemming its lack of any decent transparent key management. The issue being, there will be thousands of projects needing to generate SBOMS (and a lot of them also setting up keys for the first time) and they are all going to need a way to distribute public keys for users to verify integrity / non repudiation, which with PGP means some sort of web of trust or none at all / close your eyes and TOFU (which all to easily becomes the majority).
Key distribution will be done in a mish mash of different approaches, download it from a website (a medium that gets hacked all the time), or they will get stashed into a readme on a git repo, some will use Key servers. Users will to a degree often have to hope for the best, that it is who it is claimed to be. You're going to end up thinking, we need some sort of infra to manage this for us.
Go with x509 (even with its own shortcomings. You then you have PKIX which has a modern day applicable key management approach that can be leveraged.
@santosomar I propose to close this issue without action as the discussion brought up valuable insights but no change within a month and I do not see any material changes to the editorial drafts before public review of CSD 01.
I would like to propose adding a signature / pubkey field to the csaf_2.0/json_schema to provide non-repudiation and some level of integrity verification of the claim.
This way it will allow assurance that the claims within the schema have a degree of tamper resistance. If someone is able to tamper with a csaf vuln report they could use that to mislead over vulnerability data and perform some level of targeted attack.
On the later note, we would be interested in having rekor consume csaf data and validate the signing and store the claims into an immutable , tamper resistant transparency log. We already have a custom schema interface which would mean the csaf claims can be version controlled and referenced https://github.com/sigstore/rekor/tree/main/pkg/types
rekor supports multiple signing tools, so we have flexibility there as well (pgp, minisign, x509, ssh, openidconnect etc)
Anyone not wanting to validate can ignore the field, likewise anyone not wanting to sign could mark it as NULL / leave empty , but those who do want guarantees can still get them.