Skip to content

Commit cf70b08

Browse files
committed
omaha: bring back base64 decoding functionality
Since we need to support decoding of both hex and base64 formats, bring back base64 decoding functionality. Note, while hash_sha256 of Package has hex format, sha256 of Action has base64 format. That is the reason why we need to keep both mod sha256_from_hex_str and mod sha256_from_base64_str. Signed-off-by: Dongsu Park <[email protected]>
1 parent bdb0bba commit cf70b08

File tree

5 files changed

+64
-15
lines changed

5 files changed

+64
-15
lines changed

Cargo.lock

Lines changed: 15 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

omaha/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ uuid = "1.2"
1010
url = "2"
1111
sha2 = "0.10.8"
1212
sha1 = "0.10.6"
13+
ct-codecs = "1.1.6"
14+
log = "0.4.28"
1315

1416
[dependencies.hard-xml]
1517
path = "../vendor/hard-xml"

omaha/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::num::ParseIntError;
44
#[derive(Debug)]
55
pub enum Error {
66
TryFromHex(ParseIntError),
7+
TryFromBase64(ct_codecs::Error),
78
InvalidDigestLength {
89
expected: usize,
910
actual: usize,
@@ -19,6 +20,7 @@ impl Display for Error {
1920
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2021
match self {
2122
Error::TryFromHex(err) => write!(fmt, "failed to convert from hex: {err}"),
23+
Error::TryFromBase64(err) => write!(fmt, "failed to convert from base64: {err}"),
2224
Error::InvalidDigestLength {
2325
expected,
2426
actual,

omaha/src/hash_types.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::str;
2+
use ct_codecs::{Base64, Decoder};
23

34
use sha2::Digest;
45

@@ -42,8 +43,12 @@ pub trait Hasher {
4243
fn finalize(self) -> Self::Output;
4344

4445
/// Construct a hash of the output format of the associated hashing
45-
/// algorithm using a provided string.
46+
/// algorithm using a provided hex string.
4647
fn try_from_hex_string(s: &str) -> Result<Self::Output>;
48+
49+
/// Construct a hash of the output format of the associated hashing
50+
/// algorithm using a provided base64 string.
51+
fn try_from_base64_string(s: &str) -> Result<Self::Output>;
4752
}
4853

4954
impl Hasher for Sha1 {
@@ -67,6 +72,10 @@ impl Hasher for Sha1 {
6772
fn try_from_hex_string(s: &str) -> Result<Self::Output> {
6873
try_from_hex_string::<Self>(s)
6974
}
75+
76+
fn try_from_base64_string(s: &str) -> Result<Self::Output> {
77+
try_from_base64_string::<Self>(s)
78+
}
7079
}
7180

7281
pub(crate) mod sha1_from_str {
@@ -75,7 +84,7 @@ pub(crate) mod sha1_from_str {
7584

7685
#[inline]
7786
pub(crate) fn from_str(s: &str) -> Result<Sha1Digest> {
78-
<Sha1 as Hasher>::try_from_hex_string(s)
87+
<Sha1 as Hasher>::try_from_base64_string(s)
7988
}
8089
}
8190

@@ -96,12 +105,17 @@ impl Hasher for Sha256 {
96105
fn finalize(self) -> Self::Output {
97106
self.0.finalize().into()
98107
}
108+
99109
fn try_from_hex_string(s: &str) -> Result<Self::Output> {
100110
try_from_hex_string::<Self>(s)
101111
}
112+
113+
fn try_from_base64_string(s: &str) -> Result<Self::Output> {
114+
try_from_base64_string::<Self>(s)
115+
}
102116
}
103117

104-
pub(crate) mod sha256_from_str {
118+
pub(crate) mod sha256_from_hex_str {
105119
use crate::{Hasher, Sha256, Sha256Digest};
106120
use crate::Result;
107121

@@ -111,6 +125,16 @@ pub(crate) mod sha256_from_str {
111125
}
112126
}
113127

128+
pub(crate) mod sha256_from_base64_str {
129+
use crate::{Hasher, Sha256, Sha256Digest};
130+
use crate::Result;
131+
132+
#[inline]
133+
pub(crate) fn from_str(s: &str) -> Result<Sha256Digest> {
134+
<Sha256 as Hasher>::try_from_base64_string(s)
135+
}
136+
}
137+
114138
/// Parse a hexadecimal string into the output of the generically typed hashing
115139
/// algorithm.
116140
fn try_from_hex_string<T: Hasher>(s: &str) -> Result<T::Output> {
@@ -136,6 +160,19 @@ fn try_from_hex_string<T: Hasher>(s: &str) -> Result<T::Output> {
136160
}
137161
}
138162

163+
/// Parse a base64 string into the output of the generically typed hashing
164+
/// algorithm.
165+
fn try_from_base64_string<T: Hasher>(s: &str) -> Result<T::Output> {
166+
let mut digest = T::Output::default();
167+
let mut bytes = vec![0; s.len()];
168+
169+
let bytes = Base64::decode(bytes.as_mut(), s, None).map_err(Error::TryFromBase64)?;
170+
171+
digest.as_mut().copy_from_slice(bytes);
172+
173+
Ok(digest)
174+
}
175+
139176
#[cfg(test)]
140177
mod tests {
141178
use crate::Hasher;

omaha/src/response.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use url::Url;
88

99
use crate::Error::{UnknownActionEvent, UnknownSuccessAction};
1010
use crate::uuid::braced_uuid;
11-
use crate::{Sha1Digest, Sha256Digest, Error, sha1_from_str, sha256_from_str};
11+
use crate::{Sha1Digest, Sha256Digest, Error, sha1_from_str, sha256_from_base64_str, sha256_from_hex_str};
1212

1313
#[derive(XmlRead, Debug)]
1414
#[xml(tag = "response")]
@@ -159,7 +159,7 @@ pub struct Package<'a> {
159159
#[xml(attr = "required")]
160160
pub required: bool,
161161

162-
#[xml(attr = "hash_sha256", with = "sha256_from_str")]
162+
#[xml(attr = "hash_sha256", with = "sha256_from_hex_str")]
163163
pub hash_sha256: Option<Sha256Digest>,
164164
}
165165

@@ -178,7 +178,7 @@ pub struct Action {
178178
#[xml(attr = "event")]
179179
pub event: ActionEvent,
180180

181-
#[xml(attr = "sha256", with = "sha256_from_str")]
181+
#[xml(attr = "sha256", with = "sha256_from_base64_str")]
182182
pub sha256: Sha256Digest,
183183

184184
#[xml(attr = "DisablePayloadBackoff")]
@@ -333,7 +333,7 @@ mod tests {
333333
#[test]
334334
fn package_xml_read_hashes() {
335335
const NAME: &str = "name";
336-
const SHA1_STR: &str = "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d";
336+
const SHA1_STR: &str = "FF+ci4cThKAdESIk5GbSgrN0Q7A=";
337337
const SIZE: usize = 1;
338338
const REQUIRED: bool = false;
339339
const SHA256_STR: &str = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824";
@@ -342,7 +342,7 @@ mod tests {
342342
format!("<package name=\"{NAME}\" hash=\"{SHA1_STR}\" size=\"{SIZE}\" required=\"{REQUIRED}\" hash_sha256=\"{SHA256_STR}\"/>",).as_str(),
343343
Package {
344344
name: Cow::Borrowed(NAME),
345-
hash: Some(Sha1::try_from_hex_string(SHA1_STR).unwrap()),
345+
hash: Some(Sha1::try_from_base64_string(SHA1_STR).unwrap()),
346346
size: SIZE,
347347
required: REQUIRED,
348348
hash_sha256: Some(Sha256::try_from_hex_string(SHA256_STR).unwrap()),

0 commit comments

Comments
 (0)