Beispiel #1
0
 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())
Beispiel #3
0
 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)
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
 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)
Beispiel #7
0
 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)