geändert: README.md

neue Datei:     client/client.py
	neue Datei:     client/sec/client.crt.pem
	neue Datei:     client/sec/client.csr.pem
	neue Datei:     client/sec/client.key.pem
	neue Datei:     container/Dockerfile
	neue Datei:     container/requirements.txt
	neue Datei:     lib/__pycache__/crypto_utils.cpython-313.pyc
	neue Datei:     lib/__pycache__/jebp_utils.cpython-313.pyc
	neue Datei:     lib/__pycache__/terminal_table.cpython-313.pyc
	neue Datei:     lib/crypto_utils.py
	neue Datei:     lib/jebp_utils.py
	neue Datei:     lib/terminal_table.py
	neue Datei:     server/clients_management/chclient.py
	neue Datei:     server/clients_management/lsclients.py
	neue Datei:     server/clients_management/mkclient.py
	neue Datei:     server/clients_management/rmclient.py
	neue Datei:     server/config/clients/fingerprints
	neue Datei:     server/main.py
	neue Datei:     server/sec/ca/certs/ca.cert.pem
	neue Datei:     server/sec/ca/private/ca.key.pem
	neue Datei:     server/sec/server.crt.pem
	neue Datei:     server/sec/server.csr.pem
	neue Datei:     server/sec/server.key.pem
	gelöscht:       main.py
	gelöscht:       sec/cert.pem
	gelöscht:       sec/key.pem
