tres0r-crypt 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tres0r_crypt-1.0.1/API.md +993 -0
- tres0r_crypt-1.0.1/CHANGELOG.md +450 -0
- tres0r_crypt-1.0.1/CONTRIBUTING.md +59 -0
- tres0r_crypt-1.0.1/FORMAT.md +421 -0
- tres0r_crypt-1.0.1/LICENSE +21 -0
- tres0r_crypt-1.0.1/MANIFEST.in +7 -0
- tres0r_crypt-1.0.1/PKG-INFO +741 -0
- tres0r_crypt-1.0.1/README.md +687 -0
- tres0r_crypt-1.0.1/SECURITY.md +25 -0
- tres0r_crypt-1.0.1/completions/_tres0r +438 -0
- tres0r_crypt-1.0.1/completions/tres0r.bash +168 -0
- tres0r_crypt-1.0.1/fuzz/_common.py +25 -0
- tres0r_crypt-1.0.1/fuzz/fuzz_container.py +186 -0
- tres0r_crypt-1.0.1/fuzz/fuzz_header.py +34 -0
- tres0r_crypt-1.0.1/fuzz/fuzz_text.py +43 -0
- tres0r_crypt-1.0.1/fuzz/make_seeds.py +86 -0
- tres0r_crypt-1.0.1/man/tres0r.1 +1258 -0
- tres0r_crypt-1.0.1/pyproject.toml +71 -0
- tres0r_crypt-1.0.1/setup.cfg +4 -0
- tres0r_crypt-1.0.1/tests/api_surface.json +168 -0
- tres0r_crypt-1.0.1/tests/api_surface.py +109 -0
- tres0r_crypt-1.0.1/tests/conftest.py +134 -0
- tres0r_crypt-1.0.1/tests/reference_decoder.py +362 -0
- tres0r_crypt-1.0.1/tests/soft_token.py +168 -0
- tres0r_crypt-1.0.1/tests/test_api_surface.py +16 -0
- tres0r_crypt-1.0.1/tests/test_append.py +254 -0
- tres0r_crypt-1.0.1/tests/test_cli.py +119 -0
- tres0r_crypt-1.0.1/tests/test_cli_v11.py +197 -0
- tres0r_crypt-1.0.1/tests/test_cli_v2.py +207 -0
- tres0r_crypt-1.0.1/tests/test_container.py +336 -0
- tres0r_crypt-1.0.1/tests/test_container_v11.py +251 -0
- tres0r_crypt-1.0.1/tests/test_container_v2.py +322 -0
- tres0r_crypt-1.0.1/tests/test_docgen.py +111 -0
- tres0r_crypt-1.0.1/tests/test_features.py +296 -0
- tres0r_crypt-1.0.1/tests/test_fido2.py +181 -0
- tres0r_crypt-1.0.1/tests/test_gaps.py +147 -0
- tres0r_crypt-1.0.1/tests/test_gui.py +478 -0
- tres0r_crypt-1.0.1/tests/test_header_kdf.py +148 -0
- tres0r_crypt-1.0.1/tests/test_keys_header2.py +269 -0
- tres0r_crypt-1.0.1/tests/test_mount.py +175 -0
- tres0r_crypt-1.0.1/tests/test_passgen.py +187 -0
- tres0r_crypt-1.0.1/tests/test_payload.py +218 -0
- tres0r_crypt-1.0.1/tests/test_perf_meta.py +285 -0
- tres0r_crypt-1.0.1/tests/test_portability_exclude.py +135 -0
- tres0r_crypt-1.0.1/tests/test_prefetch.py +105 -0
- tres0r_crypt-1.0.1/tests/test_properties.py +434 -0
- tres0r_crypt-1.0.1/tests/test_pwgen_original.py +11 -0
- tres0r_crypt-1.0.1/tests/test_recovery.py +200 -0
- tres0r_crypt-1.0.1/tests/test_second_factor.py +219 -0
- tres0r_crypt-1.0.1/tests/test_segment_table.py +98 -0
- tres0r_crypt-1.0.1/tests/test_signing.py +319 -0
- tres0r_crypt-1.0.1/tests/test_split.py +140 -0
- tres0r_crypt-1.0.1/tests/test_stream.py +136 -0
- tres0r_crypt-1.0.1/tests/test_tui.py +562 -0
- tres0r_crypt-1.0.1/tests/test_vectors.py +206 -0
- tres0r_crypt-1.0.1/tests/vectors/generate.py +258 -0
- tres0r_crypt-1.0.1/tests/vectors/v1-passwort.json +36 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-roh-alle-slots.json +29 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-roh-fido2.json +28 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-roh-keyfile.json +28 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-roh-leer-empfaenger.json +27 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-roh-schwellwert.json +32 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-roh-signiert.json +29 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-roh-zstd-empfaenger.json +28 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-tar-angehaengt-zstd.json +74 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-tar-passwort.json +66 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-tar-signiert.json +68 -0
- tres0r_crypt-1.0.1/tests/vectors/v2-tar-zstd-phrase.json +66 -0
- tres0r_crypt-1.0.1/tres0r/__init__.py +100 -0
- tres0r_crypt-1.0.1/tres0r/__main__.py +3 -0
- tres0r_crypt-1.0.1/tres0r/cli.py +1717 -0
- tres0r_crypt-1.0.1/tres0r/container.py +2374 -0
- tres0r_crypt-1.0.1/tres0r/docgen.py +448 -0
- tres0r_crypt-1.0.1/tres0r/errors.py +68 -0
- tres0r_crypt-1.0.1/tres0r/exclude.py +94 -0
- tres0r_crypt-1.0.1/tres0r/gui.py +1002 -0
- tres0r_crypt-1.0.1/tres0r/header.py +157 -0
- tres0r_crypt-1.0.1/tres0r/header2.py +539 -0
- tres0r_crypt-1.0.1/tres0r/hwtoken.py +208 -0
- tres0r_crypt-1.0.1/tres0r/kdf.py +263 -0
- tres0r_crypt-1.0.1/tres0r/keys.py +437 -0
- tres0r_crypt-1.0.1/tres0r/mount.py +332 -0
- tres0r_crypt-1.0.1/tres0r/padding.py +21 -0
- tres0r_crypt-1.0.1/tres0r/passgen.py +208 -0
- tres0r_crypt-1.0.1/tres0r/payload.py +577 -0
- tres0r_crypt-1.0.1/tres0r/portability.py +135 -0
- tres0r_crypt-1.0.1/tres0r/progress.py +175 -0
- tres0r_crypt-1.0.1/tres0r/pwgen.py +772 -0
- tres0r_crypt-1.0.1/tres0r/rng.py +25 -0
- tres0r_crypt-1.0.1/tres0r/segments.py +200 -0
- tres0r_crypt-1.0.1/tres0r/shamir.py +161 -0
- tres0r_crypt-1.0.1/tres0r/sign.py +101 -0
- tres0r_crypt-1.0.1/tres0r/stream.py +203 -0
- tres0r_crypt-1.0.1/tres0r/tui.py +1069 -0
- tres0r_crypt-1.0.1/tres0r/volumes.py +238 -0
- tres0r_crypt-1.0.1/tres0r/wordlists/LICENSES.md +10 -0
- tres0r_crypt-1.0.1/tres0r/wordlists/de-7776-v1-diceware.txt +7776 -0
- tres0r_crypt-1.0.1/tres0r/wordlists/eff_large_wordlist_en.txt +7776 -0
- tres0r_crypt-1.0.1/tres0r/workers.py +89 -0
- tres0r_crypt-1.0.1/tres0r_crypt.egg-info/PKG-INFO +741 -0
- tres0r_crypt-1.0.1/tres0r_crypt.egg-info/SOURCES.txt +103 -0
- tres0r_crypt-1.0.1/tres0r_crypt.egg-info/dependency_links.txt +1 -0
- tres0r_crypt-1.0.1/tres0r_crypt.egg-info/entry_points.txt +2 -0
- tres0r_crypt-1.0.1/tres0r_crypt.egg-info/requires.txt +30 -0
- tres0r_crypt-1.0.1/tres0r_crypt.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,993 @@
|
|
|
1
|
+
# tres0r – Python-API (stabil, 1.x)
|
|
2
|
+
|
|
3
|
+
Diese Datei ist aus dem Code erzeugt (`python -m tres0r.docgen`); die Signaturen
|
|
4
|
+
sind zusätzlich per Test eingefroren (`tests/api_surface.json`).
|
|
5
|
+
|
|
6
|
+
## Stabilitätsversprechen
|
|
7
|
+
|
|
8
|
+
Stabil sind die Namen in `__all__` der Module unten. In allen 1.x-Versionen gilt:
|
|
9
|
+
|
|
10
|
+
* Keine öffentlichen Namen werden entfernt oder umbenannt; die Reihenfolge
|
|
11
|
+
positioneller Parameter bleibt, neue Pflichtparameter gibt es nicht.
|
|
12
|
+
* Erlaubt sind neue Namen, neue optionale Schlüsselwort-Parameter und neue Felder
|
|
13
|
+
(mit Standardwert) in Ergebnisklassen.
|
|
14
|
+
* Die Fehlerhierarchie bleibt; neue Unterklassen sind möglich. Alle Fehler erben
|
|
15
|
+
von `Tres0rError`.
|
|
16
|
+
* Verhalten ändert sich nur bei Fehlerkorrekturen. Das Containerformat folgt
|
|
17
|
+
FORMAT.md (Spezifikation 1.0).
|
|
18
|
+
|
|
19
|
+
**Intern** (ohne Zusage, auch in Unterversionen änderbar): alle übrigen Module
|
|
20
|
+
(`container`, `header`, `header2`, `stream`, `payload`, `sign`, `segments`,
|
|
21
|
+
`volumes`, `kdf`, `workers`, `portability`, `exclude`, `padding`, `rng`, `cli`,
|
|
22
|
+
`docgen`, `pwgen`, `tui`, `gui`) und alle Namen mit führendem `_`. Was davon gebraucht wird,
|
|
23
|
+
ist über `tres0r` erreichbar.
|
|
24
|
+
|
|
25
|
+
**Kommandozeile:** Befehle, Optionen und Exit-Codes sind ebenso stabil. Bei
|
|
26
|
+
`--json` behalten vorhandene Schlüssel ihre Bedeutung, neue können hinzukommen;
|
|
27
|
+
Fehler kommen als `{"error": {"type": …, "message": …}}`. Die menschenlesbare
|
|
28
|
+
Ausgabe ist nicht zum Auswerten gedacht.
|
|
29
|
+
|
|
30
|
+
**Threads und Fortschritt:** Lange Funktionen nehmen `progress=` (Funktion
|
|
31
|
+
`(erledigt, gesamt)` oder `Monitor`) und prüfen ein `CancelToken`. Mit mehreren
|
|
32
|
+
Threads können Ereignisse aus Arbeitsthreads kommen – Oberflächen reichen sie in
|
|
33
|
+
ihren eigenen Thread weiter.
|
|
34
|
+
|
|
35
|
+
## Gemeinsame Parameter
|
|
36
|
+
|
|
37
|
+
Diese Namen bedeuten in allen Funktionen dasselbe:
|
|
38
|
+
|
|
39
|
+
* `container` – Pfad des Containers (bei --split der Basisname oder ein Teil).
|
|
40
|
+
* `sources` – Pfade (Dateien/Ordner) oder ein `Plan` aus `scan`.
|
|
41
|
+
* `plan` – Ergebnis von `scan`.
|
|
42
|
+
* `output` – Zielpfad.
|
|
43
|
+
* `dest` – Zielordner; entsteht bei Bedarf.
|
|
44
|
+
* `path` – Pfad.
|
|
45
|
+
* `src` – Lesbares Binär-Dateiobjekt.
|
|
46
|
+
* `out` – Beschreibbares Binär-Dateiobjekt.
|
|
47
|
+
* `credentials` – Zugangsdaten: Passwort/Phrase (str, bytes) oder `Credentials` (Passwörter, Identitäten, Keyfiles, Anteile, FIDO2).
|
|
48
|
+
* `password` – Passwort für den neuen Passwort-Slot; `None` = keiner.
|
|
49
|
+
* `params` – Argon2id-Parameter (`KdfParams`, z. B. `LEVELS["normal"]`); `None` = Standard bzw. unverändert.
|
|
50
|
+
* `recipients` – Öffentliche X25519-Schlüssel; jeder bekommt einen eigenen Slot.
|
|
51
|
+
* `recovery` – Wiederherstellungsphrase (`keys.generate_recovery`) als eigener Slot.
|
|
52
|
+
* `keyfile` – Keyfile-Geheimnis (`keys.keyfile_secret`) – zweiter Faktor zum Passwort.
|
|
53
|
+
* `fido2` – `hwtoken.TokenProvider` – FIDO2-Token als zweiter Faktor zum Passwort.
|
|
54
|
+
* `threshold` – `(k, n)` – Schwellwert-Slot; die Anteile stehen im Ergebnis (`shares`).
|
|
55
|
+
* `compress` – Mit zstd komprimieren (Python 3.14 oder Paket `zstandard`).
|
|
56
|
+
* `pad` – Padmé-Padding: verbirgt die genaue Größe (Standard an).
|
|
57
|
+
* `sign_with` – Ed25519-Signaturschlüssel (`keys.generate_signing_key`).
|
|
58
|
+
* `signers` – Erwartete Prüfschlüssel: fehlt die Signatur oder passt keiner, folgt `SignatureError`.
|
|
59
|
+
* `overwrite` – Vorhandene Ausgabe ersetzen (sonst Fehler).
|
|
60
|
+
* `progress` – Fortschritt: Funktion `(erledigt, gesamt)` oder `Monitor` (Ereignisse, Abbruch).
|
|
61
|
+
* `exclude` – `ExcludeRules` (Muster, typische Junk-Dateien).
|
|
62
|
+
* `ignore_files` – `.tres0rignore`-Dateien in den Quellen beachten (Standard an).
|
|
63
|
+
* `strict_names` – Abbrechen statt warnen, wenn Namen nicht auf allen Systemen gültig sind.
|
|
64
|
+
* `check_space` – Freien Speicherplatz vorher prüfen (`InsufficientSpace`).
|
|
65
|
+
* `times` – Änderungszeiten speichern (`False`: Zeit 0, beim Entpacken die aktuelle Zeit).
|
|
66
|
+
* `xattrs` – Erweiterte Attribute `user.*` sichern bzw. wiederherstellen (Linux).
|
|
67
|
+
* `acls` – POSIX-ACLs sichern bzw. wiederherstellen (Linux).
|
|
68
|
+
* `threads` – Threads für SHA-256 und zstd; `None` = automatisch (Kerne, max. 8), `1` = aus.
|
|
69
|
+
* `split` – Teilgröße in Byte für `NAME.001 …`; `None` = eine Datei.
|
|
70
|
+
* `rename` – Kollidierende oder hier ungültige Namen umbenennen statt abbrechen.
|
|
71
|
+
* `only` – fnmatch-Muster: nur passende Einträge (samt Inhalt passender Ordner). `[`, `*` und `?` sind Sonderzeichen – einen Namen wörtlich treffen z. B. `[[]` statt `[`.
|
|
72
|
+
* `total` – Erwartete Größe in Byte – für Fortschritt und Restzeit.
|
|
73
|
+
* `passphrase` – Passphrase einer geschützten Schlüsseldatei.
|
|
74
|
+
|
|
75
|
+
## `tres0r`
|
|
76
|
+
|
|
77
|
+
### `SUFFIX`
|
|
78
|
+
|
|
79
|
+
`'.tres0r'`
|
|
80
|
+
|
|
81
|
+
### `scan(sources, *, exclude=None, ignore_files=True, output=None, progress=None)`
|
|
82
|
+
|
|
83
|
+
Quellen durchlaufen und festlegen, was in den Container kommt.
|
|
84
|
+
|
|
85
|
+
* ``exclude`` passt auf Pfade, wie ``tres0r list`` sie zeigt ("Projekt/build").
|
|
86
|
+
* Eine ``.tres0rignore`` direkt in einem Quellordner gilt relativ zu diesem.
|
|
87
|
+
* Explizit angegebene Quellen werden nie ausgeschlossen.
|
|
88
|
+
|
|
89
|
+
### `plan_sources(sources)`
|
|
90
|
+
|
|
91
|
+
Quellen prüfen und ihre Namen im Container bestimmen (ohne Durchlaufen).
|
|
92
|
+
|
|
93
|
+
### `estimate_size(plan, pad=True)`
|
|
94
|
+
|
|
95
|
+
Obere Schätzung der Containergröße in Byte (ohne Kompression gerechnet).
|
|
96
|
+
|
|
97
|
+
### `check_free_space(directory, needed, purpose)`
|
|
98
|
+
|
|
99
|
+
InsufficientSpace, wenn ``needed`` Byte (+ Reserve) nicht frei sind.
|
|
100
|
+
|
|
101
|
+
Netzlaufwerke oder Dateisysteme mit Kompression melden mitunter
|
|
102
|
+
unzuverlässige Werte – Frontends sollten die Prüfung abschaltbar machen.
|
|
103
|
+
|
|
104
|
+
``directory``: Ordner auf dem Zieldatenträger; ``needed``: Byte; ``purpose``: Text für die Fehlermeldung ("für …").
|
|
105
|
+
|
|
106
|
+
### `format_size(n)`
|
|
107
|
+
|
|
108
|
+
Bytezahl menschenlesbar (``1536`` -> ``"1.5 KiB"``).
|
|
109
|
+
|
|
110
|
+
### `atomic_output(path, *, overwrite=False, split=None)`
|
|
111
|
+
|
|
112
|
+
Datei (oder mit ``split`` einen Teilesatz) erst nach Erfolg an ihren Platz
|
|
113
|
+
bringen; bei Fehlern bleiben keine Reste. Beim Überschreiben verschwinden auch
|
|
114
|
+
Teile, die ein früherer, anders aufgeteilter Container hinterlassen hat.
|
|
115
|
+
|
|
116
|
+
### `create(sources, output, password, params=None, *, recipients=(), recovery=None, keyfile=None, threshold=None, fido2=None, compress=False, sign_with=None, overwrite=False, progress=None, exclude=None, pad=True, strict_names=False, check_space=True, times=True, xattrs=False, acls=False, threads=None, split=None)`
|
|
117
|
+
|
|
118
|
+
Dateien/Ordner in einen neuen verschlüsselten Container packen (Format v2).
|
|
119
|
+
|
|
120
|
+
``sources`` ist eine Pfadliste oder ein vorab erstellter ``Plan``. Keyslots:
|
|
121
|
+
``password`` (Argon2id mit ``params``), ``recovery`` (generierte Phrase,
|
|
122
|
+
siehe keys.generate_recovery) und beliebig viele X25519-``recipients``.
|
|
123
|
+
|
|
124
|
+
Metadaten: ``times=False`` speichert keine Änderungszeiten (0 = "unbekannt";
|
|
125
|
+
beim Entpacken gilt dann die aktuelle Zeit). ``xattrs``/``acls`` übernehmen
|
|
126
|
+
user.*-Attribute bzw. POSIX-ACLs (nur Linux). ``threads``: SHA-256 im
|
|
127
|
+
Hintergrund und zstd-Worker (None = automatisch, 1 = aus).
|
|
128
|
+
Geschrieben wird in eine temporäre Datei im Zielordner, die erst nach
|
|
129
|
+
vollständigem Erfolg per atomarem os.replace() umbenannt wird.
|
|
130
|
+
|
|
131
|
+
### `append(container, sources, credentials, *, exclude=None, ignore_files=True, compress=False, sign_with=None, pad=True, progress=None, strict_names=False, check_space=True, times=True, xattrs=False, acls=False, threads=None)`
|
|
132
|
+
|
|
133
|
+
Dateien als neues Segment an einen v2-Container anhängen – an Ort und Stelle.
|
|
134
|
+
|
|
135
|
+
Nur die neuen Daten werden verschlüsselt und geschrieben; der Bestand bleibt
|
|
136
|
+
unberührt. Gleiche Namen: die neue Fassung gilt (list/unpack/mount/diff).
|
|
137
|
+
Absturzsicher über ein Journal neben dem Container; bei einer Exception
|
|
138
|
+
(auch Abbruch) wird die Datei sofort auf den alten Stand gekürzt.
|
|
139
|
+
|
|
140
|
+
### `inspect(container)`
|
|
141
|
+
|
|
142
|
+
Header-Informationen lesen – ohne Passwort. Bei v2 sind die Angaben erst
|
|
143
|
+
nach dem Entsperren durch die Header-MAC bestätigt.
|
|
144
|
+
|
|
145
|
+
### `list_contents(container, credentials, *, progress=None)`
|
|
146
|
+
|
|
147
|
+
Inhaltsverzeichnis. Bei v2 aus dem Index – dafür werden nur die letzten
|
|
148
|
+
Chunks entschlüsselt. Vollständig prüft ``verify``.
|
|
149
|
+
|
|
150
|
+
### `verify(container, credentials, *, progress=None, signers=None, threads=None)`
|
|
151
|
+
|
|
152
|
+
Container vollständig prüfen, ohne etwas zu schreiben.
|
|
153
|
+
|
|
154
|
+
Authentifiziert jeden Chunk inkl. Padding und Index. Bei v2 mit Index wird
|
|
155
|
+
zusätzlich jeder tar-Eintrag mit dem Inhaltsverzeichnis abgeglichen
|
|
156
|
+
(Name, Typ, Größe, SHA-256). Ist der Container signiert, wird die Signatur
|
|
157
|
+
geprüft; ``signers`` verlangt zusätzlich einen dieser Unterzeichner.
|
|
158
|
+
Ohne Exception ist der Container intakt.
|
|
159
|
+
|
|
160
|
+
### `extract(container, dest, credentials, *, progress=None, rename=False, check_space=True, only=None, signers=None, xattrs=False, acls=False)`
|
|
161
|
+
|
|
162
|
+
Container in ``dest`` entpacken.
|
|
163
|
+
|
|
164
|
+
Entpackt wird zunächst in einen versteckten Staging-Ordner innerhalb von
|
|
165
|
+
``dest``; erst danach werden die Einträge an ihren Platz verschoben. Bei
|
|
166
|
+
jedem Fehler bleibt ``dest`` unverändert.
|
|
167
|
+
|
|
168
|
+
``only``: Muster (fnmatch) für Pfade; ein passender Ordner bringt seinen
|
|
169
|
+
Inhalt mit. Bei v2 springt tres0r über den Index direkt zu den Einträgen
|
|
170
|
+
und prüft dabei nur die gelesenen Chunks (plus den Abschluss) – für eine
|
|
171
|
+
Vollprüfung ``verify`` verwenden. Ohne ``only`` wird immer alles geprüft.
|
|
172
|
+
|
|
173
|
+
Namenskollisionen und (unter Windows) ungültige Namen führen zum Abbruch
|
|
174
|
+
(NameConflict) oder mit ``rename=True`` zum Umbenennen.
|
|
175
|
+
|
|
176
|
+
Signatur: Beim vollständigen Lesen wird sie geprüft, bevor irgendetwas im
|
|
177
|
+
Zielordner landet. ``signers`` verlangt einen dieser Unterzeichner – dann
|
|
178
|
+
wird auch mit ``only`` alles gelesen, weil nur so geprüft werden kann.
|
|
179
|
+
|
|
180
|
+
### `extract_stream(src, dest, credentials, *, progress=None, rename=False, only=None, signers=None, xattrs=False, acls=False)`
|
|
181
|
+
|
|
182
|
+
Container aus einem Datenstrom (Pipe, stdin) entpacken – mit denselben
|
|
183
|
+
Schutzmechanismen wie ``extract``: Staging-Ordner, Namensschutz, data-Filter,
|
|
184
|
+
Signaturprüfung vor dem Verschieben. Ohne wahlfreien Zugriff: kein
|
|
185
|
+
Inhaltsverzeichnis, keine Speicherplatzprüfung, ``only`` filtert beim Lesen.
|
|
186
|
+
|
|
187
|
+
### `diff(container, sources, credentials, *, exclude=None, ignore_files=True, quick=False, times=False, progress=None, threads=None)`
|
|
188
|
+
|
|
189
|
+
Container mit Ordnern/Dateien vergleichen – Aufruf wie bei ``create``.
|
|
190
|
+
|
|
191
|
+
Die Pfade werden genau wie beim Packen ermittelt (gleiche Namen, gleiche
|
|
192
|
+
Ausschlüsse), sodass "Projekt/a.txt" im Container auf "Projekt/a.txt" lokal
|
|
193
|
+
trifft. Dateien gleicher Größe werden per SHA-256 verglichen; ``quick``
|
|
194
|
+
begnügt sich wie rsync mit Größe und Änderungszeit. Reine Zeitunterschiede
|
|
195
|
+
meldet ``times``. Container ohne Zeitstempel (pack --no-times): ``quick``
|
|
196
|
+
hasht dann doch, ``times`` meldet nichts. ``threads``: Dateien parallel hashen.
|
|
197
|
+
|
|
198
|
+
### `encrypt_stream(src, out, password, params=None, *, recipients=(), recovery=None, compress=False, pad=True, sign_with=None, progress=None, total=None, threads=None, keyfile=None, threshold=None, fido2=None)`
|
|
199
|
+
|
|
200
|
+
Beliebigen Datenstrom verschlüsseln (Nutzdatentyp "roh"). Gibt die
|
|
201
|
+
Anzahl gelesener Bytes zurück. ``out`` bekommt den Container unmittelbar –
|
|
202
|
+
für Dateien mit atomic_output() kombinieren. ``total``: erwartete Größe
|
|
203
|
+
(für Fortschritt/Restzeit), falls bekannt.
|
|
204
|
+
|
|
205
|
+
### `decrypt_stream(src, out, credentials, *, signers=None, progress=None, total=None)`
|
|
206
|
+
|
|
207
|
+
Nutzdaten eines Containers ausgeben (roh; bei tar-Containern den tar-Stream).
|
|
208
|
+
|
|
209
|
+
Achtung bei Pipes: Die Daten fließen, bevor Abschluss und Signatur geprüft
|
|
210
|
+
sind. Erst ein Rücklauf ohne Exception (Exit-Code 0) bestätigt beides.
|
|
211
|
+
|
|
212
|
+
### `salvage(container, dest, credentials, *, rename=False, progress=None)`
|
|
213
|
+
|
|
214
|
+
Aus einem beschädigten Container retten, was intakt ist.
|
|
215
|
+
|
|
216
|
+
Voraussetzung: Der Header ist lesbar und lässt sich entsperren.
|
|
217
|
+
|
|
218
|
+
* Mit lesbarem Inhaltsverzeichnis (v2): jeder Eintrag einzeln über seinen
|
|
219
|
+
Einstiegspunkt. Ein beschädigter Chunk kostet nur die Einträge, die ihn
|
|
220
|
+
berühren; jede gerettete Datei wird per SHA-256 gegengeprüft.
|
|
221
|
+
* Sonst (v1, abgeschnittener Container): der Reihe nach bis zur ersten
|
|
222
|
+
beschädigten Stelle; die Datei, in der sie liegt, wird verworfen.
|
|
223
|
+
|
|
224
|
+
Gerettet wird nur, was vollständig und authentisch ist. Wie bei extract
|
|
225
|
+
landet alles erst am Ende im Zielordner.
|
|
226
|
+
|
|
227
|
+
### `repair(container, credentials)`
|
|
228
|
+
|
|
229
|
+
Nach einem unterbrochenen Anhängen einen gültigen Stand herstellen.
|
|
230
|
+
|
|
231
|
+
* Tabelle am Ende gültig: Anhängen war fertig geschrieben – abschließen.
|
|
232
|
+
* Sonst mit Journal: auf den Stand davor zurücksetzen.
|
|
233
|
+
* Sonst: auf die letzte gültige Segmenttabelle kürzen.
|
|
234
|
+
|
|
235
|
+
### `upgrade(container, credentials, output=None, *, compress=False, pad=True, progress=None, check_space=True, threads=None, split=None)`
|
|
236
|
+
|
|
237
|
+
Container der Formatversion 1 in Version 2 umwandeln.
|
|
238
|
+
|
|
239
|
+
Läuft als Stream – es entsteht nie Klartext auf der Platte. Passwort und
|
|
240
|
+
Stufe bleiben gleich; neu sind Inhaltsverzeichnis, Header-MAC und optional
|
|
241
|
+
Kompression. Der alte Stream wird vollständig authentifiziert, bevor der neue
|
|
242
|
+
Container an seinen Platz kommt; ohne ``output`` wird atomar ersetzt.
|
|
243
|
+
|
|
244
|
+
### `add_keys(container, credentials, *, password=None, params=None, recovery=None, recipients=(), keyfile=None, fido2=None, check_space=True, progress=None)`
|
|
245
|
+
|
|
246
|
+
Weitere Keyslots hinzufügen. Gibt die Nummern der neuen Slots zurück.
|
|
247
|
+
|
|
248
|
+
### `add_threshold(container, credentials, k, n, *, check_space=True, progress=None)`
|
|
249
|
+
|
|
250
|
+
Schwellwert-Slot hinzufügen: k von n Anteilen öffnen den Container.
|
|
251
|
+
Gibt (Slotnummer, Anteile) zurück – die Anteile gibt es nur jetzt.
|
|
252
|
+
|
|
253
|
+
### `remove_key(container, credentials, slot_index, *, check_space=True, progress=None)`
|
|
254
|
+
|
|
255
|
+
Keyslot entfernen. Der letzte Slot lässt sich nicht entfernen.
|
|
256
|
+
|
|
257
|
+
``slot_index``: Nummer des Slots wie in ``inspect().slots``.
|
|
258
|
+
|
|
259
|
+
### `change_password(container, old_password, new_password, params=None, *, check_space=True, progress=None)`
|
|
260
|
+
|
|
261
|
+
Das Passwort ändern, mit dem entsperrt wurde – ohne Neuverschlüsselung.
|
|
262
|
+
|
|
263
|
+
Bei v2 wird genau der Passwort-Slot ersetzt, der zum alten Passwort passt;
|
|
264
|
+
ohne ``params`` behält er seine Stufe.
|
|
265
|
+
|
|
266
|
+
``old_password``: Zugangsdaten zum Entsperren (wie ``credentials``); ``new_password``: das neue Passwort. Ein zweiter Faktor (Keyfile, FIDO2) bleibt.
|
|
267
|
+
|
|
268
|
+
### `check_credentials(container, credentials, *, progress=None)`
|
|
269
|
+
|
|
270
|
+
Zugangsdaten prüfen, ohne Inhalt zu lesen – z. B. bevor eine Oberfläche nach einem
|
|
271
|
+
neuen Passwort fragt. Entsperrt nur den Header (Passwort-Slots: Argon2id) und prüft
|
|
272
|
+
bei v2 die Header-MAC; passt nichts, folgt ``WrongPassword``. Gibt den Slot zurück,
|
|
273
|
+
der gepasst hat. Funktioniert für alle Container, auch für Rohdatenströme.
|
|
274
|
+
|
|
275
|
+
### `Plan` (Datenklasse)
|
|
276
|
+
|
|
277
|
+
Ergebnis von scan(): was in den Container käme.
|
|
278
|
+
|
|
279
|
+
* `entries: list[tuple[Path, str, os.stat_result]]`
|
|
280
|
+
* `skipped: list[str]`
|
|
281
|
+
* `excluded: int`
|
|
282
|
+
* `issues: list[portability.Issue]`
|
|
283
|
+
|
|
284
|
+
### `ContainerInfo` (Datenklasse)
|
|
285
|
+
|
|
286
|
+
ContainerInfo(path: 'Path', kdf: 'KdfParams | None', level: 'str | None', size: 'int', version: 'int' = 1, header_len: 'int' = 107, payload_type: 'str' = 'tar', compression: 'str | None' = None, has_index: 'bool' = False, slots: 'list[SlotInfo]' = <factory>, signed: 'bool' = False, volumes: 'int' = 1, segmented: 'bool' = False, interrupted: 'bool' = False)
|
|
287
|
+
|
|
288
|
+
* `path: Path`
|
|
289
|
+
* `kdf: KdfParams | None`
|
|
290
|
+
* `level: str | None`
|
|
291
|
+
* `size: int`
|
|
292
|
+
* `version: int`
|
|
293
|
+
* `header_len: int`
|
|
294
|
+
* `payload_type: str`
|
|
295
|
+
* `compression: str | None`
|
|
296
|
+
* `has_index: bool`
|
|
297
|
+
* `slots: list[SlotInfo]`
|
|
298
|
+
* `signed: bool`
|
|
299
|
+
* `volumes: int`
|
|
300
|
+
* `segmented: bool`
|
|
301
|
+
* `interrupted: bool`
|
|
302
|
+
|
|
303
|
+
### `SlotInfo` (Datenklasse)
|
|
304
|
+
|
|
305
|
+
SlotInfo(index: 'int', type: 'str', description: 'str', level: 'str | None' = None)
|
|
306
|
+
|
|
307
|
+
* `index: int`
|
|
308
|
+
* `type: str`
|
|
309
|
+
* `description: str`
|
|
310
|
+
* `level: str | None`
|
|
311
|
+
|
|
312
|
+
### `CreateResult` (Datenklasse)
|
|
313
|
+
|
|
314
|
+
CreateResult(path: 'Path', entries: 'int', size: 'int', padding: 'int' = 0, skipped: 'list[str]' = <factory>, excluded: 'int' = 0, issues: 'list[portability.Issue]' = <factory>, slots: 'list[str]' = <factory>, shares: 'list' = <factory>)
|
|
315
|
+
|
|
316
|
+
* `path: Path`
|
|
317
|
+
* `entries: int`
|
|
318
|
+
* `size: int`
|
|
319
|
+
* `padding: int`
|
|
320
|
+
* `skipped: list[str]`
|
|
321
|
+
* `excluded: int`
|
|
322
|
+
* `issues: list[portability.Issue]`
|
|
323
|
+
* `slots: list[str]`
|
|
324
|
+
* `shares: list`
|
|
325
|
+
|
|
326
|
+
### `AppendResult` (Datenklasse)
|
|
327
|
+
|
|
328
|
+
AppendResult(path: 'Path', segment: 'int', entries: 'int', size: 'int', added: 'int', skipped: 'list[str]' = <factory>, excluded: 'int' = 0, issues: 'list[portability.Issue]' = <factory>)
|
|
329
|
+
|
|
330
|
+
* `path: Path`
|
|
331
|
+
* `segment: int`
|
|
332
|
+
* `entries: int`
|
|
333
|
+
* `size: int`
|
|
334
|
+
* `added: int`
|
|
335
|
+
* `skipped: list[str]`
|
|
336
|
+
* `excluded: int`
|
|
337
|
+
* `issues: list[portability.Issue]`
|
|
338
|
+
|
|
339
|
+
### `Entry` (Datenklasse)
|
|
340
|
+
|
|
341
|
+
Entry(name: 'str', size: 'int', kind: 'str', mtime: 'int | None' = None, sha256: 'str | None' = None, segment: 'int' = 0)
|
|
342
|
+
|
|
343
|
+
* `name: str`
|
|
344
|
+
* `size: int`
|
|
345
|
+
* `kind: str`
|
|
346
|
+
* `mtime: int | None`
|
|
347
|
+
* `sha256: str | None`
|
|
348
|
+
* `segment: int`
|
|
349
|
+
|
|
350
|
+
### `VerifyResult` (Datenklasse)
|
|
351
|
+
|
|
352
|
+
VerifyResult(entries: 'int', files: 'int', bytes: 'int', checked_hashes: 'bool' = False, segments: 'int' = 1, signed: 'bool' = False, signer: 'str | None' = None)
|
|
353
|
+
|
|
354
|
+
* `entries: int`
|
|
355
|
+
* `files: int`
|
|
356
|
+
* `bytes: int`
|
|
357
|
+
* `checked_hashes: bool`
|
|
358
|
+
* `segments: int`
|
|
359
|
+
* `signed: bool`
|
|
360
|
+
* `signer: str | None`
|
|
361
|
+
|
|
362
|
+
### `ExtractResult` (Datenklasse)
|
|
363
|
+
|
|
364
|
+
ExtractResult(names: 'list[str]', entries: 'int', renamed: 'list[tuple[str, str]]' = <factory>, signed: 'bool' = False, signer: 'str | None' = None, warnings: 'list[str]' = <factory>)
|
|
365
|
+
|
|
366
|
+
* `names: list[str]`
|
|
367
|
+
* `entries: int`
|
|
368
|
+
* `renamed: list[tuple[str, str]]`
|
|
369
|
+
* `signed: bool`
|
|
370
|
+
* `signer: str | None`
|
|
371
|
+
* `warnings: list[str]`
|
|
372
|
+
|
|
373
|
+
### `EncryptResult` (Datenklasse)
|
|
374
|
+
|
|
375
|
+
EncryptResult(bytes: 'int', shares: 'list' = <factory>)
|
|
376
|
+
|
|
377
|
+
* `bytes: int`
|
|
378
|
+
* `shares: list`
|
|
379
|
+
|
|
380
|
+
### `DecryptResult` (Datenklasse)
|
|
381
|
+
|
|
382
|
+
DecryptResult(bytes: 'int', signed: 'bool' = False, signer: 'str | None' = None)
|
|
383
|
+
|
|
384
|
+
* `bytes: int`
|
|
385
|
+
* `signed: bool`
|
|
386
|
+
* `signer: str | None`
|
|
387
|
+
|
|
388
|
+
### `DiffEntry` (Datenklasse)
|
|
389
|
+
|
|
390
|
+
DiffEntry(name: 'str', status: 'str', detail: 'str' = '')
|
|
391
|
+
|
|
392
|
+
* `name: str`
|
|
393
|
+
* `status: str`
|
|
394
|
+
* `detail: str`
|
|
395
|
+
|
|
396
|
+
### `DiffResult` (Datenklasse)
|
|
397
|
+
|
|
398
|
+
DiffResult(changes: 'list[DiffEntry]' = <factory>, unchanged: 'int' = 0, hashed: 'int' = 0, quick: 'bool' = False)
|
|
399
|
+
|
|
400
|
+
* `changes: list[DiffEntry]`
|
|
401
|
+
* `unchanged: int`
|
|
402
|
+
* `hashed: int`
|
|
403
|
+
* `quick: bool`
|
|
404
|
+
|
|
405
|
+
### `SalvageResult` (Datenklasse)
|
|
406
|
+
|
|
407
|
+
SalvageResult(recovered: 'list[str]' = <factory>, damaged: 'list[tuple[str, str]]' = <factory>, names: 'list[str]' = <factory>, used_index: 'bool' = False, notes: 'list[str]' = <factory>, renamed: 'list[tuple[str, str]]' = <factory>)
|
|
408
|
+
|
|
409
|
+
* `recovered: list[str]`
|
|
410
|
+
* `damaged: list[tuple[str, str]]`
|
|
411
|
+
* `names: list[str]`
|
|
412
|
+
* `used_index: bool`
|
|
413
|
+
* `notes: list[str]`
|
|
414
|
+
* `renamed: list[tuple[str, str]]`
|
|
415
|
+
|
|
416
|
+
### `RepairResult` (Datenklasse)
|
|
417
|
+
|
|
418
|
+
RepairResult(action: 'str', size: 'int')
|
|
419
|
+
|
|
420
|
+
* `action: str`
|
|
421
|
+
* `size: int`
|
|
422
|
+
|
|
423
|
+
### `UpgradeResult` (Datenklasse)
|
|
424
|
+
|
|
425
|
+
UpgradeResult(path: 'Path', entries: 'int', size: 'int')
|
|
426
|
+
|
|
427
|
+
* `path: Path`
|
|
428
|
+
* `entries: int`
|
|
429
|
+
* `size: int`
|
|
430
|
+
|
|
431
|
+
### `Credentials` (Datenklasse)
|
|
432
|
+
|
|
433
|
+
Alles, womit ein Container entsperrt werden kann.
|
|
434
|
+
|
|
435
|
+
``prompt`` wird nur aufgerufen, wenn Identitäten nicht gereicht haben und
|
|
436
|
+
der Container Passwort- oder Wiederherstellungs-Slots hat.
|
|
437
|
+
|
|
438
|
+
* `passwords: list[str | bytes]`
|
|
439
|
+
* `identities: list[X25519PrivateKey]`
|
|
440
|
+
* `prompt: Callable[[], str] | None`
|
|
441
|
+
* `keyfiles: list[bytes]`
|
|
442
|
+
* `shares: list`
|
|
443
|
+
* `fido2: Callable | None`
|
|
444
|
+
|
|
445
|
+
### `KdfParams` (Datenklasse)
|
|
446
|
+
|
|
447
|
+
KdfParams(memory_kib: 'int', iterations: 'int', lanes: 'int')
|
|
448
|
+
|
|
449
|
+
* `memory_kib: int`
|
|
450
|
+
* `iterations: int`
|
|
451
|
+
* `lanes: int`
|
|
452
|
+
|
|
453
|
+
### `LEVELS`
|
|
454
|
+
|
|
455
|
+
`{'schnell': KdfParams(memory_kib=65536, iterations=3, lanes=4), 'normal': KdfParams(memory_kib=262144, iterations=4, lanes=4), 'stark': KdfParams(memory_kib=1048576, iterations=4, lanes=4)}`
|
|
456
|
+
|
|
457
|
+
### `LEVEL_HINTS`
|
|
458
|
+
|
|
459
|
+
`{'schnell': 'Öffnen in Sekundenbruchteilen, geringer RAM-Bedarf', 'normal': 'Guter Kompromiss für die meisten Rechner', 'stark': 'Maximaler Schutz gegen Passwort-Raten, braucht 1 GiB RAM beim Öffnen'}`
|
|
460
|
+
|
|
461
|
+
### `DEFAULT_LEVEL`
|
|
462
|
+
|
|
463
|
+
`'normal'`
|
|
464
|
+
|
|
465
|
+
### `calibrate(target_seconds=2.0, *, max_memory_kib=1048576, lanes=4, timer=<function measure>)`
|
|
466
|
+
|
|
467
|
+
Argon2id-Parameter für eine Zielzeit auf diesem Rechner ("-l auto").
|
|
468
|
+
|
|
469
|
+
Speicher zuerst, weil er gegen Grafikkarten-Angriffe am meisten hilft: so
|
|
470
|
+
viel wie möglich, aber höchstens ``max_memory_kib`` (Standard 1 GiB) und ein
|
|
471
|
+
Viertel des freien Arbeitsspeichers – der Rechner, der den Container später
|
|
472
|
+
öffnet, braucht genauso viel. Ist schon eine Iteration zu langsam, wird der
|
|
473
|
+
Speicher halbiert (nicht unter 64 MiB). Die Iterationen füllen dann die
|
|
474
|
+
Zielzeit auf.
|
|
475
|
+
|
|
476
|
+
Die Dauer folgt T(t) ≈ A + B·t: A ist ein fester Anteil (vor allem das
|
|
477
|
+
Bereitstellen des Speichers), B der Anteil je Iteration. Gemessen werden
|
|
478
|
+
t = 1 und t = 2 (nach einem kleinen Aufwärmlauf), daraus t = (Ziel − A) / B.
|
|
479
|
+
Nur mit t = 1 zu rechnen zählt A bei jeder Iteration mit und verfehlt das
|
|
480
|
+
Ziel nach unten (gemessen: 1,3 statt 2 s). Kostet etwa T(1) + T(2) Messzeit.
|
|
481
|
+
|
|
482
|
+
``target_seconds``: Zielzeit; ``max_memory_kib``: Speichergrenze; ``lanes``: Parallelität (p); ``timer``: Messfunktion (für Tests).
|
|
483
|
+
|
|
484
|
+
### `ExcludeRules(patterns=())`
|
|
485
|
+
|
|
486
|
+
Menge von Mustern; ``matches`` bekommt Pfade mit "/" als Trenner.
|
|
487
|
+
|
|
488
|
+
### `ProgressEvent` (Datenklasse)
|
|
489
|
+
|
|
490
|
+
ProgressEvent(phase: 'str', done: 'int', total: 'int | None', item: 'str | None' = None, rate: 'float | None' = None, eta: 'float | None' = None, unit: 'str' = 'bytes', finished: 'bool' = False)
|
|
491
|
+
|
|
492
|
+
* `phase: str`
|
|
493
|
+
* `done: int`
|
|
494
|
+
* `total: int | None`
|
|
495
|
+
* `item: str | None`
|
|
496
|
+
* `rate: float | None`
|
|
497
|
+
* `eta: float | None`
|
|
498
|
+
* `unit: str`
|
|
499
|
+
* `finished: bool`
|
|
500
|
+
|
|
501
|
+
### `Monitor(callback=None, cancel=None, interval=0.1)`
|
|
502
|
+
|
|
503
|
+
Empfängt Fortschrittsereignisse (gedrosselt) und trägt ein Abbruch-Token.
|
|
504
|
+
|
|
505
|
+
### `CancelToken()`
|
|
506
|
+
|
|
507
|
+
Threadsicheres Abbruchsignal.
|
|
508
|
+
|
|
509
|
+
### `Tres0rError(Exception)`
|
|
510
|
+
|
|
511
|
+
Basisklasse für alle erwarteten Fehler.
|
|
512
|
+
|
|
513
|
+
### `FormatError(Tres0rError)`
|
|
514
|
+
|
|
515
|
+
Keine tres0r-Datei oder Header strukturell ungültig.
|
|
516
|
+
|
|
517
|
+
### `UnsupportedVersion(FormatError)`
|
|
518
|
+
|
|
519
|
+
Formatversion wird von dieser Programmversion nicht unterstützt.
|
|
520
|
+
|
|
521
|
+
### `WrongPassword(Tres0rError)`
|
|
522
|
+
|
|
523
|
+
Falsches Passwort – oder der Header wurde manipuliert.
|
|
524
|
+
|
|
525
|
+
Beides ist kryptografisch nicht unterscheidbar: Der komplette Header ist
|
|
526
|
+
als Associated Data an den verschlüsselten Datenschlüssel gebunden.
|
|
527
|
+
|
|
528
|
+
### `IntegrityError(Tres0rError)`
|
|
529
|
+
|
|
530
|
+
Nutzdaten beschädigt, manipuliert, abgeschnitten oder verlängert.
|
|
531
|
+
|
|
532
|
+
### `SignatureError(IntegrityError)`
|
|
533
|
+
|
|
534
|
+
Signatur fehlt, ist ungültig oder stammt nicht vom erwarteten Schlüssel.
|
|
535
|
+
|
|
536
|
+
### `UnsafeArchive(Tres0rError)`
|
|
537
|
+
|
|
538
|
+
Archivinhalt würde außerhalb des Zielordners schreiben o. Ä.
|
|
539
|
+
|
|
540
|
+
### `Cancelled(Tres0rError)`
|
|
541
|
+
|
|
542
|
+
Vorgang wurde abgebrochen (Nutzer oder Progress-Callback).
|
|
543
|
+
|
|
544
|
+
### `HibpUnavailable(Tres0rError)`
|
|
545
|
+
|
|
546
|
+
Have-I-Been-Pwned-Abfrage nicht möglich (offline, Timeout, …).
|
|
547
|
+
|
|
548
|
+
### `NameConflict(Tres0rError)`
|
|
549
|
+
|
|
550
|
+
Namen würden beim Entpacken kollidieren oder sind auf diesem System ungültig.
|
|
551
|
+
|
|
552
|
+
### `InsufficientSpace(Tres0rError)`
|
|
553
|
+
|
|
554
|
+
Auf dem Zieldatenträger ist voraussichtlich nicht genug Platz.
|
|
555
|
+
|
|
556
|
+
### `InsufficientMemory(Tres0rError)`
|
|
557
|
+
|
|
558
|
+
Die Schlüsselableitung bräuchte mehr Arbeitsspeicher als verfügbar.
|
|
559
|
+
|
|
560
|
+
### `KeyFormatError(Tres0rError, ValueError)`
|
|
561
|
+
|
|
562
|
+
Schlüssel- oder Anteiltext ist ungültig (Tippfehler, falsches Präfix, falsche Länge).
|
|
563
|
+
|
|
564
|
+
## `tres0r.keys`
|
|
565
|
+
|
|
566
|
+
Schlüssel für Format v2: X25519-Identitäten, Empfänger, Signaturschlüssel,
|
|
567
|
+
Wiederherstellungsphrasen.
|
|
568
|
+
|
|
569
|
+
### `Credentials` (Datenklasse)
|
|
570
|
+
|
|
571
|
+
Alles, womit ein Container entsperrt werden kann.
|
|
572
|
+
|
|
573
|
+
``prompt`` wird nur aufgerufen, wenn Identitäten nicht gereicht haben und
|
|
574
|
+
der Container Passwort- oder Wiederherstellungs-Slots hat.
|
|
575
|
+
|
|
576
|
+
* `passwords: list[str | bytes]`
|
|
577
|
+
* `identities: list[X25519PrivateKey]`
|
|
578
|
+
* `prompt: Callable[[], str] | None`
|
|
579
|
+
* `keyfiles: list[bytes]`
|
|
580
|
+
* `shares: list`
|
|
581
|
+
* `fido2: Callable | None`
|
|
582
|
+
|
|
583
|
+
### `KeyFormatError(Tres0rError, ValueError)`
|
|
584
|
+
|
|
585
|
+
Schlüssel- oder Anteiltext ist ungültig (Tippfehler, falsches Präfix, falsche Länge).
|
|
586
|
+
|
|
587
|
+
### `KEYFILE_BYTES`
|
|
588
|
+
|
|
589
|
+
`64`
|
|
590
|
+
|
|
591
|
+
### `generate_identity()`
|
|
592
|
+
|
|
593
|
+
Neue X25519-Identität (privater Schlüssel zum Entschlüsseln).
|
|
594
|
+
|
|
595
|
+
### `generate_signing_key()`
|
|
596
|
+
|
|
597
|
+
Neuer Ed25519-Signaturschlüssel.
|
|
598
|
+
|
|
599
|
+
### `generate_recovery(lang='de')`
|
|
600
|
+
|
|
601
|
+
Neue Wiederherstellungsphrase (``lang``: Wortliste "de" oder "en").
|
|
602
|
+
|
|
603
|
+
### `generate_keyfile(path)`
|
|
604
|
+
|
|
605
|
+
Neues Keyfile (64 Byte Zufall, Rechte 0600) an ``path``; überschreibt nie.
|
|
606
|
+
|
|
607
|
+
### `encode_identity(key)`
|
|
608
|
+
|
|
609
|
+
Privaten X25519-Schlüssel (``key``) als ``TRES0R-SECRET-…`` kodieren.
|
|
610
|
+
|
|
611
|
+
### `encode_recipient(key)`
|
|
612
|
+
|
|
613
|
+
Öffentlichen X25519-Schlüssel (``key``) als ``tres0r-pub-…`` kodieren.
|
|
614
|
+
|
|
615
|
+
### `encode_signing_key(key)`
|
|
616
|
+
|
|
617
|
+
Ed25519-Signaturschlüssel (``key``) als Text kodieren.
|
|
618
|
+
|
|
619
|
+
### `encode_verify_key(key)`
|
|
620
|
+
|
|
621
|
+
Ed25519-Prüfschlüssel (``key``) als ``tres0r-sig-…`` kodieren.
|
|
622
|
+
|
|
623
|
+
### `parse_identity(text)`
|
|
624
|
+
|
|
625
|
+
``TRES0R-SECRET-…`` aus ``text`` lesen; ``KeyFormatError`` bei Tippfehlern.
|
|
626
|
+
|
|
627
|
+
### `parse_recipient(text)`
|
|
628
|
+
|
|
629
|
+
``tres0r-pub-…`` aus ``text`` lesen; ``KeyFormatError`` bei Tippfehlern.
|
|
630
|
+
|
|
631
|
+
### `parse_signing_key(text)`
|
|
632
|
+
|
|
633
|
+
Signaturschlüssel aus ``text`` lesen; ``KeyFormatError`` bei Tippfehlern.
|
|
634
|
+
|
|
635
|
+
### `parse_verify_key(text)`
|
|
636
|
+
|
|
637
|
+
``tres0r-sig-…`` aus ``text`` lesen; ``KeyFormatError`` bei Tippfehlern.
|
|
638
|
+
|
|
639
|
+
### `load_identities(path, passphrase=None)`
|
|
640
|
+
|
|
641
|
+
Alle X25519-Identitäten aus einer Identitätsdatei (ggf. mit ``passphrase``).
|
|
642
|
+
|
|
643
|
+
### `load_recipients(path, passphrase=None)`
|
|
644
|
+
|
|
645
|
+
Empfängerliste (ein Schlüssel pro Zeile) oder eine Identitätsdatei.
|
|
646
|
+
|
|
647
|
+
### `load_signing_keys(path, passphrase=None)`
|
|
648
|
+
|
|
649
|
+
Alle Signaturschlüssel aus einer Identitätsdatei (ggf. mit ``passphrase``).
|
|
650
|
+
|
|
651
|
+
### `load_verify_keys(path, passphrase=None)`
|
|
652
|
+
|
|
653
|
+
Liste von Prüfschlüsseln (tres0r-sig-…) oder eine Identitätsdatei mit Signaturschlüssel.
|
|
654
|
+
|
|
655
|
+
### `write_identity_file(path, keys, passphrase=None, params=None)`
|
|
656
|
+
|
|
657
|
+
Neue Identitätsdatei mit Rechten 0600 anlegen; überschreibt nie.
|
|
658
|
+
|
|
659
|
+
Mit ``passphrase`` wird sie als tres0r-Container verschlüsselt
|
|
660
|
+
(Standardstufe "stark", da die Datei genau gegen Offline-Raten schützen soll).
|
|
661
|
+
|
|
662
|
+
``keys``: ein oder mehrere private Schlüssel; ``params``: Argon2id für den Schutz mit ``passphrase``.
|
|
663
|
+
|
|
664
|
+
### `protect_identity_file(path, passphrase, params=None)`
|
|
665
|
+
|
|
666
|
+
Bestehende ungeschützte Identitätsdatei verschlüsseln (atomar ersetzt, 0600).
|
|
667
|
+
|
|
668
|
+
### `is_protected(path)`
|
|
669
|
+
|
|
670
|
+
Ist die Identitätsdatei mit einer Passphrase geschützt?
|
|
671
|
+
|
|
672
|
+
### `public_text(key)`
|
|
673
|
+
|
|
674
|
+
Öffentlicher Teil als Text – Empfänger- oder Prüfschlüssel.
|
|
675
|
+
|
|
676
|
+
``key``: privater X25519- oder Ed25519-Schlüssel.
|
|
677
|
+
|
|
678
|
+
### `keyfile_secret(path)`
|
|
679
|
+
|
|
680
|
+
K = SHA-256("tres0r keyfile" ‖ Dateiinhalt) – beliebige Dateien sind möglich,
|
|
681
|
+
empfohlen ist ein mit ``generate_keyfile`` erzeugtes (512 Bit Zufall).
|
|
682
|
+
|
|
683
|
+
### `keyfile_id(secret)`
|
|
684
|
+
|
|
685
|
+
Kennung im Keyslot: erkennt ein falsches Keyfile, bevor Argon2 läuft.
|
|
686
|
+
|
|
687
|
+
``secret``: Ergebnis von ``keyfile_secret``.
|
|
688
|
+
|
|
689
|
+
## `tres0r.shamir`
|
|
690
|
+
|
|
691
|
+
Schwellwert-Wiederherstellung: Shamirs Secret Sharing über GF(2⁸).
|
|
692
|
+
|
|
693
|
+
### `Share` (Datenklasse)
|
|
694
|
+
|
|
695
|
+
Share(set_id: 'bytes', k: 'int', n: 'int', x: 'int', y: 'bytes')
|
|
696
|
+
|
|
697
|
+
* `set_id: bytes`
|
|
698
|
+
* `k: int`
|
|
699
|
+
* `n: int`
|
|
700
|
+
* `x: int`
|
|
701
|
+
* `y: bytes`
|
|
702
|
+
|
|
703
|
+
### `split(secret, k, n, set_id=None)`
|
|
704
|
+
|
|
705
|
+
Geheimnis in n Anteile zerlegen, von denen k genügen.
|
|
706
|
+
|
|
707
|
+
``secret``: 32 Byte; ``k``/``n``: nötige/alle Anteile; ``set_id``: 8 Byte (sonst zufällig).
|
|
708
|
+
|
|
709
|
+
### `combine(shares)`
|
|
710
|
+
|
|
711
|
+
Geheimnis aus mindestens k Anteilen desselben Satzes (Lagrange an x = 0).
|
|
712
|
+
|
|
713
|
+
``shares``: mindestens k Anteile desselben Satzes; zu wenige -> ``WrongPassword``.
|
|
714
|
+
|
|
715
|
+
### `parse_share(text)`
|
|
716
|
+
|
|
717
|
+
Anteil ``tres0r-teil-…`` aus ``text`` lesen (Prüfsumme, kanonische Schreibweise).
|
|
718
|
+
|
|
719
|
+
### `PREFIX`
|
|
720
|
+
|
|
721
|
+
`'tres0r-teil-'`
|
|
722
|
+
|
|
723
|
+
### `SECRET_LEN`
|
|
724
|
+
|
|
725
|
+
`32`
|
|
726
|
+
|
|
727
|
+
### `MAX_SHARES`
|
|
728
|
+
|
|
729
|
+
`32`
|
|
730
|
+
|
|
731
|
+
## `tres0r.progress`
|
|
732
|
+
|
|
733
|
+
Fortschritt und Abbruch für lange Vorgänge (für CLI, TUI und GUI).
|
|
734
|
+
|
|
735
|
+
### `ProgressEvent` (Datenklasse)
|
|
736
|
+
|
|
737
|
+
ProgressEvent(phase: 'str', done: 'int', total: 'int | None', item: 'str | None' = None, rate: 'float | None' = None, eta: 'float | None' = None, unit: 'str' = 'bytes', finished: 'bool' = False)
|
|
738
|
+
|
|
739
|
+
* `phase: str`
|
|
740
|
+
* `done: int`
|
|
741
|
+
* `total: int | None`
|
|
742
|
+
* `item: str | None`
|
|
743
|
+
* `rate: float | None`
|
|
744
|
+
* `eta: float | None`
|
|
745
|
+
* `unit: str`
|
|
746
|
+
* `finished: bool`
|
|
747
|
+
|
|
748
|
+
### `CancelToken()`
|
|
749
|
+
|
|
750
|
+
Threadsicheres Abbruchsignal.
|
|
751
|
+
|
|
752
|
+
### `Monitor(callback=None, cancel=None, interval=0.1)`
|
|
753
|
+
|
|
754
|
+
Empfängt Fortschrittsereignisse (gedrosselt) und trägt ein Abbruch-Token.
|
|
755
|
+
|
|
756
|
+
### `Progress` (Typ)
|
|
757
|
+
|
|
758
|
+
`Callable[[int, int], None] | Monitor | None`
|
|
759
|
+
|
|
760
|
+
### `UNIT_BYTES`
|
|
761
|
+
|
|
762
|
+
`'bytes'`
|
|
763
|
+
|
|
764
|
+
### `UNIT_ENTRIES`
|
|
765
|
+
|
|
766
|
+
`'einträge'`
|
|
767
|
+
|
|
768
|
+
## `tres0r.errors`
|
|
769
|
+
|
|
770
|
+
Fehlerklassen von tres0r.
|
|
771
|
+
|
|
772
|
+
### `Tres0rError(Exception)`
|
|
773
|
+
|
|
774
|
+
Basisklasse für alle erwarteten Fehler.
|
|
775
|
+
|
|
776
|
+
### `FormatError(Tres0rError)`
|
|
777
|
+
|
|
778
|
+
Keine tres0r-Datei oder Header strukturell ungültig.
|
|
779
|
+
|
|
780
|
+
### `UnsupportedVersion(FormatError)`
|
|
781
|
+
|
|
782
|
+
Formatversion wird von dieser Programmversion nicht unterstützt.
|
|
783
|
+
|
|
784
|
+
### `WrongPassword(Tres0rError)`
|
|
785
|
+
|
|
786
|
+
Falsches Passwort – oder der Header wurde manipuliert.
|
|
787
|
+
|
|
788
|
+
Beides ist kryptografisch nicht unterscheidbar: Der komplette Header ist
|
|
789
|
+
als Associated Data an den verschlüsselten Datenschlüssel gebunden.
|
|
790
|
+
|
|
791
|
+
### `IntegrityError(Tres0rError)`
|
|
792
|
+
|
|
793
|
+
Nutzdaten beschädigt, manipuliert, abgeschnitten oder verlängert.
|
|
794
|
+
|
|
795
|
+
### `SignatureError(IntegrityError)`
|
|
796
|
+
|
|
797
|
+
Signatur fehlt, ist ungültig oder stammt nicht vom erwarteten Schlüssel.
|
|
798
|
+
|
|
799
|
+
### `UnsafeArchive(Tres0rError)`
|
|
800
|
+
|
|
801
|
+
Archivinhalt würde außerhalb des Zielordners schreiben o. Ä.
|
|
802
|
+
|
|
803
|
+
### `Cancelled(Tres0rError)`
|
|
804
|
+
|
|
805
|
+
Vorgang wurde abgebrochen (Nutzer oder Progress-Callback).
|
|
806
|
+
|
|
807
|
+
### `HibpUnavailable(Tres0rError)`
|
|
808
|
+
|
|
809
|
+
Have-I-Been-Pwned-Abfrage nicht möglich (offline, Timeout, …).
|
|
810
|
+
|
|
811
|
+
### `NameConflict(Tres0rError)`
|
|
812
|
+
|
|
813
|
+
Namen würden beim Entpacken kollidieren oder sind auf diesem System ungültig.
|
|
814
|
+
|
|
815
|
+
### `InsufficientSpace(Tres0rError)`
|
|
816
|
+
|
|
817
|
+
Auf dem Zieldatenträger ist voraussichtlich nicht genug Platz.
|
|
818
|
+
|
|
819
|
+
### `InsufficientMemory(Tres0rError)`
|
|
820
|
+
|
|
821
|
+
Die Schlüsselableitung bräuchte mehr Arbeitsspeicher als verfügbar.
|
|
822
|
+
|
|
823
|
+
### `KeyFormatError(Tres0rError, ValueError)`
|
|
824
|
+
|
|
825
|
+
Schlüssel- oder Anteiltext ist ungültig (Tippfehler, falsches Präfix, falsche Länge).
|
|
826
|
+
|
|
827
|
+
## `tres0r.passgen`
|
|
828
|
+
|
|
829
|
+
Anbindung von pwgen an tres0r.
|
|
830
|
+
|
|
831
|
+
### `Secret` (Datenklasse)
|
|
832
|
+
|
|
833
|
+
Secret(value: 'str', kind: 'str', entropy_bits: 'float')
|
|
834
|
+
|
|
835
|
+
* `value: str`
|
|
836
|
+
* `kind: str`
|
|
837
|
+
* `entropy_bits: float`
|
|
838
|
+
|
|
839
|
+
### `PasswordCheck` (Datenklasse)
|
|
840
|
+
|
|
841
|
+
PasswordCheck(length: 'int', classes: 'int', pwned: 'int | None' = None, hibp_error: 'str | None' = None, warnings: 'list[str]' = <factory>)
|
|
842
|
+
|
|
843
|
+
* `length: int`
|
|
844
|
+
* `classes: int`
|
|
845
|
+
* `pwned: int | None`
|
|
846
|
+
* `hibp_error: str | None`
|
|
847
|
+
* `warnings: list[str]`
|
|
848
|
+
|
|
849
|
+
### `generate_password(length=20, *, symbols=True, exclude_ambiguous=False)`
|
|
850
|
+
|
|
851
|
+
Wie pwgen: Klein-, Großbuchstaben und Ziffern immer, Sonderzeichen optional.
|
|
852
|
+
|
|
853
|
+
``length``: Zeichen; ``symbols``: Sonderzeichen verwenden; ``exclude_ambiguous``: Verwechselbares (0/O, 1/l/I) weglassen.
|
|
854
|
+
|
|
855
|
+
### `generate_passphrase(words=8, *, lang='de', separator='-', capitalize=False, append_digit=False, wordlist=None)`
|
|
856
|
+
|
|
857
|
+
Passphrase aus ``words`` Wörtern der Liste ``lang`` (oder ``wordlist``), getrennt durch ``separator``; optional ``capitalize``/``append_digit``.
|
|
858
|
+
|
|
859
|
+
Wörter, die das Trennzeichen enthalten (z. B. "t-shirt" in der englischen Liste),
|
|
860
|
+
bleiben außen vor – sonst wären die Wortgrenzen mehrdeutig. Die Entropie zählt
|
|
861
|
+
nur die tatsächlich verwendbaren Wörter.
|
|
862
|
+
|
|
863
|
+
### `check_password(password, *, online=False)`
|
|
864
|
+
|
|
865
|
+
Selbst gewähltes Passwort prüfen.
|
|
866
|
+
|
|
867
|
+
Bewusst ohne Entropie-Schätzung: Heuristiken wie "Länge × Zeichenvorrat"
|
|
868
|
+
überschätzen menschlich gewählte Passwörter massiv ("Sommer2026!" wirkt
|
|
869
|
+
nach 72 Bit, ist aber in Sekunden geraten). Stattdessen harte Kriterien
|
|
870
|
+
plus – nur wenn ``online`` – der Abgleich mit echten Datenlecks.
|
|
871
|
+
|
|
872
|
+
### `hibp_count(password)`
|
|
873
|
+
|
|
874
|
+
Treffer in der Pwned-Passwords-Datenbank (k-Anonymität, siehe pwgen).
|
|
875
|
+
|
|
876
|
+
### `load_wordlist(lang='de')`
|
|
877
|
+
|
|
878
|
+
Mitgelieferte Diceware-Liste über pwgen laden (je 7776 Wörter).
|
|
879
|
+
|
|
880
|
+
### `load_wordlist_file(path)`
|
|
881
|
+
|
|
882
|
+
Eigene Liste laden – gleiches Format wie pwgen ('würfel<TAB>wort' oder nur 'wort').
|
|
883
|
+
|
|
884
|
+
### `LANGUAGES`
|
|
885
|
+
|
|
886
|
+
`('en', 'de')`
|
|
887
|
+
|
|
888
|
+
### `AMBIGUOUS`
|
|
889
|
+
|
|
890
|
+
`['0', '1', 'I', 'O', 'l', '|']`
|
|
891
|
+
|
|
892
|
+
### `RECOMMENDED_BITS`
|
|
893
|
+
|
|
894
|
+
`80`
|
|
895
|
+
|
|
896
|
+
### `DEFAULT_SEPARATOR`
|
|
897
|
+
|
|
898
|
+
`'-'`
|
|
899
|
+
|
|
900
|
+
### `PASSWORD_MIN_LEN`
|
|
901
|
+
|
|
902
|
+
`8`
|
|
903
|
+
|
|
904
|
+
### `PASSWORD_MAX_LEN`
|
|
905
|
+
|
|
906
|
+
`128`
|
|
907
|
+
|
|
908
|
+
### `DEFAULT_PASSWORD_LEN`
|
|
909
|
+
|
|
910
|
+
`20`
|
|
911
|
+
|
|
912
|
+
### `PASSPHRASE_MIN_WORDS`
|
|
913
|
+
|
|
914
|
+
`8`
|
|
915
|
+
|
|
916
|
+
### `PASSPHRASE_MAX_WORDS`
|
|
917
|
+
|
|
918
|
+
`40`
|
|
919
|
+
|
|
920
|
+
### `DEFAULT_WORDS`
|
|
921
|
+
|
|
922
|
+
`8`
|
|
923
|
+
|
|
924
|
+
## `tres0r.hwtoken`
|
|
925
|
+
|
|
926
|
+
FIDO2-Token (YubiKey, Nitrokey, SoloKey …) als zweiter Faktor über hmac-secret.
|
|
927
|
+
|
|
928
|
+
### `TokenProvider(found=None, *, notify=None, pin=None)`
|
|
929
|
+
|
|
930
|
+
Für ``Credentials.fido2``: fragt angeschlossene Tokens nach dem Geheimnis.
|
|
931
|
+
|
|
932
|
+
Probiert jedes Gerät, bis eines den Credential kennt (fremde Geräte lehnen
|
|
933
|
+
ohne Berührung ab). Ergebnisse werden für diesen Vorgang zwischengespeichert,
|
|
934
|
+
damit z. B. ``passwd`` keine zweite Berührung braucht.
|
|
935
|
+
|
|
936
|
+
### `devices()`
|
|
937
|
+
|
|
938
|
+
Angeschlossene FIDO2-Geräte (USB-HID).
|
|
939
|
+
|
|
940
|
+
### `describe(device)`
|
|
941
|
+
|
|
942
|
+
Anzeigename eines Geräts (``device`` aus ``devices()``).
|
|
943
|
+
|
|
944
|
+
### `enroll(device, *, notify=None, pin=None)`
|
|
945
|
+
|
|
946
|
+
Neuen Credential mit hmac-secret anlegen; gibt die Credential-ID zurück.
|
|
947
|
+
|
|
948
|
+
``device``: Gerät aus ``devices()``; ``notify``: Hinweis-Funktion ("bitte berühren"); ``pin``: liefert die Token-PIN, falls verlangt.
|
|
949
|
+
|
|
950
|
+
### `secret(device, credential_id, salt, *, notify=None, pin=None)`
|
|
951
|
+
|
|
952
|
+
32-Byte-Geheimnis des Credentials für ``salt`` (Berührung nötig).
|
|
953
|
+
|
|
954
|
+
``device``: Gerät; ``credential_id``: aus ``enroll``; ``salt``: 32 Byte; ``notify``/``pin`` wie bei ``enroll``.
|
|
955
|
+
|
|
956
|
+
### `RP_ID`
|
|
957
|
+
|
|
958
|
+
`'tres0r.local'`
|
|
959
|
+
|
|
960
|
+
### `SALT_LEN`
|
|
961
|
+
|
|
962
|
+
`32`
|
|
963
|
+
|
|
964
|
+
## `tres0r.mount`
|
|
965
|
+
|
|
966
|
+
Container schreibgeschützt einhängen (FUSE).
|
|
967
|
+
|
|
968
|
+
### `ContainerFS(container, credentials)`
|
|
969
|
+
|
|
970
|
+
Schreibgeschützte Sicht auf einen entsperrten Container.
|
|
971
|
+
|
|
972
|
+
### `Node` (Datenklasse)
|
|
973
|
+
|
|
974
|
+
Node(kind: 'str', size: 'int' = 0, mtime: 'int' = 0, entry: 'payload.IndexEntry | None' = None, segment: 'int' = 0, link: 'str | None' = None, children: 'dict[str, Node]' = <factory>)
|
|
975
|
+
|
|
976
|
+
* `kind: str`
|
|
977
|
+
* `size: int`
|
|
978
|
+
* `mtime: int`
|
|
979
|
+
* `entry: payload.IndexEntry | None`
|
|
980
|
+
* `segment: int`
|
|
981
|
+
* `link: str | None`
|
|
982
|
+
* `children: dict[str, Node]`
|
|
983
|
+
|
|
984
|
+
### `mount(container, mountpoint, credentials, *, foreground=True, allow_other=False)`
|
|
985
|
+
|
|
986
|
+
Container einhängen; kehrt erst nach dem Aushängen zurück (Strg+C oder
|
|
987
|
+
``fusermount -u``). Braucht fusepy und libfuse (Linux) bzw. macFUSE (macOS).
|
|
988
|
+
|
|
989
|
+
``mountpoint``: leerer Ordner; ``foreground``: blockiert bis zum Aushängen; ``allow_other``: auch andere Benutzer dürfen lesen (FUSE-Option).
|
|
990
|
+
|
|
991
|
+
### `unmount(mountpoint)`
|
|
992
|
+
|
|
993
|
+
Eingehängten Container unter ``mountpoint`` aushängen (fusermount bzw. umount).
|