summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2021-11-13 16:42:10 -0500
committerGitHub <noreply@github.com>2021-11-14 05:42:10 +0800
commit4da2a68118840a6aeb7cdaa9bd880fb5c908a809 (patch)
tree153df76da3c8b6201114722e577b73bdcacf7481 /src
parent105400786a9d812241334effe7a7fd41b89aa76c (diff)
downloadcryptography-4da2a68118840a6aeb7cdaa9bd880fb5c908a809.tar.gz
Allow parsing CSR extensions with the critical bit having an explicitly encoded default (#6600)
* Allow parsing CSR extensions with the critical bit having an explicitly encoded default * Poke for zuul
Diffstat (limited to 'src')
-rw-r--r--src/rust/src/x509/csr.rs36
1 files changed, 33 insertions, 3 deletions
diff --git a/src/rust/src/x509/csr.rs b/src/rust/src/x509/csr.rs
index 57f62ae3c..6bf517ee7 100644
--- a/src/rust/src/x509/csr.rs
+++ b/src/rust/src/x509/csr.rs
@@ -49,15 +49,26 @@ fn check_attribute_length<'a>(values: asn1::SetOf<'a, asn1::Tlv<'a>>) -> Result<
}
}
+// CsrExtension has same layout as Extension, but doesn't use `#[default]` for
+// `critical` so we can avoid erroring on explicitly-encoded defaults.
+#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash)]
+pub(crate) struct CsrExtension<'a> {
+ pub(crate) extn_id: asn1::ObjectIdentifier<'a>,
+ pub(crate) critical: Option<bool>,
+ pub(crate) extn_value: &'a [u8],
+}
+
impl CertificationRequestInfo<'_> {
- fn get_extension_attribute<'a>(&'a self) -> Result<Option<x509::Extensions<'a>>, PyAsn1Error> {
+ fn get_extension_attribute(
+ &self,
+ ) -> Result<Option<asn1::SequenceOf<'_, CsrExtension<'_>>>, PyAsn1Error> {
for attribute in self.attributes.unwrap_read().clone() {
if attribute.type_id == *oid::EXTENSION_REQUEST
|| attribute.type_id == *oid::MS_EXTENSION_REQUEST
{
check_attribute_length(attribute.values.unwrap_read().clone())?;
let val = attribute.values.unwrap_read().clone().next().unwrap();
- let exts = asn1::parse_single::<x509::Extensions<'a>>(val.full_data())?;
+ let exts = asn1::parse_single(val.full_data())?;
return Ok(Some(exts));
}
}
@@ -242,7 +253,26 @@ impl CertificateSigningRequest {
#[getter]
fn extensions(&mut self, py: pyo3::Python<'_>) -> pyo3::PyResult<pyo3::PyObject> {
- let exts = self.raw.borrow_value().csr_info.get_extension_attribute()?;
+ let csr_exts = self.raw.borrow_value().csr_info.get_extension_attribute()?;
+ let data;
+ // This is all very inefficient, to temporarily allow accepting
+ // extensions with `critical` having an explicit default encoding.
+ let exts = if let Some(v) = csr_exts {
+ let x509_exts: Vec<x509::common::Extension<'_>> = v
+ .map(|e| x509::common::Extension {
+ extn_id: e.extn_id,
+ critical: e.critical.unwrap_or_default(),
+ extn_value: e.extn_value,
+ })
+ .collect();
+ data = asn1::write_single(&asn1::SequenceOfWriter::new(x509_exts));
+ Some(x509::Asn1ReadableOrWritable::new_read(
+ asn1::parse_single(&data).unwrap(),
+ ))
+ } else {
+ None
+ };
+
x509::parse_and_cache_extensions(py, &mut self.cached_extensions, &exts, |oid, ext_data| {
certificate::parse_cert_ext(py, oid.clone(), ext_data)
})