Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Change to spawn _test_hashlib_fips from test_hashlib with an env.
  • Loading branch information
gpshead authored and xnox committed Sep 8, 2025
commit 57241dbb2bd9bb74d36827f53e555e202cc42b4d
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@
# Licensed to PSF under a Contributor Agreement.
#

"""Primarily executed by test_hashlib.py. It can run stand alone by humans."""

import os
import sys
import unittest

OPENSSL_CONF_BACKUP = os.environ.get("OPENSSL_CONF")


class HashLibFIPSTestCase(unittest.TestCase):
_executions = 0 # prevent re-running on in refleak hunting mode, etc.

@classmethod
def setUpClass(cls):
if cls._executions > 0:
raise unittest.SkipTest("Cannot run this test within the same Python process.")
if sys.modules.get("_hashlib") or sys.modules.get("_ssl"):
raise AssertionError("_hashlib or _ssl already imported, too late to change OPENSSL_CONF.")
# This openssl.cnf mocks FIPS mode without any digest
# loaded. It means all digests must raise ValueError when
# usedforsecurity=True via either openssl or builtin
Expand Down Expand Up @@ -47,7 +42,6 @@ def tearDownClass(cls):
os.environ["OPENSSL_CONF"] = OPENSSL_CONF_BACKUP
else:
os.environ.pop("OPENSSL_CONF", None)
cls._executions += 1

def test_algorithms_available(self):
import hashlib
Expand Down
11 changes: 9 additions & 2 deletions Lib/test/support/script_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,14 @@ def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,


@support.requires_subprocess()
def run_test_script(script):
def run_test_script(script, **kwargs):
"""Run the file *script* in a child interpreter.

Keyword arguments are passed on to subprocess.run() within.

Asserts if the child exits non-zero. Prints child output after
execution when run in verbose mode.
"""
# use -u to try to get the full output if the test hangs or crash
if support.verbose:
def title(text):
Expand All @@ -315,7 +322,7 @@ def title(text):
# In verbose mode, the child process inherit stdout and stdout,
# to see output in realtime and reduce the risk of losing output.
args = [sys.executable, "-E", "-X", "faulthandler", "-u", script, "-v"]
proc = subprocess.run(args)
proc = subprocess.run(args, **kwargs)
print(title(f"{name} completed: exit code {proc.returncode}"),
flush=True)
if proc.returncode:
Expand Down
13 changes: 13 additions & 0 deletions Lib/test/test_hashlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import threading
import unittest
from test import support
from test.support import os_helper, script_helper
from test.support import _4G, bigmemtest
from test.support import hashlib_helper
from test.support.import_helper import import_fresh_module
Expand Down Expand Up @@ -1387,6 +1388,18 @@ def scrypt(password=b"password", /, **kwargs):
MAX_DKLEN = ((1 << 32) - 1) * 32 # see RFC 7914
self.assertRaises(numeric_exc_types, scrypt, dklen=MAX_DKLEN + 1)

def test_builtins_in_openssl_fips_mode(self):
try:
from _hashlib import get_fips_mode
except ImportError:
self.skipTest('OpenSSL _hashlib not available')
from test import _test_hashlib_fips
child_test_path = _test_hashlib_fips.__file__
env = os.environ.copy()
# A config to mock FIPS mode, see _test_hashlib_fips.py.
env["OPENSSL_CONF"] = os.path.join(os.path.dirname(__file__), "hashlibdata", "openssl.cnf")
script_helper.run_test_script(child_test_path, env=env)


if __name__ == "__main__":
unittest.main()