extracted.rs

crates/veilvoice-verify/src/extracted.rs

veilvoice-verify · 316 lines · read the source here · or on GitHub

What came out of the archive, and the GnuPG somebody already has.

Roadmap item 91. Two halves of the same request: check the extracted copy as well as the archive, and offer the check through GnuPG for anybody who would rather trust their own tools than this binary.

This used to be the honest limit, and it is not the limit any more

Worth reading before the code, because the module changed shape around it.

A release signs SHA256SUMS, and SHA256SUMS covers the archives. So verifying veilvoice-0.1.14-linux-x86_64.zip proved that archive was the one that was signed, and proved nothing at all about the folder sitting beside it. The folder may predate the download, may have come out of a different copy, may have been edited since. Nothing on disk records which archive a directory was extracted from.

That was written here as a limit that could not be lifted, and it could not be lifted from this side. It was lifted from the other one. A release now also publishes CONTENTS.sha256, listing every file inside every archive with its SHA-256, staged before SHA256SUMS is computed so that the signature covers it too. crate::check::contents reads it and lib.rs checks the extracted folder against it, file by file, and reports anything in that folder the release never published.

The lesson is worth keeping beside the code: "no signed list covers loose files" was a true statement about the release format, and it was being treated as a fact about the world. Publishing one more file changed it.

What is left here is the part no hash can answer. A file can be byte for byte correct and still not start, because the tool that unpacked it dropped the execute bit, and somebody in that position has a folder that looks perfect and does nothing. That is what look_in and Program::runnable are for, and they are still asked after every hash has matched.

Releases published before v0.1.15 carry no contents list, and for those the old report and the old caveat are exactly what is printed, because they were honest then and still are.

GnuPG

VeilVoice checks the signature itself, with the key compiled into this binary, so that somebody with no GnuPG installed is not stuck. That is a convenience and it has an obvious circularity: the program telling you the download is genuine is a program from the same download.

gnupg_commands is the answer to that. It prints the exact commands to run with a GnuPG this project did not write, against a key fingerprint published somewhere this project does not control. Anybody who wants the independent check has it, spelled out, with nothing to work out.

In plain words

Checks the folder you unzipped, as well as the zip.

From v0.1.15 a release publishes a signed list of everything inside each archive, so every file in that folder is checked against it, and anything in there that was not part of the release is named. For older releases, which carry no such list, it can only tell you the programs are there and that your system will run them, and it says so rather than implying more.

WHAT THIS FILE CONTAINS

316 lines defining 5 functions (4 public), 2 types and 1 constant. Everything below is read out of the source, so it cannot disagree with the code.

The types it owns.

  • struct Program line 74 · One program found in an extracted directory.
  • struct Extracted line 87 · What an extracted directory turned out to hold.

What happens when it runs. These are the ways in: public, and nothing else in this file calls them, so they are what an outside caller reaches first.

  • Extracted::is_empty line 96 · Whether anything was found at all.
  • Extracted::not_runnable line 101 · The programs the operating system will not run.
  • directory_for line 111 · The directory an archive would extract into, by this project's naming.
  • look_in line 123 · Look in directory for the programs a release carries.
    reaches runnable

WHAT CALLS WHAT

Extracted::is_empty line 96 Extracted::not_runnable line 101 directory_for line 111 look_in line 123 runnable line 144 entry: a way in: public, and nothing in this file calls it helper: private to this file dashed: a call that goes back up, or across a wrapped rank The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.

The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.

The same graph as Mermaid source
%%{init: {"theme":"base","themeVariables":{"background":"#1a1b26","primaryColor":"#1f2335","primaryTextColor":"#c0caf5","primaryBorderColor":"#7aa2f7","secondaryColor":"#16161e","tertiaryColor":"#16161e","lineColor":"#737aa2","textColor":"#c0caf5","mainBkg":"#1f2335","nodeBorder":"#7aa2f7","clusterBkg":"#16161e","clusterBorder":"#2f3549","fontFamily":"ui-monospace, SFMono-Regular, Consolas, monospace","fontSize":"14px"}}}%%
flowchart TD
    n_is_empty(["Extracted::is_empty<br/>line 96"])
    n_not_runnable(["Extracted::not_runnable<br/>line 101"])
    n_directory_for(["directory_for<br/>line 111"])
    n_look_in(["look_in<br/>line 123"])
    n_runnable["runnable<br/>line 144"]
    n_look_in --> n_runnable
    click n_is_empty href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-verify/src/extracted.rs#L96" "open the source"
    click n_not_runnable href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-verify/src/extracted.rs#L101" "open the source"
    click n_directory_for href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-verify/src/extracted.rs#L111" "open the source"
    click n_look_in href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-verify/src/extracted.rs#L123" "open the source"
    click n_runnable href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-verify/src/extracted.rs#L144" "open the source"
    classDef entry fill:#1f2335,stroke:#7aa2f7,color:#c0caf5
    class n_is_empty,n_not_runnable,n_directory_for,n_look_in entry
    classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
    class n_runnable helper

This site loads no third-party script, so it cannot run Mermaid; the diagram above is the same nodes and edges drawn by the generator instead. GitHub renders the source below directly.

ITEMS

ItemLineDocumentation
PROGRAMS pub const70The programs a release archive carries.
Program pub struct74One program found in an extracted directory.
Extracted pub struct87What an extracted directory turned out to hold.
Extracted::is_empty pub fn96Whether anything was found at all.
Extracted::not_runnable pub fn101The programs the operating system will not run.
directory_for pub fn111The directory an archive would extract into, by this project's naming.
look_in pub fn123Look in directory for the programs a release carries.
runnable fn144Whether the operating system will run this file.