def dict_items_to_text(dct, encoding='utf-8', errors='strict'): """ Returns dict where all keys and values are converted to text strings. Only works for simple dicts - one level structure. """ # TODO: make it fully recursive... for example if list of lists is passed _d = {} for k in dct.keys(): _v = dct[k] if strng.is_bin(_v): _v = _v.decode(encoding, errors=errors) elif isinstance(_v, list): _v = [ i.decode(encoding, errors=errors) if strng.is_bin(i) else i for i in _v ] elif isinstance(_v, tuple): _v = tuple([ i.decode(encoding, errors=errors) if strng.is_bin(i) else i for i in _v ]) _k = k if strng.is_bin(_k): _k = _k.decode(encoding, errors=errors) _d[_k] = _v return _d
def verify(self, signature, message, signature_as_digits=True): global _CryptoLog # if _CryptoLog is None: # _CryptoLog = os.environ.get('CRYPTO_LOG') == '1' signature_bytes = signature if signature_as_digits: signature_bytes = number.long_to_bytes(signature, blocksize=4) if not strng.is_bin(signature_bytes): raise ValueError('signature must be byte string') if not strng.is_bin(message): raise ValueError('message must be byte string') h = hashes.sha1(message, return_object=True) result = False try: pkcs1_15.new(self.keyObject).verify(h, signature_bytes) result = True except ( ValueError, TypeError, ): # do not raise any exception... just return False lg.exc('signature=%r message=%r' % ( signature, message, )) if _Debug: if _CryptoLog: lg.args(_DebugLevel, result=result, signature=signature) return result
def verify(self, signature, message, signature_as_digits=True): signature_bytes = signature if signature_as_digits: signature_text = strng.to_text(signature) signature_int = int(signature_text) signature_bytes = number.long_to_bytes(signature_int) if signature[0:1] == b'0': signature_bytes = b'\x00' + signature_bytes if not strng.is_bin(signature_bytes): raise ValueError('signature must be byte string') if not strng.is_bin(message): raise ValueError('message must be byte string') h = hashes.sha1(message, return_object=True) try: pkcs1_15.new(self.keyObject).verify(h, signature_bytes) result = True except ( ValueError, TypeError, ): if _Debug: lg.exc( msg='signature=%r\nmessage=%r\nsignature_as_digits=%r\n' % (signature, message, signature_as_digits)) result = False return result
def dict_values_to_text(dct, encoding='utf-8', errors='strict'): """ Returns dict where all values are converted to text strings. Can go recursively, but not super smart. If value is a list of dicts - will not be covered. """ # TODO: make it fully recursive... for example if list of lists is passed _d = {} for k, v in dct.items(): _v = v if strng.is_bin(_v): _v = _v.decode(encoding, errors=errors) elif isinstance(_v, dict): _v = dict_values_to_text(_v, encoding=encoding, errors=errors) elif isinstance(_v, list): _v = [ i.decode(encoding, errors=errors) if strng.is_bin(i) else i for i in _v ] elif isinstance(_v, tuple): _v = tuple([ i.decode(encoding, errors=errors) if strng.is_bin(i) else i for i in _v ]) _d[k] = _v return _d
def pack_dict(dct, encoding='utf-8', errors='strict'): """ Creates another dict from input dict where types of keys and values are also present. Keys can only be bin/text strings, integers, floats or None. Values can only be bin/text strings, integers, floats, None, lists or tuples. Result dict will always contain only text (unicode) keys and values or simple types like integer, float or None. """ if not dct: return {} _d = {} for k, v in dct.items(): _k = k _ktyp = 's' if strng.is_bin(_k): _k = _k.decode(encoding, errors=errors) _ktyp = 'b' elif isinstance(_k, int): _ktyp = 'i' elif isinstance(_k, float): _ktyp = 'f' elif _k is None: _ktyp = 'n' _v = v _vtyp = 's' if strng.is_bin(_v): _v = _v.decode(encoding, errors=errors) _vtyp = 'b' elif isinstance(_v, int): _vtyp = 'i' elif isinstance(_v, float): _vtyp = 'f' elif isinstance(_v, dict): _v = pack_dict(_v, encoding=encoding, errors=errors) _vtyp = 'd' elif isinstance(_v, list): _v = [ pack_dict({'i': i}, encoding=encoding, errors=errors) for i in _v ] _vtyp = 'l' elif isinstance(_v, tuple): _v = [ pack_dict({'i': i}, encoding=encoding, errors=errors) for i in _v ] _vtyp = 't' elif _v is None: _vtyp = 'n' _d[_k] = ( _ktyp, _vtyp, _v, ) return _d
def dict_keys_to_text(dct, encoding='utf-8', errors='strict'): """ Returns dict where all keys are converted to text strings. Only works for keys in a "root" level of the dict. """ return {(k.decode(encoding, errors=errors) if strng.is_bin(k) else k): v for k, v in dct.items()}
def sha256(inp, hexdigest=False, return_object=False): if not strng.is_bin(inp): raise ValueError('input must by byte string') h = SHA256.new(inp) if return_object: return h if hexdigest: return strng.to_bin(h.hexdigest()) return h.digest()
def __init__( self, CreatorID=None, BackupID='', BlockNumber=0, SessionKey='', SessionKeyType=None, LastBlock=True, Data=b'', EncryptKey=None, DecryptKey=None, EncryptedSessionKey=None, EncryptedData=None, Length=None, Signature=None, ): self.CreatorID = CreatorID if not self.CreatorID: self.CreatorID = my_id.getLocalID() if not isinstance(self.CreatorID, id_url.ID_URL_FIELD): self.CreatorID = id_url.field(self.CreatorID) self.BackupID = strng.to_text(BackupID) self.BlockNumber = BlockNumber self.LastBlock = bool(LastBlock) self.SessionKeyType = SessionKeyType or key.SessionKeyType() if EncryptedSessionKey: # this block to be decrypted after receiving self.EncryptedSessionKey = EncryptedSessionKey else: # this block to be encrypted before sending if callable(EncryptKey): self.EncryptedSessionKey = EncryptKey(SessionKey) elif strng.is_text(EncryptKey): self.EncryptedSessionKey = my_keys.encrypt( EncryptKey, SessionKey) elif strng.is_bin(EncryptKey): self.EncryptedSessionKey = my_keys.encrypt( strng.to_text(EncryptKey), SessionKey) else: self.EncryptedSessionKey = key.EncryptLocalPublicKey( SessionKey) if EncryptedData and Length is not None: self.Length = Length self.EncryptedData = EncryptedData else: self.Length = len(Data) self.EncryptedData = key.EncryptWithSessionKey( SessionKey, Data, session_key_type=self.SessionKeyType) if Signature: self.Signature = Signature else: self.Signature = None self.Sign(signing_key=EncryptKey) self.DecryptKey = DecryptKey if _Debug: lg.out(_DebugLevel, 'new data in %s' % self)
def verify(self, signature, message, signature_as_digits=True): if signature_as_digits: signature_raw = number.long_to_bytes(int(strng.to_text(signature))) if signature[0:1] == b'0': signature_raw = b'\x00' + signature_raw if not strng.is_bin(signature_raw): raise ValueError('signature must be byte string') if not strng.is_bin(message): raise ValueError('message must be byte string') h = hashes.sha1(message, return_object=True) try: pkcs1_15.new(self.keyObject).verify(h, signature_raw) result = True except (ValueError, TypeError, ): if _Debug: from logs import lg lg.exc() result = False return result
def verify(self, signature, message, signature_as_digits=True): signature_bytes = signature if signature_as_digits: signature_text = strng.to_text(signature) signature_int = int(signature_text) signature_bytes = number.long_to_bytes(signature_int) # if signature[0:1] == b'0': # signature_bytes = b'\x00' + signature_bytes if not strng.is_bin(signature_bytes): raise ValueError('signature must be byte string') if not strng.is_bin(message): raise ValueError('message must be byte string') h = hashes.sha1(message, return_object=True) result = False try: pkcs1_15.new(self.keyObject).verify(h, signature_bytes) result = True except ( ValueError, TypeError, ): if signature_as_digits and signature[0:1] == b'0': lg.warn('signature starts with "0", will try to verify again') try: signature_text = strng.to_text(signature) signature_int = int(signature_text) signature_bytes = number.long_to_bytes(signature_int) pkcs1_15.new(self.keyObject).verify( h, b'\x00' + signature_bytes) result = True lg.warn( 'signature with additional "0" in front passed verification' ) except: # lg.err('signature verification failed: %r' % signature) lg.err( 'signature=%r message=%r signature_as_digits=%r' % (signature, message, signature_as_digits)) # lg.exc(msg='signature=%r\nmessage=%r\nsignature_as_digits=%r\n' % ( # signature, message, signature_as_digits)) # do not raise any exception... return result
def sign(self, message, as_digits=True): if not self.keyObject: raise ValueError('key object is not exist') if not strng.is_bin(message): raise ValueError('message must be byte string') h = hashes.sha1(message, return_object=True) signature_bytes = pkcs1_15.new(self.keyObject).sign(h) if not as_digits: return signature_bytes signature_raw = strng.to_bin(number.bytes_to_long(signature_bytes)) if signature_bytes[0:1] == b'\x00': signature_raw = b'0' + signature_raw return signature_raw
def sha256(inp, hexdigest=False, return_object=False): global _CryptoLog # if _CryptoLog is None: # _CryptoLog = os.environ.get('CRYPTO_LOG') == '1' if not strng.is_bin(inp): raise ValueError('input must by byte string') h = SHA256.new(inp) if _Debug: if _CryptoLog: lg.args(_DebugLevel, hexdigest=h.hexdigest()) if return_object: return h if hexdigest: return strng.to_bin(h.hexdigest()) return h.digest()
def SessionKey(self): """ Return original SessionKey from ``EncryptedSessionKey`` using one of the methods depend on the type of ``DecryptKey`` parameter passed in the __init__() + ``crypt.key.DecryptLocalPrivateKey()`` if DecryptKey is None + ``my_keys.decrypt()`` if DecryptKey is a string with key_id + ``DecryptKey()`` if this is a callback method """ if callable(self.DecryptKey): return self.DecryptKey(self.EncryptedSessionKey) elif strng.is_text(self.DecryptKey): return my_keys.decrypt(self.DecryptKey, self.EncryptedSessionKey) elif strng.is_bin(self.DecryptKey): return my_keys.decrypt(strng.to_text(self.DecryptKey), self.EncryptedSessionKey) return key.DecryptLocalPrivateKey(self.EncryptedSessionKey)
def sign(self, message, as_digits=True): global _CryptoLog # if _CryptoLog is None: # _CryptoLog = os.environ.get('CRYPTO_LOG') == '1' if not self.keyObject: raise ValueError('key object is not exist') if not strng.is_bin(message): raise ValueError('message must be byte string') h = hashes.sha1(message, return_object=True) signature_raw = pkcs1_15.new(self.keyObject).sign(h) if not as_digits: if _Debug: if _CryptoLog: lg.args(_DebugLevel, signature_raw=signature_raw) return signature_raw signature_long = number.bytes_to_long(signature_raw) signature_bytes = strng.to_bin(signature_long) if _Debug: if _CryptoLog: lg.args(_DebugLevel, signature_bytes=signature_bytes) return signature_bytes
def _to_text(v): if strng.is_bin(v): v = v.decode(encoding, errors=enc_errors) if not strng.is_text(v): v = strng.to_text(v) return v