rtty-soda 0.2.2__py3-none-any.whl → 0.2.4__py3-none-any.whl
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.
Potentially problematic release.
This version of rtty-soda might be problematic. Click here for more details.
- rtty_soda/cli_io.py +14 -8
- rtty_soda/main.py +163 -98
- {rtty_soda-0.2.2.dist-info → rtty_soda-0.2.4.dist-info}/METADATA +50 -70
- {rtty_soda-0.2.2.dist-info → rtty_soda-0.2.4.dist-info}/RECORD +6 -6
- {rtty_soda-0.2.2.dist-info → rtty_soda-0.2.4.dist-info}/WHEEL +0 -0
- {rtty_soda-0.2.2.dist-info → rtty_soda-0.2.4.dist-info}/entry_points.txt +0 -0
rtty_soda/cli_io.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import random
|
|
2
2
|
import re
|
|
3
3
|
import string
|
|
4
|
-
from typing import TYPE_CHECKING, TextIO, cast
|
|
4
|
+
from typing import TYPE_CHECKING, BinaryIO, TextIO, cast
|
|
5
5
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
7
|
from pathlib import Path
|
|
@@ -15,6 +15,7 @@ __all__ = [
|
|
|
15
15
|
"pad_newlines",
|
|
16
16
|
"print_stats",
|
|
17
17
|
"read_bytes",
|
|
18
|
+
"read_ciphertext_bytes",
|
|
18
19
|
"read_encoded_stripped",
|
|
19
20
|
"read_key_bytes",
|
|
20
21
|
"read_password_bytes",
|
|
@@ -31,6 +32,11 @@ def read_str(source: Path) -> str:
|
|
|
31
32
|
return cast("TextIO", fd).read()
|
|
32
33
|
|
|
33
34
|
|
|
35
|
+
def read_bytes(source: Path) -> bytes:
|
|
36
|
+
with click.open_file(source, mode="rb") as fd:
|
|
37
|
+
return cast("BinaryIO", fd).read()
|
|
38
|
+
|
|
39
|
+
|
|
34
40
|
def remove_whitespace(data: str) -> str:
|
|
35
41
|
return re.sub(r"\s", "", data)
|
|
36
42
|
|
|
@@ -41,15 +47,15 @@ def read_encoded_stripped(source: Path) -> bytes:
|
|
|
41
47
|
return encode_str(data)
|
|
42
48
|
|
|
43
49
|
|
|
44
|
-
def
|
|
50
|
+
def read_ciphertext_bytes(source: Path, encoder: Encoder) -> bytes:
|
|
45
51
|
if encoder.is_binary:
|
|
46
|
-
return
|
|
52
|
+
return read_bytes(source)
|
|
47
53
|
|
|
48
54
|
return read_encoded_stripped(source)
|
|
49
55
|
|
|
50
56
|
|
|
51
57
|
def read_key_bytes(source: Path, encoder: Encoder) -> bytes:
|
|
52
|
-
key =
|
|
58
|
+
key = read_ciphertext_bytes(source, encoder)
|
|
53
59
|
return encoder.decode(key)
|
|
54
60
|
|
|
55
61
|
|
|
@@ -106,8 +112,8 @@ def write_output(target: Path | None, data: bytes) -> None:
|
|
|
106
112
|
write_bytes_atomic(target, data)
|
|
107
113
|
|
|
108
114
|
|
|
109
|
-
def print_stats(plaintext:
|
|
110
|
-
click.echo(f"Plaintext: {
|
|
111
|
-
click.echo(f"Ciphertext: {
|
|
112
|
-
overhead =
|
|
115
|
+
def print_stats(plaintext: int, ciphertext: int) -> None:
|
|
116
|
+
click.echo(f"Plaintext: {plaintext}", err=True)
|
|
117
|
+
click.echo(f"Ciphertext: {ciphertext}", err=True)
|
|
118
|
+
overhead = ciphertext / plaintext
|
|
113
119
|
click.echo(f"Overhead: {overhead:.3f}", err=True)
|
rtty_soda/main.py
CHANGED
|
@@ -9,6 +9,7 @@ from rtty_soda.cli_io import (
|
|
|
9
9
|
format_output,
|
|
10
10
|
print_stats,
|
|
11
11
|
read_bytes,
|
|
12
|
+
read_ciphertext_bytes,
|
|
12
13
|
read_key_bytes,
|
|
13
14
|
read_password_bytes,
|
|
14
15
|
write_output,
|
|
@@ -40,12 +41,16 @@ def cli() -> None:
|
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
@cli.command() # pyright: ignore[reportAny]
|
|
43
|
-
@click.option(
|
|
44
|
+
@click.option(
|
|
45
|
+
"--encoding", "-e", default="base64", show_default=True, envvar="KEY_ENCODING"
|
|
46
|
+
)
|
|
44
47
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
45
|
-
@click.option("--group-len", default=0, show_default=True)
|
|
46
|
-
@click.option("--line-len", default=80, show_default=True)
|
|
47
|
-
@click.option("--padding", default=0, show_default=True)
|
|
48
|
-
@click.option(
|
|
48
|
+
@click.option("--group-len", default=0, show_default=True, envvar="GROUP_LEN")
|
|
49
|
+
@click.option("--line-len", default=80, show_default=True, envvar="LINE_LEN")
|
|
50
|
+
@click.option("--padding", default=0, show_default=True, envvar="PADDING")
|
|
51
|
+
@click.option(
|
|
52
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
53
|
+
)
|
|
49
54
|
def genkey_cmd(
|
|
50
55
|
encoding: str,
|
|
51
56
|
output_file: Path | None,
|
|
@@ -63,10 +68,10 @@ def genkey_cmd(
|
|
|
63
68
|
key = bytes(PrivateKey.generate())
|
|
64
69
|
key = enc.encode(key)
|
|
65
70
|
|
|
66
|
-
|
|
71
|
+
formatted, groups = format_output(
|
|
67
72
|
data=key, encoder=enc, group_len=group_len, line_len=line_len, padding=padding
|
|
68
73
|
)
|
|
69
|
-
write_output(target=output_file, data=
|
|
74
|
+
write_output(target=output_file, data=formatted)
|
|
70
75
|
|
|
71
76
|
if verbose:
|
|
72
77
|
click.echo(f"Groups: {groups}", err=True)
|
|
@@ -74,12 +79,16 @@ def genkey_cmd(
|
|
|
74
79
|
|
|
75
80
|
@cli.command() # pyright: ignore[reportAny]
|
|
76
81
|
@click.argument("private_key_file", type=in_path)
|
|
77
|
-
@click.option(
|
|
82
|
+
@click.option(
|
|
83
|
+
"--encoding", "-e", default="base64", show_default=True, envvar="KEY_ENCODING"
|
|
84
|
+
)
|
|
78
85
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
79
|
-
@click.option("--group-len", default=0, show_default=True)
|
|
80
|
-
@click.option("--line-len", default=80, show_default=True)
|
|
81
|
-
@click.option("--padding", default=0, show_default=True)
|
|
82
|
-
@click.option(
|
|
86
|
+
@click.option("--group-len", default=0, show_default=True, envvar="GROUP_LEN")
|
|
87
|
+
@click.option("--line-len", default=80, show_default=True, envvar="LINE_LEN")
|
|
88
|
+
@click.option("--padding", default=0, show_default=True, envvar="PADDING")
|
|
89
|
+
@click.option(
|
|
90
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
91
|
+
)
|
|
83
92
|
def pubkey_cmd(
|
|
84
93
|
private_key_file: Path,
|
|
85
94
|
encoding: str,
|
|
@@ -100,10 +109,10 @@ def pubkey_cmd(
|
|
|
100
109
|
pub = bytes(priv.public_key)
|
|
101
110
|
pub = enc.encode(pub)
|
|
102
111
|
|
|
103
|
-
|
|
112
|
+
formatted, groups = format_output(
|
|
104
113
|
data=pub, encoder=enc, group_len=group_len, line_len=line_len, padding=padding
|
|
105
114
|
)
|
|
106
|
-
write_output(target=output_file, data=
|
|
115
|
+
write_output(target=output_file, data=formatted)
|
|
107
116
|
|
|
108
117
|
if verbose:
|
|
109
118
|
click.echo(f"Groups: {groups}", err=True)
|
|
@@ -111,13 +120,19 @@ def pubkey_cmd(
|
|
|
111
120
|
|
|
112
121
|
@cli.command() # pyright: ignore[reportAny]
|
|
113
122
|
@click.argument("password_file", type=in_path)
|
|
114
|
-
@click.option(
|
|
115
|
-
|
|
123
|
+
@click.option(
|
|
124
|
+
"--encoding", "-e", default="base64", show_default=True, envvar="KEY_ENCODING"
|
|
125
|
+
)
|
|
126
|
+
@click.option(
|
|
127
|
+
"--profile", "-p", default="sensitive", show_default=True, envvar="KDF_PROFILE"
|
|
128
|
+
)
|
|
116
129
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
117
|
-
@click.option("--group-len", default=0, show_default=True)
|
|
118
|
-
@click.option("--line-len", default=80, show_default=True)
|
|
119
|
-
@click.option("--padding", default=0, show_default=True)
|
|
120
|
-
@click.option(
|
|
130
|
+
@click.option("--group-len", default=0, show_default=True, envvar="GROUP_LEN")
|
|
131
|
+
@click.option("--line-len", default=80, show_default=True, envvar="LINE_LEN")
|
|
132
|
+
@click.option("--padding", default=0, show_default=True, envvar="PADDING")
|
|
133
|
+
@click.option(
|
|
134
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
135
|
+
)
|
|
121
136
|
def kdf_cmd(
|
|
122
137
|
password_file: Path,
|
|
123
138
|
encoding: str,
|
|
@@ -141,10 +156,10 @@ def kdf_cmd(
|
|
|
141
156
|
key = kdf(password=pw, profile=prof)
|
|
142
157
|
key = enc.encode(key)
|
|
143
158
|
|
|
144
|
-
|
|
159
|
+
formatted, groups = format_output(
|
|
145
160
|
data=key, encoder=enc, group_len=group_len, line_len=line_len, padding=padding
|
|
146
161
|
)
|
|
147
|
-
write_output(target=output_file, data=
|
|
162
|
+
write_output(target=output_file, data=formatted)
|
|
148
163
|
|
|
149
164
|
if verbose:
|
|
150
165
|
click.echo(f"Groups: {groups}", err=True)
|
|
@@ -154,14 +169,22 @@ def kdf_cmd(
|
|
|
154
169
|
@click.argument("private_key_file", type=in_path)
|
|
155
170
|
@click.argument("public_key_file", type=in_path)
|
|
156
171
|
@click.argument("message_file", type=in_path)
|
|
157
|
-
@click.option(
|
|
158
|
-
|
|
159
|
-
|
|
172
|
+
@click.option(
|
|
173
|
+
"--key-encoding", default="base64", show_default=True, envvar="KEY_ENCODING"
|
|
174
|
+
)
|
|
175
|
+
@click.option(
|
|
176
|
+
"--data-encoding", "-e", default="base64", show_default=True, envvar="DATA_ENCODING"
|
|
177
|
+
)
|
|
178
|
+
@click.option(
|
|
179
|
+
"--compression", "-c", default="zstd", show_default=True, envvar="COMPRESSION"
|
|
180
|
+
)
|
|
160
181
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
161
|
-
@click.option("--group-len", default=0, show_default=True)
|
|
162
|
-
@click.option("--line-len", default=80, show_default=True)
|
|
163
|
-
@click.option("--padding", default=0, show_default=True)
|
|
164
|
-
@click.option(
|
|
182
|
+
@click.option("--group-len", default=0, show_default=True, envvar="GROUP_LEN")
|
|
183
|
+
@click.option("--line-len", default=80, show_default=True, envvar="LINE_LEN")
|
|
184
|
+
@click.option("--padding", default=0, show_default=True, envvar="PADDING")
|
|
185
|
+
@click.option(
|
|
186
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
187
|
+
)
|
|
165
188
|
def encrypt_public_cmd(
|
|
166
189
|
private_key_file: Path,
|
|
167
190
|
public_key_file: Path,
|
|
@@ -189,36 +212,44 @@ def encrypt_public_cmd(
|
|
|
189
212
|
priv = PrivateKey(private_key=priv)
|
|
190
213
|
pub = read_key_bytes(source=public_key_file, encoder=key_enc)
|
|
191
214
|
pub = PublicKey(public_key=pub)
|
|
192
|
-
|
|
193
|
-
data = archiver(
|
|
215
|
+
plaintext = read_bytes(message_file)
|
|
216
|
+
data = archiver(plaintext)
|
|
194
217
|
data = public.encrypt(private=priv, public=pub, data=data)
|
|
195
|
-
|
|
218
|
+
ciphertext = data_enc.encode(data)
|
|
196
219
|
|
|
197
|
-
|
|
198
|
-
data=
|
|
220
|
+
formatted, groups = format_output(
|
|
221
|
+
data=ciphertext,
|
|
199
222
|
encoder=data_enc,
|
|
200
223
|
group_len=group_len,
|
|
201
224
|
line_len=line_len,
|
|
202
225
|
padding=padding,
|
|
203
226
|
)
|
|
204
|
-
write_output(target=output_file, data=
|
|
227
|
+
write_output(target=output_file, data=formatted)
|
|
205
228
|
|
|
206
229
|
if verbose:
|
|
207
|
-
print_stats(plaintext
|
|
230
|
+
print_stats(len(plaintext), len(ciphertext))
|
|
208
231
|
click.echo(f"Groups: {groups}", err=True)
|
|
209
232
|
|
|
210
233
|
|
|
211
234
|
@cli.command(aliases=["es"]) # pyright: ignore[reportAny]
|
|
212
235
|
@click.argument("key_file", type=in_path)
|
|
213
236
|
@click.argument("message_file", type=in_path)
|
|
214
|
-
@click.option(
|
|
215
|
-
|
|
216
|
-
|
|
237
|
+
@click.option(
|
|
238
|
+
"--key-encoding", default="base64", show_default=True, envvar="KEY_ENCODING"
|
|
239
|
+
)
|
|
240
|
+
@click.option(
|
|
241
|
+
"--data-encoding", "-e", default="base64", show_default=True, envvar="DATA_ENCODING"
|
|
242
|
+
)
|
|
243
|
+
@click.option(
|
|
244
|
+
"--compression", "-c", default="zstd", show_default=True, envvar="COMPRESSION"
|
|
245
|
+
)
|
|
217
246
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
218
|
-
@click.option("--group-len", default=0, show_default=True)
|
|
219
|
-
@click.option("--line-len", default=80, show_default=True)
|
|
220
|
-
@click.option("--padding", default=0, show_default=True)
|
|
221
|
-
@click.option(
|
|
247
|
+
@click.option("--group-len", default=0, show_default=True, envvar="GROUP_LEN")
|
|
248
|
+
@click.option("--line-len", default=80, show_default=True, envvar="LINE_LEN")
|
|
249
|
+
@click.option("--padding", default=0, show_default=True, envvar="PADDING")
|
|
250
|
+
@click.option(
|
|
251
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
252
|
+
)
|
|
222
253
|
def encrypt_secret_cmd(
|
|
223
254
|
key_file: Path,
|
|
224
255
|
message_file: Path,
|
|
@@ -242,36 +273,44 @@ def encrypt_secret_cmd(
|
|
|
242
273
|
archiver = ARCHIVERS[compression]
|
|
243
274
|
|
|
244
275
|
key = read_key_bytes(source=key_file, encoder=key_enc)
|
|
245
|
-
|
|
246
|
-
data = archiver(
|
|
276
|
+
plaintext = read_bytes(message_file)
|
|
277
|
+
data = archiver(plaintext)
|
|
247
278
|
data = secret.encrypt(key=key, data=data)
|
|
248
|
-
|
|
279
|
+
ciphertext = data_enc.encode(data)
|
|
249
280
|
|
|
250
|
-
|
|
251
|
-
data=
|
|
281
|
+
formatted, groups = format_output(
|
|
282
|
+
data=ciphertext,
|
|
252
283
|
encoder=data_enc,
|
|
253
284
|
group_len=group_len,
|
|
254
285
|
line_len=line_len,
|
|
255
286
|
padding=padding,
|
|
256
287
|
)
|
|
257
|
-
write_output(target=output_file, data=
|
|
288
|
+
write_output(target=output_file, data=formatted)
|
|
258
289
|
|
|
259
290
|
if verbose:
|
|
260
|
-
print_stats(plaintext
|
|
291
|
+
print_stats(len(plaintext), len(ciphertext))
|
|
261
292
|
click.echo(f"Groups: {groups}", err=True)
|
|
262
293
|
|
|
263
294
|
|
|
264
295
|
@cli.command(aliases=["ep"]) # pyright: ignore[reportAny]
|
|
265
296
|
@click.argument("password_file", type=in_path)
|
|
266
297
|
@click.argument("message_file", type=in_path)
|
|
267
|
-
@click.option(
|
|
268
|
-
|
|
269
|
-
|
|
298
|
+
@click.option(
|
|
299
|
+
"--kdf-profile", "-p", default="sensitive", show_default=True, envvar="KDF_PROFILE"
|
|
300
|
+
)
|
|
301
|
+
@click.option(
|
|
302
|
+
"--data-encoding", "-e", default="base64", show_default=True, envvar="DATA_ENCODING"
|
|
303
|
+
)
|
|
304
|
+
@click.option(
|
|
305
|
+
"--compression", "-c", default="zstd", show_default=True, envvar="COMPRESSION"
|
|
306
|
+
)
|
|
270
307
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
271
|
-
@click.option("--group-len", default=0, show_default=True)
|
|
272
|
-
@click.option("--line-len", default=80, show_default=True)
|
|
273
|
-
@click.option("--padding", default=0, show_default=True)
|
|
274
|
-
@click.option(
|
|
308
|
+
@click.option("--group-len", default=0, show_default=True, envvar="GROUP_LEN")
|
|
309
|
+
@click.option("--line-len", default=80, show_default=True, envvar="LINE_LEN")
|
|
310
|
+
@click.option("--padding", default=0, show_default=True, envvar="PADDING")
|
|
311
|
+
@click.option(
|
|
312
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
313
|
+
)
|
|
275
314
|
def encrypt_password_cmd(
|
|
276
315
|
password_file: Path,
|
|
277
316
|
message_file: Path,
|
|
@@ -298,22 +337,22 @@ def encrypt_password_cmd(
|
|
|
298
337
|
|
|
299
338
|
pw = read_password_bytes(password_file)
|
|
300
339
|
key = kdf(password=pw, profile=prof)
|
|
301
|
-
|
|
302
|
-
data = archiver(
|
|
340
|
+
plaintext = read_bytes(message_file)
|
|
341
|
+
data = archiver(plaintext)
|
|
303
342
|
data = secret.encrypt(key=key, data=data)
|
|
304
|
-
|
|
343
|
+
ciphertext = data_enc.encode(data)
|
|
305
344
|
|
|
306
|
-
|
|
307
|
-
data=
|
|
345
|
+
formatted, groups = format_output(
|
|
346
|
+
data=ciphertext,
|
|
308
347
|
encoder=data_enc,
|
|
309
348
|
group_len=group_len,
|
|
310
349
|
line_len=line_len,
|
|
311
350
|
padding=padding,
|
|
312
351
|
)
|
|
313
|
-
write_output(target=output_file, data=
|
|
352
|
+
write_output(target=output_file, data=formatted)
|
|
314
353
|
|
|
315
354
|
if verbose:
|
|
316
|
-
print_stats(plaintext
|
|
355
|
+
print_stats(len(plaintext), len(ciphertext))
|
|
317
356
|
click.echo(f"Groups: {groups}", err=True)
|
|
318
357
|
|
|
319
358
|
|
|
@@ -321,11 +360,19 @@ def encrypt_password_cmd(
|
|
|
321
360
|
@click.argument("private_key_file", type=in_path)
|
|
322
361
|
@click.argument("public_key_file", type=in_path)
|
|
323
362
|
@click.argument("message_file", type=in_path)
|
|
324
|
-
@click.option(
|
|
325
|
-
|
|
326
|
-
|
|
363
|
+
@click.option(
|
|
364
|
+
"--key-encoding", default="base64", show_default=True, envvar="KEY_ENCODING"
|
|
365
|
+
)
|
|
366
|
+
@click.option(
|
|
367
|
+
"--data-encoding", "-e", default="base64", show_default=True, envvar="DATA_ENCODING"
|
|
368
|
+
)
|
|
369
|
+
@click.option(
|
|
370
|
+
"--compression", "-c", default="zstd", show_default=True, envvar="COMPRESSION"
|
|
371
|
+
)
|
|
327
372
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
328
|
-
@click.option(
|
|
373
|
+
@click.option(
|
|
374
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
375
|
+
)
|
|
329
376
|
def decrypt_public_cmd(
|
|
330
377
|
private_key_file: Path,
|
|
331
378
|
public_key_file: Path,
|
|
@@ -350,25 +397,33 @@ def decrypt_public_cmd(
|
|
|
350
397
|
priv = PrivateKey(private_key=priv)
|
|
351
398
|
pub = read_key_bytes(source=public_key_file, encoder=key_enc)
|
|
352
399
|
pub = PublicKey(public_key=pub)
|
|
353
|
-
|
|
354
|
-
data = data_enc.decode(
|
|
400
|
+
ciphertext = read_ciphertext_bytes(source=message_file, encoder=data_enc)
|
|
401
|
+
data = data_enc.decode(ciphertext)
|
|
355
402
|
data = public.decrypt(private=priv, public=pub, data=data)
|
|
356
|
-
|
|
403
|
+
plaintext = unarchiver(data)
|
|
357
404
|
|
|
358
|
-
write_output(target=output_file, data=
|
|
405
|
+
write_output(target=output_file, data=plaintext)
|
|
359
406
|
|
|
360
407
|
if verbose:
|
|
361
|
-
print_stats(plaintext
|
|
408
|
+
print_stats(len(plaintext), len(ciphertext))
|
|
362
409
|
|
|
363
410
|
|
|
364
411
|
@cli.command(aliases=["ds"]) # pyright: ignore[reportAny]
|
|
365
412
|
@click.argument("key_file", type=in_path)
|
|
366
413
|
@click.argument("message_file", type=in_path)
|
|
367
|
-
@click.option(
|
|
368
|
-
|
|
369
|
-
|
|
414
|
+
@click.option(
|
|
415
|
+
"--key-encoding", default="base64", show_default=True, envvar="KEY_ENCODING"
|
|
416
|
+
)
|
|
417
|
+
@click.option(
|
|
418
|
+
"--data-encoding", "-e", default="base64", show_default=True, envvar="DATA_ENCODING"
|
|
419
|
+
)
|
|
420
|
+
@click.option(
|
|
421
|
+
"--compression", "-c", default="zstd", show_default=True, envvar="COMPRESSION"
|
|
422
|
+
)
|
|
370
423
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
371
|
-
@click.option(
|
|
424
|
+
@click.option(
|
|
425
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
426
|
+
)
|
|
372
427
|
def decrypt_secret_cmd(
|
|
373
428
|
key_file: Path,
|
|
374
429
|
message_file: Path,
|
|
@@ -389,25 +444,33 @@ def decrypt_secret_cmd(
|
|
|
389
444
|
unarchiver = UNARCHIVERS[compression]
|
|
390
445
|
|
|
391
446
|
key = read_key_bytes(source=key_file, encoder=key_enc)
|
|
392
|
-
|
|
393
|
-
data = data_enc.decode(
|
|
447
|
+
ciphertext = read_ciphertext_bytes(source=message_file, encoder=data_enc)
|
|
448
|
+
data = data_enc.decode(ciphertext)
|
|
394
449
|
data = secret.decrypt(key=key, data=data)
|
|
395
|
-
|
|
450
|
+
plaintext = unarchiver(data)
|
|
396
451
|
|
|
397
|
-
write_output(target=output_file, data=
|
|
452
|
+
write_output(target=output_file, data=plaintext)
|
|
398
453
|
|
|
399
454
|
if verbose:
|
|
400
|
-
print_stats(plaintext
|
|
455
|
+
print_stats(len(plaintext), len(ciphertext))
|
|
401
456
|
|
|
402
457
|
|
|
403
458
|
@cli.command(aliases=["dp"]) # pyright: ignore[reportAny]
|
|
404
459
|
@click.argument("password_file", type=in_path)
|
|
405
460
|
@click.argument("message_file", type=in_path)
|
|
406
|
-
@click.option(
|
|
407
|
-
|
|
408
|
-
|
|
461
|
+
@click.option(
|
|
462
|
+
"--kdf-profile", "-p", default="sensitive", show_default=True, envvar="KDF_PROFILE"
|
|
463
|
+
)
|
|
464
|
+
@click.option(
|
|
465
|
+
"--data-encoding", "-e", default="base64", show_default=True, envvar="DATA_ENCODING"
|
|
466
|
+
)
|
|
467
|
+
@click.option(
|
|
468
|
+
"--compression", "-c", default="zstd", show_default=True, envvar="COMPRESSION"
|
|
469
|
+
)
|
|
409
470
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
410
|
-
@click.option(
|
|
471
|
+
@click.option(
|
|
472
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
473
|
+
)
|
|
411
474
|
def decrypt_password_cmd(
|
|
412
475
|
password_file: Path,
|
|
413
476
|
message_file: Path,
|
|
@@ -431,15 +494,15 @@ def decrypt_password_cmd(
|
|
|
431
494
|
|
|
432
495
|
pw = read_password_bytes(password_file)
|
|
433
496
|
key = kdf(password=pw, profile=prof)
|
|
434
|
-
|
|
435
|
-
data = data_enc.decode(
|
|
497
|
+
ciphertext = read_ciphertext_bytes(source=message_file, encoder=data_enc)
|
|
498
|
+
data = data_enc.decode(ciphertext)
|
|
436
499
|
data = secret.decrypt(key=key, data=data)
|
|
437
|
-
|
|
500
|
+
plaintext = unarchiver(data)
|
|
438
501
|
|
|
439
|
-
write_output(target=output_file, data=
|
|
502
|
+
write_output(target=output_file, data=plaintext)
|
|
440
503
|
|
|
441
504
|
if verbose:
|
|
442
|
-
print_stats(plaintext
|
|
505
|
+
print_stats(len(plaintext), len(ciphertext))
|
|
443
506
|
|
|
444
507
|
|
|
445
508
|
@cli.command() # pyright: ignore[reportAny]
|
|
@@ -447,10 +510,12 @@ def decrypt_password_cmd(
|
|
|
447
510
|
@click.argument("out_encoding")
|
|
448
511
|
@click.argument("file", type=in_path)
|
|
449
512
|
@click.option("--output-file", "-o", type=out_path, help="Write output to file.")
|
|
450
|
-
@click.option("--group-len", default=0, show_default=True)
|
|
451
|
-
@click.option("--line-len", default=80, show_default=True)
|
|
452
|
-
@click.option("--padding", default=0, show_default=True)
|
|
453
|
-
@click.option(
|
|
513
|
+
@click.option("--group-len", default=0, show_default=True, envvar="GROUP_LEN")
|
|
514
|
+
@click.option("--line-len", default=80, show_default=True, envvar="LINE_LEN")
|
|
515
|
+
@click.option("--padding", default=0, show_default=True, envvar="PADDING")
|
|
516
|
+
@click.option(
|
|
517
|
+
"--verbose", "-v", is_flag=True, envvar="VERBOSE", help="Show verbose output."
|
|
518
|
+
)
|
|
454
519
|
def encode_cmd(
|
|
455
520
|
in_encoding: str,
|
|
456
521
|
out_encoding: str,
|
|
@@ -468,18 +533,18 @@ def encode_cmd(
|
|
|
468
533
|
in_enc = ENCODERS[in_encoding]
|
|
469
534
|
out_enc = ENCODERS[out_encoding]
|
|
470
535
|
|
|
471
|
-
data =
|
|
536
|
+
data = read_ciphertext_bytes(source=file, encoder=in_enc)
|
|
472
537
|
data = in_enc.decode(data)
|
|
473
538
|
data = out_enc.encode(data)
|
|
474
539
|
|
|
475
|
-
|
|
540
|
+
formatted, groups = format_output(
|
|
476
541
|
data=data,
|
|
477
542
|
encoder=out_enc,
|
|
478
543
|
group_len=group_len,
|
|
479
544
|
line_len=line_len,
|
|
480
545
|
padding=padding,
|
|
481
546
|
)
|
|
482
|
-
write_output(target=output_file, data=
|
|
547
|
+
write_output(target=output_file, data=formatted)
|
|
483
548
|
|
|
484
549
|
if verbose:
|
|
485
550
|
click.echo(f"Groups: {groups}", err=True)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: rtty-soda
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: A CLI tool for Unix-like environments to encrypt a RTTY session using NaCl
|
|
5
5
|
Keywords: cli,encryption,libsodium,nacl,rtty
|
|
6
6
|
Author: Theo Saveliev
|
|
@@ -57,8 +57,8 @@ A CLI tool for Unix-like environments to encrypt a RTTY session using NaCl.
|
|
|
57
57
|
#### Docker
|
|
58
58
|
|
|
59
59
|
```
|
|
60
|
-
% docker run -it --rm -h rtty-soda -v .:/app/host nett/rtty-soda:0.2.
|
|
61
|
-
% docker run -it --rm -h rtty-soda -v .:/app/host nett/rtty-soda:0.2.
|
|
60
|
+
% docker run -it --rm -h rtty-soda -v .:/app/host nett/rtty-soda:0.2.4
|
|
61
|
+
% docker run -it --rm -h rtty-soda -v .:/app/host nett/rtty-soda:0.2.4-tools
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
|
|
@@ -165,24 +165,6 @@ A telegraph key is a specialized electrical switch used by a trained operator to
|
|
|
165
165
|
transmit text messages in Morse code in a telegraphy system.
|
|
166
166
|
The first telegraph key was invented by Alfred Vail, an associate of Samuel Morse.
|
|
167
167
|
(c) Wikipedia
|
|
168
|
-
|
|
169
|
-
% soda decrypt-public -h
|
|
170
|
-
Usage: soda decrypt-public [OPTIONS] PRIVATE_KEY_FILE PUBLIC_KEY_FILE
|
|
171
|
-
MESSAGE_FILE
|
|
172
|
-
|
|
173
|
-
Decrypt Message (Public).
|
|
174
|
-
|
|
175
|
-
Encoding: base26 | base31 | base36 | base64 | base94 | binary
|
|
176
|
-
|
|
177
|
-
Compression: zstd | zlib | bz2 | lzma | raw
|
|
178
|
-
|
|
179
|
-
Options:
|
|
180
|
-
--key-encoding TEXT [default: base64]
|
|
181
|
-
-e, --data-encoding TEXT [default: base64]
|
|
182
|
-
-c, --compression TEXT [default: zstd]
|
|
183
|
-
-o, --output-file FILE Write output to file.
|
|
184
|
-
-v, --verbose Show verbose output.
|
|
185
|
-
-h, --help Show this message and exit.
|
|
186
168
|
```
|
|
187
169
|
|
|
188
170
|
|
|
@@ -194,26 +176,6 @@ Alice and Bob share a key for symmetric encryption:
|
|
|
194
176
|
% soda genkey > shared
|
|
195
177
|
% soda encrypt-secret shared message -o encrypted
|
|
196
178
|
% soda decrypt-secret shared encrypted -o message
|
|
197
|
-
|
|
198
|
-
% soda encrypt-secret -h
|
|
199
|
-
Usage: soda encrypt-secret [OPTIONS] KEY_FILE MESSAGE_FILE
|
|
200
|
-
|
|
201
|
-
Encrypt Message (Secret).
|
|
202
|
-
|
|
203
|
-
Encoding: base26 | base31 | base36 | base64 | base94 | binary
|
|
204
|
-
|
|
205
|
-
Compression: zstd | zlib | bz2 | lzma | raw
|
|
206
|
-
|
|
207
|
-
Options:
|
|
208
|
-
--key-encoding TEXT [default: base64]
|
|
209
|
-
-e, --data-encoding TEXT [default: base64]
|
|
210
|
-
-c, --compression TEXT [default: zstd]
|
|
211
|
-
-o, --output-file FILE Write output to file.
|
|
212
|
-
--group-len INTEGER [default: 0]
|
|
213
|
-
--line-len INTEGER [default: 80]
|
|
214
|
-
--padding INTEGER [default: 0]
|
|
215
|
-
-v, --verbose Show verbose output.
|
|
216
|
-
-h, --help Show this message and exit.
|
|
217
179
|
```
|
|
218
180
|
|
|
219
181
|
Another day, they share a password:
|
|
@@ -221,28 +183,6 @@ Another day, they share a password:
|
|
|
221
183
|
```
|
|
222
184
|
% echo qwerty | soda encrypt-password - message -p interactive -o encrypted
|
|
223
185
|
% echo qwerty | soda decrypt-password - encrypted -p interactive -o message
|
|
224
|
-
|
|
225
|
-
% soda encrypt-password -h
|
|
226
|
-
Usage: soda encrypt-password [OPTIONS] PASSWORD_FILE MESSAGE_FILE
|
|
227
|
-
|
|
228
|
-
Encrypt Message (Password).
|
|
229
|
-
|
|
230
|
-
KDF profile: interactive | moderate | sensitive
|
|
231
|
-
|
|
232
|
-
Encoding: base26 | base31 | base36 | base64 | base94 | binary
|
|
233
|
-
|
|
234
|
-
Compression: zstd | zlib | bz2 | lzma | raw
|
|
235
|
-
|
|
236
|
-
Options:
|
|
237
|
-
-p, --kdf-profile TEXT [default: sensitive]
|
|
238
|
-
-e, --data-encoding TEXT [default: base64]
|
|
239
|
-
-c, --compression TEXT [default: zstd]
|
|
240
|
-
-o, --output-file FILE Write output to file.
|
|
241
|
-
--group-len INTEGER [default: 0]
|
|
242
|
-
--line-len INTEGER [default: 80]
|
|
243
|
-
--padding INTEGER [default: 0]
|
|
244
|
-
-v, --verbose Show verbose output.
|
|
245
|
-
-h, --help Show this message and exit.
|
|
246
186
|
```
|
|
247
187
|
|
|
248
188
|
|
|
@@ -318,18 +258,58 @@ The rtty-soda supports various encodings:
|
|
|
318
258
|
|
|
319
259
|
```
|
|
320
260
|
% soda encrypt-public alice bob_pub message --data-encoding base36 --group-len 5 --verbose
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
261
|
+
9URCN ARRN8 MSE7G G9980 37D8S 568QP 16AZW TOHAI KYP5W VAK7R VZ6YO GZ38A QOIP7
|
|
262
|
+
60P2E GWWOG DSHDD EG2TZ 7PSZM 7FKBX 50TAD RHS2E VM063 N297Y 753BP TLUX0 9K8BD
|
|
263
|
+
DZF8O 7TPUG MJV4R T2C92 HU1G8 KGJCN URU1F 9COP9 EFLZO BSL2V 171DS 2HKPE JY2GY
|
|
264
|
+
V86IT T0HBR 9B08H M9R2V IEM7A R91IF UWQYM ZV4JN 7YU3K ILPJY E8OMA NWQC5 Q6BG7
|
|
265
|
+
PXM4I 9UU9E J9IRU HSZ41 RPZQG XTDC6 E5NMS B4HBQ 7QRI2 RRUYH HSHGQ 7USN
|
|
326
266
|
Plaintext: 239
|
|
327
|
-
Ciphertext:
|
|
328
|
-
Overhead: 1.
|
|
267
|
+
Ciphertext: 319
|
|
268
|
+
Overhead: 1.335
|
|
329
269
|
Groups: 64
|
|
330
270
|
```
|
|
331
271
|
|
|
332
272
|
|
|
273
|
+
## Environment variables
|
|
274
|
+
|
|
275
|
+
Common options can be set in the environment variables:
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
% cat .env
|
|
279
|
+
KEY_ENCODING=base26
|
|
280
|
+
DATA_ENCODING=base26
|
|
281
|
+
COMPRESSION=bz2
|
|
282
|
+
KDF_PROFILE=moderate
|
|
283
|
+
VERBOSE=1
|
|
284
|
+
GROUP_LEN=5
|
|
285
|
+
LINE_LEN=80
|
|
286
|
+
PADDING=1
|
|
287
|
+
|
|
288
|
+
% set -a
|
|
289
|
+
% source .env
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
## Alternative usage
|
|
294
|
+
|
|
295
|
+
- Password source
|
|
296
|
+
```
|
|
297
|
+
% echo 'A line from a book or a poem' | soda kdf - -e base94
|
|
298
|
+
wN/K.@3Q#]Czn4kk3(negX=R|*xvvPQmk'XW$-s
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
- WireGuard keyer
|
|
302
|
+
```
|
|
303
|
+
% echo 'A line from a book or a poem' | soda kdf - -o privkey
|
|
304
|
+
% cat privkey
|
|
305
|
+
thyA4dlQgg93+rQj/evBbBymw82GTwQCh3RJ0I6GOsY=
|
|
306
|
+
% soda pubkey privkey
|
|
307
|
+
ruIUMqbUtyqRVSIBLSGI7AOruE2DLWgTe9o+h7Yktkw=
|
|
308
|
+
% cat privkey | wg pubkey
|
|
309
|
+
ruIUMqbUtyqRVSIBLSGI7AOruE2DLWgTe9o+h7Yktkw=
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
|
|
333
313
|
## Compatibility
|
|
334
314
|
|
|
335
315
|
During the initial development (versions prior to 1.0.0),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
rtty_soda/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
rtty_soda/archivers.py,sha256=b-qZ6-MAY1rm1Jsosi2XEfjNjkU7acAedHmnSzthf-A,1343
|
|
3
|
-
rtty_soda/cli_io.py,sha256=
|
|
3
|
+
rtty_soda/cli_io.py,sha256=d99l3RSXJ5W3H9E-KFJYzAWzW8bn0F3F6o83DtMLfQs,3235
|
|
4
4
|
rtty_soda/cryptography/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
rtty_soda/cryptography/kdf.py,sha256=HymfTiK7BD7lhZu0OdtFW_i-v0r7e8XedT8_Q84ClJc,1529
|
|
6
6
|
rtty_soda/cryptography/public.py,sha256=6gwsT4ilaMDHwtdYPOEYlX8IfwHPew8lMIbxRva1mLs,612
|
|
@@ -14,10 +14,10 @@ rtty_soda/encoders/base94_encoder.py,sha256=Xbt0chbeAIM9_nRHVhRMVfMBUKS9q1gNSpg2
|
|
|
14
14
|
rtty_soda/encoders/encoder.py,sha256=trHunjg0uNEQrQWTpRMY5nQEx5_jBrcvfUAcGIKpgms,220
|
|
15
15
|
rtty_soda/encoders/functions.py,sha256=JxtgbZg3kdbFqAhjm59QwJS6zEXYsR1m02k7cg_rFI4,1385
|
|
16
16
|
rtty_soda/encoders/raw_encoder.py,sha256=eJnUSsxf3jichdQ5LqwvBZAX7-qk67p5FMlfKOOGHp8,259
|
|
17
|
-
rtty_soda/main.py,sha256=
|
|
17
|
+
rtty_soda/main.py,sha256=BlyrKtBebzAvZzrJnEt7DII48nIiBfxUnQ-njpFjTU8,17387
|
|
18
18
|
rtty_soda/main.pyi,sha256=SoTM1GXACRafCtwwLOI1X9YhvEo3DPoaPtKSgWacSS0,2242
|
|
19
19
|
rtty_soda/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
-
rtty_soda-0.2.
|
|
21
|
-
rtty_soda-0.2.
|
|
22
|
-
rtty_soda-0.2.
|
|
23
|
-
rtty_soda-0.2.
|
|
20
|
+
rtty_soda-0.2.4.dist-info/WHEEL,sha256=M6du7VZflc4UPsGphmOXHANdgk8zessdJG0DBUuoA-U,78
|
|
21
|
+
rtty_soda-0.2.4.dist-info/entry_points.txt,sha256=tFROKkaDoE_p5tM2ko7MoAjWBFurchcw3j-MdObxBU0,45
|
|
22
|
+
rtty_soda-0.2.4.dist-info/METADATA,sha256=kAzdyA6WLijrbBk8TgWGsgnSbAj8PMMA4N4g3Y1IpXU,8603
|
|
23
|
+
rtty_soda-0.2.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|