Exemplo n.º 1
0
 def test_generate_default(self):
     dest = datatypes.Destination()
     assert dest.enckey.key_type == crypto.EncType.ELGAMAL_2048
     assert dest.sigkey.key_type == crypto.SigType.DSA_SHA1
     assert dest.cert.type == datatypes.CertificateType.NULL
     dest2 = datatypes.Destination()
     assert dest2.enckey.key.y != dest.enckey.key.y
     assert dest2.sigkey.key.y != dest.sigkey.key.y
Exemplo n.º 2
0
 def test_serialize_nullcert(self):
     dest = datatypes.Destination(crypto.ElGamalKey(), crypto.DSAKey())
     assert dest.cert.type == datatypes.CertificateType.NULL
     data = dest.serialize()
     dest2 = datatypes.Destination(raw=data)
     assert dest2.enckey.key.y == dest.enckey.key.y
     assert dest2.sigkey.key.y == dest.sigkey.key.y
     assert dest2.cert.type == dest.cert.type
     assert dest2.padding == dest.padding
Exemplo n.º 3
0
    def test_generate_specify_types(self):
        dest = datatypes.Destination(crypto.EncType.ELGAMAL_2048, crypto.SigType.DSA_SHA1)
        assert dest.enckey.key_type == crypto.EncType.ELGAMAL_2048
        assert dest.sigkey.key_type == crypto.SigType.DSA_SHA1
        assert dest.cert.type == datatypes.CertificateType.NULL

        dest = datatypes.Destination(sigkey=crypto.SigType.ECDSA_SHA256_P256)
        self._assert_keycert(dest, crypto.EncType.ELGAMAL_2048,
                                   crypto.SigType.ECDSA_SHA256_P256)
Exemplo n.º 4
0
 def test_serialize_keycert(self):
     dest = datatypes.Destination(crypto.ElGamalKey(), crypto.ECDSA256Key())
     assert dest.cert.type == datatypes.CertificateType.KEY
     data = dest.serialize()
     dest2 = datatypes.Destination(raw=data)
     assert dest2.enckey.key.y == dest.enckey.key.y
     assert dest2.sigkey.key.get_pubkey() == dest.sigkey.key.get_pubkey()
     assert dest2.cert.type == dest.cert.type
     assert dest2.padding == dest.padding
Exemplo n.º 5
0
        def test_generate_from_keycert(self):
            keycert = datatypes.KeyCertificate(crypto.DSAKey(),
                                               crypto.ElGamalKey())
            dest = datatypes.Destination(cert=keycert)
            assert dest.enckey.key_type == crypto.EncType.ELGAMAL_2048
            assert dest.sigkey.key_type == crypto.SigType.DSA_SHA1
            assert dest.cert.type == datatypes.CertificateType.NULL

            keycert = datatypes.KeyCertificate(crypto.ECDSA256Key(),
                                               crypto.ElGamalKey())
            dest = datatypes.Destination(cert=keycert)
            self._assert_keycert(dest, crypto.EncType.ELGAMAL_2048,
                                 crypto.SigType.ECDSA_SHA256_P256)
Exemplo n.º 6
0
def lookup(name, samAddr=_defaultSAMAddr):
    """
    lookup an i2p name
    :returns i2p.datatypes.Destination:
    """
    if isinstance(name, datatypes.Destination):
        # if it's already a destination return it :p
        return name
    # create new socket for lookup
    sock = None
    try:
        sock = pysocket.create_connection(samAddr)
        repl = _sam_cmd(sock, _greeting())
        if repl.opts['RESULT'] != 'OK':
            # fail to handshake
            sock.close()
            raise pysocket.error(errno.EAGAIN, "cannot connect to i2p router")
    except pysocket.timeout as ex:
        raise ex
    except pysocket.error as ex:
        raise ex
    else:
        assert sock is not None
        # do lookup
        repl = _sam_cmd(sock, "NAMING LOOKUP NAME={}".format(name))
        # close socket as it is not needed anymore
        sock.close()
        if 'VALUE' in repl.opts:
            dest = datatypes.Destination(raw=repl.opts['VALUE'], b64=True)
            return dest
        else:
            # failed to lookup
            raise pysocket.herror(errno.EAGAIN, "name not resolved: {}".format(name))
Exemplo n.º 7
0
 def test_parse(self):
     dest = datatypes.Destination(crypto.ElGamalKey(), crypto.DSAKey(), datatypes.Certificate())
     lease = datatypes.Lease(b'f'*32, 1, datatypes.Date(1))
     ls = datatypes.LeaseSet(dest=dest, ls_enckey=crypto.ElGamalKey(), ls_sigkey=crypto.DSAKey(), leases=[lease])
     data = ls.serialize()
     ls2 = datatypes.LeaseSet(raw=data)
     assert ls2.dest.base64() == ls.dest.base64()
     assert ls2.enckey.key.y == ls.enckey.key.y
     assert ls2.sigkey.key.y == ls.sigkey.key.y
     assert len(ls2.leases) == len(ls.leases)
Exemplo n.º 8
0
 def test_serialize(self):
     dest = datatypes.Destination(crypto.ElGamalKey(), crypto.DSAKey(),
                                  datatypes.Certificate())
     lease = datatypes.Lease(b'f' * 32, 1, datatypes.Date(1))
     ls = datatypes.LeaseSet(dest=dest,
                             ls_enckey=crypto.ElGamalKey(),
                             ls_sigkey=crypto.DSAKey(),
                             leases=[lease])
     data = ls.serialize()
     dest.verify(data[:-40], data[-40:])
Exemplo n.º 9
0
 def recvfrom(self, nbytes, flags=0):
     """
     recv bytes from a remote sender
     :param nbytes: number of bytes to recv max
     :return (data, addressInfo):
     """
     data, addr = self._dgram_sock.recvfrom(nbytes)
     if addr == self._samDgramAddr:
         # only accept packets from the sam udp address
         idx = data.index(b'\n')
         return datatypes.Destination(raw=data[:idx], b64=True), bytearray(data[1+idx:])
     else:
         self._log.warn("invalid source address for sam packet {}".format(addr))
Exemplo n.º 10
0
 def recvfrom_into(self, buffer, nbytes=None, flags=0):
     """
     recv bytes from a remote sender
     :param buffer: buffer to recv into
     :param nbytes: number of bytes to recv max
     :return (nbytes, addressInfo):
     """
     if nbytes is None:
         nbytes = len(buffer)
     data, addr = self._dgram_sock.recvfrom(buffersize)
     if addr == self._samDgramAddr:
         # only accept packets from the sam udp address
         idx = data.index(b'\n')
         payload = data[1+idx:]
         l = buffer.write(payload)
         return l, datatypes.Destination(raw=bytearray(data[:idx]), b64=True)
     else:
         self._log.warn("invalid source address for sam packet {}".format(addr))
Exemplo n.º 11
0
 def accept(self):
     if len(self._pending_accepts) == 0:
         # Just in case the user doesn't call listen()
         self._pending_accepts.append(self._create_accept())
     sock, partialDest = self._pending_accepts.pop(0)
     # read destination for inbound
     dest, _finished = _sam_readline(sock, partialDest)
     if not _finished:
         self._pending_accepts.append((sock, dest))
         raise pysocket.error(errno.EWOULDBLOCK, "waiting for client to connect")
     self._pending_accepts.append(self._create_accept())
     # parse destination
     dest = datatypes.Destination(raw=dest, b64=True)
     # cache b32 address
     self._dest_cache[dest.base32()] = dest
     # override socket functions
     sock = _WrappedPySocket(sock, self.dest, dest)
     # return socket
     return sock, (dest, 0)
Exemplo n.º 12
0
 def lookup(self, name):
     """
     look up a name
     :param name: a name or b32 address
     :returns an i2p.datatypes.Destination instance:
     """
     if isinstance(name, datatypes.Destination):
         # if it's already a destination return it :p
         return name
     # check cache
     if name in self._dest_cache:
         # cache hit
         return self._dest_cache[name]
     # cache miss, do lookup
     # create new socket for lookup
     sock = None
     try:
         sock = pysocket.create_connection(self._samAddr)
         self._samHandshake(sock)
     except pysocket.timeout as ex:
         raise ex
     except pysocket.error as ex:
         raise ex
     else:
         # do lookup
         repl = _sam_cmd(sock, "NAMING LOOKUP NAME={}".format(name))
         # close socket as it is not needed anymore
         sock.close()
         if 'VALUE' in repl.opts:
             dest = datatypes.Destination(raw=repl.opts['VALUE'], b64=True)
             if not name.endswith(".b32.i2p"):
                 # cache name as it's not a b32 address
                 self._dest_cache[name] = dest
             # cache base32 address
             self._dest_cache[dest.base32()] = dest
             return dest
         else:
             # failed to lookup
             raise pysocket.herror(errno.EAGAIN,
                                   "name not resolved: {}".format(name))
Exemplo n.º 13
0
    def bind(self, keyfile, nickname=None, **i2cpOptions):
        """
        bind to an address
        :param keyfile: the file containing the private keys to use
        :param nickname: the nickname to use for tunnels or None for random decided by sam
        :param i2cpOptions: additional i2cp options to pass into sam
        """
        if nickname is None:
            nickname = randnick(8)
        self._state = State.Connecting
        self._log.info('bind')
        host, port = None, None
        if self._type == SAM.SOCK_STREAM:
            style = "STREAM"
        elif self._type == SAM.SOCK_DGRAM:
            style = "DATAGRAM"
            self._dgram_sock = pysocket.socket(type=pysocket.SOCK_DGRAM)
            self._dgram_sock.bind(self._dgram_bind)
            port = self._dgram_sock.getsockname()[1]
            host = self._dgram_bind[0]

        else:
            style = "RAW"

        self._keys = 'TRANSIENT'
        if keyfile:
            if isinstance(keyfile, str):
                if os.path.exists(keyfile):
                    with open(keyfile, 'rb') as f:
                        self.dest = datatypes.Destination(raw=f, private=True)
                        self._keys = self.dest.base64(True)
            elif hasattr(keyfile, 'read'):
                self.dest = datatypes.Destination(raw=keyfile, private=True)
                self._keys = self.dest.base64(True)
        cmd = 'SESSION CREATE STYLE={} DESTINATION={} ID={}'.format(
            style, self._keys, nickname)
        if host:
            cmd += " HOST={}".format(host)
        if port:
            cmd += " PORT={}".format(port)
        for opt in i2cpOptions:
            cmd += " {}={}".format(opt, i2cpOptions[opt])
        repl = _sam_cmd(self._samSocket, cmd)
        if repl.opts['RESULT'] == 'OK':
            self._keys = repl.opts['DESTINATION']
            if self.dest is None:
                self.dest = datatypes.Destination(raw=self._keys,
                                                  b64=True,
                                                  private=True)
                if keyfile:
                    data = self.dest.serialize(priv=True)
                    if isinstance(keyfile, str):
                        with open(keyfile, 'wb') as f:
                            f.write(data)
                    elif hasattr(keyfile, "write"):
                        keyfile.write(data)
            self._nick = nickname
            self._state = State.Ready
        else:
            self._state = State.Error
            # TODO: different types of errors for different types of results from sam
            raise Error("bad result from sam: {}".format(repl.opts["RESULT"]))
Exemplo n.º 14
0
    def bind(self, keyfile, nickname=None, **i2cpOptions):
        """
        bind to an address
        :param keyfile: the file containing the private keys to use or None to not store
        :param nickname: the nickname to use for tunnels or None for random decided by sam
        :param i2cpOptions: additional i2cp options to pass into sam
        """
        if nickname is None:
           nickname = randnick(8)
        self._state = State.Connecting
        if self.type == SAM.SOCK_STREAM:
            style = "STREAM"
        elif self.type == SAM.SOCK_DGRAM:
            style = "DATAGRAM"
            self._dgram_sock = pysocket.socket(type=pysocket.SOCK_DGRAM)
            self._dgram_sock.bind(self._dgram_bind)
            port = self._dgram_sock.getsockname()[1]
            i2cpOptions["HOST"] = self._dgram_bind[0]
            i2cpOptions["PORT"] = port
            # apply deferred options
            self._apply_defered_socket_props(self._dgram_sock)
        else:
            # TODO: implement
            style = "RAW"
            
        _keys = 'TRANSIENT'
        if keyfile:
            if isinstance(keyfile, str):
                if os.path.exists(keyfile):
                    with open(keyfile, 'rb') as f:
                        self.dest = datatypes.Destination(raw=f, private=True)
                        _keys = self.dest.base64()
            elif hasattr(keyfile, 'read'):
                self.dest = datatypes.Destination(raw=keyfile, private=True)
                _keys = self.dest.base64()
        cmd = 'SESSION CREATE STYLE={} DESTINATION={} ID={}'.format(style, _keys, nickname)

        for opt in i2cpOptions:
            cmd += " {}={}".format(opt, i2cpOptions[opt])

        repl = _sam_cmd(self._samSocket, cmd)

        if repl.opts['RESULT'] == 'OK':
            _keys = repl.opts['DESTINATION']
            if self.dest is None:
                self.dest = datatypes.Destination(raw=_keys, b64=True, private=True)
                if keyfile:
                    data = self.dest.serialize(priv=True)
                    if isinstance(keyfile, str):
                        with open(keyfile, 'wb') as f:
                            f.write(data)
                    elif hasattr(keyfile, "write"):
                        keyfile.write(data)
            self.socketname = nickname
            # TODO: do we really want to do this?
            self._apply_defered_socket_props(self._samSocket)
            self._state = State.Ready
        else:
            self._state = State.Error
            # TODO: different types of errors for different types of results from sam
            raise pysocket.error(errno.EADDRNOTAVAIL, "failed to bind destination with i2p: {}".format(repl.opts["RESULT"]))
Exemplo n.º 15
0
 def TODO_test_parse_eeppriv(self):
     with open(testkey, 'rb') as rf:
         dest = datatypes.Destination(raw=rf)
Exemplo n.º 16
0
 def _test_parse_b64(self, b64, cert_type, data_len):
     dest = datatypes.Destination(raw=b64, b64=True)
     assert dest.cert.type == cert_type
     assert len(dest.cert.data) == data_len
Exemplo n.º 17
0
 def _test_base32(self, b64, b32):
     dest = datatypes.Destination(raw=b64, b64=True)
     assert dest.base32() == b32