mirror of
https://github.com/r4sas/PBinCLI
synced 2025-01-24 13:34:14 +00:00
[v2] encode json for v2, move de/compress to Paste class (#13)
This commit is contained in:
parent
5b38c532a2
commit
4c124a33c0
@ -33,8 +33,9 @@ def send(args, api_client):
|
|||||||
|
|
||||||
request = paste.getJSON()
|
request = paste.getJSON()
|
||||||
|
|
||||||
if args.debug: print("Passphrase:\t{}".format(paste.getHash()))
|
if args.debug:
|
||||||
if args.debug: print("Request:\t{}".format(request))
|
print("Passphrase:\t{}".format(paste.getHash()))
|
||||||
|
print("Request:\t{}".format(request))
|
||||||
|
|
||||||
# If we use dry option, exit now
|
# If we use dry option, exit now
|
||||||
if args.dry: exit(0)
|
if args.dry: exit(0)
|
||||||
@ -76,7 +77,7 @@ def get(args, api_client):
|
|||||||
|
|
||||||
if args.debug: print("PasteID:\t{}\nPassphrase:\t{}".format(pasteid, passphrase))
|
if args.debug: print("PasteID:\t{}\nPassphrase:\t{}".format(pasteid, passphrase))
|
||||||
|
|
||||||
paste = Paste()
|
paste = Paste(args.debug)
|
||||||
|
|
||||||
if args.password:
|
if args.password:
|
||||||
paste.setPassword(args.password)
|
paste.setPassword(args.password)
|
||||||
@ -90,11 +91,9 @@ def get(args, api_client):
|
|||||||
print("Paste received!")
|
print("Paste received!")
|
||||||
|
|
||||||
version = result['v'] if 'v' in result else 1
|
version = result['v'] if 'v' in result else 1
|
||||||
if args.debug: print("Paste version:\t{}\n".format(version))
|
|
||||||
paste.setVersion(version)
|
paste.setVersion(version)
|
||||||
|
|
||||||
if version == 2:
|
if version == 2:
|
||||||
#if args.debug: print("Message:\t{}\nAuthentication data:\t{}".format(result['ct'], result['adata']))
|
|
||||||
if args.debug: print("Authentication data:\t{}".format(result['adata']))
|
if args.debug: print("Authentication data:\t{}".format(result['adata']))
|
||||||
|
|
||||||
paste.setHash(passphrase)
|
paste.setHash(passphrase)
|
||||||
|
@ -64,7 +64,11 @@ class Paste:
|
|||||||
|
|
||||||
|
|
||||||
def getJSON(self):
|
def getJSON(self):
|
||||||
return self._data
|
if self._version == 2:
|
||||||
|
from pbincli.utils import json_encode
|
||||||
|
return json_encode(self._data).decode()
|
||||||
|
else:
|
||||||
|
return self._data
|
||||||
|
|
||||||
|
|
||||||
def loadJSON(self, data):
|
def loadJSON(self, data):
|
||||||
@ -110,8 +114,28 @@ class Paste:
|
|||||||
return cipher
|
return cipher
|
||||||
|
|
||||||
|
|
||||||
|
def __decompress(self, s):
|
||||||
|
import zlib
|
||||||
|
if self._version == 2:
|
||||||
|
return zlib.decompress(s, -zlib.MAX_WBITS)
|
||||||
|
else:
|
||||||
|
return zlib.decompress(bytearray(map(ord, b64decode(s.encode('utf-8')).decode('utf-8'))), -zlib.MAX_WBITS)
|
||||||
|
|
||||||
|
|
||||||
|
def __compress(self, s):
|
||||||
|
import zlib
|
||||||
|
if self._version == 2:
|
||||||
|
# using compressobj as compress doesn't let us specify wbits
|
||||||
|
# needed to get the raw stream without headers
|
||||||
|
co = zlib.compressobj(wbits=-zlib.MAX_WBITS)
|
||||||
|
return co.compress(s) + co.flush()
|
||||||
|
else:
|
||||||
|
co = zlib.compressobj(wbits=-zlib.MAX_WBITS)
|
||||||
|
b = co.compress(s) + co.flush()
|
||||||
|
return b64encode(''.join(map(chr, b)).encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
def decrypt(self):
|
def decrypt(self):
|
||||||
from pbincli.utils import decompress
|
|
||||||
from json import loads as json_decode
|
from json import loads as json_decode
|
||||||
|
|
||||||
if self._version == 2:
|
if self._version == 2:
|
||||||
@ -124,7 +148,7 @@ class Paste:
|
|||||||
cipher_text_tag = b64decode(self._data['ct'])
|
cipher_text_tag = b64decode(self._data['ct'])
|
||||||
cipher_text = cipher_text_tag[:-CIPHER_TAG_BYTES]
|
cipher_text = cipher_text_tag[:-CIPHER_TAG_BYTES]
|
||||||
cipher_tag = cipher_text_tag[-CIPHER_TAG_BYTES:]
|
cipher_tag = cipher_text_tag[-CIPHER_TAG_BYTES:]
|
||||||
cipher_message = json_decode(decompress(cipher.decrypt_and_verify(cipher_text, cipher_tag), self._version).decode())
|
cipher_message = json_decode(self.__decompress(cipher.decrypt_and_verify(cipher_text, cipher_tag)).decode())
|
||||||
|
|
||||||
self._text = cipher_message['paste'].encode()
|
self._text = cipher_message['paste'].encode()
|
||||||
if 'attachment' in cipher_message and 'attachment_name' in cipher_message:
|
if 'attachment' in cipher_message and 'attachment_name' in cipher_message:
|
||||||
@ -147,7 +171,7 @@ class Paste:
|
|||||||
text = SJCL().decrypt(cipher_text, password)
|
text = SJCL().decrypt(cipher_text, password)
|
||||||
|
|
||||||
if len(text):
|
if len(text):
|
||||||
self._text = decompress(text.decode(), self._version)
|
self._text = self.__decompress(text.decode())
|
||||||
|
|
||||||
if 'attachment' in self._data and 'attachmentname' in self._data:
|
if 'attachment' in self._data and 'attachmentname' in self._data:
|
||||||
cipherfile = json_decode(self._data['attachment'])
|
cipherfile = json_decode(self._data['attachment'])
|
||||||
@ -158,12 +182,12 @@ class Paste:
|
|||||||
attachment = SJCL().decrypt(cipherfile, password)
|
attachment = SJCL().decrypt(cipherfile, password)
|
||||||
attachmentname = SJCL().decrypt(cipherfilename, password)
|
attachmentname = SJCL().decrypt(cipherfilename, password)
|
||||||
|
|
||||||
self._attachment = decompress(attachment.decode('utf-8'), self._version).decode('utf-8')
|
self._attachment = self.__decompress(attachment.decode('utf-8')).decode('utf-8')
|
||||||
self._attachment_name = decompress(attachmentname.decode('utf-8'), self._version).decode('utf-8')
|
self._attachment_name = self.__decompress(attachmentname.decode('utf-8')).decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
def encrypt(self, formatter, burnafterreading, discussion, expiration):
|
def encrypt(self, formatter, burnafterreading, discussion, expiration):
|
||||||
from pbincli.utils import compress, json_encode
|
from pbincli.utils import json_encode
|
||||||
if self._version == 2:
|
if self._version == 2:
|
||||||
iv = get_random_bytes(CIPHER_TAG_BYTES)
|
iv = get_random_bytes(CIPHER_TAG_BYTES)
|
||||||
salt = get_random_bytes(CIPHER_SALT_BYTES)
|
salt = get_random_bytes(CIPHER_SALT_BYTES)
|
||||||
@ -191,7 +215,7 @@ class Paste:
|
|||||||
cipher_message['attachment_name'] = self._attachment_name
|
cipher_message['attachment_name'] = self._attachment_name
|
||||||
|
|
||||||
cipher = self.__initializeCipher(key, iv, adata)
|
cipher = self.__initializeCipher(key, iv, adata)
|
||||||
ciphertext, tag = cipher.encrypt_and_digest(compress(json_encode(cipher_message), self._version))
|
ciphertext, tag = cipher.encrypt_and_digest(self.__compress(json_encode(cipher_message)))
|
||||||
|
|
||||||
self._data = {'v':2,'adata':adata,'ct':b64encode(ciphertext + tag).decode(),'meta':{'expire':expiration}}
|
self._data = {'v':2,'adata':adata,'ct':b64encode(ciphertext + tag).decode(),'meta':{'expire':expiration}}
|
||||||
|
|
||||||
@ -210,16 +234,16 @@ class Paste:
|
|||||||
if self._debug: print("Password:\t{}".format(password))
|
if self._debug: print("Password:\t{}".format(password))
|
||||||
|
|
||||||
# Encrypting text
|
# Encrypting text
|
||||||
cipher = SJCL().encrypt(compress(self._text.encode('utf-8'), self._version), password, mode='gcm')
|
cipher = SJCL().encrypt(self.__compress(self._text.encode('utf-8')), password, mode='gcm')
|
||||||
for k in ['salt', 'iv', 'ct']: cipher[k] = cipher[k].decode()
|
for k in ['salt', 'iv', 'ct']: cipher[k] = cipher[k].decode()
|
||||||
|
|
||||||
self._data['data'] = json_encode(cipher)
|
self._data['data'] = json_encode(cipher)
|
||||||
|
|
||||||
if self._attachment:
|
if self._attachment:
|
||||||
cipherfile = SJCL().encrypt(compress(self._attachment.encode('utf-8'), self._version), password, mode='gcm')
|
cipherfile = SJCL().encrypt(self.__compress(self._attachment.encode('utf-8')), password, mode='gcm')
|
||||||
for k in ['salt', 'iv', 'ct']: cipherfile[k] = cipherfile[k].decode()
|
for k in ['salt', 'iv', 'ct']: cipherfile[k] = cipherfile[k].decode()
|
||||||
|
|
||||||
cipherfilename = SJCL().encrypt(compress(self._attachment_name.encode('utf-8'), self._version), password, mode='gcm')
|
cipherfilename = SJCL().encrypt(self.__compress(self._attachment_name.encode('utf-8')), password, mode='gcm')
|
||||||
for k in ['salt', 'iv', 'ct']: cipherfilename[k] = cipherfilename[k].decode()
|
for k in ['salt', 'iv', 'ct']: cipherfilename[k] = cipherfilename[k].decode()
|
||||||
|
|
||||||
self._data['attachment'] = json_encode(cipherfile)
|
self._data['attachment'] = json_encode(cipherfile)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import json, ntpath, os, zlib
|
import json, ntpath, os
|
||||||
from base64 import b64encode, b64decode
|
from base64 import b64encode, b64decode
|
||||||
|
|
||||||
class PBinCLIException(Exception):
|
class PBinCLIException(Exception):
|
||||||
@ -22,24 +22,5 @@ def check_writable(f):
|
|||||||
raise PBinCLIException("Path is not writable: {}".format(f))
|
raise PBinCLIException("Path is not writable: {}".format(f))
|
||||||
|
|
||||||
|
|
||||||
def decompress(s, ver = 1):
|
|
||||||
if ver == 2:
|
|
||||||
return zlib.decompress(s, -zlib.MAX_WBITS)
|
|
||||||
else:
|
|
||||||
return zlib.decompress(bytearray(map(ord, b64decode(s.encode('utf-8')).decode('utf-8'))), -zlib.MAX_WBITS)
|
|
||||||
|
|
||||||
|
|
||||||
def compress(s, ver = 1):
|
|
||||||
if ver == 2:
|
|
||||||
# using compressobj as compress doesn't let us specify wbits
|
|
||||||
# needed to get the raw stream without headers
|
|
||||||
co = zlib.compressobj(wbits=-zlib.MAX_WBITS)
|
|
||||||
return co.compress(s) + co.flush()
|
|
||||||
else:
|
|
||||||
co = zlib.compressobj(wbits=-zlib.MAX_WBITS)
|
|
||||||
b = co.compress(s) + co.flush()
|
|
||||||
return b64encode(''.join(map(chr, b)).encode('utf-8'))
|
|
||||||
|
|
||||||
|
|
||||||
def json_encode(s):
|
def json_encode(s):
|
||||||
return json.dumps(s, separators=(',',':')).encode()
|
return json.dumps(s, separators=(',',':')).encode()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user