def test_short_zeroes(self): logbase = int(math.log(1<<256, len(bin2pass.allchars))) target = bin2pass.allchars[0] * (logbase//2) + bin2pass.allchars[1] for _ in range(len(target)): rwd = bin2pass.pass2bin(target) self.assertEqual(bin2pass.derive(rwd, 'uld', len(target), bin2pass.symbols), target) target = target[1:]+bin2pass.allchars[0]
def data_received(self, data): if verbose: print('Data received: ', data) try: data = pysodium.crypto_sign_open(data, self.handler.getserverkey()) except ValueError: raise ValueError('invalid signature.\nabort') if data!=b'ok' and (data[:-42] == b'fail' or len(data)!=sphinxlib.DECAF_255_SER_BYTES+42): raise ValueError('fail') if not self.b: self.cb() return rwd=sphinxlib.finish(self.pwd, self.b, data[:sphinxlib.DECAF_255_SER_BYTES]) if self.handler.namesite is not None: if self.handler.namesite['name'].encode() not in self.handler.list(self.handler.namesite['site']): self.handler.cacheuser(self.handler.namesite) rule = data[sphinxlib.DECAF_255_SER_BYTES:] if len(rule)!=42: raise ValueError('fail') rk = pysodium.crypto_generichash(self.handler.getkey(),self.handler.getsalt()) rule = pysodium.crypto_secretbox_open(rule[24:], rule[:24],rk) rule = struct.unpack(">H",rule)[0] size = (rule & 0x7f) rule = {c for i,c in enumerate(('u','l','s','d')) if (rule >> 7) & (1 << i)} self.cb(bin2pass.derive(rwd,rule,size).decode())
def test_invert_reviter(self): chars = bin2pass.allchars for i in range(1,len(chars)): target=''.join(chars[-i:]) try: rwd = bin2pass.pass2bin(target) except OverflowError: break self.assertEqual(bin2pass.derive(rwd, 'uld', len(target), bin2pass.symbols), target)
def doSphinx(s, op, pwd, user, host): id = getid(host, user) r, alpha = sphinxlib.challenge(pwd) msg = b''.join([op, id, alpha]) s.send(msg) if op != GET: # == CHANGE, UNDO, COMMIT # auth: do sphinx with current seed, use it to sign the nonce auth(s, id, pwd, r) resp = s.recv(32 + RULE_SIZE) # beta + sealed rules if resp == b'\x00\x04fail' or len(resp) != 32 + RULE_SIZE: raise ValueError("error: sphinx protocol failure.") beta = resp[:32] rules = resp[32:] rwd = sphinxlib.finish(pwd, r, beta, id) try: classes, size = unpack_rule(rules) except ValueError: return if op != GET: # == CHANGE, UNDO, COMMIT # in case of undo/commit we also need to rewrite the rules and pub auth signing key blob if op in {UNDO, COMMIT}: sk, pk = get_signkey(id, rwd) clearmem(sk) rule = encrypt_blob(pack_rule(classes, size)) # send over new signed(pubkey, rule) msg = b''.join([pk, rule]) msg = sign_blob(msg, id, rwd) s.send(msg) if s.recv(2) != b'ok': print( "ohoh, something is corrupt, and this is a bad, very bad error message in so many ways" ) return ret = bin2pass.derive(pysodium.crypto_generichash(PASS_CTX, rwd), classes, size).decode() clearmem(rwd) return ret
def create(s, pwd, user, host, char_classes, size=0): # 1st step OPRF on the new seed id = getid(host, user) r, alpha = sphinxlib.challenge(pwd) msg = b''.join([CREATE, id, alpha]) s.send(msg) # wait for response from sphinx server beta = s.recv(32) if beta == b'\x00\x04fail': raise ValueError("error: sphinx protocol failure.") rwd = sphinxlib.finish(pwd, r, beta, id) # second phase, derive new auth signing pubkey sk, pk = get_signkey(id, rwd) clearmem(sk) try: size = int(size) except: raise ValueError("error: size has to be integer.") rule = encrypt_blob(pack_rule(char_classes, size)) # send over new signed(pubkey, rule) msg = b''.join([pk, rule]) msg = sign_blob(msg, id, rwd) s.send(msg) # add user to user list for this host # a malicous server could correlate all accounts on this services to this users here update_rec(s, host, user) ret = bin2pass.derive(pysodium.crypto_generichash(PASS_CTX, rwd), char_classes, size).decode() clearmem(rwd) return ret
def test_invert_random(self): chars = bin2pass.allchars for _ in range(1000): target=''.join(random.choices(chars,k=random.randrange(1,39))) rwd = bin2pass.pass2bin(target) self.assertEqual(bin2pass.derive(rwd, 'uld', len(target), bin2pass.symbols), target)
def test_invert_simple(self): target = "this is a pass2bin test string" rwd = bin2pass.pass2bin(target) self.assertEqual(bin2pass.derive(rwd, 'uld', len(target), bin2pass.symbols), target)