use pyo3::prelude::*;
use pyo3::types::PyBytes;
#[pyclass(name = "Pbkdf2ParamsBuilder")]
pub struct PyPbkdf2ParamsBuilder {
inner: synta_certificate::Pbkdf2ParamsBuilder,
built: bool,
}
#[pymethods]
impl PyPbkdf2ParamsBuilder {
#[new]
fn new() -> Self {
Self {
inner: synta_certificate::Pbkdf2ParamsBuilder::new(),
built: false,
}
}
fn salt<'py>(slf: Bound<'py, Self>, salt: &[u8]) -> Bound<'py, Self> {
{
let mut guard = slf.borrow_mut();
let old = std::mem::replace(
&mut guard.inner,
synta_certificate::Pbkdf2ParamsBuilder::new(),
);
guard.inner = old.salt(salt);
}
slf
}
fn iteration_count<'py>(slf: Bound<'py, Self>, count: u64) -> Bound<'py, Self> {
{
let mut guard = slf.borrow_mut();
let old = std::mem::replace(
&mut guard.inner,
synta_certificate::Pbkdf2ParamsBuilder::new(),
);
guard.inner = old.iteration_count(count);
}
slf
}
fn key_length<'py>(slf: Bound<'py, Self>, len: u64) -> Bound<'py, Self> {
{
let mut guard = slf.borrow_mut();
let old = std::mem::replace(
&mut guard.inner,
synta_certificate::Pbkdf2ParamsBuilder::new(),
);
guard.inner = old.key_length(len);
}
slf
}
fn prf<'py>(slf: Bound<'py, Self>, prf_oid: Vec<u32>) -> Bound<'py, Self> {
{
let mut guard = slf.borrow_mut();
let old = std::mem::replace(
&mut guard.inner,
synta_certificate::Pbkdf2ParamsBuilder::new(),
);
guard.inner = old.prf(&prf_oid);
}
slf
}
fn build<'py>(&mut self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
if self.built {
return Err(pyo3::exceptions::PyValueError::new_err(
"build() has already been called; create a new builder",
));
}
self.built = true;
let inner = std::mem::replace(
&mut self.inner,
synta_certificate::Pbkdf2ParamsBuilder::new(),
);
let der = inner
.build()
.map_err(pyo3::exceptions::PyValueError::new_err)?;
Ok(PyBytes::new(py, &der))
}
fn build_as_algorithm_identifier<'py>(
&mut self,
py: Python<'py>,
alg_oid: Vec<u32>,
) -> PyResult<Bound<'py, PyBytes>> {
if self.built {
return Err(pyo3::exceptions::PyValueError::new_err(
"build() has already been called; create a new builder",
));
}
self.built = true;
let inner = std::mem::replace(
&mut self.inner,
synta_certificate::Pbkdf2ParamsBuilder::new(),
);
let der = inner
.build_as_algorithm_identifier(&alg_oid)
.map_err(pyo3::exceptions::PyValueError::new_err)?;
Ok(PyBytes::new(py, &der))
}
fn __repr__(&self) -> String {
"Pbkdf2ParamsBuilder()".to_string()
}
}
#[pyclass(name = "Pbes2ParamsBuilder")]
pub struct PyPbes2ParamsBuilder {
inner: synta_certificate::Pbes2ParamsBuilder,
built: bool,
}
#[pymethods]
impl PyPbes2ParamsBuilder {
#[new]
fn new() -> Self {
Self {
inner: synta_certificate::Pbes2ParamsBuilder::new(),
built: false,
}
}
fn key_derivation_func<'py>(slf: Bound<'py, Self>, alg_id_der: &[u8]) -> Bound<'py, Self> {
{
let mut guard = slf.borrow_mut();
let old = std::mem::replace(
&mut guard.inner,
synta_certificate::Pbes2ParamsBuilder::new(),
);
guard.inner = old.key_derivation_func(alg_id_der);
}
slf
}
fn encryption_scheme<'py>(slf: Bound<'py, Self>, alg_id_der: &[u8]) -> Bound<'py, Self> {
{
let mut guard = slf.borrow_mut();
let old = std::mem::replace(
&mut guard.inner,
synta_certificate::Pbes2ParamsBuilder::new(),
);
guard.inner = old.encryption_scheme(alg_id_der);
}
slf
}
fn encryption_scheme_from_oid<'py>(
slf: Bound<'py, Self>,
enc_oid: Vec<u32>,
iv: &[u8],
) -> Bound<'py, Self> {
{
let mut guard = slf.borrow_mut();
let old = std::mem::replace(
&mut guard.inner,
synta_certificate::Pbes2ParamsBuilder::new(),
);
guard.inner = old.encryption_scheme_from_oid(&enc_oid, iv);
}
slf
}
fn build<'py>(&mut self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
if self.built {
return Err(pyo3::exceptions::PyValueError::new_err(
"build() has already been called; create a new builder",
));
}
self.built = true;
let inner = std::mem::replace(
&mut self.inner,
synta_certificate::Pbes2ParamsBuilder::new(),
);
let der = inner
.build()
.map_err(pyo3::exceptions::PyValueError::new_err)?;
Ok(PyBytes::new(py, &der))
}
fn __repr__(&self) -> String {
"Pbes2ParamsBuilder()".to_string()
}
}
pub(super) fn register_pkcs5_submodule(parent: &Bound<'_, PyModule>) -> PyResult<()> {
let py = parent.py();
let m = pyo3::types::PyModule::new(py, "pkcs5")?;
m.add_class::<PyPbkdf2ParamsBuilder>()?;
m.add_class::<PyPbes2ParamsBuilder>()?;
m.add(
"ID_PBKDF2",
super::oid_const(py, synta_certificate::pkcs5_types::ID_PBKDF2),
)?;
m.add(
"ID_PBES2",
super::oid_const(py, synta_certificate::pkcs5_types::ID_PBES2),
)?;
m.add(
"ID_HMAC_WITH_SHA1",
super::oid_const(py, synta_certificate::pkcs5_types::ID_HMAC_WITH_SHA1_P5),
)?;
m.add(
"ID_HMAC_WITH_SHA224",
super::oid_const(py, synta_certificate::pkcs5_types::ID_HMAC_WITH_SHA224_P5),
)?;
m.add(
"ID_HMAC_WITH_SHA256",
super::oid_const(py, synta_certificate::pkcs5_types::ID_HMAC_WITH_SHA256_P5),
)?;
m.add(
"ID_HMAC_WITH_SHA384",
super::oid_const(py, synta_certificate::pkcs5_types::ID_HMAC_WITH_SHA384_P5),
)?;
m.add(
"ID_HMAC_WITH_SHA512",
super::oid_const(py, synta_certificate::pkcs5_types::ID_HMAC_WITH_SHA512_P5),
)?;
m.add(
"AES128_CBC_PAD",
super::oid_const(py, synta_certificate::pkcs5_types::AES128_CBC_PAD),
)?;
m.add(
"AES192_CBC_PAD",
super::oid_const(py, synta_certificate::pkcs5_types::AES192_CBC_PAD),
)?;
m.add(
"AES256_CBC_PAD",
super::oid_const(py, synta_certificate::pkcs5_types::AES256_CBC_PAD),
)?;
crate::install_submodule(
parent,
&m,
"synta.pkcs5",
Some(concat!(
"synta.pkcs5 — RFC 8018 PKCS #5 v2.1 parameter builders.\n\n",
"Provides Pbkdf2ParamsBuilder and Pbes2ParamsBuilder for constructing\n",
"DER-encoded PBKDF2 and PBES2 parameter structures, along with OID\n",
"constants for key derivation and encryption scheme algorithms.",
)),
)
}