| 1789 | |
| 1790 | #[pymethod] |
| 1791 | fn set_ecdh_curve(&self, name: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { |
| 1792 | // Validate name is not None |
| 1793 | if vm.is_none(&name) { |
| 1794 | return Err(vm.new_type_error("ECDH curve name cannot be None")); |
| 1795 | } |
| 1796 | |
| 1797 | // Validate name is str or bytes |
| 1798 | let curve_name = if let Ok(s) = PyUtf8StrRef::try_from_object(vm, name.clone()) { |
| 1799 | s.as_str().to_owned() |
| 1800 | } else if let Ok(b) = ArgBytesLike::try_from_object(vm, name) { |
| 1801 | String::from_utf8(b.borrow_buf().to_vec()) |
| 1802 | .map_err(|_| vm.new_value_error("Invalid curve name encoding"))? |
| 1803 | } else { |
| 1804 | return Err(vm.new_type_error("ECDH curve name must be str or bytes")); |
| 1805 | }; |
| 1806 | |
| 1807 | // Validate curve name (common curves for compatibility) |
| 1808 | // rustls supports: X25519, secp256r1 (prime256v1), secp384r1 |
| 1809 | let valid_curves = [ |
| 1810 | "prime256v1", |
| 1811 | "secp256r1", |
| 1812 | "prime384v1", |
| 1813 | "secp384r1", |
| 1814 | "prime521v1", |
| 1815 | "secp521r1", |
| 1816 | "X25519", |
| 1817 | "x25519", |
| 1818 | "x448", // For future compatibility |
| 1819 | ]; |
| 1820 | |
| 1821 | if !valid_curves.contains(&curve_name.as_str()) { |
| 1822 | return Err(vm.new_value_error(format!("unknown curve name '{curve_name}'"))); |
| 1823 | } |
| 1824 | |
| 1825 | // Store the curve name to be used during handshake |
| 1826 | // This will limit the key exchange groups offered/accepted |
| 1827 | *self.ecdh_curve.write() = Some(curve_name); |
| 1828 | Ok(()) |
| 1829 | } |
| 1830 | |
| 1831 | #[pymethod] |
| 1832 | fn _wrap_socket( |