Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert more sign functions to new pyo3 APIs #10734

Merged
merged 1 commit into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions src/rust/src/pkcs7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use openssl::pkcs7::Pkcs7;
use pyo3::prelude::{PyAnyMethods, PyListMethods, PyModuleMethods};
#[cfg(not(CRYPTOGRAPHY_IS_BORINGSSL))]
use pyo3::IntoPy;
use pyo3::PyNativeType;

use crate::asn1::encode_der_data;
use crate::buf::CffiBuf;
Expand Down Expand Up @@ -140,9 +141,9 @@ fn sign_and_serialize<'p>(
None,
x509::sign::sign_data(
py,
py_private_key,
py_hash_alg,
rsa_padding,
py_private_key.as_borrowed().to_owned(),
py_hash_alg.as_borrowed().to_owned(),
rsa_padding.as_borrowed().to_owned(),
&data_with_header,
)?,
)
Expand Down Expand Up @@ -189,7 +190,13 @@ fn sign_and_serialize<'p>(
Some(common::Asn1ReadableOrWritable::new_write(
asn1::SetOfWriter::new(authenticated_attrs),
)),
x509::sign::sign_data(py, py_private_key, py_hash_alg, rsa_padding, &signed_data)?,
x509::sign::sign_data(
py,
py_private_key.as_borrowed().to_owned(),
py_hash_alg.as_borrowed().to_owned(),
rsa_padding.as_borrowed().to_owned(),
&signed_data,
)?,
)
};

