Skip to content

Commit

Permalink
rust: add PyCryptoOps (#9606)
Browse files Browse the repository at this point in the history
* rust: add PyCryptoOps

Reimplements `verify_directly_issued_by` in terms of `PyCryptoOps`,
for free coverage.

Signed-off-by: William Woodruff <[email protected]>

* rust: is_signed_by -> verify_signed_by

Signed-off-by: William Woodruff <[email protected]>

---------

Signed-off-by: William Woodruff <[email protected]>
  • Loading branch information
woodruffw authored Sep 14, 2023
1 parent 3e411cf commit 324eb6f
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pyo3 = { version = "0.19", features = ["abi3-py37"] }
asn1 = { version = "0.15.5", default-features = false }
cryptography-cffi = { path = "cryptography-cffi" }
cryptography-x509 = { path = "cryptography-x509" }
cryptography-x509-validation = { path = "cryptography-x509-validation" }
cryptography-openssl = { path = "cryptography-openssl" }
pem = { version = "3", default-features = false }
openssl = "0.10.57"
Expand Down
2 changes: 1 addition & 1 deletion src/rust/cryptography-x509-validation/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ pub trait CryptoOps {

/// Verifies the signature on `Certificate` using the given
/// `Key`.
fn is_signed_by(&self, cert: &Certificate<'_>, key: Self::Key) -> Result<(), Self::Err>;
fn verify_signed_by(&self, cert: &Certificate<'_>, key: Self::Key) -> Result<(), Self::Err>;
}
14 changes: 6 additions & 8 deletions src/rust/src/x509/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::asn1::{
};
use crate::backend::hashes;
use crate::error::{CryptographyError, CryptographyResult};
use crate::x509::verify::PyCryptoOps;
use crate::x509::{extensions, sct, sign};
use crate::{exceptions, types, x509};
use cryptography_x509::certificate::Certificate as RawCertificate;
Expand All @@ -20,6 +21,7 @@ use cryptography_x509::extensions::{
};
use cryptography_x509::extensions::{Extension, SubjectAlternativeName};
use cryptography_x509::{common, oid};
use cryptography_x509_validation::ops::CryptoOps;
use pyo3::{IntoPy, ToPyObject};
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
Expand Down Expand Up @@ -267,7 +269,6 @@ impl Certificate {

fn verify_directly_issued_by(
&self,
py: pyo3::Python<'_>,
issuer: pyo3::PyRef<'_, Certificate>,
) -> CryptographyResult<()> {
if self.raw.borrow_dependent().tbs_cert.signature_alg
Expand All @@ -286,13 +287,10 @@ impl Certificate {
),
));
};
sign::verify_signature_with_signature_algorithm(
py,
issuer.public_key(py)?,
&self.raw.borrow_dependent().signature_alg,
self.raw.borrow_dependent().signature.as_bytes(),
&asn1::write_single(&self.raw.borrow_dependent().tbs_cert)?,
)

let ops = PyCryptoOps {};
let issuer_key = ops.public_key(issuer.raw.borrow_dependent())?;
ops.verify_signed_by(self.raw.borrow_dependent(), issuer_key)
}
}

Expand Down
41 changes: 40 additions & 1 deletion src/rust/src/x509/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,46 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use crate::x509::certificate::Certificate as PyCertificate;
use cryptography_x509::certificate::Certificate;
use cryptography_x509_validation::ops::CryptoOps;

use crate::x509::sign;
use crate::{
error::{CryptographyError, CryptographyResult},
types,
x509::certificate::Certificate as PyCertificate,
};

pub(crate) struct PyCryptoOps {}

impl CryptoOps for PyCryptoOps {
type Key = pyo3::Py<pyo3::PyAny>;
type Err = CryptographyError;

fn public_key(&self, cert: &Certificate<'_>) -> Result<Self::Key, Self::Err> {
pyo3::Python::with_gil(|py| -> Result<Self::Key, Self::Err> {
// This makes an unnecessary copy. It'd be nice to get rid of it.
let spki_der = pyo3::types::PyBytes::new(py, &asn1::write_single(&cert.tbs_cert.spki)?);

Ok(types::LOAD_DER_PUBLIC_KEY
.get(py)?
.call1((spki_der,))?
.into())
})
}

fn verify_signed_by(&self, cert: &Certificate<'_>, key: Self::Key) -> Result<(), Self::Err> {
pyo3::Python::with_gil(|py| -> CryptographyResult<()> {
sign::verify_signature_with_signature_algorithm(
py,
key.as_ref(py),
&cert.signature_alg,
cert.signature.as_bytes(),
&asn1::write_single(&cert.tbs_cert)?,
)
})
}
}

#[pyo3::pyclass(
frozen,
Expand Down

0 comments on commit 324eb6f

Please sign in to comment.