def test_quick(self): buff = api.new('unsigned char[]', api.EVP_MAX_MD_SIZE) key = api.new('char[]', self.key) data = api.new('char[]', self.data) size = api.new('unsigned int*') api.HMAC(self.md, api.cast('void*', key), len(self.key), api.cast('void*', data), len(self.data), api.cast('void*', buff), size) self.assertEqual(self.digest, api.buffer(buff, size[0])[:])
def test_long(self): buff = api.new('unsigned char[]', api.EVP_MAX_MD_SIZE) key = api.new('char[]', self.key) data = api.new('char[]', self.data) size = api.new('unsigned int*') ctx = api.new('HMAC_CTX*') api.HMAC_CTX_init(ctx) api.HMAC_Init_ex(ctx, api.cast('void*', key), len(self.key), self.md, api.NULL) api.HMAC_Update(ctx, api.cast('void*', data), len(self.data)) api.HMAC_Final(ctx, buff, size) api.HMAC_CTX_cleanup(ctx) self.assertEqual(self.digest, api.buffer(buff, size[0])[:])
def test_multiple_updates(self): buff = api.new('unsigned char[]', api.EVP_MAX_MD_SIZE) key = api.new('char[]', self.key) data = api.new('char[]', self.data) size = api.new('unsigned int*') ctx = api.new('HMAC_CTX*') api.HMAC_CTX_init(ctx) api.HMAC_Init_ex(ctx, api.cast('void*', key), len(self.key), self.md, api.NULL) for pos in range(len(self.data)): api.HMAC_Update(ctx, api.cast('void*', data+pos), 1) api.HMAC_Final(ctx, buff, size) api.HMAC_CTX_cleanup(ctx) self.assertEqual(self.digest, bytes(api.buffer(buff, size[0])))
def __init__(self, key, msg=None, digestmod=None): """Create a new HMAC object. key: key for the keyed hash object. msg: Initial input for the hash, if provided. digestmod: A message digest name. *OR* A module supporting PEP 247. *OR* A hashlib constructor returning a new hash object. If module or hashlib constuctor is passed as digestmod the '__name__' and 'args' attributes are searched to find a message digest name. If not provied the digestmod defaults to 'md5'. Note: key and msg must be a bytes objects. """ if digestmod is None: self._md = api.EVP_md5() else: self._md = self._get_md(digestmod) ctx = api.new('HMAC_CTX*') self._key = api.new('char[]', key) api.HMAC_Init_ex(ctx, api.cast('void*', self._key), len(key), self._md, api.NULL) cleanup = lambda _: api.HMAC_CTX_cleanup(ctx) self._weakref = weakref.ref(self, cleanup) self._ctx = ctx if msg is not None: self.update(msg)
def bio_types(self): types = [] bio = self._bio while api.cast('void*', bio) != api.NULL: types.insert(0, api.BIO_method_type(bio)) bio = api.BIO_next(bio) return types
def update(self, msg): """Update this hashing object with the string msg. """ if self._ctx is None: raise ValueError('HMAC already closed') data = api.new('char[]', msg) api.HMAC_Update(self._ctx, api.cast('void*', data), len(msg))
def test_copy(self): data = api.new('char[]', self.data_short) buf = api.new('unsigned char[]', api.EVP_MAX_MD_SIZE) size = api.new('unsigned int*') api.EVP_DigestUpdate(self.ctx, api.cast('void*', data), len(self.data_short)) api.EVP_MD_CTX_copy_ex(self.ctx_two, self.ctx) api.EVP_DigestFinal_ex(self.ctx_two, buf, size) hash_value = b''.join('{0:02x}'.format(v).encode() for v in islice(buf, size[0])) self.assertEqual(hash_value, self.hash_short) data = api.new('char[]', self.data_long[len(self.data_short):]) api.EVP_DigestUpdate(self.ctx, api.cast('void*', data), len(data) - 1) api.EVP_DigestFinal_ex(self.ctx, buf, size) hash_value = b''.join('{0:02x}'.format(v).encode() for v in islice(buf, size[0])) self.assertEqual(hash_value, self.hash_long)
def getrandbits(self, bits): """getrandbits(k) -> x. Generates a long int with k random bits.""" bytes = int(math.ceil(bits / 8)) shift = abs(8 - (bits % 8)) % 8 buff = api.new('unsigned char[]', bytes) bptr = api.cast('unsigned char*', buff) if not self._rand_bytes(bptr, len(buff)): raise RandomError('PRNG seeded with insufficient entropy') num = self._seq_to_int(buff) >> shift return num
def __getitem__(self, pos): if pos < 0: raise IndexError("list index out of range") bio = self.c_bio while pos > 0: nxt = api.BIO_next(bio) if api.cast('void*', nxt) == api.NULL: raise IndexError("list index out of range") bio = nxt pos -= 1 return bio
def random(self): """Get the next random number in the range [0.0, 1.0).""" buff = api.new('unsigned char[7]') bptr = api.cast('unsigned char*', buff) if not self._rand_bytes(bptr, len(buff)): raise RandomError('PRNG seeded with insufficient entropy') # python2 version of following python3 code # >>> num = (int.from_bytes(buff, 'big') >> 3) * EPSILON num = 0 for byte in buff: num <<= 8 num |= byte num = (num >> 3) * EPSILON return num
def __init__(self, filename, mode='r'): if mode not in self.MODES: msg = "mode string must begin with one of " msg += " ".join("'{0}'".format(m) for m in sorted(self.MODES)) msg += " not '{0}'".format(mode) raise ValueError(msg) self._filename = filename.encode() self._mode = mode.encode() mode = api.new('char[]', self._mode) filename = api.new('char[]', self._filename) bio = api.BIO_new_file(filename, mode) if api.cast('void*', bio) == api.NULL: messages = err.log_errors() raise IOError(messages[0]) super(BIOFile, self).__init__(bio)
def setUpClass(cls): api.RAND_bytes(api.cast('unsigned char*', cls.data), cls.samples)
def setUpClass(cls): if not api.RAND_status(): api.RAND_load_file(b"/dev/urandom", 1024) api.RAND_pseudo_bytes(api.cast('unsigned char*', cls.data), cls.samples)
def pop(self): bio = self._bio nxt = api.BIO_pop(bio) if api.cast('void*', nxt) != api.NULL: self._bio = nxt return bio
def update(self, data): "Update this hash object's state with the provided string." buff = api.new('char[]', data) ptr = api.cast('void*', buff) if not api.EVP_DigestUpdate(self._context, ptr, len(data)): raise DigestError('Error updating message digest')