Use pyo3's facilities for exceptions (#8785)

This commit is contained in:
Alex Gaynor 2023-04-22 13:32:59 -06:00 committed by GitHub
parent 8d616959f9
commit 2ca57be0c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 105 additions and 106 deletions

View file

@ -6,25 +6,12 @@ from __future__ import annotations
import typing
from cryptography import utils
from cryptography.hazmat.bindings._rust import exceptions as rust_exceptions
if typing.TYPE_CHECKING:
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
class _Reasons(utils.Enum):
BACKEND_MISSING_INTERFACE = 0
UNSUPPORTED_HASH = 1
UNSUPPORTED_CIPHER = 2
UNSUPPORTED_PADDING = 3
UNSUPPORTED_MGF = 4
UNSUPPORTED_PUBLIC_KEY_ALGORITHM = 5
UNSUPPORTED_ELLIPTIC_CURVE = 6
UNSUPPORTED_SERIALIZATION = 7
UNSUPPORTED_X509 = 8
UNSUPPORTED_EXCHANGE_ALGORITHM = 9
UNSUPPORTED_DIFFIE_HELLMAN = 10
UNSUPPORTED_MAC = 11
_Reasons = rust_exceptions._Reasons
class UnsupportedAlgorithm(Exception):

View file

@ -0,0 +1,17 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
class _Reasons:
BACKEND_MISSING_INTERFACE: _Reasons
UNSUPPORTED_HASH: _Reasons
UNSUPPORTED_CIPHER: _Reasons
UNSUPPORTED_PADDING: _Reasons
UNSUPPORTED_MGF: _Reasons
UNSUPPORTED_PUBLIC_KEY_ALGORITHM: _Reasons
UNSUPPORTED_ELLIPTIC_CURVE: _Reasons
UNSUPPORTED_SERIALIZATION: _Reasons
UNSUPPORTED_X509: _Reasons
UNSUPPORTED_EXCHANGE_ALGORITHM: _Reasons
UNSUPPORTED_DIFFIE_HELLMAN: _Reasons
UNSUPPORTED_MAC: _Reasons

View file

@ -4,6 +4,7 @@
use crate::buf::CffiBuf;
use crate::error::{CryptographyError, CryptographyResult};
use crate::exceptions;
use std::borrow::Cow;
#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust.openssl.hashes")]
@ -71,21 +72,12 @@ pub(crate) fn message_digest_from_algorithm(
match openssl::hash::MessageDigest::from_name(&openssl_name) {
Some(md) => Ok(md),
None => {
let exceptions_module = py.import(pyo3::intern!(py, "cryptography.exceptions"))?;
let reason = exceptions_module
.getattr(pyo3::intern!(py, "_Reasons"))?
.getattr(pyo3::intern!(py, "UNSUPPORTED_HASH"))?;
Err(CryptographyError::from(pyo3::PyErr::from_value(
exceptions_module.call_method1(
pyo3::intern!(py, "UnsupportedAlgorithm"),
(
format!("{} is not a supported hash on this backend", name),
reason,
),
)?,
)))
}
None => Err(CryptographyError::from(
exceptions::UnsupportedAlgorithm::new_err((
format!("{} is not a supported hash on this backend", name),
exceptions::Reasons::UNSUPPORTED_HASH,
)),
)),
}
}

View file

@ -0,0 +1,33 @@
// This file is dual licensed under the terms of the Apache License, Version
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.
#[pyo3::prelude::pyclass(
module = "cryptography.hazmat.bindings._rust.exceptions",
name = "_Reasons"
)]
#[allow(non_camel_case_types)]
pub(crate) enum Reasons {
BACKEND_MISSING_INTERFACE,
UNSUPPORTED_HASH,
UNSUPPORTED_CIPHER,
UNSUPPORTED_PADDING,
UNSUPPORTED_MGF,
UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
UNSUPPORTED_ELLIPTIC_CURVE,
UNSUPPORTED_SERIALIZATION,
UNSUPPORTED_X509,
UNSUPPORTED_EXCHANGE_ALGORITHM,
UNSUPPORTED_DIFFIE_HELLMAN,
UNSUPPORTED_MAC,
}
pyo3::import_exception!(cryptography.exceptions, UnsupportedAlgorithm);
pub(crate) fn create_submodule(py: pyo3::Python<'_>) -> pyo3::PyResult<&pyo3::prelude::PyModule> {
let submod = pyo3::prelude::PyModule::new(py, "exceptions")?;
submod.add_class::<Reasons>()?;
Ok(submod)
}

View file

