Skip to content

Commit 0351f45

Browse files
committed
WIP: Verify file signatures
1 parent fb8d96f commit 0351f45

File tree

11 files changed

+134
-2
lines changed

11 files changed

+134
-2
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.key binary=true -diff

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ regex = "1"
2727
log = "0.4"
2828
urlencoding = "2.1"
2929
self-replace = "1"
30+
ed25519-dalek = { version = "2", optional = true }
31+
memmap2 = { version = "0.7", optional = true }
3032

3133
[features]
3234
default = ["reqwest/default-tls"]
@@ -36,6 +38,7 @@ compression-zip-deflate = ["zip/deflate"] #
3638
archive-tar = ["tar"]
3739
compression-flate2 = ["flate2", "either"] #
3840
rustls = ["reqwest/rustls-tls"]
41+
signatures = ["ed25519-dalek", "memmap2"]
3942

4043
[package.metadata.docs.rs]
4144
# Whether to pass `--all-features` to Cargo (default: false)

examples/github-private.key

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
S��Đ*E��ʦ](Խ��V� ���yBփ�AsWVf2�N�w�� �E��<�$^}��п

examples/github-public.key

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
փ�AsWVf2�N�w�� �E��<�$^}��п

examples/github.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ extern crate self_update;
88

99
fn run() -> Result<(), Box<dyn ::std::error::Error>> {
1010
let releases = self_update::backends::github::ReleaseList::configure()
11-
.repo_owner("jaemk")
11+
.repo_owner("Kijewski")
1212
.repo_name("self_update")
1313
.build()?
1414
.fetch()?;
1515
println!("found releases:");
1616
println!("{:#?}\n", releases);
1717

1818
let status = self_update::backends::github::Update::configure()
19-
.repo_owner("jaemk")
19+
.repo_owner("Kijewski")
2020
.repo_name("self_update")
2121
.bin_name("github")
2222
.show_download_progress(true)
@@ -30,6 +30,7 @@ fn run() -> Result<(), Box<dyn ::std::error::Error>> {
3030
// or prompting the user for input
3131
//.auth_token(env!("DOWNLOAD_AUTH_TOKEN"))
3232
.current_version(cargo_crate_version!())
33+
.verifying_keys([*include_bytes!("github-public.key")])
3334
.build()?
3435
.update()?;
3536
println!("Update status: `{}`!", status.version());

src/backends/gitea.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ pub struct UpdateBuilder {
241241
progress_template: String,
242242
progress_chars: String,
243243
auth_token: Option<String>,
244+
#[cfg(feature = "signatures")]
245+
verifying_keys: Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>,
244246
}
245247

246248
impl UpdateBuilder {
@@ -385,6 +387,15 @@ impl UpdateBuilder {
385387
self
386388
}
387389

390+
#[cfg(feature = "signatures")]
391+
pub fn verifying_keys(
392+
&mut self,
393+
keys: impl Into<Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>>,
394+
) -> &mut Self {
395+
self.verifying_keys = keys.into();
396+
self
397+
}
398+
388399
/// Confirm config and create a ready-to-use `Update`
389400
///
390401
/// * Errors:
@@ -440,6 +451,8 @@ impl UpdateBuilder {
440451
show_output: self.show_output,
441452
no_confirm: self.no_confirm,
442453
auth_token: self.auth_token.clone(),
454+
#[cfg(feature = "signatures")]
455+
verifying_keys: self.verifying_keys.clone(),
443456
}))
444457
}
445458
}
@@ -462,6 +475,8 @@ pub struct Update {
462475
progress_template: String,
463476
progress_chars: String,
464477
auth_token: Option<String>,
478+
#[cfg(feature = "signatures")]
479+
verifying_keys: Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>,
465480
}
466481
impl Update {
467482
/// Initialize a new `Update` builder
@@ -566,6 +581,11 @@ impl ReleaseUpdate for Update {
566581
fn api_headers(&self, auth_token: &Option<String>) -> Result<header::HeaderMap> {
567582
api_headers(auth_token)
568583
}
584+
585+
#[cfg(feature = "signatures")]
586+
fn verifying_keys(&self) -> &[[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]] {
587+
&self.verifying_keys
588+
}
569589
}
570590

571591
impl Default for UpdateBuilder {
@@ -586,6 +606,8 @@ impl Default for UpdateBuilder {
586606
progress_template: DEFAULT_PROGRESS_TEMPLATE.to_string(),
587607
progress_chars: DEFAULT_PROGRESS_CHARS.to_string(),
588608
auth_token: None,
609+
#[cfg(feature = "signatures")]
610+
verifying_keys: vec![],
589611
}
590612
}
591613
}

