Ejemplo n.º 1
0
    def test_descriptor_creation(self):
        """
    HiddenServiceDescriptorV3 creation.
    """

        # minimal descriptor

        self.assertTrue(HiddenServiceDescriptorV3.content().startswith(
            b'hs-descriptor 3\ndescriptor-lifetime 180\n'))
        self.assertEqual(180, HiddenServiceDescriptorV3.create().lifetime)

        # specify the parameters

        desc = HiddenServiceDescriptorV3.create(
            {
                'hs-descriptor': '4',
                'descriptor-lifetime': '123',
                'descriptor-signing-key-cert':
                '\n-----BEGIN ED25519 CERT-----\nmalformed block\n-----END ED25519 CERT-----',
                'revision-counter': '5',
                'superencrypted':
                '\n-----BEGIN MESSAGE-----\nmalformed block\n-----END MESSAGE-----',
                'signature': 'abcde',
            },
            validate=False)

        self.assertEqual(4, desc.version)
        self.assertEqual(123, desc.lifetime)
        self.assertEqual(
            None, desc.signing_cert
        )  # malformed cert dropped because validation is disabled
        self.assertEqual(5, desc.revision_counter)
        self.assertEqual(
            '-----BEGIN MESSAGE-----\nmalformed block\n-----END MESSAGE-----',
            desc.superencrypted)
        self.assertEqual('abcde', desc.signature)

        # include introduction points

        from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey

        identity_key = Ed25519PrivateKey.generate()
        onion_address = HiddenServiceDescriptorV3.address_from_identity_key(
            identity_key)

        desc = HiddenServiceDescriptorV3.create(
            identity_key=identity_key,
            inner_layer=InnerLayer.create(introduction_points=[
                IntroductionPointV3.create_for_address('1.1.1.1', 9001),
                IntroductionPointV3.create_for_address('2.2.2.2', 9001),
                IntroductionPointV3.create_for_address('3.3.3.3', 9001),
            ]),
        )

        inner_layer = desc.decrypt(onion_address)
        self.assertEqual(3, len(inner_layer.introduction_points))
        self.assertEqual(
            '1.1.1.1',
            inner_layer.introduction_points[0].link_specifiers[0].address)
Ejemplo n.º 2
0
  def test_intro_point_creation(self):
    """
    Create an introduction point, encode it, then re-parse.
    """

    intro_point = IntroductionPointV3.create_for_address('1.1.1.1', 9001)

    self.assertEqual(1, len(intro_point.link_specifiers))
    self.assertEqual(stem.client.datatype.LinkByIPv4, type(intro_point.link_specifiers[0]))
    self.assertEqual('1.1.1.1', intro_point.link_specifiers[0].address)
    self.assertEqual(9001, intro_point.link_specifiers[0].port)

    reparsed = IntroductionPointV3.parse(intro_point.encode())
    self.assertEqual(intro_point, reparsed)
Ejemplo n.º 3
0
    def test_inner_layer_creation(self):
        """
    Internal layer creation.
    """

        # minimal layer

        self.assertEqual(b'create2-formats 2', InnerLayer.content())
        self.assertEqual([2], InnerLayer.create().formats)

        # specify their only mandatory parameter (formats)

        self.assertEqual(b'create2-formats 1 2 3',
                         InnerLayer.content({'create2-formats': '1 2 3'}))
        self.assertEqual([1, 2, 3],
                         InnerLayer.create({
                             'create2-formats': '1 2 3'
                         }).formats)

        # include optional parameters

        desc = InnerLayer.create(
            collections.OrderedDict((
                ('intro-auth-required', 'ed25519'),
                ('single-onion-service', ''),
            )))

        self.assertEqual([2], desc.formats)
        self.assertEqual(['ed25519'], desc.intro_auth)
        self.assertEqual(True, desc.is_single_service)
        self.assertEqual([], desc.introduction_points)

        # include introduction points

        desc = InnerLayer.create(introduction_points=[
            IntroductionPointV3.create_for_address('1.1.1.1', 9001),
            IntroductionPointV3.create_for_address('2.2.2.2', 9001),
            IntroductionPointV3.create_for_address('3.3.3.3', 9001),
        ])

        self.assertEqual(3, len(desc.introduction_points))
        self.assertEqual(
            '1.1.1.1', desc.introduction_points[0].link_specifiers[0].address)

        self.assertTrue(
            InnerLayer.content(introduction_points=[
                IntroductionPointV3.create_for_address('1.1.1.1', 9001),
            ]).startswith(
                b'create2-formats 2\nintroduction-point AQAGAQEBASMp'))