@ -13,6 +13,7 @@ mod asn1;
mod backend;
mod buf;
mod error;
mod exceptions;
pub(crate) mod oid;
mod pkcs7;
mod pool;
@ -156,6 +157,7 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()>
m.add_submodule(asn1::create_submodule(py)?)?;
m.add_submodule(pkcs7::create_submodule(py)?)?;
m.add_submodule(exceptions::create_submodule(py)?)?;
let x509_mod = pyo3::prelude::PyModule::new(py, "x509")?;
crate::x509::certificate::add_to_module(x509_mod)?;

View file

@ -6,8 +6,8 @@ use crate::asn1::{
big_byte_slice_to_py_int, encode_der_data, oid_to_py_oid, py_uint_to_big_endian_bytes,
};
use crate::error::{CryptographyError, CryptographyResult};
use crate::x509;
use crate::x509::{extensions, sct, sign};
use crate::{exceptions, x509};
use cryptography_x509::common::Asn1ReadableOrWritable;
use cryptography_x509::extensions::{
AuthorityKeyIdentifier, BasicConstraints, DisplayText, DistributionPoint,
@ -244,16 +244,12 @@ impl Certificate {
let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?);
match hash_alg {
Ok(data) => Ok(data),
Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_value(
py.import(pyo3::intern!(py, "cryptography.exceptions"))?
.call_method1(
"UnsupportedAlgorithm",
(format!(
"Signature algorithm OID: {} not recognized",
self.raw.borrow_value().signature_alg.oid
),),
)?,
))),
Err(_) => Err(CryptographyError::from(
exceptions::UnsupportedAlgorithm::new_err(format!(
"Signature algorithm OID: {} not recognized",
self.raw.borrow_value().signature_alg.oid
)),
)),
}
}

View file

@ -6,8 +6,8 @@ use crate::asn1::{
big_byte_slice_to_py_int, encode_der_data, oid_to_py_oid, py_uint_to_big_endian_bytes,
};
use crate::error::{CryptographyError, CryptographyResult};
use crate::x509;
use crate::x509::{certificate, extensions, sign};
use crate::{exceptions, x509};
use cryptography_x509::{common, crl, name, oid};
use pyo3::{IntoPy, ToPyObject};
use std::sync::Arc;
@ -201,19 +201,15 @@ impl CertificateRevocationList {
) -> pyo3::PyResult<&'p pyo3::PyAny> {
let oid = self.signature_algorithm_oid(py)?;
let oid_module = py.import(pyo3::intern!(py, "cryptography.hazmat._oid"))?;
let exceptions_module = py.import(pyo3::intern!(py, "cryptography.exceptions"))?;
match oid_module
.getattr(pyo3::intern!(py, "_SIG_OIDS_TO_HASH"))?
.get_item(oid)
{
Ok(v) => Ok(v),
Err(_) => Err(pyo3::PyErr::from_value(exceptions_module.call_method1(
"UnsupportedAlgorithm",
(format!(
"Signature algorithm OID:{} not recognized",
self.owned.borrow_value().signature_algorithm.oid
),),
)?)),
Err(_) => Err(exceptions::UnsupportedAlgorithm::new_err(format!(
"Signature algorithm OID: {} not recognized",
self.owned.borrow_value().signature_algorithm.oid
))),
}
}

View file

@ -4,8 +4,8 @@
use crate::asn1::{encode_der_data, oid_to_py_oid, py_oid_to_oid};
use crate::error::{CryptographyError, CryptographyResult};
use crate::x509;
use crate::x509::{certificate, sign};
use crate::{exceptions, x509};
use asn1::SimpleAsn1Readable;
use cryptography_x509::csr::{check_attribute_length, Attribute, CertificationRequestInfo, Csr};
use cryptography_x509::{common, oid};
@ -102,16 +102,12 @@ impl CertificateSigningRequest {
let hash_alg = sig_oids_to_hash.get_item(self.signature_algorithm_oid(py)?);
match hash_alg {
Ok(data) => Ok(data),
Err(_) => Err(CryptographyError::from(pyo3::PyErr::from_value(
py.import(pyo3::intern!(py, "cryptography.exceptions"))?
.call_method1(
"UnsupportedAlgorithm",
(format!(
"Signature algorithm OID: {} not recognized",
self.raw.borrow_value().signature_alg.oid
),),
)?,
))),
Err(_) => Err(CryptographyError::from(
exceptions::UnsupportedAlgorithm::new_err(format!(
"Signature algorithm OID: {} not recognized",
self.raw.borrow_value().signature_alg.oid
)),
)),
}
}

View file

