MCPcopy Index your code
hub / github.com/RustPython/RustPython / cert_der_to_dict_helper

Function cert_der_to_dict_helper

crates/stdlib/src/ssl/cert.rs:370–541  ·  view source on GitHub ↗

Convert DER-encoded certificate to Python dict (for get_ca_certs) Similar to cert_to_dict but includes additional fields like crlDistributionPoints and uses CPython's specific ordering: issuer, notAfter, notBefore, serialNumber, subject, version

(vm: &VirtualMachine, cert_der: &[u8])

Source from the content-addressed store, hash-verified

368/// Similar to cert_to_dict but includes additional fields like crlDistributionPoints
369/// and uses CPython's specific ordering: issuer, notAfter, notBefore, serialNumber, subject, version
370pub fn cert_der_to_dict_helper(vm: &VirtualMachine, cert_der: &[u8]) -> PyResult<PyObjectRef> {
371 // Parse the certificate using x509-parser
372 let (_, cert) = x509_parser::parse_x509_certificate(cert_der)
373 .map_err(|e| vm.new_value_error(format!("Failed to parse certificate: {e}")))?;
374
375 // Helper to convert X509Name to nested tuple format
376 let name_to_tuple = |name: &x509_parser::x509::X509Name<'_>| -> PyResult {
377 let mut entries = Vec::new();
378 for rdn in name.iter() {
379 for attr in rdn.iter() {
380 let oid_str = attr.attr_type().to_id_string();
381
382 // Get value as bytes and convert to string
383 let value_str = if let Ok(s) = attr.attr_value().as_str() {
384 s.to_string()
385 } else {
386 let value_bytes = attr.attr_value().data;
387 match core::str::from_utf8(value_bytes) {
388 Ok(s) => s.to_string(),
389 Err(_) => String::from_utf8_lossy(value_bytes).into_owned(),
390 }
391 };
392
393 let key = oid_to_attribute_name(&oid_str);
394
395 let entry =
396 vm.new_tuple((vm.ctx.new_str(key.to_string()), vm.ctx.new_str(value_str)));
397 entries.push(vm.new_tuple((entry,)).into());
398 }
399 }
400 Ok(vm.ctx.new_tuple(entries).into())
401 };
402
403 let dict = vm.ctx.new_dict();
404
405 // CPython ordering: issuer, notAfter, notBefore, serialNumber, subject, version
406 dict.set_item("issuer", name_to_tuple(cert.issuer())?, vm)?;
407
408 // Validity - format with GMT using chrono
409 dict.set_item(
410 "notAfter",
411 vm.ctx
412 .new_str(format_asn1_time(&cert.validity().not_after))
413 .into(),
414 vm,
415 )?;
416 dict.set_item(
417 "notBefore",
418 vm.ctx
419 .new_str(format_asn1_time(&cert.validity().not_before))
420 .into(),
421 vm,
422 )?;
423
424 // Serial number - hex format with even length
425 let serial = format_serial_number(&cert.serial);
426 dict.set_item("serialNumber", vm.ctx.new_str(serial).into(), vm)?;
427

Callers 2

cert_der_to_dictMethod · 0.85
_test_decode_certFunction · 0.85

Calls 15

newFunction · 0.85
oid_to_attribute_nameFunction · 0.85
format_asn1_timeFunction · 0.85
format_serial_numberFunction · 0.85
format_ip_addressFunction · 0.85
to_stringMethod · 0.80
into_ownedMethod · 0.80
new_dictMethod · 0.80
iterMethod · 0.45
as_strMethod · 0.45
new_tupleMethod · 0.45
new_strMethod · 0.45

Tested by

no test coverage detected