Open Chenthilraj opened 7 months ago
Hi @Chenthilraj! Thanks for submitting an issue.
in-toto-verify -l /home/azureuser/chenthilraj/intoto/root.layout --layout-key /home/azureuser/chenthilraj/intoto/intoto_public_key.pem --verbose
Can you paste the output of this command?
Loading layout... Loading layout key(s)... Verifying layout metadata signatures... Extracting layout from metadata... Verifying layout expiration... Reading link metadata files... Verifying link metadata signatures... Verifying sublayouts... Verifying alignment of reported commands... Verifying command alignment for 'build.57c82af1.link'... Verifying command alignment for 'copy.57c82af1.link'... Verifying threshold constraints... Skipping threshold verification for step 'build' with threshold '1'... Skipping threshold verification for step 'copy' with threshold '1'... Verifying Step rules... Verifying material rules for 'build'... Verifying product rules for 'build'... Verifying 'CREATE target/*.js'... Verifying material rules for 'copy'... Verifying 'MATCH target/app.js WITH PRODUCTS FROM build'... Verifying product rules for 'copy'... Verifying 'CREATE dist/app.js'... Executing Inspection commands... Executing command for inspection 'check'... Running 'check'... Recording materials '.'... Recording products '.'... Creating link metadata... Generating link metadata using Metablock... (in-toto-verify) BadReturnValueError: Got non-int return value 'None'.
Okay, here's what's happening:
in-toto-verify looks at the return value (in the "byproducts" field) of the ad-hoc generated link metadata of your "check" inspection. But given that the "check" inspection in the layout doesn't define a command (in the "run" field), there is no return value.
In other words, inspections must include commands that can run on the verifier and exit with 0.
I can see how this is not clear from the user feedback.
Frankly I don't need to run anything. I have added Match in the inspection, and I expect in-toto to match the two files and if both are same, the verification should complete successfully. I tried with inspect as empty : "inspect": [] Here the verification is successful. But here the verification is successful even if I alter/delete the file (app.js). Here I expect the verification to fail as the file was altered/deleted
Hope you got my point. After the copy and before inspect, I deleted/altered the files (tested with both target/app.js and dist/app.js). Then when I run verify, verification was successful (in case of empty inspect section in layout). But ideally it should fail right?
Unfortunately, the in-toto specification requires you to run "something". There's a related discussion in: https://github.com/in-toto/docs/issues/27
My question is different here. I kept the inspect as empty. After the copy step and before verify, I deleted the files. The in-toto-verify was successful in this case. But the file itself is absent so it should fail right. But its not failing.
in-toto-record start --step-name copy --key /home/azureuser/chenthilraj/intoto/intoto_private_key.pem --materials target/app.js --verbose
cp target/app.js dist/app.js
in-toto-record stop --step-name copy --key /home/azureuser/chenthilraj/intoto/intoto_private_key.pem --products dist/app.js --verbose
After this, I deleted/modified the files target/app.js or dist/app.js and then execute verify
in-toto-verify -l /home/azureuser/chenthilraj/intoto/root.layout --layout-key /home/azureuser/chenthilraj/intoto/intoto_public_key.pem --verbose
The verification is success but ideally it should fail. Please explain
I think that's exactly the problem described in https://github.com/in-toto/docs/issues/27. Without an inspection in-toto-verify misses the final link between the last step of the supply chain ("copy" in your case) and the local artifacts, which you are trying to verify ("target/app.js" and "dist/app.js").
It only verifiers in the provided link files, most notably that the "target/app.js" product in the "build" link is the same as the "target/app.js" material in the "copy" link.
So you are saying without inspection meaning if you have an empty inspection, even you delete/alter/modify the packaged file, in-toto-verification will be success though ideally it should be failure right?
in-toto-verification will be success though ideally it should be failure right?
In your case yes.
Ok. Considering this scenario, what command should I add in the run for inspect to make the verification successful if I add the inspect section in my layout. Ideally my azure pipeline does the above steps (build and copy).
Please suggest.
You can run any command that's expected to be available in the verification context.
I've used the command true
before.
Now I am facing one more issue. added true in run. but after the python create_layout.py got executed, the layout file still resulting in empty run[].
I try adding tar and other commands as well. but the generated layout always has empty run
If you share your create_layout.py
I can try to help.
from securesystemslib import interface from securesystemslib.signer import SSlibSigner from in_toto.models.layout import Layout from in_toto.models.metadata import Envelope from in_toto.models.metadata import Metablock
def main():
key_private = interface.import_rsa_privatekey_from_file("intoto_private_key.pem") signer_private = SSlibSigner(key_private)
key_public = interface.import_rsa_publickey_from_file("intoto_public_key.pem")
layout = Layout.read({
"_type": "layout",
"keys": {
key_public["keyid"]: key_public
},
"steps": [{
"name": "build",
"expected_materials": [],
"expected_products": [["CREATE", "target/*.js"]],
"pubkeys": [key_public["keyid"]],
"threshold": 1,
},
{
"name": "copy",
"expected_materials": [["MATCH", "target/app.js", "WITH", "PRODUCTS","FROM", "build"]],
"expected_products": [["CREATE", "dist/app.js"]],
"pubkeys": [key_public["keyid"]],
"threshold": 1,
}],
"inspect": [{
"name": "check",
"expected_materials": [["MATCH", "target/app.js", "WITH", "PRODUCTS","FROM", "build"]],
"expected_products": [["MATCH", "dist/app.js", "WITH", "PRODUCTS","FROM", "copy"]],
}],
"run": ["true"]
})
metadata = Metablock(signed=layout)
metadata.create_signature(signer_private) metadata.dump("root.layout") print('Created demo in-toto layout as "root.layout".')
if name == 'main': main()
The run
field should be part of the inspection object:
"inspect": [{
"name": "check",
"expected_materials": [["MATCH", "target/app.js", "WITH", "PRODUCTS","FROM", "build"]],
"expected_products": [["MATCH", "dist/app.js", "WITH", "PRODUCTS","FROM", "copy"]],
"run": ["true"],
}]
ok. I will try and come out. Please dont close the issue till then
No luck. Still the same. The generated layout is added below. You can see the run is still empty. create_layout-1.zip
{ "signatures": [ { "keyid": "57c82af1f601373488cc340eefe7b75ade898bac3865240c5213738c6654636a", "sig": "425c493a493f29271c1305e6fe52b8140b998af7b236c270470f776b8d72ffbda0a3992d2cbd07e2c9f3403f6d70341448ff10f30f809276ed5f4187887b75ee5e0329407f4f20214726233bc9ba12a0b984ab2173280c87a89f1964b204c6c728c290c7a3c1038e0a5f10df823e716b66e4ba96a4904f5c9cacb57227b99bef4e81f7bdf45471b8619764a76259765970cff8fefa3cf641fb2e3cbc18ad136a930679385ce43639a634eb9fd741b718261fa1816d7483a7584d50836887d181be33bf954d8bd8ad616095bd6db632c6927a490a17824adcabd367bf45638b917bea3c152f88c96cfee08e4540e2342c3ef0abf5b61b31d1c3330e83ff27d6db" } ], "signed": { "_type": "layout", "expires": "2024-05-04T10:36:42Z", "inspect": [ { "_type": "inspection", "expected_materials": [ [ "MATCH", "target/app.js", "WITH", "PRODUCTS", "FROM", "build" ] ], "expected_products": [ [ "MATCH", "dist/app.js", "WITH", "PRODUCTS", "FROM", "copy" ] ], "name": "check", "run": [] } ], "keys": { "57c82af1f601373488cc340eefe7b75ade898bac3865240c5213738c6654636a": { "keyid": "57c82af1f601373488cc340eefe7b75ade898bac3865240c5213738c6654636a", "keyid_hash_algorithms": [ "sha256", "sha512" ], "keytype": "rsa", "keyval": { "private": "", "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqeRMXBGIm5M9Eld+mih9\n4qxc3KMp0G8pYwOVRf/cQZQzqPWKen69mIaeRcJEzvcIwHPS3az6nfEVS37L6iz5\njf5bOr9JJyyO3kzyR1N5HoWO/JisiF5KJS4LpOLRd2C1yX7IbjbQFAuxAwUyG5w4\nDdlwXt9tXw0eqQ13CO4ugGYbiFfh5dqF6YzzQUfAiRBfvk2uQldFMyxCyV6K4Wov\nalrRG9z63xU3ivs356It0R7igZbuBFbQEGhSllQt44dtyhxPN36tbKpql9W92XJb\naMRhaldU3lOjHpBlzVLb/4wMDMiSo4Lygz0A6nfrWsA93PlNpZcAXar1AyCYCH/S\nFQIDAQAB\n-----END PUBLIC KEY-----" }, "scheme": "rsassa-pss-sha256" } }, "readme": "", "steps": [ { "_type": "step", "expected_command": [], "expected_materials": [], "expected_products": [ [ "CREATE", "target/*.js" ] ], "name": "build", "pubkeys": [ "57c82af1f601373488cc340eefe7b75ade898bac3865240c5213738c6654636a" ], "threshold": 1 }, { "_type": "step", "expected_command": [], "expected_materials": [ [ "MATCH", "target/app.js", "WITH", "PRODUCTS", "FROM", "build" ] ], "expected_products": [ [ "CREATE", "dist/app.js" ] ], "name": "copy", "pubkeys": [ "57c82af1f601373488cc340eefe7b75ade898bac3865240c5213738c6654636a" ], "threshold": 1 } ] } }
Waiting for your update..
Happy to help. If you push your code to create the layout to a GitHub repo, I can comment.
I am using the create_layout.py referred in the in-toto demo git hub. https://github.com/in-toto/demo/blob/main/owner_alice/create_layout.py
I changed the keys and the steps as mentioned in the attachment. In the demo they use 3 keys (bob, carl and alice) here I use only a single private/public key. I had attached the python code for your reference. You can use the demo git hub and replace the code with mine.
Let me know if you need any further update. create_layout-1.zip
I am doing a poc with in-toto. PoC contains the following steps:
Once I created the layout, I started executed the following commands. Consider I am in a test folder, I created 2 more folders target and dist inside test folder and executed the following commands
echo "Hello in-toto" > target/app.js
in-toto-record stop --step-name build --key /home/azureuser/chenthilraj/intoto/intoto_private_key.pem --products target/app.js --verbose
Note: target/app.js got created with content "Hello in-toto".
in-toto-record start --step-name copy --key /home/azureuser/chenthilraj/intoto/intoto_private_key.pem --materials target/app.js --verbose
cp target/app.js dist/app.js
Note: file copy successful.
in-toto-record stop --step-name copy --key /home/azureuser/chenthilraj/intoto/intoto_private_key.pem --products dist/app.js --verbose
I ensured that the same file app.js is present in both target and dist folder. Then I execute
in-toto-verify -l /home/azureuser/chenthilraj/intoto/root.layout --layout-key /home/azureuser/chenthilraj/intoto/intoto_public_key.pem --verbose
but the verification fails. Please note there is no key error since the moment I remove the inspection section from the layout, verification is successful.
I verified the build link file and copy link file and checked the sha key is same for both target/app.js and dist/app.js as shown below
build link file:
{ "signatures": [ { "keyid": "57c82af1f601373488cc340eefe7b75ade898bac3865240c5213738c6654636a", "sig": "8771ac06997dc809e8262b0fcbaefab8c47bb16bff6705855d97fe0ecb4d3f70755e74eca336194e75324876a19c77e73b5fa6b791e047a50772118ef76355dc6e213f68b8eaba849bd21631095c93b549c2ccc57a318db9c2da6f8735e0d763e012606b57dcb4fc383fcb95bb215d31679f2d42b87cbaa6142640a130b40453d49d16fc1876a40bee2ef3bd8ae124397c36113920e4f3e02433acf1a043f42749bc25a93eff89592e3ad67dcd693f11917b88578d08e3788e8fba6189b17fd838a2702832edb0de33c832e4e2428341bddfc19462933863d3f487ec8f181bb6eb87187236c9a1c0f50e4d1b263ff492259eba95531dd265e50f91acd1ba7614" } ], "signed": { "_type": "link", "byproducts": {}, "command": [], "environment": {}, "materials": {}, "name": "build", "products": { "target/app.js": { "sha256": "e40dcf0c464bf4b89a5d8384fe2a0209dccc9052c82946732111f64433b0bfd3" } } } }
Copy Link File: { "signatures": [ { "keyid": "57c82af1f601373488cc340eefe7b75ade898bac3865240c5213738c6654636a", "sig": "0295e4b57753e677a30a8e53035ae86c1bb28a97a403ceea8b664b795da494d775b96f6bab6694092438fe5870282890576291d87506bd8d13e00bee8c780a110376e861a777d84e704382b8f732034257b4a29b58a2023eba563886e4f63c2472f28a5ef0ffdb3c04ac9625c8d2aa2a92d684bc8fecdc02dd9ac735cad1355b29adace4968e0c49f42815a02f2b22d314cb122ffe27d845edf2f5b57d44ea4a0609ce8465b0f7f3fbb5780de18ece053a6f49fc81761293279ffdd6d47af5ab94394b7f536178ed3e5b3e8b2ad863db74d25ce090600699507e2d332b46f1a40f3c27a0fb700d1c5391ce08cbeea40b4a42d88a28d979cf0d9714b25bb8f8bc" } ], "signed": { "_type": "link", "byproducts": {}, "command": [], "environment": {}, "materials": { "target/app.js": { "sha256": "e40dcf0c464bf4b89a5d8384fe2a0209dccc9052c82946732111f64433b0bfd3" } }, "name": "copy", "products": { "dist/app.js": { "sha256": "e40dcf0c464bf4b89a5d8384fe2a0209dccc9052c82946732111f64433b0bfd3" } } } }
I am using version 2.1.1.