This commit is contained in:
2025-12-30 01:43:23 +01:00
parent f9e7d51015
commit 1ac4aefdc8
24 changed files with 676 additions and 1 deletions
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
import dbm
import sys
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
import hashlib
if len(sys.argv) < 2:
print(f'{sys.argv[0]}: missing key hash')
sys.exit(1)
with dbm.open('server/config/clients/fingerprints', 'c') as db:
if bytes.fromhex(sys.argv[1]) not in db.keys():
print(f'{sys.argv[0]}: hash not registered')
sys.exit(1)
db[bytes.fromhex(sys.argv[1])] = input('New common name: ')
db.close()
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env python3
import sys
import os
sys.path.append(os.getcwd())
import dbm
from lib.terminal_table import ascii_table
with dbm.open('server/config/clients/fingerprints', 'c') as db:
print(ascii_table([{
'Key Hash': k.hex(),
'Common name': v.decode()
} for k, v in db.items()], ))
db.close()
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env python3
import dbm
import sys
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
import hashlib
if len(sys.argv) < 2:
print(f'{sys.argv[0]}: missing common name')
sys.exit(1)
try:
cert = x509.load_pem_x509_certificate(sys.stdin.buffer.read(), default_backend())
except:
print(f'{sys.argv[0]}: invalid certificate')
sys.exit(1)
with dbm.open('server/config/clients/fingerprints', 'c') as db:
db[hashlib.sha256(cert.public_key().public_bytes(encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo)).digest()] = sys.argv[1]
db.close()
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
import sys
import os
sys.path.append(os.getcwd())
import dbm
from lib.terminal_table import ascii_table
if len(sys.argv) < 2:
print(f'{sys.argv[0]}: missing key hash')
sys.exit(1)
with dbm.open('server/config/clients/fingerprints', 'c') as db:
try:
del db[bytes.fromhex(sys.argv[1])]
except:
print(f'{sys.argv[0]}: hash not registered')
sys.exit(1)
db.close()
Binary file not shown.
+91
View File
@@ -0,0 +1,91 @@
import sys
import os
sys.path.append(os.getcwd())
import asyncio
from lib.crypto_utils import (
generate_keypair,
serialize_public_key,
deserialize_public_key,
derive_aes_key,
)
from lib.jebp_utils import sendmsg, readmsg, validate_cert, InvalidCertificateError
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
from cryptography import x509
import base64
import dbm
import hashlib
HOST = "0.0.0.0"
PORT = 8888
VERSION = 'jebp 1.0'
CERT_FILE = 'server/sec/server.crt.pem'
CLIENT_CERT_ISSUER_NAME = 'jCloudCA-Root-CA'
async def handle_client(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
addr = writer.get_extra_info('peername')
print(f'Connected to {addr}')
await sendmsg(VERSION, writer)
# BEGIN ENCRYPTION HANDSHAKE
server_priv, server_pub = generate_keypair()
client_pub_bytes = await readmsg(reader)
client_pub = deserialize_public_key(client_pub_bytes)
await sendmsg(serialize_public_key(server_pub), writer)
aes_key = derive_aes_key(server_priv, client_pub)
aesgcm = AESGCM(aes_key)
client_nonce = await readmsg(reader)
server_nonce = os.urandom(12)
await sendmsg(server_nonce, writer)
await sendmsg(await readmsg(reader, aesgcm, client_nonce), writer)
# BEGIN SERVER AUTHENTICATION HANDSHAKE
await readmsg(reader)
with open(CERT_FILE, 'rb') as certfile:
cert_data = certfile.read()
certfile.close()
await sendmsg(base64.b64decode(cert_data.replace(b'-----BEGIN CERTIFICATE-----', b'').replace(b'-----END CERTIFICATE-----', b'').strip()), writer, aesgcm, server_nonce)
# BEGIN CLIENT AUTHENTICATION HANDSHAKE
cert = x509.load_der_x509_certificate(await readmsg(reader, aesgcm, client_nonce))
key_hash = hashlib.sha256(cert.public_key().public_bytes(encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo)).digest()
with dbm.open('server/config/clients/fingerprints', 'c') as db:
if key_hash not in db.keys():
raise InvalidCertificateError('client not known')
if not validate_cert(cert, db[key_hash].decode(), CLIENT_CERT_ISSUER_NAME):
raise InvalidCertificateError('client certificate not trusted')
print('Client authenticated')
writer.close()
await writer.wait_closed()
async def main():
server = await asyncio.start_server(handle_client, HOST, PORT)
addr = ', '.join(str(sock.getsockname()) for sock in server.sockets)
print(f'Listening on {addr}')
async with server:
await server.serve_forever()
if __name__ == '__main__':
asyncio.run(main())
+23
View File
@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIIDzTCCArWgAwIBAgIUOKOEzdpgmyw7M7cqcJvOqcSBiMEwDQYJKoZIhvcNAQEL
BQAwdjELMAkGA1UEBhMCREUxHDAaBgNVBAgME05vcmRyaGVpbi1XZXN0ZmFsZW4x
ETAPBgNVBAcMCEJvcm5oZWltMQ8wDQYDVQQKDAZqQ2xvdWQxETAPBgNVBAsMCFNl
Y3VyaXR5MRIwEAYDVQQDDAlqQ2xvdWQgQ0EwHhcNMjUxMjI5MTMxOTU1WhcNMzUx
MjI3MTMxOTU1WjB2MQswCQYDVQQGEwJERTEcMBoGA1UECAwTTm9yZHJoZWluLVdl
c3RmYWxlbjERMA8GA1UEBwwIQm9ybmhlaW0xDzANBgNVBAoMBmpDbG91ZDERMA8G
A1UECwwIU2VjdXJpdHkxEjAQBgNVBAMMCWpDbG91ZCBDQTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBANm+Vys2wsAhkFkOCa85/92GEG9x3Y3CWIpBgbB6
SvLYk0B3Ed78NvSXpigwYgeATtsctM/pMbEGlh4vhCuRSeNaSkYozet6ZR3/qRhI
hWkULrJE5uLjwFoQkUA94IfF1hfQW5y4vrUnrfDEBoiDUP1oLN5xeNs9MpV4NJR9
og57k6jrMIKA7Ep1pnszSo5AKfo/xfaI0EmYk8M4xUI2vZUsnh4uZtTfrkoCVsZW
tk6rg82fWW/y7dEHP2oF8y61STY8jO3QCnyPFoDJNaGJagJx9pSCWypCN0+vwTU/
arfsjnjQQfvKZaCGS9+J27Yn7iIv4gPjZt8L9pMwMSrgC4kCAwEAAaNTMFEwHQYD
VR0OBBYEFIjS2hku4PJxxOyeaOgiVyN3rEwoMB8GA1UdIwQYMBaAFIjS2hku4PJx
xOyeaOgiVyN3rEwoMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB
ACG9lGtheCu4k/J4QjpxcgeVtK7UDy6CM4JVIdNzQP5Q+7uzuNjjo6IpJIjRwjNq
VRsWMtDR2Hlt0cffj0J9V8LVpDz5nah2jvxjRFo1RiBMuEhC2IYMWKdOoIeivwim
XZeUD6SEiR3x2xsJ/ZBHnZeKF33zwecIMwtrTqwMpnH+gmVDgslkR0gu1Y+SEX7n
zbysPRq3yNLW7Tdc9SvfK+2k2JOfur4XjPlXl0LwkAd1yE/MxS4qpLZUAmU/YqQH
zSfuHpTTbe0DqjotyECRs1PaPJMZ3pRFJ6PL6VZE+Xan/0p05gmwv2nimVvtRooS
NgSIHDq1B1qxB3r+VqBEA3g=
-----END CERTIFICATE-----
+28
View File
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDZvlcrNsLAIZBZ
DgmvOf/dhhBvcd2NwliKQYGwekry2JNAdxHe/Db0l6YoMGIHgE7bHLTP6TGxBpYe
L4QrkUnjWkpGKM3remUd/6kYSIVpFC6yRObi48BaEJFAPeCHxdYX0FucuL61J63w
xAaIg1D9aCzecXjbPTKVeDSUfaIOe5Oo6zCCgOxKdaZ7M0qOQCn6P8X2iNBJmJPD
OMVCNr2VLJ4eLmbU365KAlbGVrZOq4PNn1lv8u3RBz9qBfMutUk2PIzt0Ap8jxaA
yTWhiWoCcfaUglsqQjdPr8E1P2q37I540EH7ymWghkvfidu2J+4iL+ID42bfC/aT
MDEq4AuJAgMBAAECggEAZdF1Jm5xa/Fl89a2HZuT80zs44gNr2upBmFyWQkegedX
GAZ1s10h/4boOhPByzsq5JfMTwp+44YubUgP2GWUdP00DRGolMvDe98gfYvv4n5/
BXplssQIHrVvjmhA1Yxju/gA1sym1MQMuLCZU32AQjbUAGJ0PqSjwjQW9ja3MGio
/if+UMeVhg+Wf1ZYq3Le8GjkYVToZxw9RTCtF4ERBm3pCa3Jpul81kVwIijpBGCk
p72P6nwgHYKWdiwnJksk7TTsodVZNePwX1cPpX0ZpU7sPJeq9i9M+f5d6Lrd1ddb
vS2XFDPb5n5URWdANTtRznEqnscos9jCv2nwC1EyrwKBgQDw9jQ0I3qnP7p6m8++
8DByLJ1B6LamuCvNaSVKOIhCW2QZF66HJtLXFX65A8W+gEnPtuoBP6rAYLGFYI+z
usiuxEUwkU4ERbMV5BSqjHJIfm3C6T+6SM2ucX+A5WzIxOxnPsER7L/aSXjM114v
38XWTYuh1tmLZ4pwVF8gwcQ3fwKBgQDnVS8U24Kzx7SFfIRcxsBcG5NDkQp69x7O
vDszGF2o/JokCQcmKE/p6j6FMxwUMYZhMEoYeJ+rAkU6hXlk/GgtF/7BS7AoGC8K
AN+sSZlWVQB3p5GbZdUXq4zhflmYzOCa768+nMkTitwaeCzk5IJFU4dZ1Z64/uSW
vxa0RLGA9wKBgHHuR1Kbr+Oiaz6Lq1eBY7aoR5ahPLNpgzR1Ua9dOXf+lD6VBu1a
Ovh9blR2ZyoiqEOxHcWHX+nkDiudM3TsjPStUnWbToMQnZNtKyRUkbibJrSw6nPe
9nlTqtC8KYpoKcrLTih2g2Pnt1lLP3ptWLJyKeJUnrmeNEPWcMAhPfBrAoGATTF6
tX4OXkl8rrJ/RKo51EKLYJeMpL3DtP7QzlsKHfK0yOOOVChNimPVGwOUEhT4n4PK
peHSffETAtU5Tf6AENQZ+Yx1KtvvDmp+OPKSTWGt9z+ecfmIIw7mwvQzl65+IJVs
p/sPigrjKZ4CdRrfcZzO5KZJAbhktPzs6Zimlr8CgYEAuhcaEE3LeInshaPY4T/p
gcek6bRaScpi7aY0OBH6YPmO55kU+8G+eGv0ykQpu1wHJHaJIUG+s5JqfboUYVsZ
nbfuEeQ0rdcbvvaygbL0+bnDecam0Sa5x9G4UmdW/DeXb4HufCamnrxh2e59CYjZ
tVtU2HF/tg2GyPcQ9sEBIwY=
-----END PRIVATE KEY-----
+26
View File
@@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIETTCCAjUCFDyqhr6D93HlZQSik8KgrPVXMHygMA0GCSqGSIb3DQEBCwUAMHkx
CzAJBgNVBAYTAkRFMRwwGgYDVQQIDBNOb3JkcmhlaW4tV2VzdGZhbGVuMREwDwYD
VQQHDAhCb3JuaGVpbTERMA8GA1UECgwIakNsb3VkQ0ExCzAJBgNVBAsMAklUMRkw
FwYDVQQDDBBqQ2xvdWRDQS1Sb290LUNBMB4XDTI1MTIyOTE3MDkxMVoXDTI3MTIy
OTE3MDkxMVowTTELMAkGA1UEBhMCREUxDDAKBgNVBAgMA05SVzERMA8GA1UEBwwI
Qm9ybmhlaW0xDzANBgNVBAoMBmpDbG91ZDEMMAoGA1UEAwwDamViMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7zhAY0ytYvzhwuCI0nC7A485Jo74H5tO
x7sZ8XLkNWr/efjZNkEb0zfzN0BDXgWa74qmjv6JcAU7Fdzc3DMfFiCLbmgrQ0ev
FoD5PHRoC2x65LMclJQG9mNk3gWhnyB9mQRlJysi7RNDKTUruUpGg/p2wiEmXRJ3
xfWZ3Jdp0nvxEYbXrVemHBTcXqEW1Klhy7Ycr4cX7IoqLTk4MIOJrD90KFCyKXMt
6EoHQhhX2IQnX0R1ok/Suxwx+NG7yeDTe5CasqgxTvzuZeT5x8Y3vbv5uIrE6FaA
0XzvvHTtshqCcQeg1guSdzoRlgyMvh8G9l93VDXYFN922Mec9HfJGwIDAQABMA0G
CSqGSIb3DQEBCwUAA4ICAQBOVnuexCELMTymgGtx0GG4ZV/xuyGNOI9fxX0n31C9
6gQ4Uwe5gqy0O9g1Qw/UrA3Yf4o6R1gzxGZdJGUEKm7R1M3GE2/tChTrlRFbmiA5
LXC0FOhdhU+S6XBpOoj87i2FLts+4si0+EqxOUvR03EkwZeKJaKttNnHkmuxSMkm
7EJdgqTu7ohcBHlW3Gyc0TGnVX1vMBSkXrLwrRON3Zopd6nlbN/bzEY53aTGlHiN
IWfk+dE4l8ZLnJcihvm6hf2wwVWNGxiJojk5LsNDyqwvY+1dA4xU0QuJYx1rzJHW
cNfiC/qA6u9ml4N7UXZZRL/BTr8RF9zXmtr5hzV4xHWY/GmJBybLLPVlB/3fAkCC
OpNlTlOzqdd0o4y5gjup2ekEi6DFX0Ef0TVLdyJ0+OPm7HrlC76f+kE67ouKQjLT
bbnQ9j6u3GzNfuywWKPSizV/0X8X/zD/ix/jKOpE+JqRApRHLkRf7QGGOVudFYZW
L+C0/7EQNaSPjA5iDFlWOy9j20ZF44uYsL8FYJ5tjs49E9QQ2SwKf55Bdr8Kpxnw
W4zV4S9l+ZXRVK20GuXnpBvMxRDj6ZMeByj0YPyej4gCxnz1PlzT52SwwnwIj3lk
csnIxvJv15ks0ws9IQqXAEmcgu4jU08yQBh0S4LMj4l8IoDJL2bt/OO5KT7LjyLj
aQ==
-----END CERTIFICATE-----
+16
View File
@@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICkjCCAXoCAQAwTTELMAkGA1UEBhMCREUxDDAKBgNVBAgMA05SVzERMA8GA1UE
BwwIQm9ybmhlaW0xDzANBgNVBAoMBmpDbG91ZDEMMAoGA1UEAwwDamViMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7zhAY0ytYvzhwuCI0nC7A485Jo74
H5tOx7sZ8XLkNWr/efjZNkEb0zfzN0BDXgWa74qmjv6JcAU7Fdzc3DMfFiCLbmgr
Q0evFoD5PHRoC2x65LMclJQG9mNk3gWhnyB9mQRlJysi7RNDKTUruUpGg/p2wiEm
XRJ3xfWZ3Jdp0nvxEYbXrVemHBTcXqEW1Klhy7Ycr4cX7IoqLTk4MIOJrD90KFCy
KXMt6EoHQhhX2IQnX0R1ok/Suxwx+NG7yeDTe5CasqgxTvzuZeT5x8Y3vbv5uIrE
6FaA0XzvvHTtshqCcQeg1guSdzoRlgyMvh8G9l93VDXYFN922Mec9HfJGwIDAQAB
oAAwDQYJKoZIhvcNAQELBQADggEBAHeuAv3bYqIf2GGHvm0ztgar+npTd4/vPZDm
pZBdo3EAEe+Z9wZJCzSfUfpssfrRk94RPdbO10mdwBGDzcQ+V7Urb8jdFoGt1LRD
P17SvWqfYmGAyML3aA+v1efBkgOIRYPROsoTncP3LrSjRMKKC0MkO2u/QbZMiNce
ZqnzMvb3RtQAnOxNsS12FGEBiBownQrZqQyq/uIsnAjnA6QhoZJOFiXvupz9MyJq
MxeRMw9pBz7p31vhnSaWbrb1hmvhmontdmuQ2aNBEZSSMp+rxKLn3lvAlxyy22Uq
bgahiF6qi5XItOexSkVCBhSC7UACXGZr/9wQacH9FgZEUDCNIYY=
-----END CERTIFICATE REQUEST-----
+28
View File
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvOEBjTK1i/OHC
4IjScLsDjzkmjvgfm07HuxnxcuQ1av95+Nk2QRvTN/M3QENeBZrviqaO/olwBTsV
3NzcMx8WIItuaCtDR68WgPk8dGgLbHrksxyUlAb2Y2TeBaGfIH2ZBGUnKyLtE0Mp
NSu5SkaD+nbCISZdEnfF9Zncl2nSe/ERhtetV6YcFNxeoRbUqWHLthyvhxfsiiot
OTgwg4msP3QoULIpcy3oSgdCGFfYhCdfRHWiT9K7HDH40bvJ4NN7kJqyqDFO/O5l
5PnHxje9u/m4isToVoDRfO+8dO2yGoJxB6DWC5J3OhGWDIy+Hwb2X3dUNdgU33bY
x5z0d8kbAgMBAAECggEAcPQtqvWMtT3U1/CvijZCh8a75JIDZOEvjK2y7Ugjq3lv
UkeHQM/zdINpq0ADz0R0SQE97i0P9j3yDTuxaaQV3JvXWnWDYAxcBxM1HC+W5TX+
vTg5mYpf0z1RZmhgTUPJKlRh8uGyZyD+SFnb4GzK6Qx9wOJoO/A5b9atJPS1ufV0
RByegK6eQefif6oAThazxb68vMy1By5cFiAEscql0Y45tyzGB/NWYbq9AlIVkHSd
XW3z0Ro1cP76t5SrEDQNZ3udGkwZViAVZS++sOu6aXmKda9c3QzzAzu+//nucFYl
H7xvOZhoi2jyWZWwEwD5JncEtUv+MthqUYMRY3/gmQKBgQD5o3SLasvjHlxD1Vkl
W8fR2pUjaPCjQIuis9IZ8JSGKPzvA0WTnS6Qc0SnGvqrSZxsnNONPS3lnqlDg7MQ
VbiFPbH97MZe3/wuy/9oo+ZxMUi8v1X0WzA4w1iBWUh9egAOT9y4V6VXYfqeZEOE
dIGebeVixSD0aPqfthfDy5un7wKBgQD1UNQKWTh0pvSUAauMHSLmyzGuQQqSyRpS
yhYDgWr3qhu3/FRIIQaCQ5lAxhepJTgs1xysNdyjM2Tg4rSkFXM8L6YJ3cnmd+SE
fXyrasjbehwgcnpXruVGE5iWOzEmf5/n26FunHcsFgV8H+hW2Rrt609Xhi6+7v0x
qAxwCH6llQKBgQDQ344dNO+Bih6i9zkOxBuOH/kXVq+5uMDdEt5hq+Vp15PCnJcz
qpmSbY/szesdNIs4aYOssprbfISdo+1IZqDsgzGRh/J24ayMr012DWU8IoN8wg82
VLIlXHWKTN0Vd+XiE7pXV6ZVVfqvWq8PfbgSilsa6FvphIjm5yI9RfhoawKBgQCV
cSv7MecGiT6te2b58DX2ywn00YKTcRcsIBfRAuIbBfHk3z6owhWo/W063HJFhHr4
NgMtlZJXiVOG/BR3cOnGXHCVyhrY32jCnX95HZBGw9imm5aUG+NoET//JQgIH+9V
26I4M/EVVkT5HKb5YUDad2LaOs/3WLe9rFYHWeVtEQKBgG5xsN8GhCGDuWKqHkLe
hUNAGFgutDQzOM9Huk1YRk6DNog7GXRzJYUWM/XP/TqRSlGZu0I3/1VedkKwiKH3
VDY/IikRvsGC0pfjM/hnh7EVDEjlTClYh+6uZbY2tpcq+FuR1mr/2uRWiLUZIoWs
Cjt9QMUxvxXAnjvXacDAkgCj
-----END PRIVATE KEY-----