Ejemplo n.º 4
0
  def test_intro_point_encode(self):
    """
    Encode an introduction point back into a string.
    """

    intro_point = IntroductionPointV3.parse(INTRO_POINT_STR)
    self.assertEqual(INTRO_POINT_STR.rstrip(), intro_point.encode())
Ejemplo n.º 5
0
  def test_outer_layer_creation(self):
    """
    Outer layer creation.
    """

    from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey

    # minimal layer

    self.assertTrue(OuterLayer.content().startswith(b'desc-auth-type x25519\ndesc-auth-ephemeral-key '))
    self.assertEqual('x25519', OuterLayer.create().auth_type)

    # specify the parameters

    desc = OuterLayer.create({
      'desc-auth-type': 'foo',
      'desc-auth-ephemeral-key': 'bar',
      'auth-client': [
        'JNil86N07AA epkaL79NtajmgME/egi8oA qosYH4rXisxda3X7p9b6fw',
        '1D8VBAh9hdM 6K/uO3sRqBp6URrKC7GB6Q ElwRj5+6SN9kb8bRhiiQvA',
      ],
      'encrypted': '\n-----BEGIN MESSAGE-----\nmalformed block\n-----END MESSAGE-----',
    })

    self.assertEqual('foo', desc.auth_type)
    self.assertEqual('bar', desc.ephemeral_key)
    self.assertEqual('-----BEGIN MESSAGE-----\nmalformed block\n-----END MESSAGE-----', desc.encrypted)

    self.assertEqual({
      '1D8VBAh9hdM': AuthorizedClient(id = b'1D8VBAh9hdM', iv = b'6K/uO3sRqBp6URrKC7GB6Q', cookie = b'ElwRj5+6SN9kb8bRhiiQvA'),
      'JNil86N07AA': AuthorizedClient(id = b'JNil86N07AA', iv = b'epkaL79NtajmgME/egi8oA', cookie = b'qosYH4rXisxda3X7p9b6fw'),
    }, desc.clients)

    self.assertEqual(EXPECTED_OUTER_LAYER, str(desc))

    # create an inner layer then decrypt it

    revision_counter = 5
    blinded_key = stem.util._pubkey_bytes(Ed25519PrivateKey.generate())
    subcredential = HiddenServiceDescriptorV3._subcredential(Ed25519PrivateKey.generate(), blinded_key)

    outer_layer = OuterLayer.create(
      inner_layer = InnerLayer.create(
        introduction_points = [
          IntroductionPointV3.create_for_address('1.1.1.1', 9001),
        ]
      ),
      revision_counter = revision_counter,
      subcredential = subcredential,
      blinded_key = blinded_key,
    )

    inner_layer = InnerLayer._decrypt(outer_layer, revision_counter, subcredential, blinded_key)

    self.assertEqual(1, len(inner_layer.introduction_points))
    self.assertEqual('1.1.1.1', inner_layer.introduction_points[0].link_specifiers[0].address)
Ejemplo n.º 6
0
  def test_intro_point_parse(self):
    """
    Parse a v3 introduction point.
    """

    intro_point = IntroductionPointV3.parse(INTRO_POINT_STR)

    self.assertEqual('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=', intro_point.onion_key_raw)
    self.assertTrue('0Acq8QW8O7O' in intro_point.auth_key_cert.to_base64())
    self.assertEqual('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=', intro_point.enc_key_raw)
    self.assertTrue('4807i5', intro_point.enc_key_cert.to_base64())
    self.assertTrue('JAoGBAMO3' in intro_point.legacy_key_raw)
    self.assertTrue('Ln1ITJ0qP' in intro_point.legacy_key_cert)