Callback for use with OpenSSL.SSL.Context.set_ocsp_client_callback.
(conn: Connection, ocsp_bytes: bytes, user_data: Optional[_CallbackData])
| 325 | |
| 326 | |
| 327 | def _ocsp_callback(conn: Connection, ocsp_bytes: bytes, user_data: Optional[_CallbackData]) -> bool: |
| 328 | """Callback for use with OpenSSL.SSL.Context.set_ocsp_client_callback.""" |
| 329 | # always pass in user_data but OpenSSL requires it be optional |
| 330 | assert user_data |
| 331 | pycert = conn.get_peer_certificate() |
| 332 | if pycert is None: |
| 333 | _LOGGER.debug("No peer cert?") |
| 334 | return False |
| 335 | cert = pycert.to_cryptography() |
| 336 | # Use the verified chain when available (pyopenssl>=20.0). |
| 337 | if hasattr(conn, "get_verified_chain"): |
| 338 | pychain = conn.get_verified_chain() |
| 339 | trusted_ca_certs = None |
| 340 | else: |
| 341 | pychain = conn.get_peer_cert_chain() |
| 342 | trusted_ca_certs = user_data.trusted_ca_certs |
| 343 | if not pychain: |
| 344 | _LOGGER.debug("No peer cert chain?") |
| 345 | return False |
| 346 | chain = [cer.to_cryptography() for cer in pychain] |
| 347 | issuer = _get_issuer_cert(cert, chain, trusted_ca_certs) |
| 348 | must_staple = False |
| 349 | # https://tools.ietf.org/html/rfc7633#section-4.2.3.1 |
| 350 | ext_tls = _get_extension(cert, _TLSFeature) |
| 351 | if ext_tls is not None: |
| 352 | for feature in ext_tls.value: |
| 353 | if feature == _TLSFeatureType.status_request: |
| 354 | _LOGGER.debug("Peer presented a must-staple cert") |
| 355 | must_staple = True |
| 356 | break |
| 357 | ocsp_response_cache = user_data.ocsp_response_cache |
| 358 | |
| 359 | # No stapled OCSP response |
| 360 | if ocsp_bytes == b"": |
| 361 | _LOGGER.debug("Peer did not staple an OCSP response") |
| 362 | if must_staple: |
| 363 | _LOGGER.debug("Must-staple cert with no stapled response, hard fail.") |
| 364 | return False |
| 365 | if not user_data.check_ocsp_endpoint: |
| 366 | _LOGGER.debug("OCSP endpoint checking is disabled, soft fail.") |
| 367 | # No stapled OCSP response, checking responder URI disabled, soft fail. |
| 368 | return True |
| 369 | # https://tools.ietf.org/html/rfc6960#section-3.1 |
| 370 | ext_aia = _get_extension(cert, _AuthorityInformationAccess) |
| 371 | if ext_aia is None: |
| 372 | _LOGGER.debug("No authority access information, soft fail") |
| 373 | # No stapled OCSP response, no responder URI, soft fail. |
| 374 | return True |
| 375 | uris = [ |
| 376 | desc.access_location.value |
| 377 | for desc in ext_aia.value |
| 378 | if desc.access_method == _AuthorityInformationAccessOID.OCSP |
| 379 | ] |
| 380 | if not uris: |
| 381 | _LOGGER.debug("No OCSP URI, soft fail") |
| 382 | # No responder URI, soft fail. |
| 383 | return True |
| 384 | if issuer is None: |
nothing calls this directly
no test coverage detected