crates/veilvoice-gui/src/verify.rs
veilvoice-gui · 1651 lines · read the source here · or on GitHub
The verify tab: drop a download on the window and be told what it is.
Why this exists here rather than in the verifier
The ask was drag-and-drop verification. There were two ways to have it: link eframe into veilvoice-verify, or move the checking out of that binary so both front ends call the same code.
The portable verifier is the one program in this project whose smallness is a feature: it is what somebody downloads before they trust anything else here, and a 1.5 MB single file is part of why it is checkable at all. Putting a GUI toolkit in it would have cost that for a convenience the desktop application was already the right place for. So the arithmetic moved to veilvoice_verify::check and this is a second caller, not a second implementation.
Three files, and the tab says so before it is given any
Verifying needs the download, the SHA256SUMS and the SHA256SUMS.asc. Dropping one file on a window and getting a verdict would be a lie, and an interface that discovers the other two are missing after the drop teaches people that verification is fiddly rather than that it needs three things. All three slots are visible from the start, and a drop fills whichever one the file's name says it is.
Roadmap item 97: one press, three answers
The tab used to answer one question, and it was not the question somebody actually has. "Is this zip the published one" is a step; "is the program I am about to run the published one" is the thing they want to know, and it was being left to the command line.
So one press now checks the archive against the signed hash list, then every file extracted out of that archive against the signed contents list the release publishes beside it, and then runs the GnuPG on this machine over the same signature and shows what it said. Three answers, one button, and each one drawn separately so a pass on one is never mistaken for a pass on another.
Two things are deliberately not failures. A release that published no contents list -- everything before v0.1.15 -- simply has no such row, rather than a warning about a file that was never meant to be there. And a GnuPG that cannot run on this machine is drawn in the quiet colour: it is a fact about the computer and says nothing whatever about the download.
Nothing here downloads anything
Not even the key: it is compiled in, and its fingerprint is checked against a constant a reader can compare with the README. veilvoice-verify is still the tool for fetching a release, because it is the one that can be checked before it is run.
In plain words
Drop a download on the window and be told whether it is genuine.
It checks the signature over the list of hashes first, and only then compares your file against that list. That order matters: a list of hashes that has not been checked is just some numbers somebody sent you.
Drop the downloaded archive and the hash list and signature sitting beside it are picked up on their own. Nothing is downloaded and nothing leaves the machine.
One press checks the zip, then every file you unzipped out of it, and then asks your own GnuPG the same question and shows you its answer.
WHAT THIS FILE CONTAINS
1651 lines defining 25 functions (7 public), 5 types and 5 constants. Everything below is read out of the source, so it cannot disagree with the code.
The types it owns.
enum Slotline 79 · Which of the three files a dropped path is.struct Reportline 114 · Everything one press of check found out.struct Contentsline 127 · What the extracted folder turned out to hold.struct Gnupgline 142 · What this machine's GnuPG said.struct Verifyline 160 · The tab's state.
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.
Verify::wants_repaintline 248 · Whether the window has to keep drawing for this panel's sake.Verify::drainline 253 · Take the worker's answer if it has one.Verify::take_droppedline 345 · Read what the window was given this frame.
reachesaccept,fill_from_beside,slot_forVerify::tabline 363 · The whole tab.
reachesbody,checker_section,drop_target,found_beside,gnupg_section,is_busy,slot_row,start,verdict,copyable_command,poll_survey,start_survey
WHAT CALLS WHAT
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. 22 of 25 functions are drawn; the diagram is bounded at 22 so it stays readable.
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_slot_for["slot_for<br/>line 92"]
n_is_busy["Verify::is_busy<br/>line 238"]
n_accept["Verify::accept<br/>line 274"]
n_fill_from_beside["Verify::fill_from_beside<br/>line 304"]
n_found_beside["Verify::found_beside<br/>line 326"]
n_take_dropped(["Verify::take_dropped<br/>line 345"])
n_tab(["Verify::tab<br/>line 363"])
n_body["Verify::body<br/>line 369"]
n_drop_target["Verify::drop_target<br/>line 515"]
n_slot_row["Verify::slot_row<br/>line 551"]
n_gnupg_section["Verify::gnupg_section<br/>line 614"]
n_start_survey["Verify::start_survey<br/>line 731"]
n_poll_survey["Verify::poll_survey<br/>line 752"]
n_checker_section["Verify::checker_section<br/>line 764"]
n_copyable_command["Verify::copyable_command<br/>line 886"]
n_verdict["Verify::verdict<br/>line 898"]
n_contents_verdict["Verify::contents_verdict<br/>line 909"]
n_gnupg_verdict["Verify::gnupg_verdict<br/>line 956"]
n_archive_verdict["Verify::archive_verdict<br/>line 994"]
n_start["Verify::start<br/>line 1053"]
n_examine["examine<br/>line 1076"]
n_examine_contents["examine_contents<br/>line 1110"]
n_accept --> n_fill_from_beside
n_accept --> n_slot_for
n_body --> n_checker_section
n_body --> n_drop_target
n_body --> n_found_beside
n_body --> n_gnupg_section
n_body --> n_is_busy
n_body --> n_slot_row
n_body --> n_start
n_body --> n_verdict
n_checker_section --> n_copyable_command
n_checker_section --> n_poll_survey
n_checker_section --> n_start_survey
n_examine --> n_examine_contents
n_start --> n_examine
n_tab --> n_body
n_take_dropped --> n_accept
n_verdict --> n_archive_verdict
n_verdict --> n_contents_verdict
n_verdict --> n_gnupg_verdict
click n_slot_for href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L92" "open the source"
click n_is_busy href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L238" "open the source"
click n_accept href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L274" "open the source"
click n_fill_from_beside href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L304" "open the source"
click n_found_beside href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L326" "open the source"
click n_take_dropped href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L345" "open the source"
click n_tab href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L363" "open the source"
click n_body href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L369" "open the source"
click n_drop_target href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L515" "open the source"
click n_slot_row href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L551" "open the source"
click n_gnupg_section href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L614" "open the source"
click n_start_survey href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L731" "open the source"
click n_poll_survey href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L752" "open the source"
click n_checker_section href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L764" "open the source"
click n_copyable_command href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L886" "open the source"
click n_verdict href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L898" "open the source"
click n_contents_verdict href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L909" "open the source"
click n_gnupg_verdict href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L956" "open the source"
click n_archive_verdict href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L994" "open the source"
click n_start href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L1053" "open the source"
click n_examine href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L1076" "open the source"
click n_examine_contents href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs#L1110" "open the source"
classDef entry fill:#1f2335,stroke:#7aa2f7,color:#c0caf5
class n_take_dropped,n_tab entry
classDef api fill:#1f2335,stroke:#7dcfff,color:#c0caf5
class n_is_busy,n_accept,n_found_beside api
classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
class n_slot_for,n_fill_from_beside,n_body,n_drop_target,n_slot_row,n_gnupg_section,n_start_survey,n_poll_survey,n_checker_section,n_copyable_command,n_verdict,n_contents_verdict,n_gnupg_verdict,n_archive_verdict,n_start,n_examine,n_examine_contents 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
| Item | Line | Documentation |
|---|---|---|
Slot enum | 79 | Which of the three files a dropped path is. |
slot_for fn | 92 | Work out what a dropped file is from its name. |
Report pub struct | 114 | Everything one press of check found out. |
Contents pub struct | 127 | What the extracted folder turned out to hold. |
Gnupg pub struct | 142 | What this machine's GnuPG said. |
Verify pub struct | 160 | The tab's state. |
COPIED_FOR const | 212 | How long the copy button says "copied", in seconds. |
RELEASES_PAGE const | 218 | Where every release, and the files published beside it, actually are. |
SIGNING_KEY_IN_REPO const | 222 | The signing key, in the repository as well as in each release, so it can be fetched from somewhere other than the release being checked. |
SLOT_LABEL_WIDTH const | 227 | The width the slot labels are given, so the file names beside them start level. |
SLOT_NAME_WIDTH const | 234 | The width the file name is given, so the three choose… buttons land at one x whatever is in the slots. |
Verify::is_busy pub fn | 238 | Whether a check is running, so the app keeps repainting. |
Verify::wants_repaint pub fn | 248 | Whether the window has to keep drawing for this panel's sake. |
Verify::drain pub fn | 253 | Take the worker's answer if it has one. |
Verify::accept pub fn | 274 | Put a dropped or chosen file into the slot its name says it belongs in. |
Verify::fill_from_beside fn | 304 | Fill the empty slots from the folder this file came from. |
Verify::found_beside pub fn | 326 | Which slots were filled in by looking rather than by being chosen. |
Verify::take_dropped pub fn | 345 | Read what the window was given this frame. |
Verify::tab pub fn | 363 | The whole tab. |
Verify::body fn | 369 | |
Verify::drop_target fn | 515 | The rectangle that lights up while files are over the window. |
Verify::slot_row fn | 551 | One file slot: what it is, what is in it, and a way to change it. |
Verify::gnupg_section fn | 614 | Roadmap item 90. |
Verify::start_survey fn | 731 | Which implementation checks the signature, and the choice behind it. |
Verify::poll_survey fn | 752 | Take the result if it has arrived, without ever waiting for it. |
Verify::checker_section fn | 764 | |
Verify::copyable_command fn | 886 | One command, shown as it would be typed, with a button that copies it and says it did. |
Verify::verdict fn | 898 | The answer, in the colour it deserves. |
Verify::contents_verdict fn | 909 | Roadmap item 97. |
Verify::gnupg_verdict fn | 956 | Roadmap item 97. |
Verify::archive_verdict fn | 994 | The archive against the signed hash list. |
Verify::start fn | 1053 | Run the check on a thread of its own. |
examine fn | 1076 | The whole check, off the drawing thread. |
examine_contents fn | 1110 | Roadmap item 97. |
examine_gnupg fn | 1207 | Roadmap item 97. |