diff --git a/auto_dependency_updater.py b/auto_dependency_updater.py index 34af404..36f90c3 100644 --- a/auto_dependency_updater.py +++ b/auto_dependency_updater.py @@ -34,7 +34,6 @@ REQ_FILE_DEV = 'requirements-dev.txt' REQ_FILE_NET = 'requirements-relay.txt' -REQ_FILE_TAILS = 'requirements-relay-tails.txt' REQ_FILE_TCB = 'requirements.txt' persistent = False # When True, uses cached dependencies. @@ -329,8 +328,7 @@ def main() -> None: ARGON2_CFFI: Dependency(uid=ARGON2_CFFI, stylized_name='argon2-cffi', pip_name='argon2-cffi', sub_dependencies=[ARGON2_CFFI_BINDINGS], description_dict={REQ_FILE_DEV: 'Argon2 Password Hashing Function (Derives keys that protect persistent user data)', REQ_FILE_TCB: 'Argon2 Password Hashing Function (Derives keys that protect persistent user data)', - REQ_FILE_NET: 'Argon2 Password Hashing Function (Not needed but allows importing from src.common.crypto)', - REQ_FILE_TAILS: 'Argon2 Password Hashing Function (Not needed but allows importing from src.common.crypto)'}), + REQ_FILE_NET: 'Argon2 Password Hashing Function (Not needed but allows importing from src.common.crypto)'}), ARGON2_CFFI_BINDINGS: Dependency(uid=ARGON2_CFFI_BINDINGS, stylized_name='Argon2 CFFI Bindings', pip_name='argon2-cffi-bindings', sub_dependencies=[CFFI]), BLINKER: Dependency(uid=BLINKER, stylized_name='Blinker', pip_name='blinker', sub_dependencies=None), CERTIFI: Dependency(uid=CERTIFI, stylized_name='Certifi', pip_name='certifi', sub_dependencies=None), @@ -341,13 +339,11 @@ def main() -> None: CRYPTOGRAPHY: Dependency(uid=CRYPTOGRAPHY, stylized_name='cryptography', pip_name='cryptography', sub_dependencies=[CFFI], description_dict={REQ_FILE_DEV: 'cryptography (pyca) (Provides X448 key exchange)', REQ_FILE_TCB: 'cryptography (pyca) (Handles TCB-side X448 key exchange)', - REQ_FILE_NET: 'cryptography (pyca) (Handles URL token derivation)', - REQ_FILE_TAILS: 'cryptography (pyca) (Handles URL token derivation)'}), + REQ_FILE_NET: 'cryptography (pyca) (Handles URL token derivation and and derives TFC account from Onion Service private key))'}), EXECNET: Dependency(uid=EXECNET, stylized_name='execnet', pip_name='execnet', sub_dependencies=None, is_dev_dependency=True), FLASK: Dependency(uid=FLASK, stylized_name='Flask', pip_name='Flask', sub_dependencies=[BLINKER, CLICK, ITSDANGEROUS, JINJA2, WERKZEUG], description_dict={REQ_FILE_DEV: 'Flask (Onion Service web server that serves TFC public keys and ciphertexts to contacts)', - REQ_FILE_NET: 'Flask (Onion Service web server that serves TFC public keys and ciphertexts to contacts)', - REQ_FILE_TAILS: 'Flask (Onion Service web server that serves TFC public keys and ciphertexts to contacts)'}), + REQ_FILE_NET: 'Flask (Onion Service web server that serves TFC public keys and ciphertexts to contacts)'}), IDNA: Dependency(uid=IDNA, stylized_name='IDNA', pip_name='idna', sub_dependencies=None), INICONFIG: Dependency(uid=INICONFIG, stylized_name='iniconfig', pip_name='iniconfig', sub_dependencies=None, is_dev_dependency=True), ITSDANGEROUS: Dependency(uid=ITSDANGEROUS, stylized_name='ItsDangerous', pip_name='itsdangerous', sub_dependencies=None), @@ -368,17 +364,14 @@ def main() -> None: PYNACL: Dependency(uid=PYNACL, stylized_name='PyNaCl', pip_name='PyNaCl', sub_dependencies=[CFFI], description_dict={REQ_FILE_DEV: 'PyNaCl (pyca) (Handles TCB-side XChaCha20-Poly1305 symmetric encryption and Derives TFC account from Onion Service private key)', REQ_FILE_NET: 'PyNaCl (pyca) (Derives TFC account from Onion Service private key)', - REQ_FILE_TAILS: 'PyNaCl (pyca) (Derives TFC account from Onion Service private key)', REQ_FILE_TCB: 'PyNaCl (pyca) (Handles TCB-side XChaCha20-Poly1305 symmetric encryption)'}), PYSERIAL: Dependency(uid=PYSERIAL, stylized_name='pySerial', pip_name='pyserial', sub_dependencies=None, description_dict={REQ_FILE_DEV: 'pySerial (Connects the Source/Destination Computer to the Networked Computer)', REQ_FILE_NET: 'pySerial (Connects the Source/Destination Computer to the Networked Computer)', - REQ_FILE_TAILS: 'pySerial (Connects the Source/Destination Computer to the Networked Computer)', REQ_FILE_TCB: 'pySerial (Connects the Source/Destination Computer to the Networked Computer)'}), PYSOCKS: Dependency(uid=PYSOCKS, stylized_name='PySocks', pip_name='PySocks', sub_dependencies=None, description_dict={REQ_FILE_DEV: 'PySocks (Routes Requests library through SOCKS5 proxy making Onion Service connections possible)', - REQ_FILE_NET: 'PySocks (Routes Requests library through SOCKS5 proxy making Onion Service connections possible)', - REQ_FILE_TAILS: 'PySocks (Routes Requests library through SOCKS5 proxy making Onion Service connections possible)'}), + REQ_FILE_NET: 'PySocks (Routes Requests library through SOCKS5 proxy making Onion Service connections possible)'}), PYTEST: Dependency(uid=PYTEST, stylized_name='pytest', pip_name='pytest', sub_dependencies=[INICONFIG, PACKAGING, PLUGGY], description_dict={REQ_FILE_DEV: 'pytest (Test framework)'}, is_dev_dependency=True), PYTEST_COV: Dependency(uid=PYTEST_COV, stylized_name='pytest-cov', pip_name='pytest-cov', sub_dependencies=[COVERAGE, PYTEST], @@ -387,14 +380,12 @@ def main() -> None: description_dict={REQ_FILE_DEV: 'xdist (Pytest distributed testing plugin)'}, is_dev_dependency=True), REQUESTS: Dependency(uid=REQUESTS, stylized_name='Requests', pip_name='requests', sub_dependencies=[CERTIFI, CHARSET_NORMALIZER, IDNA, URLLIB3], description_dict={REQ_FILE_DEV: "Requests (Connects to the contact's Tor Onion Service)", - REQ_FILE_NET: "Requests (Connects to the contact's Tor Onion Service)", - REQ_FILE_TAILS: "Requests (Connects to the contact's Tor Onion Service)"}), + REQ_FILE_NET: "Requests (Connects to the contact's Tor Onion Service)"}), SETUPTOOLS: Dependency(uid=SETUPTOOLS, stylized_name='Setuptools', pip_name='setuptools', sub_dependencies=None), SNOWBALLSTEMMER: Dependency(uid=SNOWBALLSTEMMER, stylized_name='snowballstemmer', pip_name='snowballstemmer', sub_dependencies=None, is_dev_dependency=True), STEM: Dependency(uid=STEM, stylized_name='Stem', pip_name='stem', sub_dependencies=None, description_dict={REQ_FILE_DEV: 'Stem (Connects to Tor and manages Onion Services)', - REQ_FILE_NET: 'Stem (Connects to Tor and manages Onion Services)', - REQ_FILE_TAILS: 'Stem (Connects to Tor and manages Onion Services)'}), + REQ_FILE_NET: 'Stem (Connects to Tor and manages Onion Services)'}), TYPING_EXTENSIONS: Dependency(uid=TYPING_EXTENSIONS, stylized_name='Typing Extensions', pip_name='typing-extensions', sub_dependencies=None), URLLIB3: Dependency(uid=URLLIB3, stylized_name='urllib3', pip_name='urllib3', sub_dependencies=None), WERKZEUG: Dependency(uid=WERKZEUG, stylized_name='Werkzeug', pip_name='Werkzeug', sub_dependencies=None), @@ -430,18 +421,6 @@ def main() -> None: ARGON2_CFFI ]) - requirements_rt = RequirementsFile(file_name=REQ_FILE_TAILS, - dependency_dict=dependency_dict, - dependencies=[PYSERIAL, - # STEM, # Not needed ATM - PYSOCKS, - REQUESTS, - FLASK, - CRYPTOGRAPHY, - PYNACL, - ARGON2_CFFI - ]) - requirements_dev = RequirementsFile(file_name=REQ_FILE_DEV, dependency_dict=dependency_dict, dependencies=[ARGON2_CFFI, @@ -464,7 +443,6 @@ def main() -> None: requirements.generate_file() requirements_r.generate_file() - requirements_rt.generate_file() requirements_dev.generate_file() diff --git a/install.sh b/install.sh index 813c7e8..0db5b6e 100644 --- a/install.sh +++ b/install.sh @@ -180,10 +180,6 @@ dependency_hashes['werkzeug-3.0.1.tar.gz']='83bacda231cd714cf111ebcaf78b47f7e400 # as the dependency filename). tcb_packages=("pycparser" "cffi" "setuptools" "argon2_cffi_bindings" "argon2_cffi-" "PyNaCl" "cryptography" "pyserial") -requests_packages=("urllib3" "idna" "charset_normalizer" "certifi" "requests") -flask_packages=("werkzeug" "MarkupSafe" "Jinja2" "itsdangerous" "click" "blinker" "flask") -tails_packages=("pyserial" "PySocks" "pycparser" "cffi" "cryptography" "PyNaCl" "argon2_cffi_bindings" "argon2_cffi-") -tails_packages+=("${requests_packages[@]}" "${flask_packages[@]}") # ---------------------------------------------------------------------------------------- # TFC Source file verification @@ -217,8 +213,7 @@ function verify_files { compare_digest da5fad3d2dfcb2bb992df4af9ce5c7a792b489cf9f86f966610c2d5933536a8ff9f1be2ec2bf2cbc3eab46cd469ffba35a739eacd31dadb704a28f14cd75cefa '' LICENSE-3RD-PARTY compare_digest 55b954740233846aaed4360b5ec39e5fd52c3050541b221013fd62fe66e65f21c3ef3527dc97f3db1013a26768a9f2cc1400bf84bf4b26bb18f79c00e1f500f5 '' relay.py compare_digest 1dab82c7be5704162cf7c279e3472e573b39a1000d70407c9e7731ec767b5c394b6a8c20ebfe63b9a57176800807e66d4231891d6ffa6bf82f831ecacfe3ec9b '' requirements-dev.txt - compare_digest 6e967efe695a8e217981e5f3661c8e9ae23299538bc3509b5766921e54fbcf36fce1985cbfc32fb7f68900305c6bb5c13935eab992c933c7271abcc7abd419f6 '' requirements-relay.txt - compare_digest 88eb7830a88e16658ba0dd63e30599600595260899683191f716d474c7eae77a99b524edebb51320b78608d94d794030d57084acea583b6bed353245be3780ca '' requirements-relay-tails.txt + compare_digest 35de14ab7ba0fd91a15cce841c6f3276e9310b68a6fd1d0c895c93602472f104987036ebd639e3f74c31834ce7411653dd0449a144e113e24abee4409ef130f1 '' requirements-relay.txt compare_digest 0e66cb8609a0f9abc9ca0f76298593a076cd5c8b85abaa0d8b3b765d40a2599a4ea2d33fb4792a97dc5ceee3b71e1682715f71555d5502c87ea20da922d05a7f '' tfc.png compare_digest 14bbec9fce50ea69082724347d075ed81685b982743384a9690d7c95ae5c1655a35d01ec5b4d8e4ffeee91c37ef0e2c7ca3d79ea8578abb7c87c22b5d9fb9928 '' tfc.py compare_digest f9600e3e31075a53e009cec13474399f5553517f62fa2bcf9048987e47a5eb1b1c2443eadf14aea5ec7f4e67f4caa08809bc11ec8984a184a8c249bde1d2688a '' tfc.yml @@ -242,13 +237,13 @@ function verify_files { compare_digest 90218be097758a94ed60189393756682fa84cac0c025bd9c3c1f26bf21357800398ac505eb9f4b0f565ff3cfe52c48a0463a939a60e1e197a674d88cda314583 src/ __init__.py compare_digest 90218be097758a94ed60189393756682fa84cac0c025bd9c3c1f26bf21357800398ac505eb9f4b0f565ff3cfe52c48a0463a939a60e1e197a674d88cda314583 src/common/ __init__.py - compare_digest caa6efe18a89e570ed984613cf41026b635d7fee2c67ca6333122b3d9a1468aa1cbe8d89e30938b668181539ae3e23f0d68fccc248bb39f9ecf67097d58646bd src/common/ crypto.py + compare_digest aeb3f9b67de6ba4834910d67e1a74d1457ca1f31ca55488565ad8cb13c08bd5f9819759d17f47ed98f0300b56c98f1a7f13093433e8d316115ea4d0eaefbbebf src/common/ crypto.py compare_digest b18f02061b26b4bbfe2e6b7d073dc4f72b652756bcd7067509a2216e89ef41e9e3004541412e3dea00663a46b870d0423fa8040f2c1f613d8f32c649937f0b57 src/common/ database.py compare_digest e581b79859eb74096263732c84319260833bacc6d595b3592d61bf630271807c13896d2278724fd1d439c5d721d856c6b77f38d61e542bcd3c75828eb93d362f src/common/ db_contacts.py compare_digest b32d333356b53487761c6c7214f60ff526aff0f42cdce7eb7fe26f3d528d60ca97ed728e3deaa3d322e2c1d2460fb9f5bc8e8b7d5147f360362645a820f1ded1 src/common/ db_groups.py compare_digest 37bebfafaec2ca8d9e02ff2090092954f8fb07a4163d17c077c4c67958c97189babbc6cffb706440000c4ac1d78662bd52f088ab8dc6b29215077ef6a0af7a95 src/common/ db_keys.py compare_digest 9adb670eeac30cafcd95e64c5250cae5d7d3543cdb80e00ef8a71f3fc6b43547eb4b282b66e2483cd9905db99fc12ce2bdd8a2255dc8457cf8d589b0370f7770 src/common/ db_logs.py - compare_digest 5b22c434083e07f17a0bc8d5a8fae47ab774e244b98575541ea39fb0472c9a43a9a6e4286fb244209965394f7dad0bf57c34f360d4f7a24924a361aea505efea src/common/ db_masterkey.py + compare_digest 87b43ed3ca6d244a311e6344507c842327162851c0e32ad5e6d12bc4f770a32d148a3cf7c1b180c06f9ce0efa6d3135ff22bb7417d72d181ffefc1b928a94c30 src/common/ db_masterkey.py compare_digest 59cd5925a5727d796c516a038955965564d30b5fac529b069623d14fa43eb2cd344ed6b3688f42e7019483c12b587c21fcfc4875db273e6f959fb99c8c502029 src/common/ db_onion.py compare_digest a33144fe0650f30c50753178023169fdd77e9f23a94fc19e1bd3f555d216831f8752301524e63d90d2f89ee9ecb54fbdcdc52c47530466ee7a5182d4b1900f90 src/common/ db_settings.py compare_digest 9b67271611202da7bc112a460f53e96d9cd4e713407087a2a1ef1bf927a675ff8f51e65ce77168d325e599e59f4963c13d6e964464352011f27497e7783b3c5f src/common/ encoding.py @@ -266,7 +261,7 @@ function verify_files { compare_digest 6b3860213104873fbfd59917e4d52e31466696f3494ffbbd5edd4a8bccacfc72e3141b2c6779d52da7d393b501f03a40fb0d4e86270d65fd1129ad3d508ed98e src/receiver/ commands.py compare_digest b33c47f47ce37b7f3905ff99f690300cbd4b96e6b2d4b785f06361b47d9993e6a6740435e09313cfacd63650705e85eeb29c49706da369c2424205b9cdf44a45 src/receiver/ commands_g.py compare_digest 5838632327e7b3fdd5c5c17f3f2d75db7a62d75f7444b9d2bebda7b72ed3f48c82745d8aa78a74320f8f6c4e6d22b1228cab0a8c0dfb2fa1d642c8cc85ecfefd src/receiver/ files.py - compare_digest dfc94e6762f5c20af24aff902c039733d1c9cc89344d259de62e1acd768bfb3690401f1ebfd1c26e11346ee0b443d22d0f7029373100a9c4f08078b068b47ded src/receiver/ key_exchanges.py + compare_digest 2f2d9ecf366307c3c8bd9b18f8ad499452fae6bad9b8344ddc97e44c1ffebec9cc26fa6578206448cbf68cb33dd4546bb78121b30eb7c18eba572c0ac89eaa0d src/receiver/ key_exchanges.py compare_digest 92b4b00726e2722ca7e96178e5716e72a440ead63289a9acedb30784f7cdec410a8577ee71c5384fdb54c7a654ab09828f1713109ec2f167df9ae97fda9c2578 src/receiver/ messages.py compare_digest aa76be19d367c89f94884ddfcec88c76215628d2a12b815a7d9990e85d921c42885a60bd3dffd88b64b68a7a414a12e1ff2e8c5b6994df51576a1b31dd9b1b91 src/receiver/ output_loop.py compare_digest 0ec4241a996dce75009dc53783e06c500acdd55de45b11e191b1b1b0a41a896c9138299ef0ef5356370881249e7358d0a1a9e9d440883584603675cc3afa47ea src/receiver/ packet.py @@ -277,7 +272,7 @@ function verify_files { compare_digest d2336f5e6a5aa5c41c39f95b4fe6e1413e5a87ac305cb31916c58df130cff81a6952045942b63f1546c82d6d3b05c38e3d0c6ddd69428d239a9030d150bda562 src/relay/ client.py compare_digest a56aa18162a25b2fb665ec81b93745bd9aa8e2b5ef88f75a0984ef50ef2fb7d90cc2287c4e1ce54b2fcbca89f7a89e84024d58904c4d6c948fa356448466bc63 src/relay/ commands.py compare_digest a27e65526e0eb40319dd65a2739d94e2aae6c0d67eefc3885f54c8ebdd390d8331f8682aff56aea9911e94a24edecf28435011eed7713dbdca58a9e7f927bf22 src/relay/ diffs.py - compare_digest db49e1aefc5c25a93c86f442c6807498127373ffb7725103eb8183912fd0ac6f4097637ef2104ca1364f51f7454ba2cd232d560d2e73ba76ec8e43cc9e21e9af src/relay/ onion.py + compare_digest d3e2aa129e91c0048167dbce055c0fd14e4c71701bed84fed30783c2d79d94a01dcc3a1c1eb6476ef8cdaad33bed12c68c4bdfffefa3a27cb3be5f394a09ad51 src/relay/ onion.py compare_digest 49e838d7d5758cd94ff547fbebfe3a5de08bf5b2e1e7c35313d29c20ee24d258484996a11b36402de4113704efcf8fdec05db23a4ab774d5cfb7a4670f7f697b src/relay/ server.py compare_digest 0a702b1ef2be7f359b8f43e27ca917d39c36ecf47b98b57829b9d1729a9149e8543089ee332f67d0aece79fd16c12f563090d70ecc1203e355368fb80f5e508f src/relay/ tcb.py @@ -287,7 +282,7 @@ function verify_files { compare_digest e5fd8ab8978d38fe617606581783d0c9807dfcc8c95e0e31cd3a7d1ce6ad88d3f88ba49c070ec69743c11b8707a6cd1f4ea979f2dfe49621a095e910e14a82a8 src/transmitter/ contact.py compare_digest e14e407035e0b8342320f205d1b934c5f521ae2e86aaeb8fc6265572b0aed06e64fc86b0b96253efe45f4499b3ecd80c865e3424c5d2cf46d3e31f051232b8a9 src/transmitter/ files.py compare_digest ad73ffa1c20620a01cf846a73cf0f3d0dc786beaa3be00bb3996ca087ca1d8a960f962474989ccf096f98b94d73c65552e0905c8b697c9438ffbcb3fded235b9 src/transmitter/ input_loop.py - compare_digest 0a30f4e76bce2c9cff0511ea191e55060007f302b1b985083f6c56856893fa15a2d4e5bcf069ced0cee7e9e2c81d943838e124cfd3cd670fa732b1baff149726 src/transmitter/ key_exchanges.py + compare_digest 0bb0a0e4d51b001c12cf3135c916e34343e14f3075d210641e6d99914892af4a02a8e0652a9c81229ef6dbf746c7aca9f80331f1bc6a538bacda8dfcd25dc86e src/transmitter/ key_exchanges.py compare_digest de827c1be6adc2fc36c115eb1fee6670488cb9076b89d755d3b1edcc322321424e4b3c5e86d1e49ea1e26c75ea727765890f7aeffc88a7fa235f1359efa83d6b src/transmitter/ packet.py compare_digest 52e6332a949dc15be10699e5e156aea6ba1e4ac4bc10c2e8777474c627569b7e3ca79f79b1ed2e4799704ba94ea7aa653a85b891c35273e51170239d851de485 src/transmitter/ sender_loop.py compare_digest b4a0e38437caef8256fd46087b8bd85757b9c459684ba16b26fda80e3f7bb472dfe3cb0118c3831d08d5a96a40b97185144ad2e730cfb29492aab588a5db3e60 src/transmitter/ traffic_masking.py @@ -701,12 +696,10 @@ function install_relay_tails { read_sudo_pwd t_sudo apt update - t_sudo apt install libssl-dev python3-pip python3-virtualenv python3-tk -y || true # Ignore error in case packets can not be persistently installed + t_sudo apt install python3-tk -y || true # Ignore error in case packets can not be persistently installed create_user_data_dir - VENV_NAME="venv_relay" - torsocks git clone https://github.com/maqp/tfc.git "${HOME}/tfc" cd "${HOME}/tfc" git checkout development @@ -716,27 +709,11 @@ function install_relay_tails { verify_tcb_requirements_files verify_files - # Tails doesn't allow downloading over PIP to /opt/tfc, so we first download - # to $HOME, move the files to /opt/tfc, and then perform the hash verification - - # Install prerequisites before downloading other packages: This ensures pip accepts manylinux2014 wheels - - torsocks python3 -m pip download -r "${INSTALL_DIR}/requirements-relay-tails.txt" --require-hashes --no-deps --no-cache-dir -d "${HOME}/" - - verify_packages "${tails_packages[@]}" - - # Install Relay Program dependencies to virtualenv - t_sudo python3 -m virtualenv ${INSTALL_DIR}/${VENV_NAME} --system-site-packages --always-copy - . ${INSTALL_DIR}/${VENV_NAME}/bin/activate - install_to_venv "${tails_packages[@]}" - deactivate - t_sudo mv ${INSTALL_DIR}/tfc.png /usr/share/pixmaps/ t_sudo mv ${INSTALL_DIR}/launchers/TFC-RP-Tails.desktop /usr/share/applications/ t_sudo mv ${INSTALL_DIR}/tfc.yml /etc/onion-grater.d/ # Remove unnecessary files - remove_packages "${tails_packages[@]}" remove_common_files "t_sudo" t_sudo rm -r "${INSTALL_DIR}/src/receiver/" t_sudo rm -r "${INSTALL_DIR}/src/transmitter/" diff --git a/install.sh.asc b/install.sh.asc index dcc051c..71e2414 100644 --- a/install.sh.asc +++ b/install.sh.asc @@ -1,16 +1,16 @@ -----BEGIN PGP SIGNATURE----- -iQIzBAABCgAdFiEEbab1Q2VetFRTHbYIAsu63k/6kOYFAmYFZDIACgkQAsu63k/6 -kOarmQ/+NmRyIsNWhbskKLaz8Qw9cmF7PvhDKGecAQj7TfV7piR+Px9NAOspHzPr -db37QwMY7QE2KBwmEGos95FNVRvs9tWnBNbzbDtnk8HWf10CeeA0hIgEtWPtw7QF -Qr1+V1Y+PZcRT/JhCL0n5+CfgpUj5oqI4GevwuexYJDoFkBaRD/GNLzt20K0Cpso -s31S60KNeWep6ZUaWKoeEcI7J7YgiJNzDg3xP0bA0s21uEfkykBoLoQWGhWB0eIH -DthutRS1thgll1C86SDRMtxkYFhk/rxIC1ozv8xX6sKQA0UayIMIdr42oaS+GBGu -ivtLeY+5d7zPGi03nATa6daA6aglRyycQYoFqF2qPiNw89XRuufyBchY9qv+TCBZ -yw6pXoqYw1LJPWZjc/X7gQlUNywe/3GgfZ4C/dQjG6rg51C5WypjQA4RQUVdQoXs -qJGuFv/oll2UFbAGFcG2ylAkkrtpIiWYe9SVA4yaRz1EIeu01rDUOK4hR1MxvTo3 -21Il+kwZbwZXpPzNv8yELaHfIQQlfb8mvQmY9k5qUAw7WVl3iTT3qLbACkeClOkr -3BtcTZwUaxh9O2xy/QRUwFWJQy95zawtuAeHaEC8EVgAuoLbUuPEi9rTzMKZ3otX -XVW4p26crSI9cqp63BjK0Mj5rI3OBKmVljRz4wX8DhHk9VV1/Co= -=oFQK +iQIzBAABCgAdFiEEbab1Q2VetFRTHbYIAsu63k/6kOYFAmYMFqYACgkQAsu63k/6 +kOZkHw/+JGMh/27cbR037IfpUoDnXogGUEo+EDA8MW5r6maCIPHgmP8HtMIJp5rx +6WbsOtRmEp9JuCM3lVKNEih7dIbQiJHhQv8qUhK9nEywscanyuwULLm1qDgl4lwp +S/8+WidaMdCvWP91VWIa9/RGwP7pLR7MJoR1ZD1YFHv/mK8diWwoeCxSv54orvj6 +NWWHU2S85tanFuWKq5S+s3LHfHTfqiuvAedBIT7N6dKyYKr3/YGK0TfQB5c29D4o +m2ZEPL2Ynb3kY1a90xtqg/mfiLzdPEXp1FV4be+XDicHGWrD4Gv6pD1F2f4d4hZU +YcE/raXAXn6EYXDyXOmtliMWXUbGaF1EOaXkhWE9OpTvYmX+6qC/UBiV87MO2z6/ +wbdT4mQU99UuYdDH0clixGbuHt8NOY2+Cm+Di3wHzYHLmLhQc0eaIdpAUH/r/gxB +O5/qFP3ZH56+Y4SgNIZQS2BqUGke8+OLi7vAcaA57e9BUp/v3bVEEmeiJhAvoqGj +3ETA46GAYO6ITDGIqSoRK7jXmhFilAa6CHEHPs3w6C1yCzjJuP/CR9Fknj4lsofC +MWNo6TbKJ2wo0hIkCM8AkgoWDjRlrHE2TUF4vEkXJkUpoSQkkoRuZDQyk/hwqjte +aCITvtczzNzSR+15U5U2ccklUAcf0f3ICeKTiSedtfxuEkppnrQ= +=ib+n -----END PGP SIGNATURE----- diff --git a/requirements-relay-tails.txt b/requirements-relay-tails.txt deleted file mode 100755 index 07fdbca..0000000 --- a/requirements-relay-tails.txt +++ /dev/null @@ -1,157 +0,0 @@ -# Sub-dependencies are listed below dependencies - -# pySerial (Connects the Source/Destination Computer to the Networked Computer) -pyserial==3.5 --hash=sha512:29bce14c59e60f54ce476d919c9b9477190ef6bb44a6102f71345840f5c0f1d0a323c4c3c302c5f380bfaae32cf04142ee528b6dd7184f17789632a31d5ecab6 \ - --hash=sha512:c8df5e50d952d5a6dcf1d9253a6ba953e9763c545a867da66c22c90dfa015aba0194f2a8f29a229d0a5f4dc8bfeeaaab8bcfda4066ed78a18b151bc05e6ae327 - -# PySocks (Routes Requests library through SOCKS5 proxy making Onion Service connections possible) -PySocks==1.7.1 --hash=sha512:3e0b1775c14fe091d10e30b03f7f0c770861152e493cf3a3143b0de01aadbc73f684f0d4305f1a694932d4bdcac8056c422437130640e19028cd9fba59ff0b3f \ - --hash=sha512:313b954102231d038d52ab58f41e3642579be29f827135b8dd92c06acb362effcb0a7fd5f35de9273372b92d9fe29f38381ae44f8b41aa90d2564d6dd07ecd12 \ - --hash=sha512:cef4a5ce8c67fb485644696a23bf68a721db47f3211212de2d4431eaf9ebd26077dd5a06f6dfa7fde2dcb9d7c1ed551facd014e999929cb4d7b504972c464016 - -# Requests (Connects to the contact's Tor Onion Service) -requests==2.31.0 --hash=sha512:b795abb26ba2f04f1afcfb196f21f638014b26c8186f8f488f1c2d91e8e0220962fbd259dbc9c3875222eb47fc95c73fc0606aaa6602b9ebc524809c9ba3501f \ - --hash=sha512:ce50d64973752f4cf7f7c7c91401669854b55c66d7465bea3689772fae8a6b646cf6720d84a2984bbe6fd78fc8b9ce0aa377f291fb6d7c20c7c2a4be8193acdd -certifi==2024.2.2 --hash=sha512:7a3bd4849f95e1715fe2e99613df70a0fedd944a9bfde71a0fadb837fe62c3431c30da4f0b75c74de6f1a459f1fdf7cb62eaf404fdbe45e2d121e0b1021f1580 \ - --hash=sha512:2191710dc2cfdf781df498c3ecd5f38dfc5215e2c2dc402cdcd484376dbd7fe2e442793cc856e93f6033c1fc43cb77c71d2dc785dbfe0d8cd10fd3120ee3c2fd -charset-normalizer==2.1.1 --hash=sha512:fe2f3ae5d3c011b314a057456a7b13ba957593b22dbe7f532f9fbe077103e75b3f8b631fb1e2a4d5875a60af678b6779780eff7df0ea7c08144aa88fce34abc0 \ - --hash=sha512:f52abab683ebda4100d67ec6ee0349713baee453a742d60a1356f405c5ce2c3b4d850b0891527f08f92fa1217d59c46d6b181dc4ff1b962ce60d9c5ef8c913d1 -idna==3.6 --hash=sha512:0ec1ae5c928b4a0001a254c8598b746049406e1eed720bfafa94d4474078eff76bf6e032124e2d4df4619052836523af36162443c6d746487b387d2e3476e691 \ - --hash=sha512:8bea880d1b2fae1511f21381d73445f62e786c385eb949d2c39e611f71cb6f31f7e54927833a0f456e340857d384d960ab9e6ae31ac7481314254646de656cc0 -urllib3==2.2.1 --hash=sha512:82525e89629af701c2ce44ed6766c3b4c1f7b57ce0a3418342849dd4c13802b901b0942e7199d6e268ae03a14b67bc023bdc66fd827f4f50a3c4895271245c9d \ - --hash=sha512:dfadba099db678ee1567ee95aa11a72fcea0a76df094d04dd4bd7ed5df4ea2fda6917cc122a1e2bfa4f5303916f93a7e1c881fbbf3cbb9415a25bd7eca1b14b3 - -# Flask (Onion Service web server that serves TFC public keys and ciphertexts to contacts) -Flask==3.0.2 --hash=sha512:c817a1518315f0e9c733b0c08c66dcb95191029bfea649455f7e707a59f3f9104132962d498f408b4016e49dac634ffd9361c11039b6b85741b2c0b35cf38e54 \ - --hash=sha512:02f937dae7d654f6286eb9fcf2d68d83f3ef56dbc4d59a961ea1bd95d17fac7a5ace3f27ebb03ff0592f6a87361e59934ffda098714fc8a049a487d4c0bbc0ef -blinker==1.7.0 --hash=sha512:d7a15c140abe1ae1aab65d215748c2cab3f80c33ea31e3b5d7b3c44cd8d121b5084fe081e875e72f7cdfb85af987153288f55dc2ca0ee776dc93059fbb84df29 \ - --hash=sha512:b55dc104fd69bf9f682184202f9da7cb6925e7e863f38d5ad5b4b5988b2315aae02da6f4c9f0ec34238b8d5b9b6eec52b06258d93e14416cda3e2b718d9aa60c -click==8.1.7 --hash=sha512:687ea8c461196b234b0f0db0638ba213304b96bdeb9c9c6334a6cbd78f4e99da9e062bca2f449c88fd7a1de7ea2643e80c8ea571103dd4b2c50424a6fbd5d5e0 \ - --hash=sha512:c67146ad0112daf8ed4db62a6b0a0065109332eb8fa31962ce40d61e27e2736020a0cadfebdd1656e2f23c20291b069d3a409faffe999a0907e6dbdef77aa014 -itsdangerous==2.1.2 --hash=sha512:190df7f250b5e5985898a7f0e0e9d4c3d0b5c391268b9b5ad0f39667ec887b543651dff7623ba49e191ffadb42b0354b21be19ef61a1f68193924bf12034dd1d \ - --hash=sha512:e4d870a33992b309ed778f403c0c1e098983a693d1165260748bf36385ebfadb583811e05ddd48001a33cf6a4e963b7dd8a8c68919c5b4b86f63621d8869e259 -Jinja2==3.1.3 --hash=sha512:e3e2e6bd511dec484dd0292f4c46c55c88a885eabf15413d53edea2dd4a4dbae1571735b9424f78c0cd7f1082476a8259f31fd3f63990f726175470f636df2b3 \ - --hash=sha512:5c36d0cd094b40626511f30c561176c095c49ef4066c2752a9edc3e6feb2430dafa866c17deebddcd0168aa1f0fd3944916d592c5c999639b8152e7c1009c700 -MarkupSafe==2.1.5 --hash=sha512:f32cc6753cfaedeae6392e1f7fc8523ccbbdd996fa10636164004dba3d0d3ed80b8cccb1de3f6660c3114e8f83c260b7f92238b0a2a0bc48580ae00f4fb1f964 \ - --hash=sha512:46d4361fc36ed9f3c78b282eca731c3918c9cc3ed6a74b1dcdb74731075d63152bc5398d64691c08e79e9b7a21f7bb96bf20d7e4ee4feeb7c2dfddae0ea34d40 \ - --hash=sha512:bd0f8577d7909a1186671cf1a2f9f87d0af6597eee61e44c071a4f8d9dc51bda6cb40a8a3e328840b24ac86fbe9cd0ef8f06ec78d08b4ce764194512e0fa0634 \ - --hash=sha512:689c416c3ef1624f97d4213375ee20966cd800d9540d114323c4adafa4e3e5a2e63bae89c8f948d2e940d9bf29f485c8143e25da2a5eef130ef39a039bc5d9af \ - --hash=sha512:ca60491527e5b2da3ac3adc9ede4d68c64f7d70e1e6f7d061d6a7bf285aba3e5e2c8543dbb9f0203df4503c81b5d53559f1098abe5433f0fc8cabc8b737cc130 \ - --hash=sha512:ec77e3fcb4bf013af838bd3d67ffaf42f614705798c415a89af121326e6107943264059df97a41806036a8e6d70b894c8cdaf49ef8d8060263b61408c5102c61 \ - --hash=sha512:2d138f2261ccec4e009a71d5900d18eddb61875ef9851c63ed3e644ba3c0b5dbd3fd3ef77c39605c43a5b6bf28e5fe9614342e7bf4ed7cff03913187d5ad6017 \ - --hash=sha512:a1dfb9d014e5ac5a6523a3d4751a0d8458d6a3ceeb87aba13d303eface5b6428d62d8c989c74397aecf597545405ac1d1378308057ba1274cca0a436054a8819 \ - --hash=sha512:ccb5a63f69e5681b3eea5646dd6b163241e890d4ea502c29ca782265ef2322428213de5c1dfa37adcb328af24430c22ed49cc2ee2a96e8ead416bc7a569683f6 \ - --hash=sha512:6698232b96e1dafa8c1905b393952f6ab132bbb72bc10b0dbc567abcfcd30205bfc59c6fd9ab66e4c4f28e82f7cc3e871537b086b035dfb46ea1160e2b26cfc2 \ - --hash=sha512:efb08c3eaf132e8d10e3f8a01ff80bd0bc36ac7eec078cf99f9065a9bc4cb7e4b53c9ade1a2ad46b786c26a31662f38c4d70da2c53533c8c5759c8d439c3bc66 \ - --hash=sha512:eeef56f202babb0174ff72a65239d806a1a6070873f94dbf939443df60c259bb403aae2afee7f2e9f199ee9b8bb0e91f5e95ca9029b33730d88cf53457c36674 \ - --hash=sha512:0447b1b39d8eaacbe0bc023ef7a5f0fc304b4b562940cafe150670c7cd8be6c11c23fbd831b9a9f3645e3e085f1662e20b2f2c7114bde23aeaf4b55e9ca6f8d9 \ - --hash=sha512:77bd99171babb05f0b4d8c45936dfc91f9c2c0ab4a7e9215b6788800a13befca9256cf56422a0125f51a8e53928dac66ddc3077e655dfb3a2fc185c3f7646db4 \ - --hash=sha512:7667f36657612cf81f273608c2e5861e0cc412ec5af3ab2a080547a7b97d1670d5caf15aca23d0a2653f01157a9849e5435662f833cca868fe83c51cb17746ac \ - --hash=sha512:386f9624fe79c40e9e548323d00f2bac16c5d58914afba24a5ba94024fc15a4e531a3203f077fbb3517a6a2c4b3570caed701520933216ecd67c3721415e860e \ - --hash=sha512:270353f556509467e6183d1c440015f72e0712cb9e3420981aa7e48d09cfa8666966568bbc6530fcbecd73864714cf1bdc52948e2950c565d6b50eeb1d677f75 \ - --hash=sha512:ec755a40cb7427da58dac02ada8f2cefec4a38902140ccfba0bb663f4f4cf54eacf411b9fbbeabb5ad690c4f1140ab38a1d58fd80961adddc04bede32d65dd8d \ - --hash=sha512:7e0d8d5e85790cefa7b56b5924523a8dda606a0cfd1e9efa2fc67ab13c2eaaa5b4e8e15a45dfbc9dd7759b1f87dc1d13fc35557bf0f9dd38e4c09e039b018aa0 \ - --hash=sha512:e620c9ea18dde478e6d449803e511d7c0db079d3093063fa383bc498618ecd618edd3518f1408762d5262f4663a85d3f5aaefb9408da2c440182281678f6222a \ - --hash=sha512:81b67d2e236dfba6661aa9f06a0f11e64f2a598d3c3a80b1678eb207b856edb18372dca8d62fa419eb717339c1147fb53bbcfb4b06d8df281c0890020ffb2bfc \ - --hash=sha512:34392033b008945424d81bb0a2b201c853e3b743dc4b4ad2270903c2a031e36a59518767ceb724ae540c9b03c502c6956f8af048e4a6c1be55428a7cb0676539 \ - --hash=sha512:94233c5f239525bba1c584da6a3bd54c7a9c3d99f6f40affb32484d93d89eed9b6c2eaba522b0388c1fed5405354abccc4a48a8522188ceb1055be1799bce42d \ - --hash=sha512:ffed1823a6bcff917670c25aa7d249179899ecc9651f2e303a626d1a8e10ea189cb1875dd73bb190914bc2714574e9fa73f62d881f07522e7a50a485a6d71be6 \ - --hash=sha512:54c049098b67a7ab0876f37196d6e76f5702caedb282fb76224b472a27e48c9d3d68f841a9a45514090a55a28d3f94135ea60bcd440a5c27357ea5cc44391176 \ - --hash=sha512:9a51bca810984054d198d4081262be66fb3d05f8356772bc27a01a580d82f0552542a8b18e41e7cd9e6aff2b2065dddf103f0ad87b851b2d36c7459c926e856e \ - --hash=sha512:54e954e982df1ec116d1ae58e432c36935b582aa6e13e13645916428b918abfb5475d31c8be6308fe04bdad139b0e08667896e26ca909b242b0f104c959b2661 \ - --hash=sha512:3e409b8b9642620925066423c44eb38dbe1ef35c842c39a6e19c0dce620181395effc195ce8a3e5717c76d554a0dfcb0838965358b7190d98ac576ef475e25a5 \ - --hash=sha512:1eb79d3a71d25372dac4b11827986f01d11618baddad7145efda13cc1acccc8e2c7967c4c51fbadbd57e7c93818ac32405721b2d94bd7e3cb519b0cf5ec47423 \ - --hash=sha512:e09fafdcdcfdb7025b1fa803cba5ee04ff7ae8eb599b8d69deb6b37f958f92627b6b2e9e4de30fb338f65eb1a123e1de15afeaa75e0d8dfe0081482d303b11be \ - --hash=sha512:8a1f91b4f7ffc97332ba757cfbf4bd6d9190235854711b70250c0b0535d6025ed08b5fb5dfbd6288b0c50f04ecfe42ffd9c7d1829bab8bdce26ebf105e95059c \ - --hash=sha512:1a882d8ff38682ffc5cef0d0e29a01a1f012da22c4a4a12872c812459ceb62bef496aa5debfd68d53e9069ba0d5a33ba58f9d071e0a89cbf568df8eb0343ea8f \ - --hash=sha512:74c0871ec5ccd70bf4d84cca9f17d36ab3279253a1aadc2e6d8c349c4e381b63eccdc19152028ce26a9f03d58ea61b65780a41460b094b584585ae1708034562 \ - --hash=sha512:913f2a486f2d553a998a7adb836acffa89e3adff031abdb8964638a0a45f8257e90f50678668d624425fe743796c6d272c9b5eb1fcabbdf823aae97b4f303fc0 \ - --hash=sha512:1f1306cd2b0eb0931e12900e489180d455e62646079c9fc8c0d4a53fcb592466fa71674fb0da627d617d4e7c37c65b0243248a5ac8b6fd120b6e8e903821b558 \ - --hash=sha512:7f4b54cf745603eb15883a76e8c978a6684f1b585e119af300e52434171d2c2411bbb0731d3d6454a0ae410de1134544163961e0fb1765bfc220afcabfb1fac4 \ - --hash=sha512:3ba5af43d23c266377f5d32b11e1faa7955ea8c67eb1c32886c308527f93e75e387294d0eec7794c0c20aad0c705b27f3d1f86b04202f3b63068d12d4053cc71 -Werkzeug==3.0.1 --hash=sha512:56cfbfb2d084bf6ab08305f204647abbd2d66074770e1ade45515216d759e6dfeafd51d743801f2291b6befe670b5b3eaa59bdae736be8942611315f7abd105d \ - --hash=sha512:83bacda231cd714cf111ebcaf78b47f7e400cefbaf4a450bde99b630136c2976a2e7629a3a34140493c5f54c2ea1c034c673085dd7d1fd7ce8f1da49d8576bb8 - -# cryptography (pyca) (Handles URL token derivation) -cryptography==42.0.5 --hash=sha512:fd840cb0f6c49078d2484fd2ff75a2c62c6ae58b69a01be0885a7bd088067e5f39f9e0de582e0a824525f7bbfe4d6e5831fe176f40fb01101df3f9a41e3ab14e \ - --hash=sha512:615d99cedb543228cc45a49bde24883e920426cd32c964471149fcb994a74b8ca3edb00d1addd52d19c19d7689f9b978cd10f54ac6ca70368da9dc40c28625fe \ - --hash=sha512:8b98785ff25b2fe0745d867e7055b54bf2ace5a21f9b42eda99c5a5fbd5bb4a6e74bedd6a3cf39c179570b351503ee0e7e937a04e1451f22a4fa0d69dac1f2cf \ - --hash=sha512:8f084fff47efe264edd9101915ea31e1e16cba949b7a0d3be3e72632fd656e5989794c0ef02645192beb3c51be0ab0a3184c554355e241e5060bb1b255cb0983 \ - --hash=sha512:687f042d3470af3c6f1e64584a691d9aecff8c589de2a9ae7dc8f7a5738ea76785976ecbc345b838d3023c0cb033476ac86d8d06ecde5ce855ab3a78b465c17a \ - --hash=sha512:2a57528ef4e99daf9956823e994cad12d687e78088b7c10b3e694a859ac70cd66a86e02003f0d1120e75be19a28f299bfc87f590a2157099eb7ad95de8728d2d \ - --hash=sha512:70a54c0660561f898d715cd289be93a52082fcd986d0acbfb2af73cca703661116df34a108cf85da66e3ea1b8fd98e1c8af4f173fd487f54f3a8b840d11d9ccb \ - --hash=sha512:9d180b8749ec2682a868a3f062ed8bec0a6ac4483d23200c50afab4613e167be1e8faddaaad5c841fcc3f06e8c9a5fffd6a33527861c0b1115a624d4961f9cbd \ - --hash=sha512:49b2ba4241bb10ac9a3bca74ccff586abf83d10b2ec641ac9b4d53b334dac60135d6b3ee1bdb300997a3dac78d61abf099ab264d55f152999311588b2a213efb \ - --hash=sha512:0e5dbf32cae786fdcd855c6c065e0ced23de25eb8a667c620d7f2dab9549cb72fa08cc2a2795454d14dfb273a5f0dab4341155dc413cec9049bf2fa5d76f398d \ - --hash=sha512:cd3639bc392ebd062870c90f55ce527d39b354d0e6421d7ef9ead9ce4bfb28eddf3bf8685f9681ed7f23ec0f983f000dfc34b5d6349e825682633306bf29623d \ - --hash=sha512:4b87fe7d1a1f81a3778da62c466f35d763d359b59e79dfc26e971e18ddf4d5d8febfa927d1a7a4a20bcbcf3db8b94ffa73b0aa8e2a8950a1c7d4899f9c95d8a6 \ - --hash=sha512:f5149920cc429e841ec88cca9c68cece82172f2a74788b1ce0924b45308df5aa92920c09ec5c93335beb37ddedd09b18444664ee0879a9a72fc432554b8d5e26 \ - --hash=sha512:2ee854f1ad3fecd81d2fe2418a7ac804d8e257929f973d8fdba88b8a93362590906eec44ca6e54f9c2173b1d645b2024792f2802320bcb21d7ea7423cdcdd833 \ - --hash=sha512:e4ba05cd1f7fe2486dd2041ec2ef31b9642b1d17300025eda181413a1ad7af8d5a1daf4cd45a2a236191e591d74b51c2a63217a737eab680dd09efa8122be5bf \ - --hash=sha512:04805984237fbf618d6d87321432840701ce0bbc1fd7ff65664487faec8724398fccbd8c01ac5c5764e4ac1bc5206325320c6cda74f3ca3045e8739487ea779b \ - --hash=sha512:3b416b5c915890a8bbe75aaada1c032710dfadd352895effd7e0412ad2e2b91b3b0af087a6dd94af415394506e2598adc9f9deb8ab3820c3d0c21d5048670af1 \ - --hash=sha512:a4b10e9a9665e83434e9035b56542234fbfa07cba85d351a910ad2e81cedd9cab27497d34bf58bb3995d22ef6118438635e881418f58fca5d326b3d3495e890c \ - --hash=sha512:c8b8fae59303afef81daf85381596e366b60e1d5d499b6001c078bea669b1373fba37aca20a3617c54461f6797a1c655707fdee23cffb7aae8c1d6208dcff894 \ - --hash=sha512:2b5b7a9667fc85c691fc107ba8b32ff8931ee6ee4c34e15784b1882d21c7fb2650d63825f1bdf14626dafe671f67e7816c79a5a8c6b7f1366f20f24ee6f32bd8 \ - --hash=sha512:5524fd230b55580a2c647a0a78197a783e201fdfa8b3177b72c6d7b689afd76a689e4fe3593120d3adb7ee5cc4adf9211e8deedc8fab355e9ed70076db09f68b -cffi==1.16.0 --hash=sha512:47fc17ba58e9fc2e7829a4c028a0a067f0d2c9a23dec886674fb69098645bfa6e9a67a0a78439216e420b8f63be98818cd6dcd07fd270279385b9c3787710223 \ - --hash=sha512:e76d186d948fa47d5747c116f165fd788e808f40a043ac6bac9a0cecb4d353c1138ca4e2050ddc73c21119b254935a8097a2006f37391ccf525612c305b77dfd \ - --hash=sha512:c303d9ff3a67f7b6765eafcf0e296456673916a3c4cf4a04c40153c783cf93b380cca78298b0de6b79ba1ad53bf79798887af0cb208ffd34d3bac5528e04fb51 \ - --hash=sha512:38d62fd917816afa5795c1ff68810bda9e197e9b17f351075e03a11d0d84369093a39e0b690e1ae6d933578f90c0f8573f9640e43f9160a7431d854045ad79ef \ - --hash=sha512:4b6336b34388197360186916b81988e7421d78be4ade5d2a1b0ce19b7a19ce64d2831111ecd89a9e549b4ae4e01a46e146bd2675122c68f4ce92d4e5f865fcbb \ - --hash=sha512:e0410aa181003dce4ce74a2674450089fda1d954c3eea2ca6852bf32e45e9b1fad7173e67448d448cdc06d3c333e2572fd2ccd0b0d79bc819df452abd5ee9e08 \ - --hash=sha512:f7e5df0d9f9ae2f8621d123c3f1a88f491d42d3491560ae7dcb372da06fc9de8b9f7634c256ad1cba77c04c96d61965ab6418a39c8ce17a52a916de28edbfebc \ - --hash=sha512:1faf3db5a6078c51b7b674feeed46f507a94fc0acfba6ad7a8e97bcfac5be653873388725fe9ca95481bc465449f692d9044ed76a86fb7eef1e114dd127f268a \ - --hash=sha512:20be55a756e84c738a854fa017354095d43990db3f2343397f992415f892ba5ed1fbccae829093bfb2f6d1bd6dbe3761a978a705f833e80385fb92d05f7814a0 \ - --hash=sha512:c2a5fbad7ad536cb72af44d1e9c6c9f77ac69ad527f0a3c8473c587e9dfba462cc23e36135c82ba742190b291f8d78d3568cf0fdcf1c0afb43f8eb225e7dbe2a \ - --hash=sha512:3b1844eb7be44b411014a5728850037b65509e0e17c4583ca31b9b49194396c4053d10ed0c13ffb02bb2913bea422c4a7df9a60d5a51b68a3805ee77e3e36736 \ - --hash=sha512:24fb9a6d2d4d236cfa1a34ce965b199d487a41c333c7814240e5d5cd59dedc59f3a859922079fe68494827f9570f6e0d2fdbda77d6a224bae9912e3016ff73c4 \ - --hash=sha512:8d0ebb1c616c4c5a7c925101974ade3aef21f673c65ee5325276e0956e7469d93e5eb3a1678c81d5a024629274bdccf662c16cb6f8d1a6212aa82f999a3b9428 \ - --hash=sha512:24ab3223045e3ac04e63647f7ae521d7a654408e8857f36a98565a12e2503c1a08af6a97dac974bee61cc80bea1a702cefe44c1da1ab127132e37ce2a5151801 \ - --hash=sha512:13b4ee8013c3768f41f4f1578b40f36c6b5a4ea2402cb2a212229989d9f3129cc0f191c55c81cea54a8bfe4350fc925a767eddf9b223841435f78b596b4dab89 \ - --hash=sha512:a421becd6cb04f593543c7ad322d431621f4daa0369bf61ebd4fff9329610078df1b5e7374af11e7923eaf72b02e358b35d37bc59d9ce7f800698243ac9ef05e \ - --hash=sha512:35e793f9593208ae347f0470bea29177136da8ec9e146110fa4de1e933a231ba8cf41baf7aa14a4a716e57da17cf1abf2b8bcceb6def065871a63c307476c53d \ - --hash=sha512:860229f8a400e26fe119a40995da0dec53c6b5ae92c12eb8e7439792e5489f54634a87a7f6b501f9c0b28e92923beddb982e210315cfa9ed14678be3ac75bbf8 \ - --hash=sha512:72119121fd6e047f0e494dbd2155dff87cbbbb97e95ee91e5d5c38d7309495890e9f588de9fb1d7fd277527df38f4752ac946eaf54a43ebe41dff9747b88315f \ - --hash=sha512:445d4eb5a1ce0a97dba362d53856bbecf9a2b134c49fc04c3310756c429c094ee080d926f5dfb6302fb6cd057c2066a20636a192acb173bd430cedfabcbed105 \ - --hash=sha512:59aa1acabeec0e87c8ba93da669d33ff1012197b8dd11c504287e67da0501420e5394c007b69a6bc327c35378ced73e62a10203d70ba917b585fec8197afe554 \ - --hash=sha512:dad6c5b9a2199d3a14e1cafd6c36b92f3d4dbdbc8189db37025e44bfb2977908a8470e8f9a2896d37e5376aa4d9b3e29888562caeea3edd608c9c782868c17ae \ - --hash=sha512:81634c38dd4bb2f2be5c239017b89ec8c4dedba2ef2765536673f2b4f666b96fc593406d462d0a8df92b25cde5fe00e7e724f1485a9c4a4b7a968c4c1ce04644 \ - --hash=sha512:bdfa1f8eea7f876ff4e8433a11ad622c6abbc5022a9602a9ed219e5b7e6fc7992b12afcf50e9fc1cfa2a3e21ccf34c64c92a796bb0ff9471ab7e0a28dea52a44 \ - --hash=sha512:083782300fad3c0be0aec6a0eb8d589c25d18a67227c09346f64bdc69b9e41b672ea444d071be82bb7c3fcdeaafdd2959191e4606438cbabc4d566ee5254c0a1 \ - --hash=sha512:2c849efac9a228c5d005bd575c99c1b83289e3a1602baf1fd853d19ff2f25ef4f5536b38837dc76ab416dc3105ee9c4bbbbb6b660ff4a0333a2f0ef2cc7fd0ba \ - --hash=sha512:8193c0d306f0212d0fbbe44510b2fed7a4abc74409d6f28a87b481ff475f2e00b006bde4fcd28b0fa5c8535e015a9e16337ace0259f72c6df4d8cb9979976b9b \ - --hash=sha512:e081ee7ae2b49b2704b1d525e6b4c5f53fcca831ddf690a6d47078071525abc5e5c32300b2b76d54e2042f8f299fac0a988474d6e96cab7f8d03b1b46558581a \ - --hash=sha512:36688299733808953d17daabac798b2b2d143c122ef5355b18068d80c9402b275ca9f65e1082762684269e9c5780ed74b42369db17778492ba1d716742d90153 \ - --hash=sha512:4bbcdd72eb1856516c6235421f1562190e1333349686a079b2ec80ee6a02c370cadcb6b1e0d38fa6fb126368e90dd1b5f9712a92a1fa595a98f471ab2c8486da \ - --hash=sha512:5dc5ef04aa1b2ef2da537a932b8c11b49ee5e57c6ad214e6bddaef9a61b66a93952cc9f30b805da2c3c028fe58ea11cc25a56bb7fe2b116e7b9349dcc6075b5a \ - --hash=sha512:e6d8ff3fe823c4d99dc88877e626a9428d554d671d476826bae7117a123074eaae3d42d1f16e7b94bb601ef781c22791e742319f8a9a82599184c23045412da6 \ - --hash=sha512:fd2588115092202aa9289c9d4e0a0b3e264b5e9ec1dc192950f31aeb412fd9f9d4e5c96a3f9c6762987b58ccc1e229f2012ddda89211797104df672d8ed51152 -pycparser==2.21 --hash=sha512:aae67923f45abd1d781d03e0ce848627a07e9cf4c61a89bf32f1b5f638ceda08de39a038c46ed29d2df967d76be4f2572346bad087ac32b418e6fe654fd28e43 \ - --hash=sha512:e61fbdde484d1cf74d4b27bdde40cf2da4b7028ca8ecd37c83d77473dab707d457321aecaf97da3b114c1d58a4eb200290b76f9c958044b57e5fed949895b5f0 - -# PyNaCl (pyca) (Derives TFC account from Onion Service private key) -PyNaCl==1.5.0 --hash=sha512:853446c38ce5488e18eba166f67650bc4f50044f509987ad2ae4830d2ed85284f057c3a4304180ad265bc33fb9cd6570488a37e40bade5e202ba201ad368af84 \ - --hash=sha512:d3f24397a6a3a7a56652a56c8e8cfcb1ebc167b0d2dfc38c450d8fbc363b2b5c1226e58724a692b16a7e4f1022bb93e904664ff54640bba28720134058e2275f \ - --hash=sha512:c3502047add3590c1a1e60908e21d62455e2b4ba2f2efaf0f5118bf915934de9604d00036b3215ed54890a51a088872909409b296141d6241159c119d751a947 \ - --hash=sha512:01d38ba9cdebf0cc658b187a753f63065cea29ca757296cc1d40da4c2609b8cf96a1df1af7bb75bec61af767cee4ac6a20aa858ba060b4c61807800e57e53fe4 \ - --hash=sha512:61e07a421705e5c1613cbc888ff594d7e3457090e9654280f2b6e54a84e5d6dcd56292fd3c47b86a59be6eecafa8f17ad5d710f45b7fcda9f57d9c7343328bc2 \ - --hash=sha512:9720cfe64e70667804c197a1762db2985bf5893ae774418f50da9a3d31135b8935fd497c5fe4f92909f6e0ac70e3c5dd57f6322ab780d29b12741c64c0d2c007 \ - --hash=sha512:cea3e4556432588630382abae6debf9203c7f55da286509da547a7921e4dbad98c915743625c68e5f7187fcaf6d4cdaf7ed2ed3ba60bd4c10ae6e3f88608dc65 - -# Argon2 Password Hashing Function (Not needed but allows importing from src.common.crypto) -argon2-cffi==23.1.0 --hash=sha512:f0d80298b5617e8ed7ae7442f582caeeb3a5450562af18df4d7b5bd7395cfa99597f5ba31128d3105ee498e6661a50fa34602df374103ea523a2d7e832d7b7d6 \ - --hash=sha512:7c7730451f5ef9bb40bb5e1bbfa6e69c9718968168f3fa9b54e1020a4f805f98fba6260039bda804241717db2338479d640c7652dc26ce1a6ade076660133383 -argon2-cffi-bindings==21.2.0 --hash=sha512:c3218d723db5c8f2dbc9c737a3ce24d52291a8056b855c6e988956821894b695f2afd50b189a581e9cb5a5d1c13b9b1144be9fb6296a62681b209412caf85b42 \ - --hash=sha512:7a77d7e0becc167b7b348b19d5fc65e25fea4dd93a8e26c203b39f88691515a756a78becfb665a4aa965112a9b561be6c4461fe38db422fe20198b3139d652ff \ - --hash=sha512:1bd48d7a11cb99cc0d8526b2dc156e025002092d1f7c60632a0470275ade2374d3be6138ecf924eae2c33fb5d29fef16729b710294cc0b8f35f50a7544d17cc5 \ - --hash=sha512:c1f3ede9138689922619a240242a9d11aaf5942058c896be8ddce517d3ebf386767804e93d9dc4055ad04c682560764e9020c87f96f0d949a36e758025d09fe1 \ - --hash=sha512:ddb220ba4de3b61cefb657776d64ea0351e89b1f6e2eb04664e024f3e0dc46f1cdb11159b79f8cb9d0530c3dbc4bcfb9d89234fff567d53b06e0564ffa46afea \ - --hash=sha512:96c611449056eccf03f2e2cb5f8b6353ddd9f852c607f2fc6cda5f13bf8f8d554f2679b6c221b2114ff0b3ae5cb9ba841a7fc1affde840f5dcda65eb9c319d83 \ - --hash=sha512:7097f92df079b66b1d59b699523e2a87f2864e1e3c59bc2a4c71cf5657e6f3b094c62e626009602d1c44f07b5e1f2fc79ab03e916475cde07b6b6c6494e7388d \ - --hash=sha512:d8556d123fb96046837c6eb9205cb9fdb817f5ec6aa482f9f6ded77a3e67f1b49a21e1273acc0fcbaed7f4bf46b34fd555ec085ffc9a2daea1345186444f7c7c \ - --hash=sha512:8940ebaa9466f7810e385d0721042ae9c117480cc659436cd903b5c37af02fd9c9dce8d5ed95fb45ef7305777445cdb8fb00c82671bd577e1eeaf81f2691ae8d \ - --hash=sha512:9c77fbaecb073de920ed570cb7c7956a04c904e7e9616badde275791048a487fcd7e85eb6bf79d3f6bba6fdbc398e32cc208bda8fe368a84897b8d35da8e6bbd \ - --hash=sha512:74f931f3262333e3451295075abbfe0c323beadad36ffe73b65143e906f1e8cab924601a56a3f184ca2516fedcb69dc7d8dc6ea1d0ba25bccb21476a89bc46d8 \ - --hash=sha512:740c76d800bf8bea95f800457ef03d4125b262d034e4a62e66615144a8abe35950b37fe5627553e5bc448ffe32f77ebeee5e2a04857409f53604fb30de7d8d72 \ - --hash=sha512:71d023ae96073ed78599e4f4e42f8efcc985cc329adeea00b14b54eaac1e6a545e6ad9b7f4cfdc60a4e9c396f95053c0ccb6f6f67d92f70265f91315fff4a390 diff --git a/requirements-relay.txt b/requirements-relay.txt index bbfbb15..7a99ff8 100755 --- a/requirements-relay.txt +++ b/requirements-relay.txt @@ -75,7 +75,7 @@ MarkupSafe==2.1.5 --hash=sha512:f32cc6753cfaedeae6392e1f7fc8523ccbbd Werkzeug==3.0.1 --hash=sha512:56cfbfb2d084bf6ab08305f204647abbd2d66074770e1ade45515216d759e6dfeafd51d743801f2291b6befe670b5b3eaa59bdae736be8942611315f7abd105d \ --hash=sha512:83bacda231cd714cf111ebcaf78b47f7e400cefbaf4a450bde99b630136c2976a2e7629a3a34140493c5f54c2ea1c034c673085dd7d1fd7ce8f1da49d8576bb8 -# cryptography (pyca) (Handles URL token derivation) +# cryptography (pyca) (Handles URL token derivation and derives TFC account from Onion Service private key) cryptography==42.0.5 --hash=sha512:fd840cb0f6c49078d2484fd2ff75a2c62c6ae58b69a01be0885a7bd088067e5f39f9e0de582e0a824525f7bbfe4d6e5831fe176f40fb01101df3f9a41e3ab14e \ --hash=sha512:615d99cedb543228cc45a49bde24883e920426cd32c964471149fcb994a74b8ca3edb00d1addd52d19c19d7689f9b978cd10f54ac6ca70368da9dc40c28625fe \ --hash=sha512:8b98785ff25b2fe0745d867e7055b54bf2ace5a21f9b42eda99c5a5fbd5bb4a6e74bedd6a3cf39c179570b351503ee0e7e937a04e1451f22a4fa0d69dac1f2cf \ diff --git a/src/common/crypto.py b/src/common/crypto.py index e1e210a..95c074d 100755 --- a/src/common/crypto.py +++ b/src/common/crypto.py @@ -36,7 +36,6 @@ import hashlib import os -import argon2 import nacl.bindings import nacl.exceptions import nacl.secret @@ -50,7 +49,7 @@ from src.common.exceptions import CriticalError from src.common.misc import separate_header -from src.common.statics import (ARGON2_SALT_LENGTH, BITS_PER_BYTE, BLAKE2_DIGEST_LENGTH, BLAKE2_DIGEST_LENGTH_MAX, +from src.common.statics import (BITS_PER_BYTE, BLAKE2_DIGEST_LENGTH, BLAKE2_DIGEST_LENGTH_MAX, BLAKE2_DIGEST_LENGTH_MIN, FINGERPRINT, FINGERPRINT_LENGTH, MESSAGE_KEY, HEADER_KEY, PADDING_LENGTH, SYMMETRIC_KEY_LENGTH, TFC_PUBLIC_KEY_LENGTH, X448_SHARED_SECRET_LENGTH, XCHACHA20_NONCE_LENGTH) @@ -138,106 +137,6 @@ def blake2b(message: bytes, # Message to hash return digest -def argon2_kdf(password: str, # Password to derive the key from - salt: bytes, # Salt to derive the key from - time_cost: int, # Number of iterations - memory_cost: int, # Amount of memory to use (in bytes) - parallelism: int # Number of threads to use - ) -> bytes: # The derived key - """Derive an encryption key from password and salt using Argon2id. - - Argon2 is a password hashing function designed by Alex Biryukov, - Daniel Dinu, and Dmitry Khovratovich from the University of - Luxembourg. The algorithm is the winner of the 2015 Password Hashing - Competition (PHC). - - For more details, see - https://password-hashing.net/ - https://en.wikipedia.org/wiki/Argon2 - - The reasons for using Argon2 in TFC include - - o PBKDF2 and bcrypt are not memory-hard, thus they are weak - against massively parallel computing attacks with - FPGAs/GPUs/ASICs.[1; p.2] - - o scrypt is very complex as it "combines two independent - cryptographic primitives (the SHA256 hash function, and - the Salsa20/8 core operation), and four generic operations - (HMAC, PBKDF2, Block-Mix, and ROMix)."[2; p.10] - Furthermore, scrypt is "vulnerable to trivial time-memory - trade-off (TMTO) attacks that allows compact implementations - with the same energy cost."[1; p.2] - - o Out of all the PHC finalists, only Catena and Argon2i offer - complete cache-timing resistance by using data-independent - memory access. Catena does not support parallelism[2; p.49], - thus if it later turns out TFC needs stronger protection from - cache-timing attacks, the selection of Argon2 (that always - supports parallelism) is ideal, as switching from Argon2id - to Argon2i is trivial. - - o More secure algorithms such as the Balloon hash function[3] do - not have robust implementations. - - The purpose of Argon2 is to stretch a password into a 256-bit key. - Argon2 features a slow, memory-hard hash function that consumes - computational resources of an attacker that attempts a dictionary - or a brute force attack. - - The function also takes a salt (256-bit random value in this case) - that prevents rainbow-table attacks, and forces each attack to take - place against an individual (physically compromised) TFC-endpoint, - or PSK transmission media. - - The Argon2 version used is the Argon2id, that is the current - recommendation of the draft RFC[4]. Argon2id uses data-independent - memory access for the first half of the first iteration, and - data-dependent memory access for the rest. This provides a lot of - protection against TMTO attacks which is great because most of the - expected attacks are against physically compromised data storage - devices where the encrypted data is at rest. - Argon2id also adds some security against side-channel attacks - that malicious code injected to the Destination Computer might - perform. Considering these two attacks, Argon2id is the most secure - choice. - - The correctness of the Argon2id implementation[5] is tested by TFC - unit tests. The testing is done by comparing the output of the - argon2_cffi library with the output of the Argon2 reference - command-line utility under randomized input parameters. - - [1] https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf - [2] https://password-hashing.net/submissions/specs/Catena-v5.pdf - [3] https://crypto.stanford.edu/balloon/ - [4] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-12#section-7.4 - [5] https://github.com/P-H-C/phc-winner-argon2 - https://github.com/hynek/argon2_cffi - """ - if len(salt) != ARGON2_SALT_LENGTH: - raise CriticalError(f"Invalid salt length ({len(salt)} bytes).") - - try: - key = argon2.low_level.hash_secret_raw(secret=password.encode(), - salt=salt, - time_cost=time_cost, - memory_cost=memory_cost, - parallelism=parallelism, - hash_len=SYMMETRIC_KEY_LENGTH, - type=argon2.Type.ID) # type: bytes - - except argon2.exceptions.Argon2Error as e: - raise CriticalError(str(e)) - - if not isinstance(key, bytes): - raise CriticalError(f"Argon2 returned an invalid type ({type(key)}) key.") - - if len(key) != SYMMETRIC_KEY_LENGTH: - raise CriticalError(f"Derived an invalid length key from password ({len(key)} bytes).") - - return key - - class X448(object): """\ X448 is the Diffie-Hellman function for Curve448-Goldilocks, a diff --git a/src/common/crypto_phf.py b/src/common/crypto_phf.py new file mode 100644 index 0000000..8e3de07 --- /dev/null +++ b/src/common/crypto_phf.py @@ -0,0 +1,104 @@ +import argon2 + +from src.common.exceptions import CriticalError +from src.common.statics import ARGON2_SALT_LENGTH, SYMMETRIC_KEY_LENGTH + + +def argon2_kdf(password: str, # Password to derive the key from + salt: bytes, # Salt to derive the key from + time_cost: int, # Number of iterations + memory_cost: int, # Amount of memory to use (in bytes) + parallelism: int # Number of threads to use + ) -> bytes: # The derived key + """Derive an encryption key from password and salt using Argon2id. + + Argon2 is a password hashing function designed by Alex Biryukov, + Daniel Dinu, and Dmitry Khovratovich from the University of + Luxembourg. The algorithm is the winner of the 2015 Password Hashing + Competition (PHC). + + For more details, see + https://password-hashing.net/ + https://en.wikipedia.org/wiki/Argon2 + + The reasons for using Argon2 in TFC include + + o PBKDF2 and bcrypt are not memory-hard, thus they are weak + against massively parallel computing attacks with + FPGAs/GPUs/ASICs.[1; p.2] + + o scrypt is very complex as it "combines two independent + cryptographic primitives (the SHA256 hash function, and + the Salsa20/8 core operation), and four generic operations + (HMAC, PBKDF2, Block-Mix, and ROMix)."[2; p.10] + Furthermore, scrypt is "vulnerable to trivial time-memory + trade-off (TMTO) attacks that allows compact implementations + with the same energy cost."[1; p.2] + + o Out of all the PHC finalists, only Catena and Argon2i offer + complete cache-timing resistance by using data-independent + memory access. Catena does not support parallelism[2; p.49], + thus if it later turns out TFC needs stronger protection from + cache-timing attacks, the selection of Argon2 (that always + supports parallelism) is ideal, as switching from Argon2id + to Argon2i is trivial. + + o More secure algorithms such as the Balloon hash function[3] do + not have robust implementations. + + The purpose of Argon2 is to stretch a password into a 256-bit key. + Argon2 features a slow, memory-hard hash function that consumes + computational resources of an attacker that attempts a dictionary + or a brute force attack. + + The function also takes a salt (256-bit random value in this case) + that prevents rainbow-table attacks, and forces each attack to take + place against an individual (physically compromised) TFC-endpoint, + or PSK transmission media. + + The Argon2 version used is the Argon2id, that is the current + recommendation of the draft RFC[4]. Argon2id uses data-independent + memory access for the first half of the first iteration, and + data-dependent memory access for the rest. This provides a lot of + protection against TMTO attacks which is great because most of the + expected attacks are against physically compromised data storage + devices where the encrypted data is at rest. + Argon2id also adds some security against side-channel attacks + that malicious code injected to the Destination Computer might + perform. Considering these two attacks, Argon2id is the most secure + choice. + + The correctness of the Argon2id implementation[5] is tested by TFC + unit tests. The testing is done by comparing the output of the + argon2_cffi library with the output of the Argon2 reference + command-line utility under randomized input parameters. + + [1] https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf + [2] https://password-hashing.net/submissions/specs/Catena-v5.pdf + [3] https://crypto.stanford.edu/balloon/ + [4] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-12#section-7.4 + [5] https://github.com/P-H-C/phc-winner-argon2 + https://github.com/hynek/argon2_cffi + """ + if len(salt) != ARGON2_SALT_LENGTH: + raise CriticalError(f"Invalid salt length ({len(salt)} bytes).") + + try: + key = argon2.low_level.hash_secret_raw(secret=password.encode(), + salt=salt, + time_cost=time_cost, + memory_cost=memory_cost, + parallelism=parallelism, + hash_len=SYMMETRIC_KEY_LENGTH, + type=argon2.Type.ID) # type: bytes + + except argon2.exceptions.Argon2Error as e: + raise CriticalError(str(e)) + + if not isinstance(key, bytes): + raise CriticalError(f"Argon2 returned an invalid type ({type(key)}) key.") + + if len(key) != SYMMETRIC_KEY_LENGTH: + raise CriticalError(f"Derived an invalid length key from password ({len(key)} bytes).") + + return key diff --git a/src/common/db_masterkey.py b/src/common/db_masterkey.py index fc1cf24..d7d0973 100755 --- a/src/common/db_masterkey.py +++ b/src/common/db_masterkey.py @@ -27,7 +27,8 @@ from typing import Optional, Tuple -from src.common.crypto import argon2_kdf, blake2b, csprng +from src.common.crypto import blake2b, csprng +from src.common.crypto_phf import argon2_kdf from src.common.database import TFCUnencryptedDatabase from src.common.encoding import bytes_to_int, int_to_bytes from src.common.exceptions import CriticalError, graceful_exit, SoftError diff --git a/src/receiver/key_exchanges.py b/src/receiver/key_exchanges.py index 9b1974c..6283353 100755 --- a/src/receiver/key_exchanges.py +++ b/src/receiver/key_exchanges.py @@ -32,7 +32,8 @@ import nacl.exceptions -from src.common.crypto import argon2_kdf, auth_and_decrypt, blake2b, csprng +from src.common.crypto import auth_and_decrypt, blake2b, csprng +from src.common.crypto_phf import argon2_kdf from src.common.db_masterkey import MasterKey from src.common.encoding import b58encode, bytes_to_str, pub_key_to_short_address from src.common.exceptions import SoftError diff --git a/src/relay/onion.py b/src/relay/onion.py index d7b5b36..fe78a6f 100755 --- a/src/relay/onion.py +++ b/src/relay/onion.py @@ -31,7 +31,7 @@ from typing import Any, Dict, Optional, Union -import nacl.signing +from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey import stem.control import stem.process @@ -201,7 +201,7 @@ def onion_service(queues: Dict[bytes, 'Queue[Any]'], test_run: bool) -> None: time.sleep(0.1) private_key, c_code = queues[ONION_KEY_QUEUE].get() - public_key_user = bytes(nacl.signing.SigningKey(seed=private_key).verify_key) + public_key_user = Ed25519PrivateKey.from_private_bytes(private_key).public_key().public_bytes_raw() onion_addr_user = pub_key_to_onion_address(public_key_user) buffer_key = hashlib.blake2b(BUFFER_KEY, key=private_key, digest_size=SYMMETRIC_KEY_LENGTH).digest() diff --git a/src/transmitter/key_exchanges.py b/src/transmitter/key_exchanges.py index ad3d104..64bc3c4 100755 --- a/src/transmitter/key_exchanges.py +++ b/src/transmitter/key_exchanges.py @@ -25,7 +25,8 @@ from typing import Any, Dict -from src.common.crypto import argon2_kdf, blake2b, csprng, encrypt_and_sign, X448 +from src.common.crypto import blake2b, csprng, encrypt_and_sign, X448 +from src.common.crypto_phf import argon2_kdf from src.common.db_masterkey import MasterKey from src.common.encoding import bool_to_bytes, int_to_bytes, pub_key_to_short_address, str_to_bytes, b58encode from src.common.exceptions import SoftError diff --git a/tests/common/test_crypto.py b/tests/common/test_crypto.py index 9bd1ec7..ee3c6dd 100755 --- a/tests/common/test_crypto.py +++ b/tests/common/test_crypto.py @@ -20,18 +20,14 @@ """ import hashlib -import multiprocessing import os -import random import subprocess import unittest -from string import ascii_letters, digits from unittest import mock from unittest.mock import MagicMock from typing import Callable -import argon2 import nacl.exceptions import nacl.public import nacl.utils @@ -39,10 +35,9 @@ from cryptography.hazmat.primitives.asymmetric.x448 import X448PrivateKey from cryptography.hazmat.primitives.serialization import Encoding, NoEncryption, PrivateFormat -from src.common.crypto import (argon2_kdf, auth_and_decrypt, blake2b, byte_padding, check_kernel_version, csprng, +from src.common.crypto import (auth_and_decrypt, blake2b, byte_padding, check_kernel_version, csprng, encrypt_and_sign, rm_padding_bytes, X448) -from src.common.statics import (ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM, ARGON2_MIN_TIME_COST, - ARGON2_SALT_LENGTH, BLAKE2_DIGEST_LENGTH, BLAKE2_DIGEST_LENGTH_MAX, +from src.common.statics import (BLAKE2_DIGEST_LENGTH, BLAKE2_DIGEST_LENGTH_MAX, BLAKE2_DIGEST_LENGTH_MIN, BLAKE2_KEY_LENGTH_MAX, BLAKE2_PERSON_LENGTH_MAX, BLAKE2_SALT_LENGTH_MAX, PADDING_LENGTH, SYMMETRIC_KEY_LENGTH, TFC_PRIVATE_KEY_LENGTH, TFC_PUBLIC_KEY_LENGTH, XCHACHA20_NONCE_LENGTH) @@ -169,156 +164,6 @@ def test_invalid_size_blake2b_digest_raises_critical_error(self, mock_blake2b: M mock_blake2b.assert_called() -class TestArgon2KDF(unittest.TestCase): - """\ - Similar to normal cryptographic hash functions, a password hashing - function such as the Argon2 also generates unpredictable values - (secret keys in this case). The IETF test vectors[1] require - parameters (e.g. the "Secret" and the "Associated data" fields) that - the argon2_cffi library does not provide. The only available option - is to generate the test vectors dynamically. - To do that, this test downloads and compiles the command-line - utility[2] for the reference implementation of Argon2. Next, the - test compiles and runs the command-line utility's tests. It then - generates random (but valid) input parameters, and compares the - output of the argon2_cffi library to the output of the command-line - utility under those input parameters. - - [1] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-09#section-5.3 - [2] https://github.com/P-H-C/phc-winner-argon2#command-line-utility - """ - - def setUp(self) -> None: - """Pre-test actions.""" - self.unit_test_dir = cd_unit_test() - self.number_of_tests = 256 - - file_url = 'https://github.com/P-H-C/phc-winner-argon2/archive/master.zip' - file_name = 'phc-winner-argon2-master.zip' - - # Download the Argon2 command-line utility. - subprocess.Popen(f'wget {file_url} -O {file_name}', shell=True).wait() - - # Verify the SHA256 hash of the zip-file containing the command-line utility. - with open(file_name, 'rb') as f: - file_data = f.read() - self.assertEqual('c13017dcbc3239fbcd35ef3cf8949f4c052817ad5ce8195b59110f401479ad14', - hashlib.sha256(file_data).hexdigest()) - - # Unzip, compile, and test the command-line utility. - subprocess.Popen(f'unzip {file_name}', shell=True).wait() - os.chdir('phc-winner-argon2-master/') - subprocess.Popen(f'/usr/bin/make', shell=True).wait() - subprocess.Popen('/usr/bin/make test', shell=True).wait() - - def tearDown(self) -> None: - """Post-test actions.""" - os.chdir('..') - cleanup(self.unit_test_dir) - - def test_argon2_cffi_using_the_official_command_line_utility(self) -> None: - - # Command-line utility's parameter limits. - min_password_length = 1 - max_password_length = 127 - min_salt_length = 8 - min_parallelism = 1 - max_parallelism = multiprocessing.cpu_count() - min_time_cost = 1 - min_memory_cost = 7 - min_key_length = 4 - - # Arbitrary limits set for the test. - max_salt_length = 128 - max_time_cost = 3 - max_memory_cost = 15 - max_key_length = 64 - - sys_rand = random.SystemRandom() - - for _ in range(self.number_of_tests): - - # Generate random parameters for the test. - len_password = sys_rand.randint(min_password_length, max_password_length) - len_salt = sys_rand.randint(min_salt_length, max_salt_length) - parallelism = sys_rand.randint(min_parallelism, max_parallelism) - time_cost = sys_rand.randint(min_time_cost, max_time_cost) - memory_cost = sys_rand.randint(min_memory_cost, max_memory_cost) - key_length = sys_rand.randint(min_key_length, max_key_length) - - password = ''.join([sys_rand.choice(ascii_letters + digits) for _ in range(len_password)]) - salt = ''.join([sys_rand.choice(ascii_letters + digits) for _ in range(len_salt)]) - - # Generate a key test vector using the command-line utility. - output = subprocess.check_output( - f'echo -n "{password}" | ./argon2 {salt} ' - f'-t {time_cost} ' - f'-m {memory_cost} ' - f'-p {parallelism} ' - f'-l {key_length} ' - f'-id', - shell=True).decode() # type: str - - key_test_vector = output.split('\n')[4].split('\t')[-1] - - # Generate a key using the argon2_cffi library. - purported_key = argon2.low_level.hash_secret_raw(secret=password.encode(), - salt=salt.encode(), - time_cost=time_cost, - memory_cost=2**memory_cost, - parallelism=parallelism, - hash_len=key_length, - type=argon2.Type.ID).hex() - - self.assertEqual(purported_key, key_test_vector) - - -class TestArgon2Wrapper(unittest.TestCase): - - def setUp(self) -> None: - """Pre-test actions.""" - self.salt = os.urandom(ARGON2_SALT_LENGTH) - self.password = 'password' - - def test_invalid_length_salt_raises_critical_error(self) -> None: - invalid_salts = [salt_length * b'a' for salt_length in [0, ARGON2_SALT_LENGTH-1, - ARGON2_SALT_LENGTH+1, 1000]] - for invalid_salt in invalid_salts: - with self.assertRaises(SystemExit): - argon2_kdf(self.password, invalid_salt, - ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) - - @mock.patch("argon2.low_level.hash_secret_raw", MagicMock(side_effect=[SYMMETRIC_KEY_LENGTH*'a'])) - def test_invalid_type_key_from_argon2_raises_critical_error(self) -> None: - with self.assertRaises(SystemExit): - argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) - - @mock.patch("argon2.low_level.hash_secret_raw", MagicMock(side_effect=[(SYMMETRIC_KEY_LENGTH-1)*b'a', - (SYMMETRIC_KEY_LENGTH+1)*b'a'])) - def test_invalid_size_key_from_argon2_raises_critical_error(self) -> None: - with self.assertRaises(SystemExit): - argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) - with self.assertRaises(SystemExit): - argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) - - def test_too_small_time_cost_raises_critical_error(self) -> None: - with self.assertRaises(SystemExit): - argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST-1, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) - - def test_too_small_memory_cost_raises_critical_error(self) -> None: - with self.assertRaises(SystemExit): - argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST-1, ARGON2_MIN_PARALLELISM) - - def test_too_small_parallelism_raises_critical_error(self) -> None: - with self.assertRaises(SystemExit): - argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM-1) - - def test_argon2_kdf_key_type_and_length(self) -> None: - key = argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) - self.assertIsInstance(key, bytes) - self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH) - - class TestX448(unittest.TestCase): """\ Again, since the X448 output (shared secret) is an unpredictable diff --git a/tests/common/test_crypto_phf.py b/tests/common/test_crypto_phf.py new file mode 100644 index 0000000..bbc898e --- /dev/null +++ b/tests/common/test_crypto_phf.py @@ -0,0 +1,167 @@ +import hashlib +import multiprocessing +import os +import random +import subprocess +import unittest +from string import ascii_letters, digits +from unittest import mock +from unittest.mock import MagicMock + +import argon2 + +from src.common.crypto_phf import argon2_kdf +from src.common.statics import ARGON2_SALT_LENGTH, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM, \ + SYMMETRIC_KEY_LENGTH + +from tests.utils import cd_unit_test, cleanup + + +class TestArgon2KDF(unittest.TestCase): + """\ + Similar to normal cryptographic hash functions, a password hashing + function such as the Argon2 also generates unpredictable values + (secret keys in this case). The IETF test vectors[1] require + parameters (e.g. the "Secret" and the "Associated data" fields) that + the argon2_cffi library does not provide. The only available option + is to generate the test vectors dynamically. + To do that, this test downloads and compiles the command-line + utility[2] for the reference implementation of Argon2. Next, the + test compiles and runs the command-line utility's tests. It then + generates random (but valid) input parameters, and compares the + output of the argon2_cffi library to the output of the command-line + utility under those input parameters. + + [1] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-09#section-5.3 + [2] https://github.com/P-H-C/phc-winner-argon2#command-line-utility + """ + + def setUp(self) -> None: + """Pre-test actions.""" + self.unit_test_dir = cd_unit_test() + self.number_of_tests = 256 + + file_url = 'https://github.com/P-H-C/phc-winner-argon2/archive/master.zip' + file_name = 'phc-winner-argon2-master.zip' + + # Download the Argon2 command-line utility. + subprocess.Popen(f'wget {file_url} -O {file_name}', shell=True).wait() + + # Verify the SHA256 hash of the zip-file containing the command-line utility. + with open(file_name, 'rb') as f: + file_data = f.read() + self.assertEqual('c13017dcbc3239fbcd35ef3cf8949f4c052817ad5ce8195b59110f401479ad14', + hashlib.sha256(file_data).hexdigest()) + + # Unzip, compile, and test the command-line utility. + subprocess.Popen(f'unzip {file_name}', shell=True).wait() + os.chdir('phc-winner-argon2-master/') + subprocess.Popen(f'/usr/bin/make', shell=True).wait() + subprocess.Popen('/usr/bin/make test', shell=True).wait() + + def tearDown(self) -> None: + """Post-test actions.""" + os.chdir('..') + cleanup(self.unit_test_dir) + + def test_argon2_cffi_using_the_official_command_line_utility(self) -> None: + + # Command-line utility's parameter limits. + min_password_length = 1 + max_password_length = 127 + min_salt_length = 8 + min_parallelism = 1 + max_parallelism = multiprocessing.cpu_count() + min_time_cost = 1 + min_memory_cost = 7 + min_key_length = 4 + + # Arbitrary limits set for the test. + max_salt_length = 128 + max_time_cost = 3 + max_memory_cost = 15 + max_key_length = 64 + + sys_rand = random.SystemRandom() + + for _ in range(self.number_of_tests): + + # Generate random parameters for the test. + len_password = sys_rand.randint(min_password_length, max_password_length) + len_salt = sys_rand.randint(min_salt_length, max_salt_length) + parallelism = sys_rand.randint(min_parallelism, max_parallelism) + time_cost = sys_rand.randint(min_time_cost, max_time_cost) + memory_cost = sys_rand.randint(min_memory_cost, max_memory_cost) + key_length = sys_rand.randint(min_key_length, max_key_length) + + password = ''.join([sys_rand.choice(ascii_letters + digits) for _ in range(len_password)]) + salt = ''.join([sys_rand.choice(ascii_letters + digits) for _ in range(len_salt)]) + + # Generate a key test vector using the command-line utility. + output = subprocess.check_output( + f'echo -n "{password}" | ./argon2 {salt} ' + f'-t {time_cost} ' + f'-m {memory_cost} ' + f'-p {parallelism} ' + f'-l {key_length} ' + f'-id', + shell=True).decode() # type: str + + key_test_vector = output.split('\n')[4].split('\t')[-1] + + # Generate a key using the argon2_cffi library. + purported_key = argon2.low_level.hash_secret_raw(secret=password.encode(), + salt=salt.encode(), + time_cost=time_cost, + memory_cost=2**memory_cost, + parallelism=parallelism, + hash_len=key_length, + type=argon2.Type.ID).hex() + + self.assertEqual(purported_key, key_test_vector) + + +class TestArgon2Wrapper(unittest.TestCase): + + def setUp(self) -> None: + """Pre-test actions.""" + self.salt = os.urandom(ARGON2_SALT_LENGTH) + self.password = 'password' + + def test_invalid_length_salt_raises_critical_error(self) -> None: + invalid_salts = [salt_length * b'a' for salt_length in [0, ARGON2_SALT_LENGTH-1, + ARGON2_SALT_LENGTH+1, 1000]] + for invalid_salt in invalid_salts: + with self.assertRaises(SystemExit): + argon2_kdf(self.password, invalid_salt, + ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) + + @mock.patch("argon2.low_level.hash_secret_raw", MagicMock(side_effect=[SYMMETRIC_KEY_LENGTH*'a'])) + def test_invalid_type_key_from_argon2_raises_critical_error(self) -> None: + with self.assertRaises(SystemExit): + argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) + + @mock.patch("argon2.low_level.hash_secret_raw", MagicMock(side_effect=[(SYMMETRIC_KEY_LENGTH-1)*b'a', + (SYMMETRIC_KEY_LENGTH+1)*b'a'])) + def test_invalid_size_key_from_argon2_raises_critical_error(self) -> None: + with self.assertRaises(SystemExit): + argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) + with self.assertRaises(SystemExit): + argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) + + def test_too_small_time_cost_raises_critical_error(self) -> None: + with self.assertRaises(SystemExit): + argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST-1, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) + + def test_too_small_memory_cost_raises_critical_error(self) -> None: + with self.assertRaises(SystemExit): + argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST-1, ARGON2_MIN_PARALLELISM) + + def test_too_small_parallelism_raises_critical_error(self) -> None: + with self.assertRaises(SystemExit): + argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM-1) + + def test_argon2_kdf_key_type_and_length(self) -> None: + key = argon2_kdf(self.password, self.salt, ARGON2_MIN_TIME_COST, ARGON2_MIN_MEMORY_COST, ARGON2_MIN_PARALLELISM) + self.assertIsInstance(key, bytes) + self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH) diff --git a/tests/receiver/test_key_exchanges.py b/tests/receiver/test_key_exchanges.py index 2f1dc43..adceb9f 100755 --- a/tests/receiver/test_key_exchanges.py +++ b/tests/receiver/test_key_exchanges.py @@ -30,7 +30,8 @@ from unittest.mock import MagicMock from typing import Any -from src.common.crypto import argon2_kdf, encrypt_and_sign +from src.common.crypto import encrypt_and_sign +from src.common.crypto_phf import argon2_kdf from src.common.encoding import b58encode, str_to_bytes from src.common.exceptions import SoftError from src.common.statics import (ARGON2_SALT_LENGTH, BOLD_ON, CLEAR_ENTIRE_SCREEN, CONFIRM_CODE_LENGTH,