Loading Cargo.lock +25 −0 Original line number Diff line number Diff line Loading @@ -1001,6 +1001,21 @@ dependencies = [ "typenum", ] [[package]] name = "crypto_hash" version = "0.1.0" dependencies = [ "base64 0.21.0", "digest", "libc", "md-5", "nserror", "nsstring", "sha1", "sha2", "xpcom", ] [[package]] name = "cssparser" version = "0.31.0" Loading Loading @@ -2082,6 +2097,7 @@ dependencies = [ "cert_storage", "chardetng_c", "cose-c", "crypto_hash", "cubeb-coreaudio", "cubeb-pulse", "cubeb-sys", Loading Loading @@ -3097,6 +3113,15 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "md-5" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ "digest", ] [[package]] name = "mdns_service" version = "0.1.1" Loading security/manager/ssl/components.conf +2 −2 Original line number Diff line number Diff line Loading @@ -69,8 +69,8 @@ Classes = [ { 'cid': '{36a1d3b3-d886-4317-96ff-87b0005cfef7}', 'contract_ids': ['@mozilla.org/security/hash;1'], 'type': 'nsCryptoHash', 'legacy_constructor': 'mozilla::psm::NSSConstructor<nsCryptoHash>', 'headers': ['/security/manager/ssl/crypto_hash/crypto_hash.h'], 'legacy_constructor': 'crypto_hash_constructor', }, { 'cid': '{45a5fe2f-c350-4b86-962d-02d5aaaa955a}', Loading security/manager/ssl/crypto_hash/Cargo.toml 0 → 100644 +15 −0 Original line number Diff line number Diff line [package] name = "crypto_hash" version = "0.1.0" edition = "2021" [dependencies] base64 = "0.21" digest = "0.10.2" libc = "0.2" md-5 = "0.10.2" nserror = { path = "../../../../xpcom/rust/nserror" } nsstring = { path = "../../../../xpcom/rust/nsstring" } sha1 = "0.10.2" sha2 = "0.10.2" xpcom = { path = "../../../../xpcom/rust/xpcom" } security/manager/ssl/crypto_hash/crypto_hash.h 0 → 100644 +46 −0 Original line number Diff line number Diff line /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsICryptoHash.h" extern "C" { nsresult crypto_hash_constructor(REFNSIID iid, void** result); }; nsresult NS_NewCryptoHash(uint32_t aHashType, nsICryptoHash** aOutHasher) { MOZ_ASSERT(aOutHasher); nsCOMPtr<nsICryptoHash> hasher; nsresult rv = crypto_hash_constructor(NS_ICRYPTOHASH_IID, getter_AddRefs(hasher)); if (NS_FAILED(rv)) { return rv; } rv = hasher->Init(aHashType); if (NS_FAILED(rv)) { return rv; } hasher.forget(aOutHasher); return NS_OK; } nsresult NS_NewCryptoHash(const nsACString& aHashType, nsICryptoHash** aOutHasher) { MOZ_ASSERT(aOutHasher); nsCOMPtr<nsICryptoHash> hasher; nsresult rv = crypto_hash_constructor(NS_ICRYPTOHASH_IID, getter_AddRefs(hasher)); if (NS_FAILED(rv)) { return rv; } rv = hasher->InitWithString(aHashType); if (NS_FAILED(rv)) { return rv; } hasher.forget(aOutHasher); return NS_OK; } security/manager/ssl/crypto_hash/src/lib.rs 0 → 100644 +177 −0 Original line number Diff line number Diff line /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate base64; extern crate digest; extern crate libc; extern crate md5; extern crate nsstring; extern crate sha1; extern crate sha2; #[macro_use] extern crate xpcom; use base64::Engine; use digest::{Digest, DynDigest}; use nserror::{ nsresult, NS_ERROR_FAILURE, NS_ERROR_INVALID_ARG, NS_ERROR_NOT_AVAILABLE, NS_ERROR_NOT_INITIALIZED, NS_OK, }; use nsstring::{nsACString, nsCString}; use xpcom::interfaces::{nsICryptoHash, nsIInputStream}; use xpcom::xpcom_method; use std::borrow::Borrow; use std::sync::Mutex; enum Algorithm { Md5, Sha1, Sha256, Sha384, Sha512, } impl TryFrom<u32> for Algorithm { type Error = nsresult; fn try_from(value: u32) -> Result<Self, Self::Error> { match value { nsICryptoHash::MD5 => Ok(Algorithm::Md5), nsICryptoHash::SHA1 => Ok(Algorithm::Sha1), nsICryptoHash::SHA256 => Ok(Algorithm::Sha256), nsICryptoHash::SHA384 => Ok(Algorithm::Sha384), nsICryptoHash::SHA512 => Ok(Algorithm::Sha512), _ => Err(NS_ERROR_INVALID_ARG), } } } impl TryFrom<&nsACString> for Algorithm { type Error = nsresult; fn try_from(value: &nsACString) -> Result<Self, Self::Error> { match value.to_utf8().borrow() { "md5" => Ok(Algorithm::Md5), "sha1" => Ok(Algorithm::Sha1), "sha256" => Ok(Algorithm::Sha256), "sha384" => Ok(Algorithm::Sha384), "sha512" => Ok(Algorithm::Sha512), _ => Err(NS_ERROR_INVALID_ARG), } } } #[xpcom(implement(nsICryptoHash), atomic)] struct CryptoHash { digest: Mutex<Option<Box<dyn DynDigest>>>, } impl CryptoHash { xpcom_method!(init => Init(algorithm: u32)); fn init(&self, algorithm: u32) -> Result<(), nsresult> { let algorithm = algorithm.try_into()?; self.init_with_algorithm(algorithm) } xpcom_method!(init_with_string => InitWithString(algorithm: *const nsACString)); fn init_with_string(&self, algorithm: &nsACString) -> Result<(), nsresult> { let algorithm = algorithm.try_into()?; self.init_with_algorithm(algorithm) } fn init_with_algorithm(&self, algorithm: Algorithm) -> Result<(), nsresult> { let digest = match algorithm { Algorithm::Md5 => Box::new(md5::Md5::new()) as Box<dyn DynDigest>, Algorithm::Sha1 => Box::new(sha1::Sha1::new()) as Box<dyn DynDigest>, Algorithm::Sha256 => Box::new(sha2::Sha256::new()) as Box<dyn DynDigest>, Algorithm::Sha384 => Box::new(sha2::Sha384::new()) as Box<dyn DynDigest>, Algorithm::Sha512 => Box::new(sha2::Sha512::new()) as Box<dyn DynDigest>, }; let mut guard = self.digest.lock().map_err(|_| NS_ERROR_FAILURE)?; if let Some(_expected_none_digest) = (*guard).replace(digest) { return Err(NS_ERROR_FAILURE); } Ok(()) } xpcom_method!(update => Update(data: *const u8, len: u32)); fn update(&self, data: *const u8, len: u32) -> Result<(), nsresult> { let mut guard = self.digest.lock().map_err(|_| NS_ERROR_FAILURE)?; let digest = match (*guard).as_mut() { Some(digest) => digest, None => return Err(NS_ERROR_NOT_INITIALIZED), }; // Safety: this is safe as long as xpcom gave us valid arguments. let data = unsafe { std::slice::from_raw_parts(data, len.try_into().map_err(|_| NS_ERROR_INVALID_ARG)?) }; digest.update(data); Ok(()) } xpcom_method!(update_from_stream => UpdateFromStream(stream: *const nsIInputStream, len: u32)); fn update_from_stream(&self, stream: &nsIInputStream, len: u32) -> Result<(), nsresult> { let mut guard = self.digest.lock().map_err(|_| NS_ERROR_FAILURE)?; let digest = match (*guard).as_mut() { Some(digest) => digest, None => return Err(NS_ERROR_NOT_INITIALIZED), }; let mut available = 0u64; unsafe { stream.Available(&mut available as *mut u64).to_result()? }; let mut to_read = if len == u32::MAX { available } else { len as u64 }; if available == 0 || available < to_read { return Err(NS_ERROR_NOT_AVAILABLE); } let mut buf = vec![0u8; 4096]; let buf_len = buf.len() as u64; while to_read > 0 { let chunk_len = if to_read >= buf_len { buf_len as u32 } else { to_read as u32 }; let mut read = 0u32; unsafe { stream .Read( buf.as_mut_ptr() as *mut libc::c_char, chunk_len, &mut read as *mut u32, ) .to_result()? }; if read > chunk_len { return Err(NS_ERROR_FAILURE); } digest.update(&buf[0..read.try_into().map_err(|_| NS_ERROR_FAILURE)?]); to_read -= read as u64; } Ok(()) } xpcom_method!(finish => Finish(ascii: bool) -> nsACString); fn finish(&self, ascii: bool) -> Result<nsCString, nsresult> { let mut guard = self.digest.lock().map_err(|_| NS_ERROR_FAILURE)?; let digest = match (*guard).take() { Some(digest) => digest, None => return Err(NS_ERROR_NOT_INITIALIZED), }; let result = digest.finalize(); if ascii { Ok(nsCString::from( base64::engine::general_purpose::STANDARD.encode(result), )) } else { Ok(nsCString::from(result)) } } } #[no_mangle] pub extern "C" fn crypto_hash_constructor( iid: *const xpcom::nsIID, result: *mut *mut xpcom::reexports::libc::c_void, ) -> nserror::nsresult { let crypto_hash = CryptoHash::allocate(InitCryptoHash { digest: Mutex::new(None), }); unsafe { crypto_hash.QueryInterface(iid, result) } } Loading
Cargo.lock +25 −0 Original line number Diff line number Diff line Loading @@ -1001,6 +1001,21 @@ dependencies = [ "typenum", ] [[package]] name = "crypto_hash" version = "0.1.0" dependencies = [ "base64 0.21.0", "digest", "libc", "md-5", "nserror", "nsstring", "sha1", "sha2", "xpcom", ] [[package]] name = "cssparser" version = "0.31.0" Loading Loading @@ -2082,6 +2097,7 @@ dependencies = [ "cert_storage", "chardetng_c", "cose-c", "crypto_hash", "cubeb-coreaudio", "cubeb-pulse", "cubeb-sys", Loading Loading @@ -3097,6 +3113,15 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "md-5" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ "digest", ] [[package]] name = "mdns_service" version = "0.1.1" Loading
security/manager/ssl/components.conf +2 −2 Original line number Diff line number Diff line Loading @@ -69,8 +69,8 @@ Classes = [ { 'cid': '{36a1d3b3-d886-4317-96ff-87b0005cfef7}', 'contract_ids': ['@mozilla.org/security/hash;1'], 'type': 'nsCryptoHash', 'legacy_constructor': 'mozilla::psm::NSSConstructor<nsCryptoHash>', 'headers': ['/security/manager/ssl/crypto_hash/crypto_hash.h'], 'legacy_constructor': 'crypto_hash_constructor', }, { 'cid': '{45a5fe2f-c350-4b86-962d-02d5aaaa955a}', Loading
security/manager/ssl/crypto_hash/Cargo.toml 0 → 100644 +15 −0 Original line number Diff line number Diff line [package] name = "crypto_hash" version = "0.1.0" edition = "2021" [dependencies] base64 = "0.21" digest = "0.10.2" libc = "0.2" md-5 = "0.10.2" nserror = { path = "../../../../xpcom/rust/nserror" } nsstring = { path = "../../../../xpcom/rust/nsstring" } sha1 = "0.10.2" sha2 = "0.10.2" xpcom = { path = "../../../../xpcom/rust/xpcom" }
security/manager/ssl/crypto_hash/crypto_hash.h 0 → 100644 +46 −0 Original line number Diff line number Diff line /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsICryptoHash.h" extern "C" { nsresult crypto_hash_constructor(REFNSIID iid, void** result); }; nsresult NS_NewCryptoHash(uint32_t aHashType, nsICryptoHash** aOutHasher) { MOZ_ASSERT(aOutHasher); nsCOMPtr<nsICryptoHash> hasher; nsresult rv = crypto_hash_constructor(NS_ICRYPTOHASH_IID, getter_AddRefs(hasher)); if (NS_FAILED(rv)) { return rv; } rv = hasher->Init(aHashType); if (NS_FAILED(rv)) { return rv; } hasher.forget(aOutHasher); return NS_OK; } nsresult NS_NewCryptoHash(const nsACString& aHashType, nsICryptoHash** aOutHasher) { MOZ_ASSERT(aOutHasher); nsCOMPtr<nsICryptoHash> hasher; nsresult rv = crypto_hash_constructor(NS_ICRYPTOHASH_IID, getter_AddRefs(hasher)); if (NS_FAILED(rv)) { return rv; } rv = hasher->InitWithString(aHashType); if (NS_FAILED(rv)) { return rv; } hasher.forget(aOutHasher); return NS_OK; }
security/manager/ssl/crypto_hash/src/lib.rs 0 → 100644 +177 −0 Original line number Diff line number Diff line /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate base64; extern crate digest; extern crate libc; extern crate md5; extern crate nsstring; extern crate sha1; extern crate sha2; #[macro_use] extern crate xpcom; use base64::Engine; use digest::{Digest, DynDigest}; use nserror::{ nsresult, NS_ERROR_FAILURE, NS_ERROR_INVALID_ARG, NS_ERROR_NOT_AVAILABLE, NS_ERROR_NOT_INITIALIZED, NS_OK, }; use nsstring::{nsACString, nsCString}; use xpcom::interfaces::{nsICryptoHash, nsIInputStream}; use xpcom::xpcom_method; use std::borrow::Borrow; use std::sync::Mutex; enum Algorithm { Md5, Sha1, Sha256, Sha384, Sha512, } impl TryFrom<u32> for Algorithm { type Error = nsresult; fn try_from(value: u32) -> Result<Self, Self::Error> { match value { nsICryptoHash::MD5 => Ok(Algorithm::Md5), nsICryptoHash::SHA1 => Ok(Algorithm::Sha1), nsICryptoHash::SHA256 => Ok(Algorithm::Sha256), nsICryptoHash::SHA384 => Ok(Algorithm::Sha384), nsICryptoHash::SHA512 => Ok(Algorithm::Sha512), _ => Err(NS_ERROR_INVALID_ARG), } } } impl TryFrom<&nsACString> for Algorithm { type Error = nsresult; fn try_from(value: &nsACString) -> Result<Self, Self::Error> { match value.to_utf8().borrow() { "md5" => Ok(Algorithm::Md5), "sha1" => Ok(Algorithm::Sha1), "sha256" => Ok(Algorithm::Sha256), "sha384" => Ok(Algorithm::Sha384), "sha512" => Ok(Algorithm::Sha512), _ => Err(NS_ERROR_INVALID_ARG), } } } #[xpcom(implement(nsICryptoHash), atomic)] struct CryptoHash { digest: Mutex<Option<Box<dyn DynDigest>>>, } impl CryptoHash { xpcom_method!(init => Init(algorithm: u32)); fn init(&self, algorithm: u32) -> Result<(), nsresult> { let algorithm = algorithm.try_into()?; self.init_with_algorithm(algorithm) } xpcom_method!(init_with_string => InitWithString(algorithm: *const nsACString)); fn init_with_string(&self, algorithm: &nsACString) -> Result<(), nsresult> { let algorithm = algorithm.try_into()?; self.init_with_algorithm(algorithm) } fn init_with_algorithm(&self, algorithm: Algorithm) -> Result<(), nsresult> { let digest = match algorithm { Algorithm::Md5 => Box::new(md5::Md5::new()) as Box<dyn DynDigest>, Algorithm::Sha1 => Box::new(sha1::Sha1::new()) as Box<dyn DynDigest>, Algorithm::Sha256 => Box::new(sha2::Sha256::new()) as Box<dyn DynDigest>, Algorithm::Sha384 => Box::new(sha2::Sha384::new()) as Box<dyn DynDigest>, Algorithm::Sha512 => Box::new(sha2::Sha512::new()) as Box<dyn DynDigest>, }; let mut guard = self.digest.lock().map_err(|_| NS_ERROR_FAILURE)?; if let Some(_expected_none_digest) = (*guard).replace(digest) { return Err(NS_ERROR_FAILURE); } Ok(()) } xpcom_method!(update => Update(data: *const u8, len: u32)); fn update(&self, data: *const u8, len: u32) -> Result<(), nsresult> { let mut guard = self.digest.lock().map_err(|_| NS_ERROR_FAILURE)?; let digest = match (*guard).as_mut() { Some(digest) => digest, None => return Err(NS_ERROR_NOT_INITIALIZED), }; // Safety: this is safe as long as xpcom gave us valid arguments. let data = unsafe { std::slice::from_raw_parts(data, len.try_into().map_err(|_| NS_ERROR_INVALID_ARG)?) }; digest.update(data); Ok(()) } xpcom_method!(update_from_stream => UpdateFromStream(stream: *const nsIInputStream, len: u32)); fn update_from_stream(&self, stream: &nsIInputStream, len: u32) -> Result<(), nsresult> { let mut guard = self.digest.lock().map_err(|_| NS_ERROR_FAILURE)?; let digest = match (*guard).as_mut() { Some(digest) => digest, None => return Err(NS_ERROR_NOT_INITIALIZED), }; let mut available = 0u64; unsafe { stream.Available(&mut available as *mut u64).to_result()? }; let mut to_read = if len == u32::MAX { available } else { len as u64 }; if available == 0 || available < to_read { return Err(NS_ERROR_NOT_AVAILABLE); } let mut buf = vec![0u8; 4096]; let buf_len = buf.len() as u64; while to_read > 0 { let chunk_len = if to_read >= buf_len { buf_len as u32 } else { to_read as u32 }; let mut read = 0u32; unsafe { stream .Read( buf.as_mut_ptr() as *mut libc::c_char, chunk_len, &mut read as *mut u32, ) .to_result()? }; if read > chunk_len { return Err(NS_ERROR_FAILURE); } digest.update(&buf[0..read.try_into().map_err(|_| NS_ERROR_FAILURE)?]); to_read -= read as u64; } Ok(()) } xpcom_method!(finish => Finish(ascii: bool) -> nsACString); fn finish(&self, ascii: bool) -> Result<nsCString, nsresult> { let mut guard = self.digest.lock().map_err(|_| NS_ERROR_FAILURE)?; let digest = match (*guard).take() { Some(digest) => digest, None => return Err(NS_ERROR_NOT_INITIALIZED), }; let result = digest.finalize(); if ascii { Ok(nsCString::from( base64::engine::general_purpose::STANDARD.encode(result), )) } else { Ok(nsCString::from(result)) } } } #[no_mangle] pub extern "C" fn crypto_hash_constructor( iid: *const xpcom::nsIID, result: *mut *mut xpcom::reexports::libc::c_void, ) -> nserror::nsresult { let crypto_hash = CryptoHash::allocate(InitCryptoHash { digest: Mutex::new(None), }); unsafe { crypto_hash.QueryInterface(iid, result) } }