コード例 #1
0
ファイル: test_pysodium.py プロジェクト: Aeory/pysodium
 def test_crypto_sign_open(self):
     pk, sk = pysodium.crypto_sign_keypair()
     signed = pysodium.crypto_sign(b'howdy', sk)
     changed = signed[:pysodium.crypto_sign_BYTES] + b'0' + signed[
         pysodium.crypto_sign_BYTES + 1:]
     pysodium.crypto_sign_open(signed, pk)
     self.assertRaises(ValueError, pysodium.crypto_sign_open, changed, pk)
コード例 #2
0
    def change(self, data):
        # needs id, challenge, sig(id)
        # returns output from ./response | fail
        try:
            pk = self.getpk(data)
        except:
            return b'fail'
        try:
            data = pysodium.crypto_sign_open(data, pk)
        except ValueError:
            print('invalid signature')
            return b'fail'
        id = data[1:33]
        chal = data[33:65]

        tdir = os.path.expanduser(datadir + binascii.hexlify(id).decode())
        k = pysodium.randombytes(32)
        with open(tdir + '/new', 'wb') as fd:
            os.fchmod(fd.fileno(), 0o600)
            fd.write(k)

        try:
            rule = readf(tdir + "/rule")
        except:
            return b'fail'

        try:
            return respond(chal, id, secret=k)
        except ValueError:
            if verbose: print("respond fail")
            return b'fail'
コード例 #3
0
    def loadkey(self, type):
        if type in ['mp', 'cp', 'sp', 'created', 'valid']:
            with open(get_pk_filename(self.basedir, self.name), 'rb') as fd:
                tmp = fd.read()
            mk = tmp[nacl.crypto_sign_BYTES:nacl.crypto_sign_BYTES +
                     nacl.crypto_sign_PUBLICKEYBYTES]
            tmp = nacl.crypto_sign_open(tmp, mk)
            if type == 'mp': self.mp = mk
            i = nacl.crypto_sign_PUBLICKEYBYTES
            if type == 'sp':
                self.sp = tmp[i:i + nacl.crypto_sign_PUBLICKEYBYTES]
            i += nacl.crypto_sign_PUBLICKEYBYTES
            if type == 'cp':
                self.cp = tmp[i:i + nacl.crypto_box_PUBLICKEYBYTES]
            i += nacl.crypto_box_PUBLICKEYBYTES
            self.created = parse_isodatetime(tmp[i:i + 32])
            self.valid = parse_isodatetime(tmp[i + 32:i + 64])

        elif type in ['cs', 'ss']:
            tmp = get_sk_filename(self.basedir, self.name)
            if os.path.exists(tmp):
                tmp = self.decrypt_with_user_pw(tmp, 'subkeys')
                if type == 'ss':
                    self.ss = tmp[:nacl.crypto_sign_SECRETKEYBYTES]
                if type == 'cs':
                    self.cs = tmp[nacl.crypto_sign_SECRETKEYBYTES:]

        elif type == 'ms':
            tmp = get_sk_filename(self.basedir, self.name, ext='mk')
            if os.path.exists(tmp):
                self.ms = self.decrypt_with_user_pw(tmp, 'master key')
コード例 #4
0
def verify(msg, master=False, basedir=None):
    for keys in get_public_keys(basedir=basedir or pbp.defaultbase):
        try:
            verifying_key = keys.mp if master else keys.sp
            return keys.name, nacl.crypto_sign_open(msg, verifying_key)
        except ValueError:
            pass
