asignify icon indicating copy to clipboard operation
asignify copied to clipboard

check+echo mode

Open kevans91 opened this issue 3 years ago • 3 comments

This is something I've been tossing back and forth that I think I'd like to implement before trying to import asignify into FreeBSD base.

The basic idea is pretty simple: given an existing pubkey and sigfile, output the contents if verification passes. Use case, for example:

# $pubkey already exists
fetch https://kevans.dev/script.sh.sig
fetch -o - https://kevans.dev/script.sh | asignify check -x $pubkey script.sh.sig - > script.sh
[ ! -s "script.sh" ] && exit 1

Though, I picture a more realistic use-case to be:

# $pubkey already exists
fetch https://kevans.dev/script.sh.sig
fetch -o - https://kevans.dev/script.sh | asignify check -x $pubkey script.sh.sig - | sh

This would be a slightly better version of existing curl|sh constructs, since we'll execute the script only if verification succeeds against our known-good key.

kevans91 avatar Apr 15 '21 14:04 kevans91

The main challenge here is how to verify and write output simultaneously. Then, upon sucessful validation we would need to rename an output to target or to unlink it in case of verify failure. This would require to add a new method to libasignify together with asignify_verify_file and, in turn, asignify_digest_fd.

vstakhov avatar Apr 17 '21 14:04 vstakhov

No, that's not the only issue I'm afraid. Asignify signatures imply filename, so it is not easy to adopt it to -. The second issue is that you can specify output file but not output stream as the fail path will not work for stream. So imagine, that we have an input stream and the output stream, then we read input and calculate digest. If we simultaneously write to the output stream then what can we do on failure aside of setting of the exit code? One sollution would be to do 2 passes of reading (which I don't like) but it won't work for the input stream as streams do not support lseek to rewind reading apparently. Another (bad) option would be to read the whole input and write output merely if input is verified. This option is not suitable for large files and will waste memory in many scenarios.

vstakhov avatar Apr 18 '21 19:04 vstakhov

The main challenge here is how to verify and write output simultaneously. Then, upon sucessful validation we would need to rename an output to target or to unlink it in case of verify failure. This would require to add a new method to libasignify together with asignify_verify_file and, in turn, asignify_digest_fd.

What I'd considered for this mode was that we could just buffer input into a shmfd, verify it, then seek back and write it out.

No, that's not the only issue I'm afraid. Asignify signatures imply filename, so it is not easy to adopt it to -.

In my local pkg branch, a filename has to be passed in anyways since libasignify only takes FILE * -- I had pictured just adding an optional -f flag to specify a name, which would also let me provide a manifest with signatures for more than one script.

The second issue is that you can specify output file but not output stream as the fail path will not work for stream. So imagine, that we have an input stream and the output stream, then we read input and calculate digest. If we simultaneously write to the output stream then what can we do on failure aside of setting of the exit code? One sollution would be to do 2 passes of reading (which I don't like) but it won't work for the input stream as streams do not support lseek to rewind reading apparently. Another (bad) option would be to read the whole input and write output merely if input is verified. This option is not suitable for large files and will waste memory in many scenarios.

Ah, that's a fair point and makes buffering into a shmfd seem less desirable.

kevans91 avatar Apr 19 '21 14:04 kevans91