mirror of
https://github.com/PurpleI2P/pyseeder
synced 2025-03-13 05:41:23 +00:00
add support for NoneWithRSA signing
This commit is contained in:
parent
e5e39fe77e
commit
5eb614be66
@ -61,16 +61,30 @@ def keygen(pub_key, priv_key, user_id, priv_key_password=None):
|
||||
f.write(cert.public_bytes(serialization.Encoding.PEM))
|
||||
|
||||
|
||||
def append_signature(target_file, priv_key, priv_key_password=None):
|
||||
"""Append signature to the end of file"""
|
||||
with open(target_file, "rb") as f:
|
||||
contents = f.read()
|
||||
def get_signature(contents, priv_key, priv_key_password=None):
|
||||
"""Calculate signature for prepared reseed file"""
|
||||
"""Singing with NoneWithRSA algorithm: https://stackoverflow.com/a/68301530"""
|
||||
import rsa as pyrsa
|
||||
|
||||
with open(priv_key, "rb") as kf:
|
||||
private_key = serialization.load_pem_private_key(
|
||||
kf.read(), password=priv_key_password, backend=default_backend())
|
||||
pk = pyrsa.PrivateKey.load_pkcs1(
|
||||
serialization.load_pem_private_key(
|
||||
kf.read(), password=priv_key_password, backend=default_backend()
|
||||
).private_bytes(
|
||||
serialization.Encoding.PEM,
|
||||
serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
serialization.NoEncryption()
|
||||
)
|
||||
)
|
||||
|
||||
signature = private_key.sign(contents, padding.PKCS1v15(), hashes.SHA512())
|
||||
digest = hashes.Hash(hashes.SHA512())
|
||||
digest.update(contents)
|
||||
h = digest.finalize()
|
||||
|
||||
with open(target_file, "ab") as f:
|
||||
f.write(signature)
|
||||
keylength = pyrsa.pkcs1.common.byte_size(pk.n)
|
||||
padded = pyrsa.pkcs1._pad_for_signing(h, keylength)
|
||||
payload = pyrsa.pkcs1.transform.bytes2int(padded)
|
||||
encrypted = pk.blinded_encrypt(payload)
|
||||
sig = pyrsa.pkcs1.transform.int2bytes(encrypted, keylength)
|
||||
|
||||
return sig
|
||||
|
@ -24,31 +24,43 @@ class SU3File:
|
||||
self.CONTENT_LENGTH = None
|
||||
self.VERSION = str(int(time.time())).encode("utf-8")
|
||||
#self.keytype = "RSA_SHA512_4096"
|
||||
self.OUTPUT = None
|
||||
|
||||
def write(self, filename, priv_key, priv_key_password=None):
|
||||
"""Write file to disc"""
|
||||
nullbyte = bytes([0])
|
||||
with open(filename, "wb") as f:
|
||||
f.write("I2Psu3".encode("utf-8"))
|
||||
f.write(bytes([0,0]))
|
||||
f.write(self.SIGNATURE_TYPE.to_bytes(2, "big"))
|
||||
f.write(self.SIGNATURE_LENGTH.to_bytes(2, "big"))
|
||||
f.write(nullbyte)
|
||||
f.write(bytes([self.VERSION_LENGTH]))
|
||||
f.write(nullbyte)
|
||||
f.write(bytes([self.SIGNER_ID_LENGTH]))
|
||||
f.write(self.CONTENT_LENGTH.to_bytes(8, "big"))
|
||||
f.write(nullbyte)
|
||||
f.write(bytes([self.FILE_TYPE]))
|
||||
f.write(nullbyte)
|
||||
f.write(bytes([self.CONTENT_TYPE]))
|
||||
f.write(bytes([0 for _ in range(12)]))
|
||||
f.write(self.VERSION + bytes(
|
||||
[0 for _ in range(16 - len(self.VERSION))]))
|
||||
f.write(self.SIGNER_ID.encode("utf-8"))
|
||||
f.write(self.CONTENT)
|
||||
|
||||
pyseeder.crypto.append_signature(filename, priv_key, priv_key_password)
|
||||
self.OUTPUT = "I2Psu3".encode("utf-8")
|
||||
self.OUTPUT += bytes([0,0])
|
||||
self.OUTPUT += self.SIGNATURE_TYPE.to_bytes(2, "big")
|
||||
self.OUTPUT += self.SIGNATURE_LENGTH.to_bytes(2, "big")
|
||||
self.OUTPUT += nullbyte
|
||||
self.OUTPUT += bytes([self.VERSION_LENGTH])
|
||||
self.OUTPUT += nullbyte
|
||||
self.OUTPUT += bytes([self.SIGNER_ID_LENGTH])
|
||||
self.OUTPUT += self.CONTENT_LENGTH.to_bytes(8, "big")
|
||||
self.OUTPUT += nullbyte
|
||||
self.OUTPUT += bytes([self.FILE_TYPE])
|
||||
self.OUTPUT += nullbyte
|
||||
self.OUTPUT += bytes([self.CONTENT_TYPE])
|
||||
self.OUTPUT += bytes([0 for _ in range(12)])
|
||||
self.OUTPUT += self.VERSION + bytes(
|
||||
[0 for _ in range(16 - len(self.VERSION))])
|
||||
self.OUTPUT += self.SIGNER_ID.encode("utf-8")
|
||||
self.OUTPUT += self.CONTENT
|
||||
|
||||
with open(filename + "-data", "wb") as f:
|
||||
f.write(self.OUTPUT)
|
||||
|
||||
signature = pyseeder.crypto.get_signature(self.OUTPUT, priv_key, priv_key_password)
|
||||
|
||||
with open(filename + "-sig", "wb") as f:
|
||||
f.write(signature)
|
||||
|
||||
self.OUTPUT += signature
|
||||
|
||||
with open(filename, "wb") as f:
|
||||
f.write(self.OUTPUT)
|
||||
|
||||
def reseed(self, netdb, yggseeds):
|
||||
"""Compress netdb entries and set content"""
|
||||
|
@ -21,22 +21,28 @@ def run(filename, config):
|
||||
|
||||
# get release info
|
||||
try:
|
||||
resp = requests.get(release_info_url, auth=creds)
|
||||
release = requests.get(release_info_url, auth=creds)
|
||||
except:
|
||||
raise TransportException("Failed to connect to GitHub API")
|
||||
|
||||
if resp.status_code is not 200:
|
||||
if release.status_code is not 200:
|
||||
raise TransportException("Check your GitHub API auth settings")
|
||||
|
||||
# fetch release assets
|
||||
try:
|
||||
assets = requests.get(release.json()["assets_url"], auth=creds)
|
||||
except:
|
||||
raise TransportException("Unable get release assets")
|
||||
|
||||
# delete old asset
|
||||
for x in resp.json()["assets"]:
|
||||
for x in assets.json():
|
||||
if x["name"] == asset_name:
|
||||
r = requests.delete(x["url"], auth=creds)
|
||||
if r.status_code is not 204:
|
||||
raise TransportException("Failed to delete asset from GitHub")
|
||||
|
||||
# upload new asset
|
||||
upload_url = resp.json()["upload_url"].split("{")[0] # wat
|
||||
upload_url = release.json()["upload_url"].split("{")[0] # wat
|
||||
headers = {'Content-Type': content_type}
|
||||
params = {'name': asset_name}
|
||||
|
||||
@ -45,5 +51,5 @@ def run(filename, config):
|
||||
data=data)
|
||||
|
||||
if r.status_code is not 201:
|
||||
raise TransportException("Failed to upload asset to GitHub API")
|
||||
raise TransportException("Failed to upload asset to GitHub API : code %d" % (r.status_code))
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
cryptography>=1.4
|
||||
rsa
|
||||
requests
|
||||
|
Loading…
x
Reference in New Issue
Block a user