コード例 #5
0
ファイル: publickey.py プロジェクト: stef/pbp
    def loadkey(self, type):
        if type in ['mp','cp','sp', 'created', 'valid']:
            with open(get_pk_filename(self.basedir, self.name), 'rb') as fd:
                tmp=fd.read()
            mk=tmp[nacl.crypto_sign_BYTES:nacl.crypto_sign_BYTES+nacl.crypto_sign_PUBLICKEYBYTES]
            tmp = nacl.crypto_sign_open(tmp, mk)
            if type == 'mp': self.mp=mk
            i=nacl.crypto_sign_PUBLICKEYBYTES
            if type == 'sp': self.sp=tmp[i:i+nacl.crypto_sign_PUBLICKEYBYTES]
            i+=nacl.crypto_sign_PUBLICKEYBYTES
            if type == 'cp': self.cp=tmp[i:i+nacl.crypto_box_PUBLICKEYBYTES]
            i+=nacl.crypto_box_PUBLICKEYBYTES
            self.created = parse_isodatetime(tmp[i:i + 32].decode('utf-8'))
            self.valid = parse_isodatetime(tmp[i + 32:i + 64].decode('utf-8'))

        elif type in ['cs', 'ss']:
            tmp = get_sk_filename(self.basedir, self.name)
            if os.path.exists(tmp):
                tmp = self.decrypt_with_user_pw(tmp, '%s subkey' % ('signing' if type == 'ss' else 'encryption'))
                if type == 'ss': self.ss = tmp[:nacl.crypto_sign_SECRETKEYBYTES]
                if type == 'cs': self.cs = tmp[nacl.crypto_sign_SECRETKEYBYTES:]
            else:
                raise ValueError("missing key %s" % self.name)

        elif type == 'ms':
            tmp = get_sk_filename(self.basedir, self.name, ext='mk')
            if os.path.exists(tmp):
                self.ms = self.decrypt_with_user_pw(tmp, 'master key')
            else:
                raise ValueError("missing key %s" % self.name)
コード例 #6
0
    def create(self, data):
        # needs pubkey, id, challenge, sig(id)
        # returns output from ./response | fail
        pk = data[129:161]
        try:
            data = pysodium.crypto_sign_open(data, pk)
        except ValueError:
            print('invalid signature')
            return b'fail'
        id = data[1:33]
        chal = data[33:65]
        tdir = datadir + binascii.hexlify(id).decode()

        if os.path.exists(tdir):
            print(tdir, 'exists')
            return b'fail'  # key already exists

        os.mkdir(tdir, 0o700)

        with open(tdir + '/pub', 'wb') as fd:
            os.fchmod(fd.fileno(), 0o600)
            fd.write(pk)

        key = pysodium.randombytes(32)
        with open(tdir + '/key', 'wb') as fd:
            os.fchmod(fd.fileno(), 0o600)
            fd.write(key)

        return respond(chal, id)
コード例 #7
0
ファイル: publickey.py プロジェクト: TLINDEN/pbp
    def loadkey(self, type):
        if type in ["mp", "cp", "sp", "created", "valid"]:
            with open(get_pk_filename(self.basedir, self.name), "r") as fd:
                tmp = fd.read()
            mk = tmp[nacl.crypto_sign_BYTES : nacl.crypto_sign_BYTES + nacl.crypto_sign_PUBLICKEYBYTES]
            tmp = nacl.crypto_sign_open(tmp, mk)
            if type == "mp":
                self.mp = mk
            i = nacl.crypto_sign_PUBLICKEYBYTES
            if type == "sp":
                self.sp = tmp[i : i + nacl.crypto_sign_PUBLICKEYBYTES]
            i += nacl.crypto_sign_PUBLICKEYBYTES
            if type == "cp":
                self.cp = tmp[i : i + nacl.crypto_box_PUBLICKEYBYTES]
            i += nacl.crypto_box_PUBLICKEYBYTES
            self.created = parse_isodatetime(tmp[i : i + 32])
            self.valid = parse_isodatetime(tmp[i + 32 : i + 64])

        elif type in ["cs", "ss"]:
            tmp = get_sk_filename(self.basedir, self.name)
            if os.path.exists(tmp):
                tmp = self.decrypt_with_user_pw(tmp, "%s subkey" % ("signing" if type == "ss" else "encryption"))
                if type == "ss":
                    self.ss = tmp[: nacl.crypto_sign_SECRETKEYBYTES]
                if type == "cs":
                    self.cs = tmp[nacl.crypto_sign_SECRETKEYBYTES :]
            else:
                raise ValueError("missing key")

        elif type == "ms":
            tmp = get_sk_filename(self.basedir, self.name, ext="mk")
            if os.path.exists(tmp):
                self.ms = self.decrypt_with_user_pw(tmp, "master key")
            else:
                raise ValueError("missing key")
コード例 #8
0
ファイル: publickey.py プロジェクト: TLINDEN/pbp
def verify(msg, master=False, basedir=None):
    for keys in get_public_keys(basedir=basedir or pbp.defaultbase):
        try:
            verifying_key = keys.mp if master else keys.sp
            return keys.name, nacl.crypto_sign_open(msg, verifying_key)
        except ValueError:
            pass
