|
| 1 | +use crate::function::PyFuncArgs; |
| 2 | +use crate::obj::objbytes::PyBytesRef; |
| 3 | +use crate::obj::objtype::PyClassRef; |
| 4 | +use crate::pyobject::{PyClassImpl, PyObjectRef, PyResult, PyValue}; |
| 5 | +use crate::vm::VirtualMachine; |
| 6 | +use std::cell::RefCell; |
| 7 | +use std::fmt; |
| 8 | + |
| 9 | +use crypto; |
| 10 | +use crypto::digest::Digest; |
| 11 | + |
| 12 | +#[pyclass(name = "hasher")] |
| 13 | +struct PyHasher { |
| 14 | + name: String, |
| 15 | + buffer: Box<RefCell<Digest>>, |
| 16 | +} |
| 17 | + |
| 18 | +impl fmt::Debug for PyHasher { |
| 19 | + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 20 | + write!(f, "hasher {}", self.name) |
| 21 | + } |
| 22 | +} |
| 23 | + |
| 24 | +impl PyValue for PyHasher { |
| 25 | + fn class(vm: &VirtualMachine) -> PyClassRef { |
| 26 | + vm.class("hashlib", "hasher") |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +#[pyimpl] |
| 31 | +impl PyHasher { |
| 32 | + // fn new<D: 'static>(d: D) -> Self where D: Digest, D: Sized { |
| 33 | + fn new<D: 'static>(name: &str, d: D) -> Self |
| 34 | + where |
| 35 | + D: Digest, |
| 36 | + D: Sized, |
| 37 | + { |
| 38 | + /* |
| 39 | + let d = match name { |
| 40 | + "md5" => crypto::md5::Md5::new(), |
| 41 | + crypto::sha2::Sha256::new() |
| 42 | + }; |
| 43 | + */ |
| 44 | + |
| 45 | + PyHasher { |
| 46 | + name: name.to_string(), |
| 47 | + buffer: Box::new(RefCell::new(d)), |
| 48 | + } |
| 49 | + } |
| 50 | + |
| 51 | + #[pymethod(name = "__new__")] |
| 52 | + fn py_new(_cls: PyClassRef, _args: PyFuncArgs, vm: &VirtualMachine) -> PyResult { |
| 53 | + Ok(PyHasher::new("md5", crypto::md5::Md5::new()) |
| 54 | + .into_ref(vm) |
| 55 | + .into_object()) |
| 56 | + } |
| 57 | + |
| 58 | + #[pymethod(name = "update")] |
| 59 | + fn update(&self, data: PyBytesRef, vm: &VirtualMachine) -> PyResult { |
| 60 | + self.buffer.borrow_mut().input(data.get_value()); |
| 61 | + Ok(vm.get_none()) |
| 62 | + } |
| 63 | + |
| 64 | + #[pymethod(name = "hexdigest")] |
| 65 | + fn hexdigest(&self, vm: &VirtualMachine) -> PyResult { |
| 66 | + Ok(vm.new_str(self.buffer.borrow_mut().result_str())) |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +fn md5(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 71 | + Ok(PyHasher::new("md5", crypto::md5::Md5::new())) |
| 72 | +} |
| 73 | + |
| 74 | +fn sha1(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 75 | + Ok(PyHasher::new("sha1", crypto::sha1::Sha1::new())) |
| 76 | +} |
| 77 | + |
| 78 | +fn sha224(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 79 | + Ok(PyHasher::new("224", crypto::sha2::Sha224::new())) |
| 80 | +} |
| 81 | + |
| 82 | +fn sha256(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 83 | + Ok(PyHasher::new("sha256", crypto::sha2::Sha256::new())) |
| 84 | +} |
| 85 | + |
| 86 | +fn sha384(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 87 | + Ok(PyHasher::new("sha384", crypto::sha2::Sha384::new())) |
| 88 | +} |
| 89 | + |
| 90 | +fn sha512(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 91 | + Ok(PyHasher::new("sha512", crypto::sha2::Sha512::new())) |
| 92 | +} |
| 93 | + |
| 94 | +fn sha3_224(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 95 | + Ok(PyHasher::new("sha3_224", crypto::sha3::Sha3::sha3_224())) |
| 96 | +} |
| 97 | + |
| 98 | +fn sha3_256(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 99 | + Ok(PyHasher::new("sha3_256", crypto::sha3::Sha3::sha3_256())) |
| 100 | +} |
| 101 | + |
| 102 | +fn sha3_384(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 103 | + Ok(PyHasher::new("sha3_384", crypto::sha3::Sha3::sha3_384())) |
| 104 | +} |
| 105 | + |
| 106 | +fn sha3_512(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 107 | + Ok(PyHasher::new("sha3_512", crypto::sha3::Sha3::sha3_512())) |
| 108 | +} |
| 109 | + |
| 110 | +fn blake2b(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 111 | + // TODO: handle parameters |
| 112 | + Ok(PyHasher::new("blake2b", crypto::blake2b::Blake2b::new(0))) |
| 113 | +} |
| 114 | + |
| 115 | +fn blake2s(_vm: &VirtualMachine) -> PyResult<PyHasher> { |
| 116 | + // TODO: handle parameters |
| 117 | + Ok(PyHasher::new("blake2s", crypto::blake2s::Blake2s::new(0))) |
| 118 | +} |
| 119 | + |
| 120 | +pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { |
| 121 | + let ctx = &vm.ctx; |
| 122 | + |
| 123 | + let hasher_type = PyHasher::make_class(ctx); |
| 124 | + |
| 125 | + py_module!(vm, "hashlib", { |
| 126 | + "md5" => ctx.new_rustfunc(md5), |
| 127 | + "sha1" => ctx.new_rustfunc(sha1), |
| 128 | + "sha224" => ctx.new_rustfunc(sha224), |
| 129 | + "sha256" => ctx.new_rustfunc(sha256), |
| 130 | + "sha384" => ctx.new_rustfunc(sha384), |
| 131 | + "sha512" => ctx.new_rustfunc(sha512), |
| 132 | + "sha3_224" => ctx.new_rustfunc(sha3_224), |
| 133 | + "sha3_256" => ctx.new_rustfunc(sha3_256), |
| 134 | + "sha3_384" => ctx.new_rustfunc(sha3_384), |
| 135 | + "sha3_512" => ctx.new_rustfunc(sha3_512), |
| 136 | + "blake2b" => ctx.new_rustfunc(blake2b), |
| 137 | + "blake2s" => ctx.new_rustfunc(blake2s), |
| 138 | + "hasher" => hasher_type, |
| 139 | + }) |
| 140 | +} |
0 commit comments