[Pkg-privacy-commits] [onionbalance] 90/117: Refactors the intro point selection code and adds basic IP selection tests.
Donncha O'Cearbahill
donncha-guest at moszumanska.debian.org
Wed Dec 16 23:18:52 UTC 2015
This is an automated email from the git hooks/post-receive script.
donncha-guest pushed a commit to branch debian/sid
in repository onionbalance.
commit f8c3456fbd7bdeaf0fc42bc6025aafbfb535b4b0
Author: Donncha O'Cearbhaill <donncha at donncha.is>
Date: Thu Jul 16 16:38:50 2015 +0200
Refactors the intro point selection code and adds basic IP selection tests.
Squashed commit of the following:
commit 221c1b7effaf513a8b05552c5c995812b0ece79d
Author: Donncha O'Cearbhaill <donncha at donncha.is>
Date: Thu Jul 16 16:28:49 2015 +0200
Fix incorrect test which reference a non-existant assert_called_once() Mock attribute
commit 3f751cc5d21e0eec26b6b4a20868bde9aaacc0c8
Author: Donncha O'Cearbhaill <donncha at donncha.is>
Date: Thu Jul 16 16:01:51 2015 +0200
Fix tests failing because of timezones, now uses utcfromtimezone() to mock timestamps
commit 6900c8bc9806c840ef1403050351d4158c5a8170
Author: Donncha O'Cearbhaill <donncha at donncha.is>
Date: Wed Jul 8 15:34:29 2015 +0100
Add more tests for descriptor generation code
commit 1fa47069268f337742a55285b74699bb50c2d435
Author: Donncha O'Cearbhaill <donncha at donncha.is>
Date: Tue Jul 7 23:05:38 2015 +0100
Add basic test that the correct number of IPs get selected
commit 524cfe4f11557d702fb333ca3e4bb1131f981550
Author: Donncha O'Cearbhaill <donncha at donncha.is>
Date: Tue Jul 7 17:46:09 2015 +0100
Move intropoint selection to seperate function
---
onionbalance/descriptor.py | 56 ++++++++
onionbalance/service.py | 35 +----
test/test_descriptor.py | 342 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 401 insertions(+), 32 deletions(-)
diff --git a/onionbalance/descriptor.py b/onionbalance/descriptor.py
index eadf1a5..b24460f 100644
--- a/onionbalance/descriptor.py
+++ b/onionbalance/descriptor.py
@@ -3,6 +3,7 @@ import hashlib
import base64
import textwrap
import datetime
+import random
import Crypto.Util.number
import stem
@@ -14,6 +15,61 @@ from onionbalance import config
logger = log.get_logger()
+def choose_introduction_point_set(available_introduction_points):
+ """
+ Select a set introduction points to included in a HS descriptor.
+
+ Provided with a list of available introduction points for each
+ backend instance for an onionbalance service.
+
+ Introduciton points are selected to try and achieve the greatest
+ distribution of introduction points across all of the available backend
+ instances.
+
+ Return a list of IntroductionPoints.
+ """
+
+ # Shuffle the instance order before beginning to pick intro points
+ random.shuffle(available_introduction_points)
+
+ num_active_instances = len(available_introduction_points)
+ ips_per_instance = [len(ips) for ips in available_introduction_points]
+ num_intro_points = sum(ips_per_instance)
+
+ # Choose up to `MAX_INTRO_POINTS` IPs from the service instances. If less
+ # than `MAX_INTRO_POINTS` IPs are available, we should pick all available
+ # IP's
+ max_introduction_points = min(num_intro_points,
+ config.MAX_INTRO_POINTS)
+
+ # Determine the maximum number of IP's which can be selected from
+ # each instance to give the widest distribution of introduction
+ # point
+ pos = 0
+ intro_selection = [0] * num_active_instances
+
+ # Keep looping until we have selected enough introduction points
+ while sum(intro_selection) < max_introduction_points:
+ # Check if the current instance has more IPs available
+ if(ips_per_instance[pos] - intro_selection[pos] > 0):
+ intro_selection[pos] += 1
+ # Increment and wrap the pointer to the current instance
+ pos = ((pos + 1) % num_active_instances)
+
+ # intro_selection now lists the count/number of IPs to select from each
+ # instance. We now sample the determined number of IPs from the IPs
+ # available for each instance.
+ choosen_intro_points = []
+ for count, intros in zip(intro_selection, available_introduction_points):
+ choosen_intro_points.extend(random.sample(intros, count))
+
+ # Shuffle choosen IP's to try reveal less information about which
+ # instances are online and have introduction points included.
+ random.shuffle(choosen_intro_points)
+
+ return choosen_intro_points
+
+
def generate_service_descriptor(permanent_key, introduction_point_list=None,
replica=0, timestamp=None, deviation=0):
"""
diff --git a/onionbalance/service.py b/onionbalance/service.py
index ecca9d6..77e73de 100644
--- a/onionbalance/service.py
+++ b/onionbalance/service.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
import datetime
-import random
import time
import base64
@@ -126,37 +125,9 @@ class Service(object):
instance.changed_since_published = False
available_intro_points.append(instance.introduction_points)
- # Shuffle the instance order before beginning to pick intro points
- random.shuffle(available_intro_points)
-
- num_active_instances = len(available_intro_points)
- ips_per_instance = [len(ips) for ips in available_intro_points]
- num_intro_points = sum(ips_per_instance)
-
- # Choose up to `MAX_INTRO_POINTS` IPs from the service instances.
- max_introduction_points = min(num_intro_points,
- config.MAX_INTRO_POINTS)
-
- # Determine the maximum number of IP's which can be selected from
- # each instance to give the widest distribution of introduction
- # point
- pos = 0
- intro_selection = [0] * num_active_instances
- # Keep looping until we have selected enough introduction points
- while sum(intro_selection) < max_introduction_points:
- # Check if any more IPs are available from the current instance
- if(ips_per_instance[pos] - intro_selection[pos] > 0):
- intro_selection[pos] += 1
- # Increment and wrap the pointer to the current instance
- pos = ((pos + 1) % num_active_instances)
-
- choosen_intro_points = []
- for count, intros in zip(intro_selection, available_intro_points):
- choosen_intro_points.extend(random.sample(intros, count))
-
- # Shuffle IP's to try reveal less information about which
- # instances are online and have introduction points included.
- random.shuffle(choosen_intro_points)
+ num_intro_points = sum(len(ips) for ips in available_intro_points)
+ choosen_intro_points = descriptor.choose_introduction_point_set(
+ available_intro_points)
logger.debug("Selected %d IPs of %d for service %s.onion.",
len(choosen_intro_points), num_intro_points,
diff --git a/test/test_descriptor.py b/test/test_descriptor.py
new file mode 100644
index 0000000..baba067
--- /dev/null
+++ b/test/test_descriptor.py
@@ -0,0 +1,342 @@
+# -*- coding: utf-8 -*-
+import datetime
+
+import pytest
+import Crypto.PublicKey.RSA
+import stem.descriptor
+import hashlib
+from binascii import unhexlify
+
+from onionbalance import descriptor
+
+PEM_PRIVATE_KEY = u'\n'.join([
+ '-----BEGIN RSA PRIVATE KEY-----',
+ 'MIICWwIBAAKBgQDXzP6HGtjPSy7uF9OlY7ZmefTVKcFLsq0mSEzQrW5wSiNuYc+d',
+ 'oSV2OWxPg+1fVe19ES43AUkq/bS/gjAMLOunP6u9FbPDojyh1Vs/6TVqftS3sPkl',
+ 'Q0ItrrZwAwhtHC0WaEyrwYJNOSCBq3wpupdQhpRyWJFqMwm9+iBCG1QcJQIDAQAB',
+ 'AoGAegc2Sqm4vgdyozof+R8Ybnw6ISu6XRbNaJ9rqHjZwW9695khsK4GJAM2pwQf',
+ '/0/0ukszyfDVMhVC1yREDS59lgzNecItd6nQZWbwr9TFxIoa9ouTqk8PcAoNixTb',
+ 'wafjPcMmWGakizXeAHiOfazPBH4x2keDQCulxfYxXZxTpyECQQDqZu61kd1S3U7T',
+ 'BT2NQBd3tHX0Hvonx+IkOKXwpHFY0Mo4d32Bi+MxRuEnd3tO44AaMvlkl13QMTF2',
+ 'kHFSC70dAkEA669LZavGjW67+rO+f+xyDVby9pD5GJQBb78xRCf93Zcu2KW4NSp3',
+ 'XC4p4eWfLgff1VuXL7g0VdFm4wUUHqYUqQJAZLmqpjdyBeO3tZIw6vu5meTgMvEE',
+ 'ygdos+vr0sa3NlUyMKWYNwznqgstQYpkYHf+WkPBS2qIE6iv+qUDLSCCOQJAESSk',
+ 'CFYxUBJQ7BBs9+Mb/Kppa9Ppuobxf85ZaAq8pYScrLeJKZzYJ8VX2I2aQX/jISLT',
+ 'YW41qFRd9n9lEkGkWQJAcxPmNI+2r5zJG+K148LLmWCIDTVZ4nxOcxffHka/3tCJ',
+ 'lDGUw4p2wU6pVRDpNfKrF5Nc9ZKO8NAtC17ZvDyVkQ==',
+ '-----END RSA PRIVATE KEY-----',
+])
+
+INTRODUCTION_POINT_PART = u'\n'.join([
+ '-----BEGIN MESSAGE-----',
+ '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',
+ '-----END MESSAGE-----',
+])
+
+UNSIGNED_DESCRIPTOR = u'\n'.join([
+ 'rendezvous-service-descriptor 6wgohrr64y2od75psnrfdkbc74ddqx2v',
+ 'version 2',
+ 'permanent-key',
+ '-----BEGIN RSA PUBLIC KEY-----',
+ 'MIGJAoGBANfM/oca2M9LLu4X06VjtmZ59NUpwUuyrSZITNCtbnBKI25hz52hJXY5',
+ 'bE+D7V9V7X0RLjcBSSr9tL+CMAws66c/q70Vs8OiPKHVWz/pNWp+1Lew+SVDQi2u',
+ 'tnADCG0cLRZoTKvBgk05IIGrfCm6l1CGlHJYkWozCb36IEIbVBwlAgMBAAE=',
+ '-----END RSA PUBLIC KEY-----',
+ 'secret-id-part udmoj3e2ykfp73kpvauoq4t4p7kkwsjq',
+ 'publication-time 2015-06-25 11:00:00',
+ 'protocol-versions 2,3',
+ 'introduction-points',
+ '-----BEGIN MESSAGE-----',
+ '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',
+ '-----END MESSAGE-----',
+ 'signature',
+ '-----BEGIN SIGNATURE-----',
+ 'VX4GC6s6zmY84mKsh+YdAqyZqDevJwGYr9yJntBNms4XRQHlgiW/JCspJzCqvrQG',
+ 'N4Fh8XNTodQFnxz/kz8K3SBFlLnJHzKxSBTSZTLd8hRp84F/XxDcPaIPda8UJZuF',
+ 'pOT8V0hfhgo8WxLpOyUzxrYugPB2GRkWYLhHaKhxkJY=',
+ '-----END SIGNATURE-----',
+])
+
+SIGNED_DESCRIPTOR = u'\n'.join([
+ 'rendezvous-service-descriptor 6wgohrr64y2od75psnrfdkbc74ddqx2v',
+ 'version 2',
+ 'permanent-key',
+ '-----BEGIN RSA PUBLIC KEY-----',
+ 'MIGJAoGBANfM/oca2M9LLu4X06VjtmZ59NUpwUuyrSZITNCtbnBKI25hz52hJXY5',
+ 'bE+D7V9V7X0RLjcBSSr9tL+CMAws66c/q70Vs8OiPKHVWz/pNWp+1Lew+SVDQi2u',
+ 'tnADCG0cLRZoTKvBgk05IIGrfCm6l1CGlHJYkWozCb36IEIbVBwlAgMBAAE=',
+ '-----END RSA PUBLIC KEY-----',
+ 'secret-id-part udmoj3e2ykfp73kpvauoq4t4p7kkwsjq',
+ 'publication-time 2015-06-25 11:00:00',
+ 'protocol-versions 2,3',
+ 'introduction-points',
+ '-----BEGIN MESSAGE-----',
+ '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',
+ '-----END MESSAGE-----',
+ 'signature',
+ '-----BEGIN SIGNATURE-----',
+ 'VX4GC6s6zmY84mKsh+YdAqyZqDevJwGYr9yJntBNms4XRQHlgiW/JCspJzCqvrQG',
+ 'N4Fh8XNTodQFnxz/kz8K3SBFlLnJHzKxSBTSZTLd8hRp84F/XxDcPaIPda8UJZuF',
+ 'pOT8V0hfhgo8WxLpOyUzxrYugPB2GRkWYLhHaKhxkJY=',
+ '-----END SIGNATURE-----',
+])
+
+PRIVATE_KEY = Crypto.PublicKey.RSA.importKey(PEM_PRIVATE_KEY)
+UNIX_TIMESTAMP = 1435233021
+
+
+def setup_introduction_point_lists(desired_intro_points):
+ '''
+ Create a list of lists of IntroductionPoint instances for unit
+ tests
+ '''
+
+
+ at pytest.mark.parametrize('intro_point_distribution, selected_count', [
+ ([3], 3),
+ ([3, 3], 6),
+ ([0], 0),
+ ([10, 10], 10),
+ ([3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3], 10),
+ pytest.mark.xfail(([0, 3, 3], 9)),
+])
+def test_choose_introduction_point_set(intro_point_distribution,
+ selected_count):
+ '''
+ Basic test case to check that the correct number of IPs are selected.
+ '''
+
+ # Create Mock list of instances and respective introduction points.
+ available_intro_points = [['IP'] * count for count
+ in intro_point_distribution]
+
+ selected_introduction_points = descriptor.choose_introduction_point_set(
+ available_intro_points)
+
+ assert len(selected_introduction_points) == selected_count
+
+
+def test_generate_service_descriptor(monkeypatch, mocker):
+ '''
+ Test creation of a fully signed hidden service descriptor
+ '''
+ # Mock the datetime function to return a constant timestamp
+ class frozen_datetime(datetime.datetime):
+ @classmethod
+ def utcnow(cls):
+ return datetime.datetime.utcfromtimestamp(UNIX_TIMESTAMP)
+ monkeypatch.setattr(datetime, 'datetime', frozen_datetime)
+
+ # Patch make_introduction_points_part to return the test introduction
+ # point section
+ mocker.patch('onionbalance.descriptor.make_introduction_points_part',
+ lambda *_: INTRODUCTION_POINT_PART)
+
+ # Test basic descriptor generation.
+ signed_descriptor = descriptor.generate_service_descriptor(
+ PRIVATE_KEY,
+ introduction_point_list=['mocked-ip-list'],
+ ).encode('utf-8')
+ stem.descriptor.hidden_service_descriptor.\
+ HiddenServiceDescriptor(signed_descriptor, validate=True)
+ assert (hashlib.sha1(signed_descriptor).hexdigest() ==
+ 'df4f4a7a15492205f073c32cbcfc4eb9511e4ad8')
+
+ # Test descriptor generation with specified timestamp
+ signed_descriptor = descriptor.generate_service_descriptor(
+ PRIVATE_KEY,
+ introduction_point_list=['mocked-ip-list'],
+ timestamp=datetime.datetime.utcfromtimestamp(UNIX_TIMESTAMP),
+ ).encode('utf-8')
+ stem.descriptor.hidden_service_descriptor.\
+ HiddenServiceDescriptor(signed_descriptor, validate=True)
+ assert (hashlib.sha1(signed_descriptor).hexdigest() ==
+ 'df4f4a7a15492205f073c32cbcfc4eb9511e4ad8')
+
+ # Test descriptor for deviation and replica 1
+ signed_descriptor = descriptor.generate_service_descriptor(
+ PRIVATE_KEY,
+ introduction_point_list=['mocked-ip-list'],
+ replica=1,
+ deviation=24*60*60,
+ ).encode('utf-8')
+ stem.descriptor.hidden_service_descriptor.\
+ HiddenServiceDescriptor(signed_descriptor, validate=True)
+ assert (hashlib.sha1(signed_descriptor).hexdigest() ==
+ 'd828140cdccb1165dbc5a4b39622fcb45e6438fb')
+
+
+def test_generate_service_descriptor_no_intros():
+ with pytest.raises(ValueError):
+ descriptor.generate_service_descriptor(
+ PRIVATE_KEY,
+ introduction_point_list=[],
+ )
+
+
+def test_make_public_key_block():
+ """
+ Test generation of ASN.1 representation of public key
+ """
+ public_key_block = descriptor.make_public_key_block(PRIVATE_KEY)
+ assert (hashlib.sha1(public_key_block.encode('utf-8')).hexdigest() ==
+ '2cf75da5e1a198ca7cb3db7b0baa6708feaf26e8')
+
+
+def test_sign_digest():
+ """
+ Test signing a SHA1 digest
+ """
+ test_digest = unhexlify('2a447f044d2f8d8127e8133b2d545450bc58760e')
+ signature = descriptor.sign_digest(test_digest, PRIVATE_KEY)
+ assert (hashlib.sha1(signature.encode('utf-8')).hexdigest() ==
+ '27bee071a7e0f0af26a1c176f0c0af00854c05c1')
+
+
+def test_sign_descriptor():
+ """
+ Test signing a descriptor
+ """
+
+ # Test signing an unsigned descriptor
+ signed_descriptor = descriptor.sign_descriptor(
+ UNSIGNED_DESCRIPTOR, PRIVATE_KEY).encode('utf-8')
+ stem.descriptor.hidden_service_descriptor.\
+ HiddenServiceDescriptor(signed_descriptor, validate=True)
+ assert (hashlib.sha1(signed_descriptor).hexdigest() ==
+ 'df4f4a7a15492205f073c32cbcfc4eb9511e4ad8')
+
+ # Test resigning a previously signed descriptor
+ signed_descriptor = descriptor.sign_descriptor(
+ SIGNED_DESCRIPTOR, PRIVATE_KEY).encode('utf-8')
+ stem.descriptor.hidden_service_descriptor.\
+ HiddenServiceDescriptor(signed_descriptor, validate=True)
+ assert (hashlib.sha1(signed_descriptor).hexdigest() ==
+ 'df4f4a7a15492205f073c32cbcfc4eb9511e4ad8')
+
+
+def test_descriptor_received_invalid_descriptor(mocker):
+ """
+ Test invalid descriptor content received from the HSDir
+ """
+ mocker.patch("onionbalance.descriptor.logger.exception",
+ side_effect=ValueError('InvalidDescriptorException'))
+
+ # Check that the invalid descriptor error is logged.
+ with pytest.raises(ValueError):
+ descriptor.descriptor_received(u'not-a-valid-descriptor-input')
+ assert descriptor.logger.exception.call_count == 1
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/onionbalance.git
More information about the Pkg-privacy-commits
mailing list