Refactored some code, added better documentation

This commit is contained in:
thecookingsenpai 2024-02-06 16:11:05 +01:00
parent c0ec66f63b
commit a370ae66c3
15 changed files with 111 additions and 29 deletions

9
.trunk/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
*out
*logs
*actions
*notifications
*tools
plugins
user_trunk.yaml
user.yaml
tmp

View File

@ -0,0 +1,2 @@
[settings]
profile=black

View File

@ -0,0 +1,10 @@
# Autoformatter friendly markdownlint config (all formatting rules disabled)
default: true
blank_lines: false
bullet: false
html: false
indentation: false
line_length: false
spaces: false
url: false
whitespace: false

View File

@ -0,0 +1,7 @@
enable=all
source-path=SCRIPTDIR
disable=SC2154
# If you're having issues with shellcheck following source, disable the errors via:
# disable=SC1090
# disable=SC1091

View File

@ -0,0 +1,10 @@
rules:
quoted-strings:
required: only-when-needed
extra-allowed: ["{|}"]
empty-values:
forbid-in-block-mappings: true
forbid-in-flow-mappings: true
key-duplicates: {}
octal-values:
forbid-implicit-octal: true

5
.trunk/configs/ruff.toml Normal file
View File

@ -0,0 +1,5 @@
# Generic, formatter-friendly config.
select = ["B", "D3", "E", "F"]
# Never enforce `E501` (line length violations). This should be handled by formatters.
ignore = ["E501"]

42
.trunk/trunk.yaml Normal file
View File

@ -0,0 +1,42 @@
# This file controls the behavior of Trunk: https://docs.trunk.io/cli
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
version: 0.1
cli:
version: 1.19.0
# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
plugins:
sources:
- id: trunk
ref: v1.4.2
uri: https://github.com/trunk-io/plugins
# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
runtimes:
enabled:
- go@1.21.0
- node@18.12.1
- python@3.10.8
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
lint:
disabled:
- bandit
enabled:
- black@24.1.0
- checkov@3.1.70
- git-diff-check
- isort@5.13.2
- markdownlint@0.38.0
- osv-scanner@1.6.1
- prettier@3.2.4
- ruff@0.1.14
- shellcheck@0.9.0
- shfmt@3.6.0
- trivy@0.48.3
- trufflehog@3.64.0
- yamllint@1.33.0
actions:
disabled:
- trunk-announce
- trunk-check-pre-push
- trunk-fmt-pre-commit
enabled:
- trunk-upgrade-available

View File

@ -15,15 +15,7 @@ if not os.path.isfile(filepath):
print("File not found") print("File not found")
sys.exit(1) sys.exit(1)
hmacrypt.self_encrypt_file(filepath, filepath + ".enc")
# FIXME Do the below operations in chunks print("Encrypted file: " + filepath + ".enc")
hmacrypt.self_decrypt_file(filepath + ".enc", filepath + ".dec.png")
print("Decrypted file: " + filepath + ".dec.png")
# Read the file
with open(filepath, "rb") as f:
filebytes = f.read()
encodedbytes = hmacrypt.self_encrypt(filebytes, encoded=True)
# Write the file
with open(filepath + ".enc", "wb") as f:
f.write(encodedbytes)

View File

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
cd bins cd bins || exit
./first_run ./first_run

View File

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
cd routines cd routines || exit
./1_hmac_secret_enumerate > .device ./1_hmac_secret_enumerate > .device
./2_hmac_secret_enroll ../.keyfile ./2_hmac_secret_enroll ../.keyfile
cd .. cd ..

View File

@ -2,4 +2,4 @@
echo "Please note: the secret will be shown here and will NOT be saved. You MUST have your hardware key or equivalent to regenerate the secret. Saving your secret locally defeat the whole purpose of this tool." echo "Please note: the secret will be shown here and will NOT be saved. You MUST have your hardware key or equivalent to regenerate the secret. Saving your secret locally defeat the whole purpose of this tool."
echo "--" echo "--"
fido2-hmac-secret generate -f $1 fido2-hmac-secret generate -f "$1"

View File

@ -1,3 +1,4 @@
#!/bin/bash #!/bin/bash
# trunk-ignore(shellcheck/SC2312)
HIDEVICE=$(fido2-hmac-secret enumerate | awk -F"dev" '{print $2}' | awk -F" " '{print $1}') HIDEVICE=$(fido2-hmac-secret enumerate | awk -F"dev" '{print $2}' | awk -F" " '{print $1}')
echo $HIDEVICE echo "${HIDEVICE}"

