| 1363 | |
| 1364 | #[pymethod] |
| 1365 | fn _set_alpn_protocols(&self, protos: ArgBytesLike, vm: &VirtualMachine) -> PyResult<()> { |
| 1366 | #[cfg(ossl102)] |
| 1367 | { |
| 1368 | let mut ctx = self.builder(); |
| 1369 | let server = protos.with_ref(|pbuf| { |
| 1370 | if pbuf.len() > libc::c_uint::MAX as usize { |
| 1371 | return Err(vm.new_overflow_error(format!( |
| 1372 | "protocols longer than {} bytes", |
| 1373 | libc::c_uint::MAX |
| 1374 | ))); |
| 1375 | } |
| 1376 | ctx.set_alpn_protos(pbuf) |
| 1377 | .map_err(|e| convert_openssl_error(vm, e))?; |
| 1378 | Ok(pbuf.to_vec()) |
| 1379 | })?; |
| 1380 | ctx.set_alpn_select_callback(move |_, client| { |
| 1381 | let proto = |
| 1382 | ssl::select_next_proto(&server, client).ok_or(ssl::AlpnError::NOACK)?; |
| 1383 | let pos = memchr::memmem::find(client, proto) |
| 1384 | .expect("selected alpn proto should be present in client protos"); |
| 1385 | Ok(&client[pos..pos + proto.len()]) |
| 1386 | }); |
| 1387 | Ok(()) |
| 1388 | } |
| 1389 | #[cfg(not(ossl102))] |
| 1390 | { |
| 1391 | Err(vm.new_not_implemented_error( |
| 1392 | "The NPN extension requires OpenSSL 1.0.1 or later.", |
| 1393 | )) |
| 1394 | } |
| 1395 | } |
| 1396 | |
| 1397 | #[pymethod] |
| 1398 | fn set_psk_client_callback( |