src/backends/github.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ pub struct UpdateBuilder {
244244
progress_chars: String,
245245
auth_token: Option<String>,
246246
custom_url: Option<String>,
247+
#[cfg(feature = "signatures")]
248+
verifying_keys: Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>,
247249
}
248250

249251
impl UpdateBuilder {
@@ -398,6 +400,15 @@ impl UpdateBuilder {
398400
self
399401
}
400402

403+
#[cfg(feature = "signatures")]
404+
pub fn verifying_keys(
405+
&mut self,
406+
keys: impl Into<Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>>,
407+
) -> &mut Self {
408+
self.verifying_keys = keys.into();
409+
self
410+
}
411+
401412
/// Confirm config and create a ready-to-use `Update`
402413
///
403414
/// * Errors:
@@ -450,6 +461,8 @@ impl UpdateBuilder {
450461
no_confirm: self.no_confirm,
451462
auth_token: self.auth_token.clone(),
452463
custom_url: self.custom_url.clone(),
464+
#[cfg(feature = "signatures")]
465+
verifying_keys: self.verifying_keys.clone(),
453466
}))
454467
}
455468
}
@@ -473,6 +486,8 @@ pub struct Update {
473486
progress_chars: String,
474487
auth_token: Option<String>,
475488
custom_url: Option<String>,
489+
#[cfg(feature = "signatures")]
490+
verifying_keys: Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>,
476491
}
477492
impl Update {
478493
/// Initialize a new `Update` builder
@@ -590,6 +605,11 @@ impl ReleaseUpdate for Update {
590605
fn api_headers(&self, auth_token: &Option<String>) -> Result<HeaderMap> {
591606
api_headers(auth_token)
592607
}
608+
609+
#[cfg(feature = "signatures")]
610+
fn verifying_keys(&self) -> &[[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]] {
611+
&self.verifying_keys
612+
}
593613
}
594614

595615
impl Default for UpdateBuilder {
@@ -611,6 +631,8 @@ impl Default for UpdateBuilder {
611631
progress_chars: DEFAULT_PROGRESS_CHARS.to_string(),
612632
auth_token: None,
613633
custom_url: None,
634+
#[cfg(feature = "signatures")]
635+
verifying_keys: vec![],
614636
}
615637
}
616638
}

src/backends/gitlab.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ pub struct UpdateBuilder {
238238
progress_template: String,
239239
progress_chars: String,
240240
auth_token: Option<String>,
241+
#[cfg(feature = "signatures")]
242+
verifying_keys: Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>,
241243
}
242244