View File

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
HIDEV=$(cat .device) HIDEV=$(cat .device)
echo "Please press the button or use the hardware key when prompted (usually AFTER setting your passphrase)" echo "Please press the button or use the hardware key when prompted (usually AFTER setting your passphrase)"
fido2-hmac-secret enrol -d /dev$HIDEV -f $1 fido2-hmac-secret enrol -d /dev"${HIDEV}" -f "$1"

View File

@ -1,7 +1,7 @@
from src.libs.seedable_rsa import generate_key, encrypt, decrypt from src.libs.seedable_rsa import generate_key, encrypt, decrypt
import subprocess import subprocess
# INFO This method is the core of the whole process as it derives a RSA keypair from the stored secret and the hardware key
def inferKeys(hidePrivate=False, savePublic=False, keyfilePath="src/bins/.keyfile"): def inferKeys(hidePrivate=False, savePublic=False, keyfilePath="src/bins/.keyfile"):
"""Infer keys from the secret stored in the hardware key""" """Infer keys from the secret stored in the hardware key"""
hmac_secret_raw = subprocess.check_output(["src/bins/hmac_secret_regenerate", keyfilePath]) hmac_secret_raw = subprocess.check_output(["src/bins/hmac_secret_regenerate", keyfilePath])
@ -24,6 +24,9 @@ def inferKeys(hidePrivate=False, savePublic=False, keyfilePath="src/bins/.keyfil
f.write(public_key) f.write(public_key)
return private_key, public_key return private_key, public_key
# NOTE All the below methods generates keys on the fly to avoid persistance
# NOTE You should NEVER save the keypair to disk or even to a globlal variable
# NOTE Security is only guaranteed by the observance of the above rule
# STRINGS # STRINGS
@ -39,13 +42,11 @@ def self_decrypt(encrypted):
secret = decrypt(encrypted, private_key) secret = decrypt(encrypted, private_key)
return secret return secret
# FILES # SMALL FILES
# TODO Encrypt files in chunks to reduce memory usage
def self_encrypt_file(filepath, outpath): def self_encrypt_file(filepath, outpath):
"""Encrypt file with public key""" """Encrypt file with public key"""
private_key, public_key = inferKeys() private_key, public_key = inferKeys(hidePrivate=True)
with open(filepath, "rb") as f: with open(filepath, "rb") as f:
filebytes = f.read() filebytes = f.read()
encrypted = encrypt(filebytes, public_key, encoded=True) encrypted = encrypt(filebytes, public_key, encoded=True)
@ -63,6 +64,8 @@ def self_decrypt_file(filepath, outpath):
f.write(decrypted) f.write(decrypted)
return outpath return outpath
# TODO LARGE FILES
# Self testing # Self testing
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -4,13 +4,13 @@
# Motivation: customization and actualization, also less dependencies # Motivation: customization and actualization, also less dependencies
# License: As per original repository # License: As per original repository
import base64
import binascii
from struct import pack
from Crypto.Cipher import PKCS1_OAEP from Crypto.Cipher import PKCS1_OAEP
from Crypto.Hash import HMAC from Crypto.Hash import HMAC
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from struct import pack
import base64
import binascii
def encrypt(message, public_key, encoded=False): def encrypt(message, public_key, encoded=False):
@ -33,7 +33,9 @@ def decrypt(encrypted_message, private_key):
def generate_key(seed, nbytes=2048): def generate_key(seed, nbytes=2048):
# based on https://stackoverflow.com/questions/18264314/#answer-18266970 # based on https://stackoverflow.com/questions/18264314/#answer-18266970
seed_128 = HMAC.new( seed_128 = HMAC.new(
bytes(seed, 'utf-8') # + b'Application: 2nd key derivation' # Please note: this is not needed for the hardware key as the secret is already long enough (usually 128 bytes) bytes(
seed, "utf-8"
) # + b'Application: 2nd key derivation' # Please note: this is not needed for the hardware key as the secret is already long enough (usually 128 bytes)
).digest() ).digest()
class PRNG(object): class PRNG(object):
@ -45,8 +47,7 @@ def generate_key(seed, nbytes=2048):
def __call__(self, n): def __call__(self, n):
while len(self.buffer) < n: while len(self.buffer) < n:
self.buffer += HMAC.new( self.buffer += HMAC.new(self.seed + pack("<I", self.index)).digest()
self.seed + pack("<I", self.index)).digest()
self.index += 1 self.index += 1
result, self.buffer = self.buffer[:n], self.buffer[n:] result, self.buffer = self.buffer[:n], self.buffer[n:]
return result return result