コード例 #9
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())
コード例 #10
0
ファイル: publickey.py プロジェクト: fpletz/pbp
    def loadkey(self, type):
        if type in ['mp','cp','sp', 'created', 'valid']:
            with open(get_pk_filename(self.basedir, self.name), 'r') as fd:
                tmp=fd.read()
            mk=tmp[nacl.crypto_sign_BYTES:nacl.crypto_sign_BYTES+nacl.crypto_sign_PUBLICKEYBYTES]
            tmp = nacl.crypto_sign_open(tmp, mk)
            if type == 'mp': self.mp=mk
            i=nacl.crypto_sign_PUBLICKEYBYTES
            if type == 'sp': self.sp=tmp[i:i+nacl.crypto_sign_PUBLICKEYBYTES]
            i+=nacl.crypto_sign_PUBLICKEYBYTES
            if type == 'cp': self.cp=tmp[i:i+nacl.crypto_box_PUBLICKEYBYTES]
            i+=nacl.crypto_box_PUBLICKEYBYTES
            self.created = parse_isodatetime(tmp[i:i + 32])
            self.valid = parse_isodatetime(tmp[i + 32:i + 64])

        elif type in ['cs', 'ss']:
            tmp = get_sk_filename(self.basedir, self.name)
            if os.path.exists(tmp):
                tmp = self.decrypt_with_user_pw(tmp, 'subkeys')
                if type == 'ss': self.ss = tmp[:nacl.crypto_sign_SECRETKEYBYTES]
                if type == 'cs': self.cs = tmp[nacl.crypto_sign_SECRETKEYBYTES:]

        elif type == 'ms':
            tmp = get_sk_filename(self.basedir, self.name, ext='mk')
            if os.path.exists(tmp):
                self.ms = self.decrypt_with_user_pw(tmp, 'master key')
    def sync(self, pk, payload):
        """Update hg and return new event ids in topological order."""

        info = crypto_sign(dumps({c: self.height[h]
                for c, h in self.can_see[self.head].items()}), self.sk)
        msg = crypto_sign_open(self.network[pk](self.pk, info), pk)

        remote_head, remote_hg = loads(msg)
        new = tuple(toposort(remote_hg.keys() - self.hg.keys(),
                       lambda u: remote_hg[u].p))

        for h in new:
            ev = remote_hg[h]
            if self.is_valid_event(h, ev):
                self.add_event(h, ev)


        if self.is_valid_event(remote_head, remote_hg[remote_head]):
            h, ev = self.new_event(payload, (self.head, remote_head))
            # this really shouldn't fail, let's check it to be sure
            assert self.is_valid_event(h, ev)
            self.add_event(h, ev)
            self.head = h

        return new + (h,)
コード例 #12
0
    def commit(self, data):
        # needs id, sig(id)
        try:
            pk = self.getpk(data)
        except:
            return b'fail'
        try:
            data = pysodium.crypto_sign_open(data, pk)
        except ValueError:
            print('invalid signature')
            return b'fail'
        id = data[1:33]
        tdir = os.path.expanduser(datadir + binascii.hexlify(id).decode())

        try:
            with open(tdir + '/new', 'rb') as fd:
                k = fd.read()
        except FileNotFoundError:
            return b'fail'

        if (len(k) != 32):
            return b'fail'

        with open(tdir + '/key', 'wb') as fd:
            os.fchmod(fd.fileno(), 0o600)
            fd.write(k)

        os.unlink(tdir + '/new')

        return b'ok'
コード例 #13
0
def verify_signed_message(signed: bytes, verkey: bytes) -> bool:
    """
    Verify a signed message according to a public verification key.

    Args:
        signed: The signed message
        verkey: The verkey to use in verification

    Returns:
        True if verified, else False

    """
    try:
        pysodium.crypto_sign_open(signed, verkey)
    except ValueError:
        return False
    return True
コード例 #14
0
def proof_open(team, proof):
    assert isinstance(proof, bytes)
    proof = b64decode(proof)

    claimed_chall_id = proof[2 * 64:].decode('utf-8')
    claimed_chall = Challenge(claimed_chall_id)

    chall_pk = claimed_chall['pk']
    team_pk = team['sign_pk']

    membership_proof = pysodium.crypto_sign_open(proof, chall_pk)
    chall_id = pysodium.crypto_sign_open(membership_proof,
                                         team_pk).decode('utf-8')

    if claimed_chall_id != chall_id:
        raise ValueError('invalid proof')

    return claimed_chall
