+552 -66 +/-4 browse
1 | diff --git a/Cargo.lock b/Cargo.lock |
2 | index f0373f1..dfcce4e 100644 |
3 | --- a/Cargo.lock |
4 | +++ b/Cargo.lock |
5 | @@ -429,6 +429,12 @@ dependencies = [ |
6 | ] |
7 | |
8 | [[package]] |
9 | + name = "base16ct" |
10 | + version = "0.2.0" |
11 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
12 | + checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" |
13 | + |
14 | + [[package]] |
15 | name = "base64" |
16 | version = "0.13.1" |
17 | source = "registry+https://github.com/rust-lang/crates.io-index" |
18 | @@ -450,6 +456,12 @@ dependencies = [ |
19 | ] |
20 | |
21 | [[package]] |
22 | + name = "base64ct" |
23 | + version = "1.6.0" |
24 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
25 | + checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" |
26 | + |
27 | + [[package]] |
28 | name = "bcrypt" |
29 | version = "0.14.0" |
30 | source = "registry+https://github.com/rust-lang/crates.io-index" |
31 | @@ -851,6 +863,12 @@ dependencies = [ |
32 | ] |
33 | |
34 | [[package]] |
35 | + name = "const-oid" |
36 | + version = "0.9.5" |
37 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
38 | + checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" |
39 | + |
40 | + [[package]] |
41 | name = "constant_time_eq" |
42 | version = "0.1.5" |
43 | source = "registry+https://github.com/rust-lang/crates.io-index" |
44 | @@ -872,7 +890,7 @@ dependencies = [ |
45 | "hmac 0.12.1", |
46 | "percent-encoding", |
47 | "rand", |
48 | - "sha2 0.10.6", |
49 | + "sha2 0.10.8", |
50 | "subtle", |
51 | "time 0.3.21", |
52 | "version_check", |
53 | @@ -913,6 +931,18 @@ dependencies = [ |
54 | ] |
55 | |
56 | [[package]] |
57 | + name = "crypto-bigint" |
58 | + version = "0.5.3" |
59 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
60 | + checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" |
61 | + dependencies = [ |
62 | + "generic-array", |
63 | + "rand_core", |
64 | + "subtle", |
65 | + "zeroize", |
66 | + ] |
67 | + |
68 | + [[package]] |
69 | name = "crypto-common" |
70 | version = "0.1.6" |
71 | source = "registry+https://github.com/rust-lang/crates.io-index" |
72 | @@ -953,6 +983,33 @@ dependencies = [ |
73 | ] |
74 | |
75 | [[package]] |
76 | + name = "curve25519-dalek" |
77 | + version = "4.1.1" |
78 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
79 | + checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" |
80 | + dependencies = [ |
81 | + "cfg-if 1.0.0", |
82 | + "cpufeatures", |
83 | + "curve25519-dalek-derive", |
84 | + "digest 0.10.7", |
85 | + "fiat-crypto", |
86 | + "platforms", |
87 | + "rustc_version", |
88 | + "subtle", |
89 | + ] |
90 | + |
91 | + [[package]] |
92 | + name = "curve25519-dalek-derive" |
93 | + version = "0.1.1" |
94 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
95 | + checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" |
96 | + dependencies = [ |
97 | + "proc-macro2", |
98 | + "quote", |
99 | + "syn 2.0.35", |
100 | + ] |
101 | + |
102 | + [[package]] |
103 | name = "cxx" |
104 | version = "1.0.94" |
105 | source = "registry+https://github.com/rust-lang/crates.io-index" |
106 | @@ -1003,6 +1060,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
107 | checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" |
108 | |
109 | [[package]] |
110 | + name = "der" |
111 | + version = "0.7.8" |
112 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
113 | + checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" |
114 | + dependencies = [ |
115 | + "const-oid", |
116 | + "zeroize", |
117 | + ] |
118 | + |
119 | + [[package]] |
120 | name = "derive_more" |
121 | version = "0.99.17" |
122 | source = "registry+https://github.com/rust-lang/crates.io-index" |
123 | @@ -1038,11 +1105,12 @@ dependencies = [ |
124 | |
125 | [[package]] |
126 | name = "digest" |
127 | - version = "0.10.6" |
128 | + version = "0.10.7" |
129 | source = "registry+https://github.com/rust-lang/crates.io-index" |
130 | - checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" |
131 | + checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" |
132 | dependencies = [ |
133 | "block-buffer 0.10.4", |
134 | + "const-oid", |
135 | "crypto-common", |
136 | "subtle", |
137 | ] |
138 | @@ -1066,12 +1134,65 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
139 | checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" |
140 | |
141 | [[package]] |
142 | + name = "ecdsa" |
143 | + version = "0.16.8" |
144 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
145 | + checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" |
146 | + dependencies = [ |
147 | + "der", |
148 | + "digest 0.10.7", |
149 | + "elliptic-curve", |
150 | + "rfc6979", |
151 | + "signature", |
152 | + "spki", |
153 | + ] |
154 | + |
155 | + [[package]] |
156 | + name = "ed25519" |
157 | + version = "2.2.3" |
158 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
159 | + checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" |
160 | + dependencies = [ |
161 | + "signature", |
162 | + ] |
163 | + |
164 | + [[package]] |
165 | + name = "ed25519-dalek" |
166 | + version = "2.0.0" |
167 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
168 | + checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" |
169 | + dependencies = [ |
170 | + "curve25519-dalek", |
171 | + "ed25519", |
172 | + "sha2 0.10.8", |
173 | + ] |
174 | + |
175 | + [[package]] |
176 | name = "either" |
177 | version = "1.8.1" |
178 | source = "registry+https://github.com/rust-lang/crates.io-index" |
179 | checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" |
180 | |
181 | [[package]] |
182 | + name = "elliptic-curve" |
183 | + version = "0.13.6" |
184 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
185 | + checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" |
186 | + dependencies = [ |
187 | + "base16ct", |
188 | + "crypto-bigint", |
189 | + "digest 0.10.7", |
190 | + "ff", |
191 | + "generic-array", |
192 | + "group", |
193 | + "pkcs8", |
194 | + "rand_core", |
195 | + "sec1", |
196 | + "subtle", |
197 | + "zeroize", |
198 | + ] |
199 | + |
200 | + [[package]] |
201 | name = "encoding" |
202 | version = "0.2.33" |
203 | source = "registry+https://github.com/rust-lang/crates.io-index" |
204 | @@ -1213,6 +1334,22 @@ dependencies = [ |
205 | ] |
206 | |
207 | [[package]] |
208 | + name = "ff" |
209 | + version = "0.13.0" |
210 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
211 | + checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" |
212 | + dependencies = [ |
213 | + "rand_core", |
214 | + "subtle", |
215 | + ] |
216 | + |
217 | + [[package]] |
218 | + name = "fiat-crypto" |
219 | + version = "0.2.2" |
220 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
221 | + checksum = "a481586acf778f1b1455424c343f71124b048ffa5f4fc3f8f6ae9dc432dcb3c7" |
222 | + |
223 | + [[package]] |
224 | name = "filetime" |
225 | version = "0.2.21" |
226 | source = "registry+https://github.com/rust-lang/crates.io-index" |
227 | @@ -1420,6 +1557,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" |
228 | dependencies = [ |
229 | "typenum", |
230 | "version_check", |
231 | + "zeroize", |
232 | ] |
233 | |
234 | [[package]] |
235 | @@ -1455,6 +1593,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
236 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" |
237 | |
238 | [[package]] |
239 | + name = "group" |
240 | + version = "0.13.0" |
241 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
242 | + checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" |
243 | + dependencies = [ |
244 | + "ff", |
245 | + "rand_core", |
246 | + "subtle", |
247 | + ] |
248 | + |
249 | + [[package]] |
250 | name = "h2" |
251 | version = "0.3.18" |
252 | source = "registry+https://github.com/rust-lang/crates.io-index" |
253 | @@ -1562,7 +1711,7 @@ version = "0.12.1" |
254 | source = "registry+https://github.com/rust-lang/crates.io-index" |
255 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" |
256 | dependencies = [ |
257 | - "digest 0.10.6", |
258 | + "digest 0.10.7", |
259 | ] |
260 | |
261 | [[package]] |
262 | @@ -1862,6 +2011,9 @@ name = "lazy_static" |
263 | version = "1.4.0" |
264 | source = "registry+https://github.com/rust-lang/crates.io-index" |
265 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" |
266 | + dependencies = [ |
267 | + "spin", |
268 | + ] |
269 | |
270 | [[package]] |
271 | name = "lazycell" |
272 | @@ -1898,6 +2050,12 @@ dependencies = [ |
273 | ] |
274 | |
275 | [[package]] |
276 | + name = "libm" |
277 | + version = "0.2.8" |
278 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
279 | + checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" |
280 | + |
281 | + [[package]] |
282 | name = "libsqlite3-sys" |
283 | version = "0.25.2" |
284 | source = "registry+https://github.com/rust-lang/crates.io-index" |
285 | @@ -2122,6 +2280,7 @@ dependencies = [ |
286 | "serde", |
287 | "serde_json", |
288 | "serde_urlencoded", |
289 | + "ssh-key", |
290 | "stderrlog", |
291 | "tempfile", |
292 | "tokio", |
293 | @@ -2366,6 +2525,23 @@ dependencies = [ |
294 | ] |
295 | |
296 | [[package]] |
297 | + name = "num-bigint-dig" |
298 | + version = "0.8.4" |
299 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
300 | + checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" |
301 | + dependencies = [ |
302 | + "byteorder", |
303 | + "lazy_static", |
304 | + "libm", |
305 | + "num-integer", |
306 | + "num-iter", |
307 | + "num-traits", |
308 | + "rand", |
309 | + "smallvec", |
310 | + "zeroize", |
311 | + ] |
312 | + |
313 | + [[package]] |
314 | name = "num-cmp" |
315 | version = "0.1.0" |
316 | source = "registry+https://github.com/rust-lang/crates.io-index" |
317 | @@ -2420,6 +2596,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
318 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" |
319 | dependencies = [ |
320 | "autocfg", |
321 | + "libm", |
322 | ] |
323 | |
324 | [[package]] |
325 | @@ -2508,6 +2685,30 @@ dependencies = [ |
326 | ] |
327 | |
328 | [[package]] |
329 | + name = "p256" |
330 | + version = "0.13.2" |
331 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
332 | + checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" |
333 | + dependencies = [ |
334 | + "ecdsa", |
335 | + "elliptic-curve", |
336 | + "primeorder", |
337 | + "sha2 0.10.8", |
338 | + ] |
339 | + |
340 | + [[package]] |
341 | + name = "p384" |
342 | + version = "0.13.0" |
343 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
344 | + checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" |
345 | + dependencies = [ |
346 | + "ecdsa", |
347 | + "elliptic-curve", |
348 | + "primeorder", |
349 | + "sha2 0.10.8", |
350 | + ] |
351 | + |
352 | + [[package]] |
353 | name = "parking" |
354 | version = "2.1.0" |
355 | source = "registry+https://github.com/rust-lang/crates.io-index" |
356 | @@ -2543,6 +2744,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
357 | checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" |
358 | |
359 | [[package]] |
360 | + name = "pem-rfc7468" |
361 | + version = "0.7.0" |
362 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
363 | + checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" |
364 | + dependencies = [ |
365 | + "base64ct", |
366 | + ] |
367 | + |
368 | + [[package]] |
369 | name = "percent-encoding" |
370 | version = "2.2.0" |
371 | source = "registry+https://github.com/rust-lang/crates.io-index" |
372 | @@ -2589,7 +2799,7 @@ checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411" |
373 | dependencies = [ |
374 | "once_cell", |
375 | "pest", |
376 | - "sha2 0.10.6", |
377 | + "sha2 0.10.8", |
378 | ] |
379 | |
380 | [[package]] |
381 | @@ -2625,12 +2835,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
382 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" |
383 | |
384 | [[package]] |
385 | + name = "pkcs1" |
386 | + version = "0.7.5" |
387 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
388 | + checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" |
389 | + dependencies = [ |
390 | + "der", |
391 | + "pkcs8", |
392 | + "spki", |
393 | + ] |
394 | + |
395 | + [[package]] |
396 | + name = "pkcs8" |
397 | + version = "0.10.2" |
398 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
399 | + checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" |
400 | + dependencies = [ |
401 | + "der", |
402 | + "spki", |
403 | + ] |
404 | + |
405 | + [[package]] |
406 | name = "pkg-config" |
407 | version = "0.3.27" |
408 | source = "registry+https://github.com/rust-lang/crates.io-index" |
409 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" |
410 | |
411 | [[package]] |
412 | + name = "platforms" |
413 | + version = "3.2.0" |
414 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
415 | + checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" |
416 | + |
417 | + [[package]] |
418 | name = "polling" |
419 | version = "2.8.0" |
420 | source = "registry+https://github.com/rust-lang/crates.io-index" |
421 | @@ -2696,6 +2933,15 @@ dependencies = [ |
422 | ] |
423 | |
424 | [[package]] |
425 | + name = "primeorder" |
426 | + version = "0.13.2" |
427 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
428 | + checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" |
429 | + dependencies = [ |
430 | + "elliptic-curve", |
431 | + ] |
432 | + |
433 | + [[package]] |
434 | name = "proc-macro-error" |
435 | version = "1.0.4" |
436 | source = "registry+https://github.com/rust-lang/crates.io-index" |
437 | @@ -2846,6 +3092,16 @@ dependencies = [ |
438 | ] |
439 | |
440 | [[package]] |
441 | + name = "rfc6979" |
442 | + version = "0.4.0" |
443 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
444 | + checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" |
445 | + dependencies = [ |
446 | + "hmac 0.12.1", |
447 | + "subtle", |
448 | + ] |
449 | + |
450 | + [[package]] |
451 | name = "ring" |
452 | version = "0.16.20" |
453 | source = "registry+https://github.com/rust-lang/crates.io-index" |
454 | @@ -2878,6 +3134,27 @@ dependencies = [ |
455 | ] |
456 | |
457 | [[package]] |
458 | + name = "rsa" |
459 | + version = "0.9.3" |
460 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
461 | + checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d" |
462 | + dependencies = [ |
463 | + "const-oid", |
464 | + "digest 0.10.7", |
465 | + "num-bigint-dig", |
466 | + "num-integer", |
467 | + "num-traits", |
468 | + "pkcs1", |
469 | + "pkcs8", |
470 | + "rand_core", |
471 | + "sha2 0.10.8", |
472 | + "signature", |
473 | + "spki", |
474 | + "subtle", |
475 | + "zeroize", |
476 | + ] |
477 | + |
478 | + [[package]] |
479 | name = "rusqlite" |
480 | version = "0.28.0" |
481 | source = "registry+https://github.com/rust-lang/crates.io-index" |
482 | @@ -3006,6 +3283,20 @@ dependencies = [ |
483 | ] |
484 | |
485 | [[package]] |
486 | + name = "sec1" |
487 | + version = "0.7.3" |
488 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
489 | + checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" |
490 | + dependencies = [ |
491 | + "base16ct", |
492 | + "der", |
493 | + "generic-array", |
494 | + "pkcs8", |
495 | + "subtle", |
496 | + "zeroize", |
497 | + ] |
498 | + |
499 | + [[package]] |
500 | name = "secrecy" |
501 | version = "0.8.0" |
502 | source = "registry+https://github.com/rust-lang/crates.io-index" |
503 | @@ -3125,7 +3416,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" |
504 | dependencies = [ |
505 | "cfg-if 1.0.0", |
506 | "cpufeatures", |
507 | - "digest 0.10.6", |
508 | + "digest 0.10.7", |
509 | ] |
510 | |
511 | [[package]] |
512 | @@ -3149,13 +3440,13 @@ dependencies = [ |
513 | |
514 | [[package]] |
515 | name = "sha2" |
516 | - version = "0.10.6" |
517 | + version = "0.10.8" |
518 | source = "registry+https://github.com/rust-lang/crates.io-index" |
519 | - checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" |
520 | + checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" |
521 | dependencies = [ |
522 | "cfg-if 1.0.0", |
523 | "cpufeatures", |
524 | - "digest 0.10.6", |
525 | + "digest 0.10.7", |
526 | ] |
527 | |
528 | [[package]] |
529 | @@ -3178,6 +3469,16 @@ dependencies = [ |
530 | ] |
531 | |
532 | [[package]] |
533 | + name = "signature" |
534 | + version = "2.1.0" |
535 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
536 | + checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" |
537 | + dependencies = [ |
538 | + "digest 0.10.7", |
539 | + "rand_core", |
540 | + ] |
541 | + |
542 | + [[package]] |
543 | name = "slab" |
544 | version = "0.4.8" |
545 | source = "registry+https://github.com/rust-lang/crates.io-index" |
546 | @@ -3229,6 +3530,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
547 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" |
548 | |
549 | [[package]] |
550 | + name = "spki" |
551 | + version = "0.7.2" |
552 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
553 | + checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" |
554 | + dependencies = [ |
555 | + "base64ct", |
556 | + "der", |
557 | + ] |
558 | + |
559 | + [[package]] |
560 | + name = "ssh-cipher" |
561 | + version = "0.2.0" |
562 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
563 | + checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" |
564 | + dependencies = [ |
565 | + "cipher", |
566 | + "ssh-encoding", |
567 | + ] |
568 | + |
569 | + [[package]] |
570 | + name = "ssh-encoding" |
571 | + version = "0.2.0" |
572 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
573 | + checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" |
574 | + dependencies = [ |
575 | + "base64ct", |
576 | + "pem-rfc7468", |
577 | + "sha2 0.10.8", |
578 | + ] |
579 | + |
580 | + [[package]] |
581 | + name = "ssh-key" |
582 | + version = "0.6.2" |
583 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
584 | + checksum = "2180b3bc4955efd5661a97658d3cf4c8107e0d132f619195afe9486c13cca313" |
585 | + dependencies = [ |
586 | + "ed25519-dalek", |
587 | + "num-bigint-dig", |
588 | + "p256", |
589 | + "p384", |
590 | + "rand_core", |
591 | + "rsa", |
592 | + "sec1", |
593 | + "sha2 0.10.8", |
594 | + "signature", |
595 | + "ssh-cipher", |
596 | + "ssh-encoding", |
597 | + "subtle", |
598 | + "zeroize", |
599 | + ] |
600 | + |
601 | + [[package]] |
602 | name = "stderrlog" |
603 | version = "0.5.4" |
604 | source = "registry+https://github.com/rust-lang/crates.io-index" |
605 | diff --git a/web/Cargo.toml b/web/Cargo.toml |
606 | index 39e8d99..8cf5eec 100644 |
607 | --- a/web/Cargo.toml |
608 | +++ b/web/Cargo.toml |
609 | @@ -15,6 +15,10 @@ name = "mpot-web" |
610 | path = "src/main.rs" |
611 | doc-scrape-examples = true |
612 | |
613 | + [features] |
614 | + default = ["ssh-key"] |
615 | + ssh-key = ["dep:ssh-key"] |
616 | + |
617 | [dependencies] |
618 | axum = { version = "^0.6" } |
619 | axum-extra = { version = "^0.7", features = ["typed-routing"] } |
620 | @@ -35,6 +39,7 @@ percent-encoding = { version = "^2.1" } |
621 | rand = { version = "^0.8", features = ["min_const_gen"] } |
622 | serde = { version = "^1", features = ["derive", ] } |
623 | serde_json = "^1" |
624 | + ssh-key = { version = "0.6.2", optional = true, features = ["crypto"] } |
625 | stderrlog = "^0.5" |
626 | tempfile = { version = "^3.5" } |
627 | tokio = { version = "1", features = ["full"] } |
628 | diff --git a/web/src/auth.rs b/web/src/auth.rs |
629 | index cc852b2..5da49ae 100644 |
630 | --- a/web/src/auth.rs |
631 | +++ b/web/src/auth.rs |
632 | @@ -255,21 +255,30 @@ pub async fn ssh_signin_POST( |
633 | token: _prev_token, |
634 | }; |
635 | #[cfg(not(debug_assertions))] |
636 | - if let Err(err) = ssh_keygen(sig).await { |
637 | - session.add_message(Message { |
638 | - message: format!("Could not verify signature: {err}").into(), |
639 | - level: Level::Error, |
640 | - })?; |
641 | - return Ok(Redirect::to(&format!( |
642 | - "{}{}{}", |
643 | - state.root_url_prefix, |
644 | - LoginPath.to_uri(), |
645 | - next.next.as_ref().map_or(Cow::Borrowed(""), |next| format!( |
646 | - "?next={}", |
647 | - percent_encoding::utf8_percent_encode(next.as_str(), percent_encoding::CONTROLS) |
648 | - ) |
649 | - .into()) |
650 | - ))); |
651 | + { |
652 | + #[cfg(not(feature = "ssh-key"))] |
653 | + let ssh_verify_fn = ssh_verify; |
654 | + #[cfg(feature = "ssh-key")] |
655 | + let ssh_verify_fn = ssh_verify_in_memory; |
656 | + if let Err(err) = ssh_verify_fn(sig).await { |
657 | + session.add_message(Message { |
658 | + message: format!("Could not verify signature: {err}").into(), |
659 | + level: Level::Error, |
660 | + })?; |
661 | + return Ok(Redirect::to(&format!( |
662 | + "{}{}{}", |
663 | + state.root_url_prefix, |
664 | + LoginPath.to_uri(), |
665 | + next.next.as_ref().map_or(Cow::Borrowed(""), |next| format!( |
666 | + "?next={}", |
667 | + percent_encoding::utf8_percent_encode( |
668 | + next.as_str(), |
669 | + percent_encoding::CONTROLS |
670 | + ) |
671 | + ) |
672 | + .into()) |
673 | + ))); |
674 | + } |
675 | } |
676 | |
677 | let user = User { |
678 | @@ -311,13 +320,13 @@ pub struct SshSignature { |
679 | /// Run ssh signature validation with `ssh-keygen` binary. |
680 | /// |
681 | /// ```no_run |
682 | - /// use mailpot_web::{ssh_keygen, SshSignature}; |
683 | + /// use mailpot_web::{ssh_verify, SshSignature}; |
684 | /// |
685 | - /// async fn key_gen( |
686 | + /// async fn verify_signature( |
687 | /// ssh_public_key: String, |
688 | /// ssh_signature: String, |
689 | /// ) -> std::result::Result<(), Box<dyn std::error::Error>> { |
690 | - /// let mut sig = SshSignature { |
691 | + /// let sig = SshSignature { |
692 | /// email: "user@example.com".to_string(), |
693 | /// ssh_public_key, |
694 | /// ssh_signature, |
695 | @@ -325,11 +334,11 @@ pub struct SshSignature { |
696 | /// token: "d074a61990".to_string(), |
697 | /// }; |
698 | /// |
699 | - /// ssh_keygen(sig.clone()).await?; |
700 | + /// ssh_verify(sig).await?; |
701 | /// Ok(()) |
702 | /// } |
703 | /// ``` |
704 | - pub async fn ssh_keygen(sig: SshSignature) -> Result<(), Box<dyn std::error::Error>> { |
705 | + pub async fn ssh_verify(sig: SshSignature) -> Result<(), Box<dyn std::error::Error>> { |
706 | let SshSignature { |
707 | email, |
708 | ssh_public_key, |
709 | @@ -435,6 +444,83 @@ pub async fn ssh_keygen(sig: SshSignature) -> Result<(), Box<dyn std::error::Err |
710 | Ok(()) |
711 | } |
712 | |
713 | + /// Run ssh signature validation. |
714 | + /// |
715 | + /// ```no_run |
716 | + /// use mailpot_web::{ssh_verify_in_memory, SshSignature}; |
717 | + /// |
718 | + /// async fn ssh_verify( |
719 | + /// ssh_public_key: String, |
720 | + /// ssh_signature: String, |
721 | + /// ) -> std::result::Result<(), Box<dyn std::error::Error>> { |
722 | + /// let sig = SshSignature { |
723 | + /// email: "user@example.com".to_string(), |
724 | + /// ssh_public_key, |
725 | + /// ssh_signature, |
726 | + /// namespace: "doc-test@example.com".into(), |
727 | + /// token: "d074a61990".to_string(), |
728 | + /// }; |
729 | + /// |
730 | + /// ssh_verify_in_memory(sig).await?; |
731 | + /// Ok(()) |
732 | + /// } |
733 | + /// ``` |
734 | + #[cfg(feature = "ssh-key")] |
735 | + pub async fn ssh_verify_in_memory(sig: SshSignature) -> Result<(), Box<dyn std::error::Error>> { |
736 | + use ssh_key::{PublicKey, SshSig}; |
737 | + |
738 | + let SshSignature { |
739 | + email: _, |
740 | + ref ssh_public_key, |
741 | + ref ssh_signature, |
742 | + ref namespace, |
743 | + ref token, |
744 | + } = sig; |
745 | + |
746 | + let public_key = ssh_public_key.parse::<PublicKey>().map_err(|err| { |
747 | + format!("Could not parse user's SSH public key. Is it valid? Reason given: {err}") |
748 | + })?; |
749 | + let signature = if ssh_signature.contains("\r\n") { |
750 | + ssh_signature.trim().replace("\r\n", "\n").parse::<SshSig>() |
751 | + } else { |
752 | + ssh_signature.parse::<SshSig>() |
753 | + } |
754 | + .map_err(|err| format!("Invalid SSH signature. Reason given: {err}"))?; |
755 | + |
756 | + if let Err(err) = public_key.verify(namespace, token.as_bytes(), &signature) { |
757 | + use ssh_key::Error; |
758 | + |
759 | + #[allow(clippy::wildcard_in_or_patterns)] |
760 | + return match err { |
761 | + Error::Io(err_kind) => { |
762 | + log::error!( |
763 | + "ssh signature could not be verified because of internal error:\nSignature \ |
764 | + was {sig:#?}\nError was {err_kind}." |
765 | + ); |
766 | + Err("SSH signature could not be verified because of internal error.".into()) |
767 | + } |
768 | + Error::Crypto => Err("SSH signature is invalid.".into()), |
769 | + Error::AlgorithmUnknown |
770 | + | Error::AlgorithmUnsupported { .. } |
771 | + | Error::CertificateFieldInvalid(_) |
772 | + | Error::CertificateValidation |
773 | + | Error::Decrypted |
774 | + | Error::Ecdsa(_) |
775 | + | Error::Encoding(_) |
776 | + | Error::Encrypted |
777 | + | Error::FormatEncoding |
778 | + | Error::Namespace |
779 | + | Error::PublicKey |
780 | + | Error::Time |
781 | + | Error::TrailingData { .. } |
782 | + | Error::Version { .. } |
783 | + | _ => Err(format!("SSH signature could not be verified: Reason given: {err}").into()), |
784 | + }; |
785 | + } |
786 | + |
787 | + Ok(()) |
788 | + } |
789 | + |
790 | pub async fn logout_handler( |
791 | _: LogoutPath, |
792 | mut auth: AuthContext, |
793 | @@ -657,10 +743,8 @@ pub mod auth_request { |
794 | #[cfg(test)] |
795 | mod tests { |
796 | use super::*; |
797 | - |
798 | - #[tokio::test] |
799 | - async fn test_ssh_keygen() { |
800 | - const PKEY: &str = concat!("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCzXp8nLJL8GPNw7S+Dqt0m3Dw/", |
801 | + const PKEY: &str = concat!( |
802 | + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCzXp8nLJL8GPNw7S+Dqt0m3Dw/", |
803 | "xFOAdwKXcekTFI9cLDEUII2rNPf0uUZTpv57OgU+", |
804 | "QOEEIvWMjz+5KSWBX8qdP8OtV0QNvynlZkEKZN0cUqGKaNXo5a+PUDyiJ2rHroPe1aMo6mUBL9kLR6J2U1CYD/dLfL8ywXsAGmOL0bsK0GRPVBJAjpUNRjpGU/", |
805 | "2FFIlU6s6GawdbDXEHDox/UoOVAKIlhKabaTrFBA0ACFLRX2/GCBmHqqt5d4ZZjefYzReLs/beOjafYImoyhHC428wZDcUjvLrpSJbIOE/", |
806 | @@ -668,48 +752,54 @@ mod tests { |
807 | "lyjxeWIUYyj7rjlqKJ9tzygek7QNxCtuqH5xsZAZqzQCN8wfrPAlwDykvWityKOw+Bt2DWjimITqyKgsBsOaA+", |
808 | "eVCllFvooJxoYvAjODASjAUoOdgVzyBDpFnOhLFYiIIyL3F6NROS9i7z086paX7mrzcQzvLr4ckF9qT7DrI88ikISCR9bFR4vPq3aH", |
809 | "zJdjDDpWxACa5b11NG8KdCJPe/L0kDw82Q00U13CpW9FI9sZjvk+", |
810 | - "lyw8bTFvVsIl6A0ueboFvrNvznAqHrtfWu75fXRh5sKj2TGk8rhm3vyNgrBSr5zAfFVM8LgqBxbAAYw=="); |
811 | - |
812 | - const SIG: &str = concat!( |
813 | - "-----BEGIN SSH SIGNATURE-----\n", |
814 | - "U1NIU0lHAAAAAQAAAhcAAAAHc3NoLXJzYQAAAAMBAAEAAAIBALNenycskvwY83DtL4Oq3S\n", |
815 | - "bcPD/EU4B3Apdx6RMUj1wsMRQgjas09/S5RlOm/ns6BT5A4QQi9YyPP7kpJYFfyp0/w61X\n", |
816 | - "RA2/KeVmQQpk3RxSoYpo1ejlr49QPKInaseug97VoyjqZQEv2QtHonZTUJgP90t8vzLBew\n", |
817 | - "AaY4vRuwrQZE9UEkCOlQ1GOkZT/YUUiVTqzoZrB1sNcQcOjH9Sg5UAoiWEpptpOsUEDQAI\n", |
818 | - "UtFfb8YIGYeqq3l3hlmN59jNF4uz9t46Np9giajKEcLjbzBkNxSO8uulIlsg4T+BI8JaVF\n", |
819 | - "tyzGDgkZwo60AtS6sT6iT5q/L0zt4WMaEsZKVMot2yEhVCv/dbrrsztth85PrE/+XKPF5Y\n", |
820 | - "hRjKPuuOWoon23PKB6TtA3EK26ofnGxkBmrNAI3zB+s8CXAPKS9aK3Io7D4G3YNaOKYhOr\n", |
821 | - "IqCwGw5oD55UKWUW+ignGhi8CM4MBKMBSg52BXPIEOkWc6EsViIgjIvcXo1E5L2LvPTzql\n", |
822 | - "pfuavNxDO8uvhyQX2pPsOsjzyKQhIJH1sVHi8+rdofMl2MMOlbEAJrlvXU0bwp0Ik978vS\n", |
823 | - "QPDzZDTRTXcKlb0Uj2xmO+T6XLDxtMW9WwiXoDS55ugW+s2/OcCoeu19a7vl9dGHmwqPZM\n", |
824 | - "aTyuGbe/I2CsFKvnMB8VUzwuCoHFsABjAAAAFGRvYy10ZXN0QGV4YW1wbGUuY29tAAAAAA\n", |
825 | - "AAAAZzaGE1MTIAAAIUAAAADHJzYS1zaGEyLTUxMgAAAgBxaMqIfeapKTrhQzggDssD+76s\n", |
826 | - "jZxv3XxzgsuAjlIdtw+/nyxU6skTnrGoam2shpmQvx0HuqSQ7HyS2USBK7T4LZNoE53zR/\n", |
827 | - "ZmHLGoyQAoexiHSEW9Lk53kyRNPhpXQedTvm8REHPGM3zw6WO6mAXVVxvebvawf81LTbBb\n", |
828 | - "p9ubNRcHgktVeywMO/sD6zWSyShq1gjVv1PdRBOjUgqkwjImL8dFKi1QUeoffCxyk3JhTO\n", |
829 | - "siTy79HZSz/kOvkvL1vQuqaP2R8lE9P1uaD19dGOMTPRod3u+QmpYX47ri5KM3Fmkfxdwq\n", |
830 | - "p8JVmfAA9nme7bmNS1hWgmF2Nbh9qjh1zOZvCimIpuNtz5eEl9K+1DxG6w5tX86wSGvBMO\n", |
831 | - "znx0k1gGfkiAULqgrkdul7mqMPRvPN9J6QlNJ7SLFChRhzlJIJc6tOvCs7qkVD43Zcb+I5\n", |
832 | - "Z+K4NiFf5jf8kVX/pjjeW/ucbrctJIkGsZ58OkHKi1EDRcq7NtCF6SKlcv8g3fMLd9wW6K\n", |
833 | - "aaed0TBDC+s+f6naNIGvWqfWCwDuK5xGyDTTmJGcrsMwWuT9K6uLk8cGdv7t5mOFuWi5jl\n", |
834 | - "E+IKZKVABMuWqSj96ErMIiBjtsAZfNSezpsK49wQztoSPhdwLhD6fHrSAyPCqN2xRkcsIb\n", |
835 | - "6PxWKC/OELf3gyEBRPouxsF7xSZQ==\n", |
836 | - "-----END SSH SIGNATURE-----\n" |
837 | - ); |
838 | + "lyw8bTFvVsIl6A0ueboFvrNvznAqHrtfWu75fXRh5sKj2TGk8rhm3vyNgrBSr5zAfFVM8LgqBxbAAYw==" |
839 | + ); |
840 | + |
841 | + const ARMOR_SIG: &str = concat!( |
842 | + "-----BEGIN SSH SIGNATURE-----\n", |
843 | + "U1NIU0lHAAAAAQAAAhcAAAAHc3NoLXJzYQAAAAMBAAEAAAIBALNenycskvwY83DtL4Oq3S\n", |
844 | + "bcPD/EU4B3Apdx6RMUj1wsMRQgjas09/S5RlOm/ns6BT5A4QQi9YyPP7kpJYFfyp0/w61X\n", |
845 | + "RA2/KeVmQQpk3RxSoYpo1ejlr49QPKInaseug97VoyjqZQEv2QtHonZTUJgP90t8vzLBew\n", |
846 | + "AaY4vRuwrQZE9UEkCOlQ1GOkZT/YUUiVTqzoZrB1sNcQcOjH9Sg5UAoiWEpptpOsUEDQAI\n", |
847 | + "UtFfb8YIGYeqq3l3hlmN59jNF4uz9t46Np9giajKEcLjbzBkNxSO8uulIlsg4T+BI8JaVF\n", |
848 | + "tyzGDgkZwo60AtS6sT6iT5q/L0zt4WMaEsZKVMot2yEhVCv/dbrrsztth85PrE/+XKPF5Y\n", |
849 | + "hRjKPuuOWoon23PKB6TtA3EK26ofnGxkBmrNAI3zB+s8CXAPKS9aK3Io7D4G3YNaOKYhOr\n", |
850 | + "IqCwGw5oD55UKWUW+ignGhi8CM4MBKMBSg52BXPIEOkWc6EsViIgjIvcXo1E5L2LvPTzql\n", |
851 | + "pfuavNxDO8uvhyQX2pPsOsjzyKQhIJH1sVHi8+rdofMl2MMOlbEAJrlvXU0bwp0Ik978vS\n", |
852 | + "QPDzZDTRTXcKlb0Uj2xmO+T6XLDxtMW9WwiXoDS55ugW+s2/OcCoeu19a7vl9dGHmwqPZM\n", |
853 | + "aTyuGbe/I2CsFKvnMB8VUzwuCoHFsABjAAAAFGRvYy10ZXN0QGV4YW1wbGUuY29tAAAAAA\n", |
854 | + "AAAAZzaGE1MTIAAAIUAAAADHJzYS1zaGEyLTUxMgAAAgBxaMqIfeapKTrhQzggDssD+76s\n", |
855 | + "jZxv3XxzgsuAjlIdtw+/nyxU6skTnrGoam2shpmQvx0HuqSQ7HyS2USBK7T4LZNoE53zR/\n", |
856 | + "ZmHLGoyQAoexiHSEW9Lk53kyRNPhpXQedTvm8REHPGM3zw6WO6mAXVVxvebvawf81LTbBb\n", |
857 | + "p9ubNRcHgktVeywMO/sD6zWSyShq1gjVv1PdRBOjUgqkwjImL8dFKi1QUeoffCxyk3JhTO\n", |
858 | + "siTy79HZSz/kOvkvL1vQuqaP2R8lE9P1uaD19dGOMTPRod3u+QmpYX47ri5KM3Fmkfxdwq\n", |
859 | + "p8JVmfAA9nme7bmNS1hWgmF2Nbh9qjh1zOZvCimIpuNtz5eEl9K+1DxG6w5tX86wSGvBMO\n", |
860 | + "znx0k1gGfkiAULqgrkdul7mqMPRvPN9J6QlNJ7SLFChRhzlJIJc6tOvCs7qkVD43Zcb+I5\n", |
861 | + "Z+K4NiFf5jf8kVX/pjjeW/ucbrctJIkGsZ58OkHKi1EDRcq7NtCF6SKlcv8g3fMLd9wW6K\n", |
862 | + "aaed0TBDC+s+f6naNIGvWqfWCwDuK5xGyDTTmJGcrsMwWuT9K6uLk8cGdv7t5mOFuWi5jl\n", |
863 | + "E+IKZKVABMuWqSj96ErMIiBjtsAZfNSezpsK49wQztoSPhdwLhD6fHrSAyPCqN2xRkcsIb\n", |
864 | + "6PxWKC/OELf3gyEBRPouxsF7xSZQ==\n", |
865 | + "-----END SSH SIGNATURE-----\n" |
866 | + ); |
867 | |
868 | - let mut sig = SshSignature { |
869 | + fn create_sig() -> SshSignature { |
870 | + SshSignature { |
871 | email: "user@example.com".to_string(), |
872 | ssh_public_key: PKEY.to_string(), |
873 | - ssh_signature: SIG.to_string(), |
874 | + ssh_signature: ARMOR_SIG.to_string(), |
875 | namespace: "doc-test@example.com".into(), |
876 | token: "d074a61990".to_string(), |
877 | - }; |
878 | + } |
879 | + } |
880 | |
881 | - ssh_keygen(sig.clone()).await.unwrap(); |
882 | + #[tokio::test] |
883 | + async fn test_ssh_verify() { |
884 | + let mut sig = create_sig(); |
885 | + ssh_verify(sig.clone()).await.unwrap(); |
886 | |
887 | sig.ssh_signature = sig.ssh_signature.replace('J', "0"); |
888 | |
889 | - let err = ssh_keygen(sig).await.unwrap_err(); |
890 | + let err = ssh_verify(sig).await.unwrap_err(); |
891 | |
892 | assert!( |
893 | err.to_string().starts_with("ssh-keygen exited with"), |
894 | @@ -717,4 +807,38 @@ mod tests { |
895 | err |
896 | ); |
897 | } |
898 | + |
899 | + #[cfg(feature = "ssh-key")] |
900 | + #[tokio::test] |
901 | + async fn test_ssh_verify_in_memory() { |
902 | + let mut sig = create_sig(); |
903 | + ssh_verify_in_memory(sig.clone()).await.unwrap(); |
904 | + |
905 | + sig.ssh_signature = sig.ssh_signature.replace('J', "0"); |
906 | + |
907 | + let err = ssh_verify_in_memory(sig.clone()).await.unwrap_err(); |
908 | + |
909 | + assert_eq!( |
910 | + &err.to_string(), |
911 | + "Invalid SSH signature. Reason given: invalid label: 'ssh-}3a'", |
912 | + "{}", |
913 | + err |
914 | + ); |
915 | + |
916 | + sig.ssh_public_key = sig.ssh_public_key.replace(' ', "0"); |
917 | + |
918 | + let err = ssh_verify_in_memory(sig).await.unwrap_err(); |
919 | + assert_eq!( |
920 | + &err.to_string(), |
921 | + "Could not parse user's SSH public key. Is it valid? Reason given: length invalid", |
922 | + "{}", |
923 | + err |
924 | + ); |
925 | + |
926 | + let mut sig = create_sig(); |
927 | + sig.token = sig.token.replace('d', "0"); |
928 | + |
929 | + let err = ssh_verify_in_memory(sig).await.unwrap_err(); |
930 | + assert_eq!(&err.to_string(), "SSH signature is invalid.", "{}", err); |
931 | + } |
932 | } |
933 | diff --git a/web/src/main.rs b/web/src/main.rs |
934 | index 45520a4..125742a 100644 |
935 | --- a/web/src/main.rs |
936 | +++ b/web/src/main.rs |
937 | @@ -246,6 +246,8 @@ mod tests { |
938 | |
939 | #[tokio::test] |
940 | async fn test_routes() { |
941 | + #![cfg_attr(not(debug_assertions), allow(unreachable_code))] |
942 | + |
943 | init_stderr_logging(); |
944 | |
945 | macro_rules! req { |
946 | @@ -375,6 +377,8 @@ mod tests { |
947 | assert_eq!(response.status(), StatusCode::OK); |
948 | } |
949 | |
950 | + #[cfg(not(debug_assertions))] |
951 | + return; |
952 | // ------------------------------------------------------------ |
953 | // auth.rs... |
954 |