onionv3 support WIP

thanks to @anonymoose, @zeroseed and @geekless
This commit is contained in:
caryoscelus 2021-12-22 14:41:20 +00:00
parent be00a7e855
commit acb313f481
2 changed files with 34 additions and 11 deletions

View file

@ -1,31 +1,49 @@
import base64 import base64
import hashlib import hashlib
import Crypt.ed25519 as ed25519
import rsa
def sign(data, privatekey): def sign(data, privatekey):
import rsa # !ONION v3!
from rsa import pkcs1 if len(privatekey) == 88:
prv_key = base64.b64decode(privatekey)
pub_key = ed25519.publickey_unsafe(prv_key)
signed = ed25519.signature_unsafe(data, prv_key, pub_key)
return signed
# FIXME: doesn't look good
if "BEGIN RSA PRIVATE KEY" not in privatekey: if "BEGIN RSA PRIVATE KEY" not in privatekey:
privatekey = "-----BEGIN RSA PRIVATE KEY-----\n%s\n-----END RSA PRIVATE KEY-----" % privatekey privatekey = "-----BEGIN RSA PRIVATE KEY-----\n%s\n-----END RSA PRIVATE KEY-----" % privatekey
priv = rsa.PrivateKey.load_pkcs1(privatekey) priv = rsa.PrivateKey.load_pkcs1(privatekey)
sign = rsa.pkcs1.sign(data, priv, 'SHA-256') signed = rsa.pkcs1.sign(data, priv, 'SHA-256')
return sign return signed
def verify(data, publickey, sign): def verify(data, publickey, sign):
import rsa # !ONION v3!
from rsa import pkcs1 if len(publickey) == 32:
try:
valid = CryptEd25519.checkvalid(sign, data, publickey)
valid = 'SHA-256'
except Exception as err:
# TODO: traceback
print(err)
valid = False
return valid
pub = rsa.PublicKey.load_pkcs1(publickey, format="DER") pub = rsa.PublicKey.load_pkcs1(publickey, format="DER")
try: try:
valid = rsa.pkcs1.verify(data, sign, pub) valid = rsa.pkcs1.verify(data, sign, pub)
except pkcs1.VerificationError: except rsa.pkcs1.VerificationError:
valid = False valid = False
return valid return valid
def privatekeyToPublickey(privatekey): def privatekeyToPublickey(privatekey):
import rsa # !ONION v3!
from rsa import pkcs1 if len(privatekey) == 88:
prv_key = base64.b64decode(privatekey)
pub_key = ed25519.publickey_unsafe(prv_key)
return pub_key
if "BEGIN RSA PRIVATE KEY" not in privatekey: if "BEGIN RSA PRIVATE KEY" not in privatekey:
privatekey = "-----BEGIN RSA PRIVATE KEY-----\n%s\n-----END RSA PRIVATE KEY-----" % privatekey privatekey = "-----BEGIN RSA PRIVATE KEY-----\n%s\n-----END RSA PRIVATE KEY-----" % privatekey
@ -35,4 +53,8 @@ def privatekeyToPublickey(privatekey):
return pub.save_pkcs1("DER") return pub.save_pkcs1("DER")
def publickeyToOnion(publickey): def publickeyToOnion(publickey):
# !ONION v3!
if len(publickey) == 32:
addr = ed25519.publickey_to_onionaddress(publickey)[:-6]
return addr
return base64.b32encode(hashlib.sha1(publickey).digest()[:10]).lower().decode("ascii") return base64.b32encode(hashlib.sha1(publickey).digest()[:10]).lower().decode("ascii")

View file

@ -13,6 +13,7 @@ import gevent
from Config import config from Config import config
from Crypt import CryptRsa from Crypt import CryptRsa
from Crypt import ed25519
from Site import SiteManager from Site import SiteManager
import socks import socks
from gevent.lock import RLock from gevent.lock import RLock
@ -214,8 +215,8 @@ class TorManager(object):
return False return False
def makeOnionAndKey(self): def makeOnionAndKey(self):
res = self.request("ADD_ONION NEW:RSA1024 port=%s" % self.fileserver_port) res = self.request(f"ADD_ONION NEW:ED25519-V3 port={self.fileserver_port}")
match = re.search("ServiceID=([A-Za-z0-9]+).*PrivateKey=RSA1024:(.*?)[\r\n]", res, re.DOTALL) match = re.search("ServiceID=([A-Za-z0-9]+).*PrivateKey=ED25519-V3:(.*?)[\r\n]", res, re.DOTALL)
if match: if match:
onion_address, onion_privatekey = match.groups() onion_address, onion_privatekey = match.groups()
return (onion_address, onion_privatekey) return (onion_address, onion_privatekey)