コード例 #15
0
def get_public_key(ip, port, provider_key, provider_url):
    '''Get public key from provider.'''
    header = DnsHeader()

    question = DnsQuestion()
    question.labels = provider_url.split('.')
    question.qtype = 16  # TXT record

    packet = DnsPacket(header)
    packet.addQuestion(question)

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    dest = (ip, port)
    sock.sendto(packet.toBinary(), dest)

    (response, address) = sock.recvfrom(1024)

    bincerts = find_certificates(response)

    if not bincerts:
        raise DnscryptException("No certificate received.")

    certificates = []

    for bincert in bincerts:
        certificates.append(Certificate(bincert))

    certificate = max(certificates, key=lambda x: x.serial and not x.expired())

    if certificate.expired():
        raise DnscryptException("Certificate expired.")

    if USE_LOCAL_LIBS:
        try:
            import pysodium
            return pysodium.crypto_sign_open(
                certificate.bincert,
                provider_key.decode('hex')), certificate.magic_query
        except ImportError:
            pass

        try:
            import nacl
            import nacl.bindings
            return nacl.bindings.crypto_sign_open(
                certificate.bincert,
                provider_key.decode('hex')), certificate.magic_query
        except ImportError:
            pass

    import ed25519py
    return ed25519py.crypto_sign_open(
        certificate.bincert,
        provider_key.decode('hex')), certificate.magic_query
    def ask_sync(self, pk, info):
        """Respond to someone wanting to sync (only public method)."""

        # TODO: only send a diff? maybe with the help of self.height
        # TODO: thread safe? (allow to run while mainloop is running)

        cs = loads(crypto_sign_open(info, pk))

        subset = {h: self.hg[h] for h in bfs(
            (self.head,),
            lambda u: (p for p in self.hg[u].p
                       if self.hg[p].c not in cs or self.height[p] > cs[self.hg[p].c]))}
        msg = dumps((self.head, subset))
        return crypto_sign(msg, self.sk)
コード例 #17
0
def get_public_key(ip, port, provider_key, provider_url):
    '''Get public key from provider.'''
    header = DnsHeader()

    question = DnsQuestion()
    question.labels = provider_url.split('.')
    question.qtype = 16  # TXT record

    packet = DnsPacket(header)
    packet.addQuestion(question)

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    dest = (ip, port)
    sock.sendto(packet.toBinary(), dest)

    (response, address) = sock.recvfrom(1024)

    bincerts = find_certificates(response)

    if not bincerts:
        raise DnscryptException("No certificate received.")

    certificates = []

    for bincert in bincerts:
        certificates.append(Certificate(bincert))

    certificate = max(certificates, key=lambda x: x.serial and not x.expired())

    if certificate.expired():
        raise DnscryptException("Certificate expired.")

    if USE_LOCAL_LIBS:
        try:
            import pysodium
            return pysodium.crypto_sign_open(certificate.bincert, provider_key.decode('hex')), certificate.magic_query
        except ImportError:
            pass

        try:
            import nacl
            import nacl.bindings
            return nacl.bindings.crypto_sign_open(certificate.bincert, provider_key.decode('hex')), certificate.magic_query
        except ImportError:
            pass

    import ed25519py
    return ed25519py.crypto_sign_open(certificate.bincert, provider_key.decode('hex')), certificate.magic_query
コード例 #18
0
ファイル: crypto.py プロジェクト: nickodell/dhtdns
def parse_innerbox(bytes_):
    pubkey, rawsigned = mid_pack.unpack(bytes_)
    try:
        signed_message = pysodium.crypto_sign_open(rawsigned, pubkey)
    except:
        raise SignatureError()
    inner_ver, ts, seq, signed_message, payload = \
        inner_pack.unpack(signed_message)
    record = Record(pubkey=pubkey, \
                    inner_ver=inner_ver, \
                    ts=ts, \
                    seq=seq, \
                    rawsig=rawsigned, \
                    payload=payload)
    return record
コード例 #19
0
    def get(self, data):
        # needs id, challenge, sig(id)
        # returns output from ./response | fail
        try:
            pk = self.getpk(data)
        except:
            return b'fail'
        try:
            data = pysodium.crypto_sign_open(data, pk)
        except ValueError:
            print('invalid signature')
            return b'fail'
        id = data[1:33]
        chal = data[33:65]

        return respond(chal, id)
コード例 #20
0
    def delete(self, data):
        # needs id, sig(id)
        # returns ok | fail
        try:
            pk = self.getpk(data)
        except:
            return b'fail'
        try:
            data = pysodium.crypto_sign_open(data, pk)
        except ValueError:
            print('invalid signature')
            return b'fail'
        id = data[1:33]

        tdir = datadir + binascii.hexlify(id).decode()
        shutil.rmtree(tdir)
        return b'ok'
コード例 #21
0
ファイル: pbp.py プロジェクト: fpletz/pbp
def import_handler(infile=None, basedir=None):
    # imports ascii armored key from infile or stdin to basedir
    if not infile:
        b85 = sys.stdin.readline().strip()
    else:
        with file(infile) as fd:
            b85 = fd.readline().strip()
    pkt = b85decode(b85)
    mp = pkt[nacl.crypto_sign_BYTES:nacl.crypto_sign_BYTES+nacl.crypto_sign_PUBLICKEYBYTES]
    keys = nacl.crypto_sign_open(pkt, mp)
    if not keys:
        return
    name = keys[nacl.crypto_sign_PUBLICKEYBYTES*3:]
    peer = publickey.Identity(name, basedir=basedir)
    peer.mp = mp
    peer.cp = keys[nacl.crypto_sign_PUBLICKEYBYTES:nacl.crypto_sign_PUBLICKEYBYTES*2]
    peer.sp = keys[nacl.crypto_sign_PUBLICKEYBYTES*2:nacl.crypto_sign_PUBLICKEYBYTES*3]
    # TODO check if key exists, then ask for confirmation of pk overwrite
    peer.save()
    return name
コード例 #22
0
    def parse_and_validate_redirect_url(self, url: str, state: str):
        data_object = parse_signed_attempt_from_url(url)
        signed_attempt, double_name, rest = (
            lambda signedAttempt, doubleName, **rest: (signedAttempt, doubleName, rest))(
            **data_object)

        user_public_key = self.get_public_key_for_double_name(double_name)

        sign_result = pysodium.crypto_sign_open(
            b64decode(signed_attempt),
            user_public_key
        )

        sign_result_dict = json.loads(sign_result.decode("utf-8"))

        if sign_result_dict['signedState'] != state:
            raise ValueError('state could not be matched')

        if sign_result_dict['doubleName'] != double_name:
            raise ValueError('The name cannot be matched.')

        if sign_result_dict['appId'] != self.app_id:
            raise ValueError('The appId cannot be matched.')

        encrypted_data = sign_result_dict['data']

        keyPair = generate_key_pair(self.seed_phrase)

        profile_data = decrypt(
            encrypted_data['ciphertext'],
            encrypted_data['nonce'],
            keyPair[1],
            user_public_key
        )

        return {
            'selectedImageId': sign_result_dict['selectedImageId'],
            'randomRoom': sign_result_dict['randomRoom'],
            'profile': json.loads(profile_data),
        }
コード例 #23
0
ファイル: pbp.py プロジェクト: stef/pbp
def import_handler(infile=None, basedir=None):
    # imports ascii armored key from infile or stdin to basedir
    if not infile:
        b85 = sys.stdin.readline().strip()
    else:
        with open(infile, 'r') as fd:
            b85 = fd.readline().strip()
    pkt = b85decode(b85)
    mp = pkt[nacl.crypto_sign_BYTES:nacl.crypto_sign_BYTES+nacl.crypto_sign_PUBLICKEYBYTES]
    keys = nacl.crypto_sign_open(pkt, mp)
    if not keys:
        return
    name = keys[(nacl.crypto_sign_PUBLICKEYBYTES*3)+2*32:].decode('utf-8')
    kfile = publickey.get_pk_filename(basedir, name)
    if os.path.exists(kfile):
        bkp = kfile+'.old'
        print >>sys.stderr, "backing up existing key to %s" % bkp
        os.rename(kfile,bkp)
    with open(kfile, 'wb') as fd:
        fd.write(pkt)
    # TODO check if key exists, then ask for confirmation of pk overwrite
    return name
コード例 #24
0
    def change(self, data):
        # needs id, challenge, sig(id)
        # returns output from ./response | fail
        try:
            pk = self.getpk(data)
        except:
            return b'fail'
        try:
            data = pysodium.crypto_sign_open(data, pk)
        except ValueError:
            print('invalid signature')
            return b'fail'
        id = data[1:33]
        chal = data[33:65]

        tdir = datadir + binascii.hexlify(id).decode()
        key = pysodium.randombytes(32)
        with open(tdir + '/key', 'wb') as fd:
            os.fchmod(fd.fileno(), 0o600)
            fd.write(key)

        return respond(chal, id)
コード例 #25
0
    def data_received(self, data):
        if verbose: print('Data received: {!r}'.format(data.decode()))

        try:
            data = pysodium.crypto_sign_open(data, serverkey)
        except ValueError:
            print('invalid signature.\nabort')
            return

        if data == b'fail':
            print('fail')
            return

        if not self.b:
            return

        rwd = sphinx.finish(self.b, data)

        rule = getrule(datadir, id)
        if not rule:
            print("no password rule defined for this password.")
        rule, size = rule
        print(bin2pass.derive(rwd, rule, size).decode())
コード例 #26
0
ファイル: pbp.py プロジェクト: dnet/pbp
def import_handler(infile=None, basedir=None):
    if not infile:
        b85 = sys.stdin.readline().strip()
    else:
        with open(infile, 'rb') as fd:
            b85 = fd.readline().strip()
    pkt = b85decode(b85)
    mp = pkt[nacl.crypto_sign_BYTES:nacl.crypto_sign_BYTES +
             nacl.crypto_sign_PUBLICKEYBYTES]
    keys = nacl.crypto_sign_open(pkt, mp)
    if not keys:
        die("invalid key")
    name = keys[nacl.crypto_sign_PUBLICKEYBYTES * 3:]
    peer = publickey.Identity(name, basedir=basedir)
    peer.mp = mp
    peer.cp = keys[nacl.
                   crypto_sign_PUBLICKEYBYTES:nacl.crypto_sign_PUBLICKEYBYTES *
                   2]
    peer.sp = keys[nacl.crypto_sign_PUBLICKEYBYTES *
                   2:nacl.crypto_sign_PUBLICKEYBYTES * 3]
    # TODO check if key exists, then ask for confirmation of pk overwrite
    peer.save()
    print('Success: imported public keys for', name)
コード例 #27
0
ファイル: publickey.py プロジェクト: stef/pbp
    def loadkey(self, type):
        if type in ['mp', 'cp', 'sp', 'created', 'valid']:
            with open(get_pk_filename(self.basedir, self.name), 'rb') as fd:
                tmp = fd.read()
            mk = tmp[nacl.crypto_sign_BYTES:nacl.crypto_sign_BYTES +
                     nacl.crypto_sign_PUBLICKEYBYTES]
            tmp = nacl.crypto_sign_open(tmp, mk)
            if type == 'mp': self.mp = mk
            i = nacl.crypto_sign_PUBLICKEYBYTES
            if type == 'sp':
                self.sp = tmp[i:i + nacl.crypto_sign_PUBLICKEYBYTES]
            i += nacl.crypto_sign_PUBLICKEYBYTES
            if type == 'cp':
                self.cp = tmp[i:i + nacl.crypto_box_PUBLICKEYBYTES]
            i += nacl.crypto_box_PUBLICKEYBYTES
            self.created = parse_isodatetime(tmp[i:i + 32].decode('utf-8'))
            self.valid = parse_isodatetime(tmp[i + 32:i + 64].decode('utf-8'))

        elif type in ['cs', 'ss']:
            tmp = get_sk_filename(self.basedir, self.name)
            if os.path.exists(tmp):
                tmp = self.decrypt_with_user_pw(
                    tmp, '%s subkey' %
                    ('signing' if type == 'ss' else 'encryption'))
                if type == 'ss':
                    self.ss = tmp[:nacl.crypto_sign_SECRETKEYBYTES]
                if type == 'cs':
                    self.cs = tmp[nacl.crypto_sign_SECRETKEYBYTES:]
            else:
                raise ValueError("missing key %s" % self.name)

        elif type == 'ms':
            tmp = get_sk_filename(self.basedir, self.name, ext='mk')
            if os.path.exists(tmp):
                self.ms = self.decrypt_with_user_pw(tmp, 'master key')
            else:
                raise ValueError("missing key %s" % self.name)
コード例 #28
0
ファイル: publickey.py プロジェクト: stef/pbp
 def verify(self, msg, master=False):
     try:
         return nacl.crypto_sign_open(msg, self.mp if master else self.sp)
     except ValueError:
         return
コード例 #29
0
ファイル: test_pysodium.py プロジェクト: apsyxyz/pysodium
 def test_crypto_sign_open(self):
     pk, sk = pysodium.crypto_sign_keypair()
     signed = pysodium.crypto_sign(b'howdy', sk)
     changed = signed[:pysodium.crypto_sign_BYTES] + b'0' + signed[pysodium.crypto_sign_BYTES + 1:]
     pysodium.crypto_sign_open(signed, pk)
     self.assertRaises(ValueError, pysodium.crypto_sign_open, changed, pk)
コード例 #30
0
ファイル: test_sign.py プロジェクト: data-luminosity/message
import pysodium

pk=None
sk=None

with open("keys/sign_public.key", "rb") as in_file:
    pk = in_file.read()
with open("keys/sign_private.key", "rb") as in_file:
    sk = in_file.read()

signed = pysodium.crypto_sign(b'test', sk)
ret=pysodium.crypto_sign_open(signed, pk)
print(ret)
コード例 #31
0
def decrypt_payload(payload, pubkey):
    return crypto_sign_open(payload, pubkey)
コード例 #32
0
#!/usr/bin/python3
import msgpack
import base64
import pysodium
rot = base64.b64decode('kwDEAZDEIHn1MDouHBP7X1w945IARpSuHVVsCdwAA7B4E2+AWXKh')
chain = base64.b64decode('chain-to-analyze')
try:
    chain = msgpack.unpackb(chain, raw=False)
    legacy = False
except:
    print("Warning: Legacy chain.")
    legacy = True
    chain = msgpack.unpackb(chain, raw=True)
chain = [rot] + chain
pk = None
for npk in chain:
    if pk != None:
        pk = msgpack.unpackb(pysodium.crypto_sign_open(npk, pk[2]), raw=legacy)
    else:
        pk = msgpack.unpackb(npk, raw=legacy)
    print("Raw Key:",
          base64.b64encode(msgpack.packb(pk, use_bin_type=(not legacy))))
    print("Timestamp:", pk[0])
    print("Posion:", msgpack.unpackb(pk[1], raw=legacy))
    print("Key:", pk[2].hex())
    print("")
コード例 #33
0
ファイル: publickey.py プロジェクト: stef/pbp
 def verify(self, msg, master=False):
     try:
         return nacl.crypto_sign_open(msg, self.mp if master else self.sp)
     except ValueError:
         return
コード例 #34
0
query.write(protocolOut)
bytes = transportOut.getvalue()

sign_pk=None
sign_sk=None
with open("keys/sign_public.key", "rb") as in_file:
    sign_pk = in_file.read()
with open("keys/sign_private.key", "rb") as in_file:
    sign_sk = in_file.read()

signed = pysodium.crypto_sign(bytes, sign_sk)
base64bytes=base64.b64encode(signed)

#assert can verify and de-serialize
recoveredbytes=base64.b64decode(base64bytes)
plaintextbytes=pysodium.crypto_sign_open(recoveredbytes, sign_pk)
transportIn = TTransport.TMemoryBuffer(plaintextbytes)
protocolIn = TBinaryProtocol.TBinaryProtocol(transportIn)
recoveredqueries = Query()
recoveredqueries.read(protocolIn)
print(recoveredqueries)

queryFile = open ("queries/ucla.query", "wb")
querybytearray=bytearray(base64bytes)
queryFile.write(querybytearray)


keyfile=os.path.join(".","keys/sign_public.key")
with open(keyfile, "rb") as in_file:
    sign_pk = in_file.read()
コード例 #35
0
def process_chain(chain,
                  topic=None,
                  usage=None,
                  allowlist=None,
                  denylist=None):
    #
    # chain should be a single msgpack array, with the next item in the array
    # signed by the entity with public key given in the current item. The first
    # item must be signed by a root of trust (which are given in allowlist).
    # Each (signed) item is itself a msgpack array containing:
    # (0) a max_age timestamp (64-bit unsigned unix maximum time signature is valid)
    # (1) a poison array. Sets allowed signature key usages, topics, pathlengths.
    # (2) public key
    # Possibly more items in (3)+, especially common for the final item,
    # but not needed to check the chain.
    #
    # Raises a ValueError if chain does not match topic or usage criteria, or
    # uses a denylisted key, unless there is ultimately a chain between
    # an allowlisted key and the final item with no denylisted keys.
    # The final item might itself be the allowlisted key.
    #
    # Otherwise, returns an array containing two arrays. The first array
    #  contains:
    #  (0) The minimum max_age timestamp
    #  (1) The intersection of allowed topics and usages, in the
    #      poison array (i.e. the net allowed topics and usages)
    #  (2) The public key
    #  And any items in (3)+ from the final item.
    # The second array contains one entry per item in the chain, containing
    # a textual / human readable description (useful for verbose messages) of
    # how the item was interpreted.
    #
    printable = []
    if allowlist is None:
        raise ProcessChainError("No possible roots of trust!", printable)
    last_error = ProcessChainError("No roots of trust found!", printable)
    for rot in allowlist:
        printable = []
        try:
            denylisted = False
            val = [rot] + msgpack.unpackb(chain, raw=True)
            if len(val) < 2:
                # must be validating at least one chain item beyond the item from the allowlist
                raise ValueError("Chain too short!")
            pk = None
            for npk in val:
                if not (pk is None):
                    if key_in_list(pk[2], denylist) != None:
                        denylisted = True
                        logging.warning(
                            "Chain uses denylisted signing key %s.",
                            pk[2].hex())
                        # this is not immediately fatal because a subkey might be allowlisted
                    elif key_in_list(pk[2], allowlist) != None:
                        # allowlisted subkey overrides denylist
                        denylisted = False
                        pk = intersect_certs(
                            pk,
                            msgpack.unpackb(key_in_list(pk[2], allowlist),
                                            raw=True), True)
                    try:
                        pk = intersect_certs(
                            pk,
                            msgpack.unpackb(pysodium.crypto_sign_open(
                                npk, pk[2]),
                                            raw=True), False)
                    except:
                        raise ValueError("Invalid signing!")
                else:
                    pk = msgpack.unpackb(npk, raw=True)  # root is unsigned
                printable.append(str(printable_cert(pk)))
            # must finally check if leaf key is in allowlist/denylist
            if key_in_list(pk[2], allowlist) != None:
                denylisted = False
            if key_in_list(pk[2], denylist) != None:
                denylisted = True
            # make sure our chain doesn't have breaking denylisted keys
            if denylisted:
                raise ValueError("Chain uses denylisted public key")
            # ensure composite chain is valid
            if (pk[0] < time() and pk[0] != 0):
                raise ValueError("Expired Chain!")
            if not validate_poison('topics', topic, pk):
                raise ValueError(
                    "No matching topic in allowed intersection set.")
            if not validate_poison('usages', usage, pk):
                raise ValueError(
                    "No matching usage in allowed intersection set.")
            if not validate_poison('pathlen', 0, pk):
                raise ValueError("Exceeded allowed pathlen.")
            return [pk, printable]
        except ValueError as e:
            printable.append(str(e))
            last_error = ProcessChainError("Error during Validation:",
                                           printable)
    # We allow a key to self-sign itself to be denylisted. This enables any private
    # key to denylist itself
    try:
        chain = msgpack.unpackb(chain, raw=True)
        if len(chain) == 2:
            pk = msgpack.unpackb(chain[0], raw=True)
            pk0 = pk[2]
            pk = intersect_certs(
                pk,
                msgpack.unpackb(pysodium.crypto_sign_open(chain[1], pk[2]),
                                raw=True), False)
            if pk0 == pk[2] and multimatch(
                    usage, ['key-denylist']) and validate_poison(
                        'usages', 'key-denylist', pk) and validate_poison(
                            'pathlen', 0, pk):
                return [pk, [str(printable_cert(pk))]]
    except:
        pass
    raise last_error