Expand Down Expand Up @@ -279,7 +286,7 @@ fn compute_pkcs7_signature_algorithm<'p>(
hash_algorithm: &'p pyo3::PyAny,
rsa_padding: &'p pyo3::PyAny,
) -> pyo3::PyResult<common::AlgorithmIdentifier<'static>> {
let key_type = x509::sign::identify_key_type(py, private_key)?;
let key_type = x509::sign::identify_key_type(py, private_key.as_borrowed().to_owned())?;
let has_pss_padding = rsa_padding.is_instance(types::PSS.get(py)?)?;
// For RSA signatures (with no PSS padding), the OID is always the same no matter the
// digest algorithm. See RFC 3370 (section 3.2).
Expand All @@ -289,7 +296,12 @@ fn compute_pkcs7_signature_algorithm<'p>(
params: common::AlgorithmParameters::Rsa(Some(())),
})
} else {
x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm, rsa_padding)
x509::sign::compute_signature_algorithm(
py,
private_key.as_borrowed().to_owned(),
hash_algorithm.as_borrowed().to_owned(),
rsa_padding.as_borrowed().to_owned(),
)
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/rust/src/x509/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,9 +924,9 @@ fn create_x509_certificate(
) -> CryptographyResult<Certificate> {
let sigalg = x509::sign::compute_signature_algorithm(
py,
private_key.clone().into_gil_ref(),
hash_algorithm.clone().into_gil_ref(),
rsa_padding.clone().into_gil_ref(),
private_key.clone(),
hash_algorithm.clone(),
rsa_padding.clone(),
)?;

let der = types::ENCODING_DER.get(py)?;
Expand Down Expand Up @@ -974,9 +974,9 @@ fn create_x509_certificate(
let tbs_bytes = asn1::write_single(&tbs_cert)?;
let signature = x509::sign::sign_data(
py,
private_key.clone().into_gil_ref(),
hash_algorithm.clone().into_gil_ref(),
rsa_padding.clone().into_gil_ref(),
private_key.clone(),
hash_algorithm.clone(),
rsa_padding.clone(),
&tbs_bytes,
)?;
let data = asn1::write_single(&cryptography_x509::certificate::Certificate {
Expand Down
21 changes: 15 additions & 6 deletions src/rust/src/x509/crl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,11 +433,11 @@ impl CertificateRevocationList {

// Error on invalid public key -- below we treat any error as just
// being an invalid signature.
sign::identify_public_key_type(py, public_key.clone().into_gil_ref())?;
sign::identify_public_key_type(py, public_key.clone())?;

Ok(sign::verify_signature_with_signature_algorithm(
py,
public_key.into_gil_ref(),
public_key,
&slf.owned.borrow_dependent().signature_algorithm,
slf.owned.borrow_dependent().signature_value.as_bytes(),
&asn1::write_single(&slf.owned.borrow_dependent().tbs_cert_list)?,
Expand Down Expand Up @@ -646,8 +646,12 @@ fn create_x509_crl(
hash_algorithm: &pyo3::PyAny,
rsa_padding: &pyo3::PyAny,
) -> CryptographyResult<CertificateRevocationList> {
let sigalg =
x509::sign::compute_signature_algorithm(py, private_key, hash_algorithm, rsa_padding)?;
let sigalg = x509::sign::compute_signature_algorithm(
py,
private_key.as_borrowed().to_owned(),
hash_algorithm.as_borrowed().to_owned(),
rsa_padding.as_borrowed().to_owned(),
)?;
let mut revoked_certs = vec![];
for py_revoked_cert in builder
.getattr(pyo3::intern!(py, "_revoked_certificates"))?
Expand Down Expand Up @@ -701,8 +705,13 @@ fn create_x509_crl(
};

let tbs_bytes = asn1::write_single(&tbs_cert_list)?;
let signature =
x509::sign::sign_data(py, private_key, hash_algorithm, rsa_padding, &tbs_bytes)?;
let signature = x509::sign::sign_data(
py,
private_key.as_borrowed().to_owned(),
hash_algorithm.as_borrowed().to_owned(),
rsa_padding.as_borrowed().to_owned(),
&tbs_bytes,
)?;
let data = asn1::write_single(&crl::CertificateRevocationList {
tbs_cert_list,
signature_algorithm: sigalg,
Expand Down
14 changes: 7 additions & 7 deletions src/rust/src/x509/csr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ impl CertificateSigningRequest {
let public_key = slf.public_key(py)?;
Ok(sign::verify_signature_with_signature_algorithm(
py,
public_key.bind(py).clone().into_gil_ref(),
public_key.bind(py).clone(),
&slf.raw.borrow_dependent().signature_alg,
slf.raw.borrow_dependent().signature.as_bytes(),
&asn1::write_single(&slf.raw.borrow_dependent().csr_info)?,
Expand Down Expand Up @@ -301,9 +301,9 @@ fn create_x509_csr(
) -> CryptographyResult<CertificateSigningRequest> {
let sigalg = x509::sign::compute_signature_algorithm(
py,
private_key.clone().into_gil_ref(),
hash_algorithm.clone().into_gil_ref(),
rsa_padding.clone().into_gil_ref(),
private_key.clone(),
hash_algorithm.clone(),
rsa_padding.clone(),
)?;

let der = types::ENCODING_DER.get(py)?;
Expand Down Expand Up @@ -368,9 +368,9 @@ fn create_x509_csr(
let tbs_bytes = asn1::write_single(&csr_info)?;
let signature = x509::sign::sign_data(
py,
private_key.clone().into_gil_ref(),
hash_algorithm.clone().into_gil_ref(),
rsa_padding.clone().into_gil_ref(),
private_key.clone(),
hash_algorithm.clone(),
rsa_padding.clone(),
&tbs_bytes,
)?;
let data = asn1::write_single(&Csr {
Expand Down
12 changes: 6 additions & 6 deletions src/rust/src/x509/ocsp_resp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,16 +704,16 @@ fn create_ocsp_response(

let sigalg = x509::sign::compute_signature_algorithm(
py,
private_key,
hash_algorithm,
py.None().into_ref(py),
private_key.as_borrowed().to_owned(),
hash_algorithm.as_borrowed().to_owned(),
py.None().into_bound(py),
)?;
let tbs_bytes = asn1::write_single(&tbs_response_data)?;
let signature = x509::sign::sign_data(
py,
private_key,
hash_algorithm,
py.None().into_ref(py),
private_key.as_borrowed().to_owned(),
hash_algorithm.as_borrowed().to_owned(),
py.None().into_bound(py),
&tbs_bytes,
)?;

Expand Down
73 changes: 37 additions & 36 deletions src/rust/src/x509/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,17 @@ enum HashType {

pub(crate) fn identify_key_type(
py: pyo3::Python<'_>,
private_key: &pyo3::PyAny,
private_key: pyo3::Bound<'_, pyo3::PyAny>,
) -> pyo3::PyResult<KeyType> {
if private_key.is_instance(types::RSA_PRIVATE_KEY.get(py)?)? {
if private_key.is_instance(&types::RSA_PRIVATE_KEY.get_bound(py)?)? {
Ok(KeyType::Rsa)
} else if private_key.is_instance(types::DSA_PRIVATE_KEY.get(py)?)? {
} else if private_key.is_instance(&types::DSA_PRIVATE_KEY.get_bound(py)?)? {
Ok(KeyType::Dsa)
} else if private_key.is_instance(types::ELLIPTIC_CURVE_PRIVATE_KEY.get(py)?)? {
} else if private_key.is_instance(&types::ELLIPTIC_CURVE_PRIVATE_KEY.get_bound(py)?)? {
Ok(KeyType::Ec)
} else if private_key.is_instance(types::ED25519_PRIVATE_KEY.get(py)?)? {
} else if private_key.is_instance(&types::ED25519_PRIVATE_KEY.get_bound(py)?)? {
Ok(KeyType::Ed25519)
} else if private_key.is_instance(types::ED448_PRIVATE_KEY.get(py)?)? {
} else if private_key.is_instance(&types::ED448_PRIVATE_KEY.get_bound(py)?)? {
Ok(KeyType::Ed448)
} else {
Err(pyo3::exceptions::PyTypeError::new_err(
Expand All @@ -73,13 +73,13 @@ pub(crate) fn identify_key_type(

fn identify_hash_type(
py: pyo3::Python<'_>,
hash_algorithm: &pyo3::PyAny,
hash_algorithm: pyo3::Bound<'_, pyo3::PyAny>,
) -> pyo3::PyResult<HashType> {
if hash_algorithm.is_none() {
return Ok(HashType::None);
}

if !hash_algorithm.is_instance(types::HASH_ALGORITHM.get(py)?)? {
if !hash_algorithm.is_instance(&types::HASH_ALGORITHM.get_bound(py)?)? {
return Err(pyo3::exceptions::PyTypeError::new_err(
"Algorithm must be a registered hash algorithm.",
));
Expand All @@ -105,17 +105,17 @@ fn identify_hash_type(

fn compute_pss_salt_length<'p>(
py: pyo3::Python<'p>,
private_key: &'p pyo3::PyAny,
hash_algorithm: &'p pyo3::PyAny,
rsa_padding: &'p pyo3::PyAny,
private_key: pyo3::Bound<'p, pyo3::PyAny>,
hash_algorithm: pyo3::Bound<'p, pyo3::PyAny>,
rsa_padding: pyo3::Bound<'p, pyo3::PyAny>,
) -> pyo3::PyResult<u16> {
let py_saltlen = rsa_padding.getattr(pyo3::intern!(py, "_salt_length"))?;
if py_saltlen.is_instance(types::PADDING_MAX_LENGTH.get(py)?)? {
if py_saltlen.is_instance(&types::PADDING_MAX_LENGTH.get_bound(py)?)? {
types::CALCULATE_MAX_PSS_SALT_LENGTH
.get(py)?
.get_bound(py)?
.call1((private_key, hash_algorithm))?
.extract::<u16>()
} else if py_saltlen.is_instance(types::PADDING_DIGEST_LENGTH.get(py)?)? {
} else if py_saltlen.is_instance(&types::PADDING_DIGEST_LENGTH.get_bound(py)?)? {
hash_algorithm
.getattr(pyo3::intern!(py, "digest_size"))?
.extract::<u16>()
Expand All @@ -130,26 +130,27 @@ fn compute_pss_salt_length<'p>(

pub(crate) fn compute_signature_algorithm<'p>(
py: pyo3::Python<'p>,
private_key: &'p pyo3::PyAny,
hash_algorithm: &'p pyo3::PyAny,
rsa_padding: &'p pyo3::PyAny,
private_key: pyo3::Bound<'p, pyo3::PyAny>,
hash_algorithm: pyo3::Bound<'p, pyo3::PyAny>,
rsa_padding: pyo3::Bound<'p, pyo3::PyAny>,
) -> pyo3::PyResult<common::AlgorithmIdentifier<'static>> {
let key_type = identify_key_type(py, private_key)?;
let hash_type = identify_hash_type(py, hash_algorithm)?;
let key_type = identify_key_type(py, private_key.clone())?;
let hash_type = identify_hash_type(py, hash_algorithm.clone())?;

// If this is RSA-PSS we need to compute the signature algorithm from the
// parameters provided in rsa_padding.
if rsa_padding.is_instance(types::PSS.get(py)?)? {
if rsa_padding.is_instance(&types::PSS.get_bound(py)?)? {
let hash_alg_params = identify_alg_params_for_hash_type(hash_type)?;
let hash_algorithm_id = common::AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: hash_alg_params,
};
let salt_length = compute_pss_salt_length(py, private_key, hash_algorithm, rsa_padding)?;
let salt_length =
compute_pss_salt_length(py, private_key, hash_algorithm, rsa_padding.clone())?;
let py_mgf_alg = rsa_padding
.getattr(pyo3::intern!(py, "_mgf"))?
.getattr(pyo3::intern!(py, "_algorithm"))?;
let mgf_hash_type = identify_hash_type(py, py_mgf_alg)?;
let mgf_hash_type = identify_hash_type(py, py_mgf_alg.as_borrowed().to_owned())?;
let mgf_alg = common::AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: identify_alg_params_for_hash_type(mgf_hash_type)?,
Expand Down Expand Up @@ -281,25 +282,25 @@ pub(crate) fn compute_signature_algorithm<'p>(

pub(crate) fn sign_data<'p>(
py: pyo3::Python<'p>,
private_key: &'p pyo3::PyAny,
hash_algorithm: &'p pyo3::PyAny,
rsa_padding: &'p pyo3::PyAny,
private_key: pyo3::Bound<'p, pyo3::PyAny>,
hash_algorithm: pyo3::Bound<'p, pyo3::PyAny>,
rsa_padding: pyo3::Bound<'p, pyo3::PyAny>,
data: &[u8],
) -> pyo3::PyResult<&'p [u8]> {
let key_type = identify_key_type(py, private_key)?;
let key_type = identify_key_type(py, private_key.clone())?;

let signature = match key_type {
KeyType::Ed25519 | KeyType::Ed448 => {
private_key.call_method1(pyo3::intern!(py, "sign"), (data,))?
}
KeyType::Ec => {
let ecdsa = types::ECDSA.get(py)?.call1((hash_algorithm,))?;
let ecdsa = types::ECDSA.get_bound(py)?.call1((hash_algorithm,))?;
private_key.call_method1(pyo3::intern!(py, "sign"), (data, ecdsa))?
}
KeyType::Rsa => {
let mut padding = rsa_padding;
if padding.is_none() {
padding = types::PKCS1V15.get(py)?.call0()?;
padding = types::PKCS1V15.get_bound(py)?.call0()?;
}
private_key.call_method1(pyo3::intern!(py, "sign"), (data, padding, hash_algorithm))?
}
Expand All @@ -312,12 +313,12 @@ pub(crate) fn sign_data<'p>(

pub(crate) fn verify_signature_with_signature_algorithm<'p>(
py: pyo3::Python<'p>,
issuer_public_key: &'p pyo3::PyAny,
issuer_public_key: pyo3::Bound<'p, pyo3::PyAny>,
signature_algorithm: &common::AlgorithmIdentifier<'_>,
signature: &[u8],
data: &[u8],
) -> CryptographyResult<()> {
let key_type = identify_public_key_type(py, issuer_public_key)?;
let key_type = identify_public_key_type(py, issuer_public_key.clone())?;
let sig_key_type = identify_key_type_for_algorithm_params(&signature_algorithm.params)?;
if key_type != sig_key_type {
return Err(CryptographyError::from(
Expand Down Expand Up @@ -356,17 +357,17 @@ pub(crate) fn verify_signature_with_signature_algorithm<'p>(

pub(crate) fn identify_public_key_type(
py: pyo3::Python<'_>,
public_key: &pyo3::PyAny,
public_key: pyo3::Bound<'_, pyo3::PyAny>,
) -> pyo3::PyResult<KeyType> {
if public_key.is_instance(types::RSA_PUBLIC_KEY.get(py)?)? {
if public_key.is_instance(&types::RSA_PUBLIC_KEY.get_bound(py)?)? {
Ok(KeyType::Rsa)
} else if public_key.is_instance(types::DSA_PUBLIC_KEY.get(py)?)? {
} else if public_key.is_instance(&types::DSA_PUBLIC_KEY.get_bound(py)?)? {
Ok(KeyType::Dsa)
} else if public_key.is_instance(types::ELLIPTIC_CURVE_PUBLIC_KEY.get(py)?)? {
} else if public_key.is_instance(&types::ELLIPTIC_CURVE_PUBLIC_KEY.get_bound(py)?)? {
Ok(KeyType::Ec)
} else if public_key.is_instance(types::ED25519_PUBLIC_KEY.get(py)?)? {
} else if public_key.is_instance(&types::ED25519_PUBLIC_KEY.get_bound(py)?)? {
Ok(KeyType::Ed25519)
} else if public_key.is_instance(types::ED448_PUBLIC_KEY.get(py)?)? {
} else if public_key.is_instance(&types::ED448_PUBLIC_KEY.get_bound(py)?)? {
Ok(KeyType::Ed448)
} else {
Err(pyo3::exceptions::PyTypeError::new_err(
Expand Down
2 changes: 1 addition & 1 deletion src/rust/src/x509/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl CryptoOps for PyCryptoOps {
pyo3::Python::with_gil(|py| -> CryptographyResult<()> {
sign::verify_signature_with_signature_algorithm(
py,
key.as_ref(py),
key.bind(py).clone(),
&cert.signature_alg,
cert.signature.as_bytes(),
&asn1::write_single(&cert.tbs_cert)?,
Expand Down