mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-07 07:58:09 +00:00
fix(proxy): probe scrypt instead of MD5 in the fips_mode OpenSSL check (#50305)
* fix(proxy): probe scrypt instead of MD5 in the fips_mode OpenSSL check * test(proxy): fake a working scrypt so the fips_mode check tests pass on FIPS hosts
This commit is contained in:
parent
d96da7267b
commit
9f489430a6
2 changed files with 19 additions and 18 deletions
|
|
@ -23,7 +23,7 @@ def _fips_mode_setting(general_settings: Mapping[str, object]) -> bool | None:
|
|||
|
||||
|
||||
def openssl_enforces_fips() -> bool:
|
||||
"""Python's OpenSSL runs with FIPS-only defaults and itself refuses MD5."""
|
||||
"""Python's OpenSSL runs with FIPS-only defaults and itself refuses scrypt."""
|
||||
try:
|
||||
import _hashlib
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ def openssl_enforces_fips() -> bool:
|
|||
except (ImportError, AttributeError, ValueError):
|
||||
return False
|
||||
try:
|
||||
_hashlib.new("md5", b"", usedforsecurity=True)
|
||||
_hashlib.scrypt(b"", salt=b"\0" * 16, n=2, r=1, p=1, dklen=16)
|
||||
except ValueError:
|
||||
return True
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import _hashlib
|
||||
from collections.abc import Mapping
|
||||
from contextlib import nullcontext
|
||||
from typing import Final
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
|
|
@ -17,30 +16,32 @@ from litellm.proxy.common_utils.fips import (
|
|||
)
|
||||
|
||||
|
||||
def _fake_openssl(monkeypatch: pytest.MonkeyPatch, *, fips_flag: int, md5_refused: bool) -> None:
|
||||
real_new: Final = _hashlib.new
|
||||
|
||||
def new(name: str, data: bytes = b"", *, usedforsecurity: bool = True) -> _hashlib.HASH:
|
||||
if name == "md5" and md5_refused:
|
||||
raise _hashlib.UnsupportedDigestmodError("unsupported hash type")
|
||||
return real_new(name, data, usedforsecurity=usedforsecurity)
|
||||
|
||||
def _fake_openssl(monkeypatch: pytest.MonkeyPatch, *, fips_flag: int, scrypt_refused: bool) -> None:
|
||||
monkeypatch.setattr(_hashlib, "get_fips_mode", lambda: fips_flag)
|
||||
monkeypatch.setattr(_hashlib, "new", new)
|
||||
if scrypt_refused:
|
||||
monkeypatch.setattr(_hashlib, "scrypt", Mock(side_effect=ValueError("[digital envelope routines] unsupported")))
|
||||
else:
|
||||
monkeypatch.setattr(_hashlib, "scrypt", Mock(return_value=b"\0" * 16))
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"fips_flag, md5_refused, enforces",
|
||||
"fips_flag, scrypt_refused, enforces",
|
||||
[(1, True, True), (0, True, False), (1, False, False)],
|
||||
ids=["fips", "fips-flag-off", "md5-allowed"],
|
||||
ids=["fips", "fips-flag-off", "scrypt-allowed"],
|
||||
)
|
||||
def test_openssl_enforces_fips_needs_the_fips_flag_and_a_refused_md5(
|
||||
monkeypatch: pytest.MonkeyPatch, fips_flag: int, md5_refused: bool, enforces: bool
|
||||
def test_openssl_enforces_fips_needs_the_fips_flag_and_a_refused_scrypt(
|
||||
monkeypatch: pytest.MonkeyPatch, fips_flag: int, scrypt_refused: bool, enforces: bool
|
||||
) -> None:
|
||||
_fake_openssl(monkeypatch, fips_flag=fips_flag, md5_refused=md5_refused)
|
||||
_fake_openssl(monkeypatch, fips_flag=fips_flag, scrypt_refused=scrypt_refused)
|
||||
assert openssl_enforces_fips() is enforces
|
||||
|
||||
|
||||
def test_openssl_enforces_fips_while_md5_is_still_served_for_non_security_use(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
_fake_openssl(monkeypatch, fips_flag=1, scrypt_refused=True)
|
||||
monkeypatch.setattr(_hashlib, "new", Mock(return_value=Mock()))
|
||||
assert openssl_enforces_fips() is True
|
||||
|
||||
|
||||
def test_openssl_without_get_fips_mode_does_not_enforce_fips(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.delattr(_hashlib, "get_fips_mode")
|
||||
assert openssl_enforces_fips() is False
|
||||
|
|
@ -113,7 +114,7 @@ def test_enforce_fips_mode(
|
|||
cryptography_fips: bool,
|
||||
refusal: str | None,
|
||||
) -> None:
|
||||
_fake_openssl(monkeypatch, fips_flag=int(openssl_fips), md5_refused=openssl_fips)
|
||||
_fake_openssl(monkeypatch, fips_flag=int(openssl_fips), scrypt_refused=openssl_fips)
|
||||
monkeypatch.setattr(rust_openssl, "is_fips_enabled", lambda: cryptography_fips)
|
||||
|
||||
with pytest.raises(FipsModeError, match=refusal) if refusal else nullcontext():
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue