Switch to the sha2 crate for SRI digests.

This removes one (simple) use of OpenSSL
This commit is contained in:
Fabrice Desré 2023-02-24 18:38:06 -08:00
parent f4c4f4472d
commit fec4c589b2
6 changed files with 31 additions and 26 deletions

View file

@ -30,7 +30,7 @@ servo = [
[dependencies]
accountable-refcell = { version = "0.2.0", optional = true }
app_units = "0.7"
content-security-policy = { version = "0.4.0", features = ["serde"], optional = true }
content-security-policy = { version = "0.5", features = ["serde"], optional = true }
crossbeam-channel = { version = "0.4", optional = true }
cssparser = "0.29"
euclid = "0.22"

View file

@ -20,7 +20,7 @@ async-tungstenite = { version = "0.9", features = ["tokio-openssl"] }
base64 = "0.10.1"
brotli = "3"
bytes = "1"
content-security-policy = { version = "0.4.0", features = ["serde"] }
content-security-policy = { version = "0.5", features = ["serde"] }
cookie_rs = { package = "cookie", version = "0.12" }
crossbeam-channel = "0.4"
data-url = "0.1.0"
@ -29,6 +29,7 @@ embedder_traits = { path = "../embedder_traits" }
flate2 = "1"
futures = { version = "0.3", package = "futures" }
futures-util = { version = "0.3" }
generic-array = "0.14"
headers = "0.3"
http = "0.2"
hyper = { version = "0.14", features = ["client", "http1", "http2", "tcp", "stream"] }
@ -57,6 +58,7 @@ servo_allocator = { path = "../allocator" }
servo_arc = { path = "../servo_arc" }
servo_config = { path = "../config" }
servo_url = { path = "../url" }
sha2 = "0.10"
time = "0.1.41"
tokio = { version = "1", package = "tokio", features = ["sync", "macros", "rt-multi-thread"] }
tokio2 = { version = "0.2", package = "tokio", features = ["sync", "macros", "rt-threaded", "tcp"] }

View file

@ -3,8 +3,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use base64;
use generic_array::ArrayLength;
use net_traits::response::{Response, ResponseBody, ResponseType};
use openssl::hash::{hash, MessageDigest};
use sha2::{Digest, Sha256, Sha384, Sha512};
use std::iter::Filter;
use std::str::Split;
use std::sync::MutexGuard;
@ -115,12 +116,13 @@ pub fn get_strongest_metadata(integrity_metadata_list: Vec<SriEntry>) -> Vec<Sri
}
/// <https://w3c.github.io/webappsec-subresource-integrity/#apply-algorithm-to-response>
fn apply_algorithm_to_response(
fn apply_algorithm_to_response<S: ArrayLength<u8>, D: Digest<OutputSize = S>>(
body: MutexGuard<ResponseBody>,
message_digest: MessageDigest,
mut hasher: D,
) -> String {
if let ResponseBody::Done(ref vec) = *body {
let response_digest = hash(message_digest, vec).unwrap(); //Now hash
hasher.update(vec);
let response_digest = hasher.finalize(); //Now hash
base64::encode(&response_digest)
} else {
unreachable!("Tried to calculate digest of incomplete response body")
@ -156,14 +158,14 @@ pub fn is_response_integrity_valid(integrity_metadata: &str, response: &Response
let algorithm = item.alg;
let digest = item.val;
let message_digest = match &*algorithm {
"sha256" => MessageDigest::sha256(),
"sha384" => MessageDigest::sha384(),
"sha512" => MessageDigest::sha512(),
let hashed = match &*algorithm {
"sha256" => apply_algorithm_to_response(body, Sha256::new()),
"sha384" => apply_algorithm_to_response(body, Sha384::new()),
"sha512" => apply_algorithm_to_response(body, Sha512::new()),
_ => continue,
};
if apply_algorithm_to_response(body, message_digest) == digest {
if hashed == digest {
return true;
}
}

View file

@ -13,7 +13,7 @@ test = false
doctest = false
[dependencies]
content-security-policy = { version = "0.4.0", features = ["serde"] }
content-security-policy = { version = "0.5", features = ["serde"] }
cookie = "0.12"
embedder_traits = { path = "../embedder_traits" }
headers = "0.3"

View file

@ -39,7 +39,7 @@ bitflags = "1.0"
bluetooth_traits = { path = "../bluetooth_traits" }
canvas_traits = { path = "../canvas_traits" }
chrono = "0.4"
content-security-policy = { version = "0.4.0", features = ["serde"] }
content-security-policy = { version = "0.5", features = ["serde"] }
cookie = "0.12"
crossbeam-channel = "0.4"
cssparser = "0.29"