diff options
| author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2023-04-24 12:22:21 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-24 12:22:21 +0200 |
| commit | 1f0360c07382dbd86066d1aa8aa4bae34aff18c5 (patch) | |
| tree | cc82d00aea829f0b3d3949f40df9696b099ee662 /ext/node/crypto/x509.rs | |
| parent | 28e2c7204fe02304a8fc3339d7758eec0f64f723 (diff) | |
refactor(ext/node): reorganize ops (#18799)
Move all op related code of "ext/node" to "ext/node/ops" module.
These files were unnecessarily scattered around the extension.
Diffstat (limited to 'ext/node/crypto/x509.rs')
| -rw-r--r-- | ext/node/crypto/x509.rs | 319 |
1 files changed, 0 insertions, 319 deletions
diff --git a/ext/node/crypto/x509.rs b/ext/node/crypto/x509.rs deleted file mode 100644 index 402c58b72..000000000 --- a/ext/node/crypto/x509.rs +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::bad_resource_id; -use deno_core::error::AnyError; -use deno_core::op; -use deno_core::OpState; -use deno_core::Resource; - -use std::borrow::Cow; - -use x509_parser::der_parser::asn1_rs::Any; -use x509_parser::der_parser::asn1_rs::Tag; -use x509_parser::der_parser::oid::Oid; -use x509_parser::extensions; -use x509_parser::pem; -use x509_parser::prelude::*; - -use digest::Digest; - -struct Certificate { - _buf: Vec<u8>, - pem: Option<pem::Pem>, - cert: X509Certificate<'static>, -} - -impl Certificate { - fn fingerprint<D: Digest>(&self) -> Option<String> { - self.pem.as_ref().map(|pem| { - let mut hasher = D::new(); - hasher.update(&pem.contents); - let bytes = hasher.finalize(); - // OpenSSL returns colon separated upper case hex values. - let mut hex = String::with_capacity(bytes.len() * 2); - for byte in bytes { - hex.push_str(&format!("{:02X}:", byte)); - } - hex.pop(); - hex - }) - } -} - -impl std::ops::Deref for Certificate { - type Target = X509Certificate<'static>; - - fn deref(&self) -> &Self::Target { - &self.cert - } -} - -impl Resource for Certificate { - fn name(&self) -> Cow<str> { - "x509Certificate".into() - } -} - -#[op] -pub fn op_node_x509_parse( - state: &mut OpState, - buf: &[u8], -) -> Result<u32, AnyError> { - let pem = match pem::parse_x509_pem(buf) { - Ok((_, pem)) => Some(pem), - Err(_) => None, - }; - - let cert = pem - .as_ref() - .map(|pem| pem.parse_x509()) - .unwrap_or_else(|| X509Certificate::from_der(buf).map(|(_, cert)| cert))?; - - let cert = Certificate { - _buf: buf.to_vec(), - // SAFETY: Extending the lifetime of the certificate. Backing buffer is - // owned by the resource. - cert: unsafe { std::mem::transmute(cert) }, - pem, - }; - let rid = state.resource_table.add(cert); - Ok(rid) -} - -#[op] -pub fn op_node_x509_ca( - state: &mut OpState, - rid: u32, -) -> Result<bool, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - Ok(cert.is_ca()) -} - -#[op] -pub fn op_node_x509_check_email( - state: &mut OpState, - rid: u32, - email: &str, -) -> Result<bool, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - - let subject = cert.subject(); - if subject - .iter_email() - .any(|e| e.as_str().unwrap_or("") == email) - { - return Ok(true); - } - - let subject_alt = cert - .extensions() - .iter() - .find(|e| e.oid == x509_parser::oid_registry::OID_X509_EXT_SUBJECT_ALT_NAME) - .and_then(|e| match e.parsed_extension() { - extensions::ParsedExtension::SubjectAlternativeName(s) => Some(s), - _ => None, - }); - - if let Some(subject_alt) = subject_alt { - for name in &subject_alt.general_names { - dbg!(name); - if let extensions::GeneralName::RFC822Name(n) = name { - if *n == email { - return Ok(true); - } - } - } - } - - Ok(false) -} - -#[op] -pub fn op_node_x509_fingerprint( - state: &mut OpState, - rid: u32, -) -> Result<Option<String>, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - Ok(cert.fingerprint::<sha1::Sha1>()) -} - -#[op] -pub fn op_node_x509_fingerprint256( - state: &mut OpState, - rid: u32, -) -> Result<Option<String>, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - Ok(cert.fingerprint::<sha2::Sha256>()) -} - -#[op] -pub fn op_node_x509_fingerprint512( - state: &mut OpState, - rid: u32, -) -> Result<Option<String>, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - Ok(cert.fingerprint::<sha2::Sha512>()) -} - -#[op] -pub fn op_node_x509_get_issuer( - state: &mut OpState, - rid: u32, -) -> Result<String, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - Ok(x509name_to_string(cert.issuer(), oid_registry())?) -} - -#[op] -pub fn op_node_x509_get_subject( - state: &mut OpState, - rid: u32, -) -> Result<String, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - Ok(x509name_to_string(cert.subject(), oid_registry())?) -} - -// Attempt to convert attribute to string. If type is not a string, return value is the hex -// encoding of the attribute value -fn attribute_value_to_string( - attr: &Any, - _attr_type: &Oid, -) -> Result<String, X509Error> { - // TODO: replace this with helper function, when it is added to asn1-rs - match attr.tag() { - Tag::NumericString - | Tag::BmpString - | Tag::VisibleString - | Tag::PrintableString - | Tag::GeneralString - | Tag::ObjectDescriptor - | Tag::GraphicString - | Tag::T61String - | Tag::VideotexString - | Tag::Utf8String - | Tag::Ia5String => { - let s = core::str::from_utf8(attr.data) - .map_err(|_| X509Error::InvalidAttributes)?; - Ok(s.to_owned()) - } - _ => { - // type is not a string, get slice and convert it to base64 - Ok(data_encoding::HEXUPPER.encode(attr.as_bytes())) - } - } -} - -fn x509name_to_string( - name: &X509Name, - oid_registry: &oid_registry::OidRegistry, -) -> Result<String, x509_parser::error::X509Error> { - // Lifted from https://github.com/rusticata/x509-parser/blob/4d618c2ed6b1fc102df16797545895f7c67ee0fe/src/x509.rs#L543-L566 - // since it's a private function (Copyright 2017 Pierre Chifflier) - name.iter_rdn().fold(Ok(String::new()), |acc, rdn| { - acc.and_then(|mut _vec| { - rdn - .iter() - .fold(Ok(String::new()), |acc2, attr| { - acc2.and_then(|mut _vec2| { - let val_str = - attribute_value_to_string(attr.attr_value(), attr.attr_type())?; - // look ABBREV, and if not found, use shortname - let abbrev = match oid2abbrev(attr.attr_type(), oid_registry) { - Ok(s) => String::from(s), - _ => format!("{:?}", attr.attr_type()), - }; - let rdn = format!("{}={}", abbrev, val_str); - match _vec2.len() { - 0 => Ok(rdn), - _ => Ok(_vec2 + " + " + rdn.as_str()), - } - }) - }) - .map(|v| match _vec.len() { - 0 => v, - _ => _vec + "\n" + v.as_str(), - }) - }) - }) -} - -#[op] -pub fn op_node_x509_get_valid_from( - state: &mut OpState, - rid: u32, -) -> Result<String, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - Ok(cert.validity().not_before.to_string()) -} - -#[op] -pub fn op_node_x509_get_valid_to( - state: &mut OpState, - rid: u32, -) -> Result<String, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - Ok(cert.validity().not_after.to_string()) -} - -#[op] -pub fn op_node_x509_get_serial_number( - state: &mut OpState, - rid: u32, -) -> Result<String, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - let mut s = cert.serial.to_str_radix(16); - s.make_ascii_uppercase(); - Ok(s) -} - -#[op] -pub fn op_node_x509_key_usage( - state: &mut OpState, - rid: u32, -) -> Result<u16, AnyError> { - let cert = state - .resource_table - .get::<Certificate>(rid) - .map_err(|_| bad_resource_id())?; - - let key_usage = cert - .extensions() - .iter() - .find(|e| e.oid == x509_parser::oid_registry::OID_X509_EXT_KEY_USAGE) - .and_then(|e| match e.parsed_extension() { - extensions::ParsedExtension::KeyUsage(k) => Some(k), - _ => None, - }); - - Ok(key_usage.map(|k| k.flags).unwrap_or(0)) -} |
