| 1734 | |
| 1735 | #[pymethod] |
| 1736 | fn load_dh_params(&self, filepath: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { |
| 1737 | // Validate filepath is not None |
| 1738 | if vm.is_none(&filepath) { |
| 1739 | return Err(vm.new_type_error("DH params filepath cannot be None")); |
| 1740 | } |
| 1741 | |
| 1742 | // Validate filepath is str or bytes |
| 1743 | let path_str = if let Ok(s) = PyUtf8StrRef::try_from_object(vm, filepath.clone()) { |
| 1744 | s.as_str().to_owned() |
| 1745 | } else if let Ok(b) = ArgBytesLike::try_from_object(vm, filepath) { |
| 1746 | String::from_utf8(b.borrow_buf().to_vec()) |
| 1747 | .map_err(|_| vm.new_value_error("Invalid path encoding"))? |
| 1748 | } else { |
| 1749 | return Err(vm.new_type_error("DH params filepath must be str or bytes")); |
| 1750 | }; |
| 1751 | |
| 1752 | // Check if file exists |
| 1753 | if !std::path::Path::new(&path_str).exists() { |
| 1754 | // Create FileNotFoundError with errno=ENOENT (2) |
| 1755 | let exc = vm.new_os_subtype_error( |
| 1756 | vm.ctx.exceptions.file_not_found_error.to_owned(), |
| 1757 | Some(2), // errno = ENOENT (2) |
| 1758 | "No such file or directory", |
| 1759 | ); |
| 1760 | // Set filename attribute |
| 1761 | let _ = exc |
| 1762 | .as_object() |
| 1763 | .set_attr("filename", vm.ctx.new_str(path_str.clone()), vm); |
| 1764 | return Err(exc.upcast()); |
| 1765 | } |
| 1766 | |
| 1767 | // Validate that the file contains DH parameters |
| 1768 | // Read the file and check for DH PARAMETERS header |
| 1769 | let contents = |
| 1770 | std::fs::read_to_string(&path_str).map_err(|e| vm.new_os_error(e.to_string()))?; |
| 1771 | |
| 1772 | if !contents.contains("BEGIN DH PARAMETERS") |
| 1773 | && !contents.contains("BEGIN X9.42 DH PARAMETERS") |
| 1774 | { |
| 1775 | // File exists but doesn't contain DH parameters - raise SSLError |
| 1776 | // [PEM: NO_START_LINE] no start line |
| 1777 | return Err(super::compat::SslError::create_ssl_error_with_reason( |
| 1778 | vm, |
| 1779 | Some("PEM"), |
| 1780 | "NO_START_LINE", |
| 1781 | "[PEM: NO_START_LINE] no start line", |
| 1782 | )); |
| 1783 | } |
| 1784 | |
| 1785 | // rustls doesn't use DH parameters (it uses ECDHE for key exchange) |
| 1786 | // This is a no-op for compatibility with OpenSSL-based code |
| 1787 | Ok(()) |
| 1788 | } |
| 1789 | |
| 1790 | #[pymethod] |
| 1791 | fn set_ecdh_curve(&self, name: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { |