<commit_before># coding: utf-8
"""
Test the RSA ANSI X9.31 signer and verifier
"""

# python libs
from __future__ import absolute_import, print_function, unicode_literals
import ctypes
import fnmatch
import glob
import sys

# salt libs
from salt.utils.rsax931 import (
    _find_libcrypto,
    _load_libcrypto,
    RSAX931Signer,
    RSAX931Verifier,
)
import salt.utils.platform

# salt testing libs
from tests.support.unit import TestCase
from tests.support.mock import patch


class RSAX931Test(TestCase):

    privkey_data = (
        "-----BEGIN RSA PRIVATE KEY-----\n"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>n"
        "zw6VL5NO9mfOPO2W/3FaG1sRgBQcerWonoSSSn8OJwVBHMFLG3a+U1Zh1UvPoiPK\n"
        "S734swIM+zFpNYivGPvOm/muF/waFf8tF/47t1cwt/JGXYQnkG/P7z0vp47Irpsb\n"
        "Yjw7vPe4BnbY6SppSxscW3KoV7GtJLFKIxAXbxsuJMF/rYe3O3w2VKJ1Sug1VDJl\n"
        "/GytwAkSUer84WwP2b07Wn4c5pCnmLslMgXCLkENgi1NnJMhYVOnckxGDZk54hqP\n"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "Klu4W8ZEdZyzPcJrfk7PdopfGOfrhWzkREK9C40H7ou/1jUecq/STPfSOmxh3Y+D\n"
        "<KEY>sQAHx8VaHaxVsJ7SGR/spr0pkZL+NXsCgYEA84rIgBKWB1W+TGRXJzdf\n"
        "yHIGaCjXpm2pQMN3LmP3RrcuZWm0vBt94dHcrR5l+u/zc6iwEDTAjJvqdU4rdyEr\n"
        "tfkwr7v6TNlQB3WvpWanIPyVzfVSNFX/ZWSsAgZvxYjr9ixw6vzWBXOeOb/Gqu7b\n"
        "cvpLkjmJ0wxDhbXtyXKhZA8CgYBZyvcQb+hUs732M4mtQBSD0kohc5TsGdlOQ1AQ\n"
        "McFcmbpnzDghkclyW8jzwdLMk9uxEeDAwuxWE/UEvhlSi6qdzxC+Zifp5NBc0fVe\n"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>1/<KEY>0Dr1bN9V+F<KEY>EAWpIbLXGDw==\n"
        "-----END RSA PRIVATE KEY-----"
    )

    pubkey_data = (
        "-----BEGIN PUBLIC KEY-----\n"
        "<KEY>"
        "<KEY>"
        "<KEY>9Dygu3mJ2VgRC7XhlFpmdo5NN8J2E7B/CNB3R\n"
        "4hOcMMZNZdi0xLtFoTfwU61UPfFX14mV2laqLbvDEfQLJhUTDeFFV8EN5Z4H1ttL\n"
        "P3sMXJvc3EvM0JiDVj4l1TWFUHHzeFgCA1Im0lv8i7PFrgW7nyMfK9uDSsUmIp7k\n"
        "6ai4tVzwkTmV5PsriP1ju88Lo3MB4/sUmDv/JmlZ9YyzTO3Po8Uz3Aeq9HJWyBWH\n"
        "AQIDAQAB\n"
        "-----END PUBLIC KEY-----"
    )

    hello_world = b"hello, world"

    hello_world_sig = (
        b"\x63\xa0\x70\xd2\xe4\xd4\x6b\x8a\xa2\x59\x27\x5f\x00\x69"
        b"\x1e\x3c\x50\xed\x50\x13\x09\x80\xe3\x47\x4e\x14\xb5\x7c"
        b"\x07\x26\x4e\x20\x74\xea\x0e\xf8\xda\xff\x1e\x57\x8c\x67"
        b"\x76\x73\xaa\xea\x0f\x0a\xe7\xa2\xe3\x88\xfc\x09\x87\x36"
        b"\x01\x3a\xb7\x4c\x40\xe0\xf4\x54\xc5\xf1\xaa\xb2\x1d\x7f"
        b"\xb6\xd3\xa8\xdd\x28\x69\x8b\x88\xe4\x42\x1e\x48\x3e\x1f"
        b"\xe2\x2b\x3c\x7c\x85\x11\xe9\x59\xd7\xf3\xc2\x21\xd3\x55"
        b"\xcb\x9c\x3c\x93\xcc\x20\xdf\x64\x81\xd0\x0d\xbf\x8e\x8d"
        b"\x47\xec\x1d\x9e\x27\xec\x12\xed\x8b\x5f\xd6\x1d\xec\x8d"
        b"\x77\x5a\x58\x8a\x24\xb6\x0f\x12\xb7\x51\xef\x7d\x85\x0f"
        b"\x49\x39\x02\x81\x15\x08\x70\xd6\xe0\x0b\x31\xff\x5f\xf9"
        b"\xd1\x92\x38\x59\x8c\x22\x9c\xbb\xbf\xcf\x85\x34\xe2\x47"
        b"\xf5\xe2\xaa\xb4\x62\x33\x3c\x13\x78\x33\x87\x08\x9e\xb5"
        b"\xbc\x5d\xc1\xbf\x79\x7c\xfa\x5f\x06\x6a\x3b\x17\x40\x09"
        b"\xb9\x09\xbf\x32\xc3\x00\xe2\xbc\x91\x77\x14\xa5\x23\xf5"
        b"\xf5\xf1\x09\x12\x38\xda\x3b\x6a\x82\x81\x7b\x5e\x1c\xcb"
        b"\xaa\x36\x9b\x08\x36\x03\x14\x96\xa3\x31\x39\x59\x16\x75"
        b"\xc9\xb6\x66\x94\x1b\x97\xff\xc8\xa1\xe3\x21\x35\x23\x06"
        b"\x4c\x9b\xf4\xee"
    )

    def test_signer(self):
        with self.assertRaises(ValueError):
            signer = RSAX931Signer("bogus key data")
        with self.assertRaises(ValueError):
            signer = RSAX931Signer(RSAX931Test.pubkey_data)

        signer = RSAX931Signer(RSAX931Test.privkey_data)
        with self.assertRaises(ValueError):
            signer.sign("x" * 255)  # message too long

        sig = signer.sign(RSAX931Test.hello_world)
        self.assertEqual(RSAX931Test.hello_world_sig, sig)

    def test_verifier(self):
        with self.assertRaises(ValueError):
            verifier = RSAX931Verifier("bogus key data")
        with self.assertRaises(ValueError):
            verifier = RSAX931Verifier(RSAX931Test.privkey_data)

        verifier = RSAX931Verifier(RSAX931Test.pubkey_data)
        with self.assertRaises(ValueError):
            verifier.verify("")
        with self.assertRaises(ValueError):
            verifier.verify(RSAX931Test.hello_world_sig + b"junk")

        msg = verifier.verify(RSAX931Test.hello_world_sig)
        self.assertEqual(RSAX931Test.hello_world, msg)

    def test_find_libcrypto(self):
        """
        Test _find_libcrypto.
        """
        # Test supported systems.
        lib_path = _find_libcrypto()
        self.assertFalse(not lib_path)
        if sys.platform.startswith("win"):
            # For Microsoft Windows variants.
            self.assertEqual(lib_path, "libeay32")
        elif getattr(sys, "frozen", False) and salt.utils.platform.is_smartos():
            # For SmartOS.
            self.assertTrue(
                fnmatch.fnmatch(
                    lib_path,
                    os.path.join(os.path.dirname(sys.executable), "libcrypto*"),
                )
            )
        elif not lib_path:
            if salt.utils.platform.is_sunos():
                # For Solaris-like distributions.
                passed = False
                for i in (
                    "/opt/local/lib/libcrypto.so*",
                    "/opt/tools/lib/libcrypto.so*",
                ):
                    if fnmatch.fnmatch(lib_path, i):
                        passed = True
                        break
                self.assertTrue(passed)
            elif salt.utils.platform.is_aix():
                # For IBM AIX.
                if os.path.isdir("/opt/salt/lib"):
                    self.assertTrue(fnmatch.fnmatch("/opt/salt/lib/libcrypto.so*"))
                else:
                    self.assertTrue(fnmatch.fnmatch("/opt/freeware/lib/libcrypto.so*"))
        elif salt.utils.platform.is_darwin():
            # For Darwin distributions/macOS.
            passed = False
            for i in (
                "/usr/lib/libcrypto.*.dylib",
                "/usr/local/opt/openssl/lib/libcrypto.dylib",
                "/usr/local/opt/openssl@*/lib/libcrypto.dylib",
            ):
                if fnmatch.fnmatch(lib_path, i):
                    passed = True
                    break
            self.assertTrue(passed)
        # Test unsupported systems.
        with patch.object(sys, "platform", "unknown"), patch.object(
            glob, "glob", lambda a: []
        ), self.assertRaises(OSError):
            _find_libcrypto()

    def test_load_libcrypto(self):
        """
        Test _load_libcrypto.
        """
        lib = _load_libcrypto()
        self.assertTrue(isinstance(lib, ctypes.CDLL))<commit_msg>Fix typoes; forgot to lint.<commit_after># coding: utf-8
"""
Test the RSA ANSI X9.31 signer and verifier
"""

# python libs
from __future__ import absolute_import, print_function, unicode_literals

import ctypes
import ctypes.util
import fnmatch
import glob
import os
import sys

# salt libs
from salt.utils.rsax931 import (
    RSAX931Signer,
    RSAX931Verifier,
    _find_libcrypto,
    _load_libcrypto,
)
import salt.utils.platform
from tests.support.mock import patch

# salt testing libs
from tests.support.unit import TestCase


class RSAX931Test(TestCase):

    privkey_data = (
        "-----BEGIN RSA PRIVATE KEY-----\n"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "zw6VL5NO9mfOPO2W/3FaG1sRgBQcerWonoSSSn8OJwVBHMFLG3a+U1Zh1UvPoiPK\n"
        "S734swIM+zFpNYivGPvOm/muF/waFf8tF/47t1cwt/JGXYQnkG/P7z0vp47Irpsb\n"
        "Yjw7vPe4BnbY6SppSxscW3KoV7GtJLFKIxAXbxsuJMF/rYe3O3w2VKJ1Sug1VDJl\n"
        "/GytwAkSUer84WwP2b07Wn4c5pCnmLslMgXCLkENgi1NnJMhYVOnckxGDZk54hqP\n"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>fGOfrhWzkREK9C40H7ou/1jUecq/STPfSOmxh3Y+D\n"
        "ifMNO6z4sQAHx8VaHaxVsJ7SGR/<KEY>"
        "yHIGaCjXpm2pQMN3LmP3RrcuZWm0vBt94dHcrR5l+u/zc6iwEDTAjJvqdU4rdyEr\n"
        "tfkwr7v6TNlQB3WvpWanIPyVzfVSNFX/ZWSsAgZvxYjr9ixw6vzWBXOeOb/Gqu7b\n"
        "cvpLkjmJ0wxDhbXtyXKhZA8CgYBZyvcQb+hUs732M4mtQBSD0kohc5TsGdlOQ1AQ\n"
        "McFcmbpnzDghkclyW8jzwdLMk9uxEeDAwuxWE/UEvhlSi6qdzxC+Zifp5NBc0fVe\n"
        "<KEY>"
        "<KEY>"
        "<KEY>"
        "<KEY>1/2l4V2NLQZU40Dr1bN9V+Ftd9L0pvpCAEAWpIbLXGDw==\n"
        "-----END RSA PRIVATE KEY-----"
    )

    pubkey_data = (
        "-----BEGIN PUBLIC KEY-----\n"
        "<KEY>"
        "<KEY>"
        "4ZMsYqLzqjWMekLC8bjhxc+EuPo9Dygu3mJ2VgRC7XhlFpmdo5NN8J2E7B/CNB3R\n"
        "4hOcMMZNZdi0xLtFoTfwU61UPfFX14mV2laqLbvDEfQLJhUTDeFFV8EN5Z4H1ttL\n"
        "P3sMXJvc3EvM0JiDVj4l1TWFUHHzeFgCA1Im0lv8i7PFrgW7nyMfK9uDSsUmIp7k\n"
        "6ai4tVzwkTmV5PsriP1ju88Lo3MB4/sUmDv/JmlZ9YyzTO3Po8Uz3Aeq9HJWyBWH\n"
        "AQIDAQAB\n"
        "-----END PUBLIC KEY-----"
    )

    hello_world = b"hello, world"

    hello_world_sig = (
        b"\x63\xa0\x70\xd2\xe4\xd4\x6b\x8a\xa2\x59\x27\x5f\x00\x69"
        b"\x1e\x3c\x50\xed\x50\x13\x09\x80\xe3\x47\x4e\x14\xb5\x7c"
        b"\x07\x26\x4e\x20\x74\xea\x0e\xf8\xda\xff\x1e\x57\x8c\x67"
        b"\x76\x73\xaa\xea\x0f\x0a\xe7\xa2\xe3\x88\xfc\x09\x87\x36"
        b"\x01\x3a\xb7\x4c\x40\xe0\xf4\x54\xc5\xf1\xaa\xb2\x1d\x7f"
        b"\xb6\xd3\xa8\xdd\x28\x69\x8b\x88\xe4\x42\x1e\x48\x3e\x1f"
        b"\xe2\x2b\x3c\x7c\x85\x11\xe9\x59\xd7\xf3\xc2\x21\xd3\x55"
        b"\xcb\x9c\x3c\x93\xcc\x20\xdf\x64\x81\xd0\x0d\xbf\x8e\x8d"
        b"\x47\xec\x1d\x9e\x27\xec\x12\xed\x8b\x5f\xd6\x1d\xec\x8d"
        b"\x77\x5a\x58\x8a\x24\xb6\x0f\x12\xb7\x51\xef\x7d\x85\x0f"
        b"\x49\x39\x02\x81\x15\x08\x70\xd6\xe0\x0b\x31\xff\x5f\xf9"
        b"\xd1\x92\x38\x59\x8c\x22\x9c\xbb\xbf\xcf\x85\x34\xe2\x47"
        b"\xf5\xe2\xaa\xb4\x62\x33\x3c\x13\x78\x33\x87\x08\x9e\xb5"
        b"\xbc\x5d\xc1\xbf\x79\x7c\xfa\x5f\x06\x6a\x3b\x17\x40\x09"
        b"\xb9\x09\xbf\x32\xc3\x00\xe2\xbc\x91\x77\x14\xa5\x23\xf5"
        b"\xf5\xf1\x09\x12\x38\xda\x3b\x6a\x82\x81\x7b\x5e\x1c\xcb"
        b"\xaa\x36\x9b\x08\x36\x03\x14\x96\xa3\x31\x39\x59\x16\x75"
        b"\xc9\xb6\x66\x94\x1b\x97\xff\xc8\xa1\xe3\x21\x35\x23\x06"
        b"\x4c\x9b\xf4\xee"
    )

    def test_signer(self):
        with self.assertRaises(ValueError):
            signer = RSAX931Signer("bogus key data")
        with self.assertRaises(ValueError):
            signer = RSAX931Signer(RSAX931Test.pubkey_data)

        signer = RSAX931Signer(RSAX931Test.privkey_data)
        with self.assertRaises(ValueError):
            signer.sign("x" * 255)  # message too long

        sig = signer.sign(RSAX931Test.hello_world)
        self.assertEqual(RSAX931Test.hello_world_sig, sig)

    def test_verifier(self):
        with self.assertRaises(ValueError):
            verifier = RSAX931Verifier("bogus key data")
        with self.assertRaises(ValueError):
            verifier = RSAX931Verifier(RSAX931Test.privkey_data)

        verifier = RSAX931Verifier(RSAX931Test.pubkey_data)
        with self.assertRaises(ValueError):
            verifier.verify("")
        with self.assertRaises(ValueError):
            verifier.verify(RSAX931Test.hello_world_sig + b"junk")

        msg = verifier.verify(RSAX931Test.hello_world_sig)
        self.assertEqual(RSAX931Test.hello_world, msg)

    def test_find_libcrypto(self):
        """
        Test _find_libcrypto.
        """
        # Test supported systems.
        lib_path = _find_libcrypto()
        self.assertFalse(not lib_path)
        if sys.platform.startswith("win"):
            # For Microsoft Windows variants.
            self.assertEqual(lib_path, "libeay32")
        elif getattr(sys, "frozen", False) and salt.utils.platform.is_smartos():
            # For SmartOS.
            self.assertTrue(
                fnmatch.fnmatch(
                    lib_path,
                    os.path.join(os.path.dirname(sys.executable), "libcrypto*"),
                )
            )
        elif not lib_path:
            if salt.utils.platform.is_sunos():
                # For Solaris-like distributions.
                passed = False
                for i in (
                    "/opt/local/lib/libcrypto.so*",
                    "/opt/tools/lib/libcrypto.so*",
                ):
                    if fnmatch.fnmatch(lib_path, i):
                        passed = True
                        break
                self.assertTrue(passed)
            elif salt.utils.platform.is_aix():
                # For IBM AIX.
                if os.path.isdir("/opt/salt/lib"):
                    self.assertTrue(
                        fnmatch.fnmatch(lib_path, "/opt/salt/lib/libcrypto.so*")
                    )
                else:
                    self.assertTrue(
                        fnmatch.fnmatch(lib_path, "/opt/freeware/lib/libcrypto.so*")
                    )
        elif salt.utils.platform.is_darwin():
            # For Darwin distributions/macOS.
            passed = False
            for i in (
                "/usr/lib/libcrypto.*.dylib",
                "/usr/local/opt/openssl/lib/libcrypto.dylib",
                "/usr/local/opt/openssl@*/lib/libcrypto.dylib",
            ):
                if fnmatch.fnmatch(lib_path, i):
                    passed = True
                    break
            self.assertTrue(passed)
        # Test unsupported systems.
        with patch.object(sys, "platform", "unknown"), patch.object(
            glob, "glob", lambda a: []
        ), patch.object(ctypes.util, "find_library", lambda: None), self.assertRaises(
            OSError
        ):
            _find_libcrypto()

    def test_load_libcrypto(self):
        """
        Test _load_libcrypto.
        """
        lib = _load_libcrypto()
        self.assertTrue(isinstance(lib, ctypes.CDLL))
{'fraction_non_alphanumeric': 0.13030651892358613, 'fraction_numerical': 0.07662973089653187, 'mean_word_length': 1.9909619109102648, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6253516', 'n_tokens_mistral': 6563, 'n_tokens_neox': 6074, 'n_words': 572}