243245
impl UpdateBuilder {
@@ -382,6 +384,15 @@ impl UpdateBuilder {
382384
self
383385
}
384386

387+
#[cfg(feature = "signatures")]
388+
pub fn verifying_keys(
389+
&mut self,
390+
keys: impl Into<Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>>,
391+
) -> &mut Self {
392+
self.verifying_keys = keys.into();
393+
self
394+
}
395+
385396
/// Confirm config and create a ready-to-use `Update`
386397
///
387398
/// * Errors:
@@ -433,6 +444,8 @@ impl UpdateBuilder {
433444
show_output: self.show_output,
434445
no_confirm: self.no_confirm,
435446
auth_token: self.auth_token.clone(),
447+
#[cfg(feature = "signatures")]
448+
verifying_keys: self.verifying_keys.clone(),
436449
}))
437450
}
438451
}
@@ -455,6 +468,8 @@ pub struct Update {
455468
progress_template: String,
456469
progress_chars: String,
457470
auth_token: Option<String>,
471+
#[cfg(feature = "signatures")]
472+
verifying_keys: Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>,
458473
}
459474
impl Update {
460475
/// Initialize a new `Update` builder
@@ -564,6 +579,11 @@ impl ReleaseUpdate for Update {
564579
fn api_headers(&self, auth_token: &Option<String>) -> Result<header::HeaderMap> {
565580
api_headers(auth_token)
566581
}
582+
583+
#[cfg(feature = "signatures")]
584+
fn verifying_keys(&self) -> &[[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]] {
585+
&self.verifying_keys
586+
}
567587
}
568588

569589
impl Default for UpdateBuilder {
@@ -584,6 +604,8 @@ impl Default for UpdateBuilder {
584604
progress_template: DEFAULT_PROGRESS_TEMPLATE.to_string(),
585605
progress_chars: DEFAULT_PROGRESS_CHARS.to_string(),
586606
auth_token: None,
607+
#[cfg(feature = "signatures")]
608+
verifying_keys: vec![],
587609
}
588610
}
589611
}

src/backends/s3.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ pub struct UpdateBuilder {
153153
progress_template: String,
154154
progress_chars: String,
155155
auth_token: Option<String>,
156+
#[cfg(feature = "signatures")]
157+
verifying_keys: Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>,
156158
}
157159

158160
impl Default for UpdateBuilder {
@@ -174,6 +176,8 @@ impl Default for UpdateBuilder {
174176
progress_template: DEFAULT_PROGRESS_TEMPLATE.to_string(),
175177
progress_chars: DEFAULT_PROGRESS_CHARS.to_string(),
176178
auth_token: None,
179+
#[cfg(feature = "signatures")]
180+
verifying_keys: vec![],
177181
}
178182
}
179183
}
@@ -318,6 +322,15 @@ impl UpdateBuilder {
318322
self
319323
}
320324

325+
#[cfg(feature = "signatures")]
326+
pub fn verifying_keys(
327+
&mut self,
328+
keys: impl Into<Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>>,
329+
) -> &mut Self {
330+
self.verifying_keys = keys.into();
331+
self
332+
}
333+
321334
/// Confirm config and create a ready-to-use `Update`
322335
///
323336
/// * Errors:
@@ -366,6 +379,8 @@ impl UpdateBuilder {
366379
show_output: self.show_output,
367380
no_confirm: self.no_confirm,
368381
auth_token: self.auth_token.clone(),
382+
#[cfg(feature = "signatures")]
383+
verifying_keys: self.verifying_keys.clone(),
369384
}))
370385
}
371386
}
@@ -389,6 +404,8 @@ pub struct Update {
389404
progress_template: String,
390405
progress_chars: String,
391406
auth_token: Option<String>,
407+
#[cfg(feature = "signatures")]
408+
verifying_keys: Vec<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>,
392409
}
393410

394411
impl Update {
@@ -493,6 +510,11 @@ impl ReleaseUpdate for Update {
493510
fn auth_token(&self) -> Option<String> {
494511
self.auth_token.clone()
495512
}
513+
514+
#[cfg(feature = "signatures")]
515+
fn verifying_keys(&self) -> &[[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]] {
516+
&self.verifying_keys
517+
}
496518
}
497519

498520
/// Obtain list of releases from AWS S3 API, from bucket and region specified,

src/errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub enum Error {
2020
Reqwest(reqwest::Error),
2121
SemVer(semver::Error),
2222
ArchiveNotEnabled(String),
23+
NoValidSignature,
2324
}
2425

2526
impl std::fmt::Display for Error {
@@ -37,6 +38,7 @@ impl std::fmt::Display for Error {
3738
#[cfg(feature = "archive-zip")]
3839
Zip(ref e) => write!(f, "ZipError: {}", e),
3940
ArchiveNotEnabled(ref s) => write!(f, "ArchiveNotEnabled: Archive extension '{}' not supported, please enable 'archive-{}' feature!", s, s),
41+
NoValidSignature => write!(f, "No valid signature found"),
4042
}
4143
}
4244
}

0 commit comments

Comments
 (0)