Integrated hmac.py and test_hmac.py:

* fix typing issue on digest update function
* implemented copy for PyHasher object
* fixed two test_hashlib.py expected failure as a side-effect
This commit is contained in:
Charles Hubain
2023-02-21 11:35:09 +09:00
parent 33da5bf81f
commit b5f54f1624
5 changed files with 31 additions and 14 deletions

7
Cargo.lock generated
View File

@@ -691,6 +691,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "dyn-clone"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60"
[[package]]
name = "either"
version = "1.8.1"
@@ -2134,6 +2140,7 @@ dependencies = [
"csv-core",
"digest",
"dns-lookup",
"dyn-clone",
"flate2",
"foreign-types-shared",
"gethostname",

View File

@@ -206,8 +206,6 @@ class HashLibTestCase(unittest.TestCase):
def is_fips_mode(self):
return get_fips_mode()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_hash_array(self):
a = array.array("b", range(10))
for cons in self.hash_constructors:
@@ -334,8 +332,6 @@ class HashLibTestCase(unittest.TestCase):
hashlib.new(h.name, usedforsecurity=False).name
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_large_update(self):
aas = b'a' * 128
bees = b'b' * 127

View File

@@ -331,10 +331,14 @@ class TestVectorsTestCase(unittest.TestCase):
def test_sha256_rfc4231(self):
self._rfc4231_test_cases(hashlib.sha256, 'sha256', 32, 64)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@hashlib_helper.requires_hashdigest('sha384', openssl=True)
def test_sha384_rfc4231(self):
self._rfc4231_test_cases(hashlib.sha384, 'sha384', 48, 128)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@hashlib_helper.requires_hashdigest('sha512', openssl=True)
def test_sha512_rfc4231(self):
self._rfc4231_test_cases(hashlib.sha512, 'sha512', 64, 128)

View File

@@ -38,6 +38,7 @@ parking_lot = { workspace = true }
memchr = "2.4.1"
base64 = "0.13.0"
csv-core = "0.1.10"
dyn-clone = "1.0.10"
libz-sys = { version = "1.1.5", optional = true }
puruspe = "0.1.5"
xml-rs = "0.8.4"

View File

@@ -4,12 +4,13 @@ pub(crate) use hashlib::make_module;
mod hashlib {
use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
use crate::vm::{
builtins::{PyBytes, PyBytesRef, PyStrRef, PyTypeRef},
function::{FuncArgs, OptionalArg},
builtins::{PyBytes, PyStrRef, PyTypeRef},
function::{ArgBytesLike, FuncArgs, OptionalArg},
PyPayload, PyResult, VirtualMachine,
};
use blake2::{Blake2b512, Blake2s256};
use digest::DynDigest;
use dyn_clone::{clone_trait_object, DynClone};
use md5::Md5;
use sha1::Sha1;
use sha2::{Sha224, Sha256, Sha384, Sha512};
@@ -21,7 +22,7 @@ mod hashlib {
#[pyarg(positional)]
name: PyStrRef,
#[pyarg(any, optional)]
data: OptionalArg<PyBytesRef>,
data: OptionalArg<ArgBytesLike>,
#[pyarg(named, default = "true")]
usedforsecurity: bool,
}
@@ -30,7 +31,7 @@ mod hashlib {
#[allow(unused)]
struct BlakeHashArgs {
#[pyarg(positional, optional)]
data: OptionalArg<PyBytesRef>,
data: OptionalArg<ArgBytesLike>,
#[pyarg(named, default = "true")]
usedforsecurity: bool,
}
@@ -39,7 +40,7 @@ mod hashlib {
#[allow(unused)]
struct HashArgs {
#[pyarg(any, optional)]
string: OptionalArg<PyBytesRef>,
string: OptionalArg<ArgBytesLike>,
#[pyarg(named, default = "true")]
usedforsecurity: bool,
}
@@ -91,8 +92,8 @@ mod hashlib {
}
#[pymethod]
fn update(&self, data: PyBytesRef) {
self.write().input(data.as_bytes());
fn update(&self, data: ArgBytesLike) {
data.with_ref(|bytes| self.write().input(bytes));
}
#[pymethod]
@@ -106,6 +107,11 @@ mod hashlib {
hex::encode(result)
}
#[pymethod]
fn copy(&self) -> Self {
PyHasher::new(&self.name, self.buffer.read().clone())
}
fn get_digest(&self) -> Vec<u8> {
self.read().get_digest()
}
@@ -168,7 +174,7 @@ mod hashlib {
}
}
fn init(hasher: PyHasher, data: OptionalArg<PyBytesRef>) -> PyResult<PyHasher> {
fn init(hasher: PyHasher, data: OptionalArg<ArgBytesLike>) -> PyResult<PyHasher> {
if let OptionalArg::Present(data) = data {
hasher.update(data);
}
@@ -260,10 +266,13 @@ mod hashlib {
init(PyHasher::new("blake2s", HashWrapper::blake2s()), args.data)
}
trait ThreadSafeDynDigest: DynDigest + Sync + Send {}
impl<T> ThreadSafeDynDigest for T where T: DynDigest + Sync + Send {}
trait ThreadSafeDynDigest: DynClone + DynDigest + Sync + Send {}
impl<T> ThreadSafeDynDigest for T where T: DynClone + DynDigest + Sync + Send {}
clone_trait_object!(ThreadSafeDynDigest);
/// Generic wrapper patching around the hashing libraries.
#[derive(Clone)]
struct HashWrapper {
inner: Box<dyn ThreadSafeDynDigest>,
}