@ -4,8 +4,8 @@
use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid, py_uint_to_big_endian_bytes};
use crate::error::{CryptographyError, CryptographyResult};
use crate::x509;
use crate::x509::{extensions, ocsp};
use crate::{exceptions, x509};
use cryptography_x509::{common, ocsp_req, oid};
use pyo3::IntoPy;
@ -88,17 +88,12 @@ impl OCSPRequest {
let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?;
match ocsp::OIDS_TO_HASH.get(&cert_id.hash_algorithm.oid) {
Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?),
None => {
let exceptions = py.import(pyo3::intern!(py, "cryptography.exceptions"))?;
Err(CryptographyError::from(pyo3::PyErr::from_value(
exceptions
.getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))?
.call1((format!(
"Signature algorithm OID: {} not recognized",
cert_id.hash_algorithm.oid
),))?,
)))
}
None => Err(CryptographyError::from(
exceptions::UnsupportedAlgorithm::new_err(format!(
"Signature algorithm OID: {} not recognized",
cert_id.hash_algorithm.oid
)),
)),
}
}

View file

@ -4,8 +4,8 @@
use crate::asn1::{big_byte_slice_to_py_int, oid_to_py_oid};
use crate::error::{CryptographyError, CryptographyResult};
use crate::x509;
use crate::x509::{certificate, crl, extensions, ocsp, py_to_datetime, sct};
use crate::{exceptions, x509};
use cryptography_x509::ocsp_resp::SingleResponse;
use cryptography_x509::{common, ocsp_resp, oid};
use pyo3::IntoPy;
@ -187,10 +187,9 @@ impl OCSPResponse {
"Signature algorithm OID: {} not recognized",
self.requires_successful_response()?.signature_algorithm.oid
);
Err(CryptographyError::from(pyo3::PyErr::from_value(
py.import(pyo3::intern!(py, "cryptography.exceptions"))?
.call_method1(pyo3::intern!(py, "UnsupportedAlgorithm"), (exc_messsage,))?,
)))
Err(CryptographyError::from(
exceptions::UnsupportedAlgorithm::new_err(exc_messsage),
))
}
}
}
@ -480,17 +479,12 @@ fn singleresp_py_hash_algorithm<'p>(
let hashes = py.import(pyo3::intern!(py, "cryptography.hazmat.primitives.hashes"))?;
match ocsp::OIDS_TO_HASH.get(&resp.cert_id.hash_algorithm.oid) {
Some(alg_name) => Ok(hashes.getattr(*alg_name)?.call0()?),
None => {
let exceptions = py.import(pyo3::intern!(py, "cryptography.exceptions"))?;
Err(CryptographyError::from(pyo3::PyErr::from_value(
exceptions
.getattr(pyo3::intern!(py, "UnsupportedAlgorithm"))?
.call1((format!(
"Signature algorithm OID: {} not recognized",
resp.cert_id.hash_algorithm.oid
),))?,
)))
}
None => Err(CryptographyError::from(
exceptions::UnsupportedAlgorithm::new_err(format!(
"Signature algorithm OID: {} not recognized",
resp.cert_id.hash_algorithm.oid
)),
)),
}
}

View file

@ -3,6 +3,7 @@
// for complete details.
use crate::error::{CryptographyError, CryptographyResult};
use crate::exceptions;
use cryptography_x509::{common, oid};
use once_cell::sync::Lazy;
@ -120,16 +121,10 @@ fn identify_hash_type(
"sha3-256" => Ok(HashType::Sha3_256),
"sha3-384" => Ok(HashType::Sha3_384),
"sha3-512" => Ok(HashType::Sha3_512),
name => Err(pyo3::PyErr::from_value(
py.import(pyo3::intern!(py, "cryptography.exceptions"))?
.call_method1(
"UnsupportedAlgorithm",
(format!(
"Hash algorithm {:?} not supported for signatures",
name
),),
)?,
)),
name => Err(exceptions::UnsupportedAlgorithm::new_err(format!(
"Hash algorithm {:?} not supported for signatures",
name
))),
}
}
@ -239,12 +234,8 @@ pub(crate) fn compute_signature_algorithm<'p>(
(
KeyType::Dsa,
HashType::Sha3_224 | HashType::Sha3_256 | HashType::Sha3_384 | HashType::Sha3_512,
) => Err(pyo3::PyErr::from_value(
py.import(pyo3::intern!(py, "cryptography.exceptions"))?
.call_method1(
"UnsupportedAlgorithm",
("SHA3 hashes are not supported with DSA keys",),
)?,
) => Err(exceptions::UnsupportedAlgorithm::new_err(
"SHA3 hashes are not supported with DSA keys",
)),
(_, HashType::None) => Err(pyo3::exceptions::PyTypeError::new_err(
"Algorithm must be a registered hash algorithm, not None.",

View file

@ -33,7 +33,7 @@ def raises_unsupported_algorithm(reason):
with pytest.raises(UnsupportedAlgorithm) as exc_info:
yield exc_info
assert exc_info.value._reason is reason
assert exc_info.value._reason == reason
T = typing.TypeVar("T")