コード例 #1
0
    def test_create_wait_certificate(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Smart, Maxwell Smart',
                local_mean=2.71828)

        wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                wait_timer=wait_timer,
                nonce='Eeny, meeny, miny, moe.',
                block_hash='Indigestion. Pepto Bismol.')

        self.assertAlmostEqual(wait_timer.request_time,
                               wait_certificate.request_time)
        self.assertAlmostEqual(wait_timer.duration, wait_certificate.duration)
        self.assertEqual(wait_timer.previous_certificate_id,
                         wait_certificate.previous_certificate_id)
        self.assertAlmostEqual(wait_timer.local_mean,
                               wait_certificate.local_mean)
        self.assertEqual(wait_timer.validator_address,
                         wait_certificate.validator_address)
        self.assertEqual(wait_certificate.nonce, 'Eeny, meeny, miny, moe.')
        self.assertEqual(wait_certificate.block_hash,
                         'Indigestion. Pepto Bismol.')
        self.assertIsNone(wait_certificate.signature)

        # You probably wonder why I bother assigning
        # wait_certificate.previous_certificate_id  to a local variable -
        # this is to simply get around PEP8.
        # If I don't, it complains about the line being too long.
        # If I do a line continuation, it complains about a space around the =.
        previous_certificate_id = wait_certificate.previous_certificate_id
        other_wait_certificate = \
            EnclaveWaitCertificate(
                duration=wait_certificate.duration,
                previous_certificate_id=previous_certificate_id,
                local_mean=wait_certificate.local_mean,
                request_time=wait_certificate.request_time,
                validator_address='1600 Pennsylvania Avenue NW',
                nonce='Eeny, meeny, miny, moe.',
                block_hash=wait_certificate.block_hash)

        self.assertAlmostEqual(wait_certificate.duration,
                               other_wait_certificate.duration)
        self.assertEqual(wait_certificate.previous_certificate_id,
                         other_wait_certificate.previous_certificate_id)
        self.assertAlmostEqual(wait_certificate.local_mean,
                               other_wait_certificate.local_mean)
        self.assertAlmostEqual(wait_certificate.request_time,
                               other_wait_certificate.request_time)
        self.assertEqual(wait_certificate.validator_address,
                         other_wait_certificate.validator_address)
        self.assertEqual(wait_certificate.nonce, other_wait_certificate.nonce)
        self.assertEqual(wait_certificate.block_hash,
                         other_wait_certificate.block_hash)
        self.assertIsNone(other_wait_certificate.signature)
コード例 #2
0
    def test_deserialized_wait_certificate(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Smart, Maxwell Smart',
                local_mean=2.71828)

        wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                wait_timer=wait_timer,
                nonce='Eeny, meeny, miny, moe.',
                block_hash='Indigestion. Pepto Bismol.')

        serialized = wait_certificate.serialize()
        private_key = self._create_random_key()
        wait_certificate.signature = \
            create_context('secp256k1').sign(serialized.encode(), private_key)

        copy_wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_from_serialized(
                serialized,
                wait_certificate.signature)

        self.assertAlmostEqual(
            wait_certificate.request_time,
            copy_wait_certificate.request_time)
        self.assertAlmostEqual(
            wait_certificate.duration,
            copy_wait_certificate.duration)
        self.assertEqual(
            wait_certificate.previous_certificate_id,
            copy_wait_certificate.previous_certificate_id)
        self.assertAlmostEqual(
            wait_certificate.local_mean,
            copy_wait_certificate.local_mean)
        self.assertEqual(
            wait_certificate.validator_address,
            copy_wait_certificate.validator_address)
        self.assertEqual(
            wait_certificate.nonce,
            copy_wait_certificate.nonce)
        self.assertEqual(
            wait_certificate.block_hash,
            copy_wait_certificate.block_hash)
        self.assertEqual(
            wait_certificate.signature,
            copy_wait_certificate.signature)

        self.assertEqual(serialized, copy_wait_certificate.serialize())
コード例 #3
0
    def test_deserialized_wait_certificate(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Smart, Maxwell Smart',
                local_mean=2.71828)

        wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                wait_timer=wait_timer,
                nonce='Eeny, meeny, miny, moe.',
                block_hash='Indigestion. Pepto Bismol.')

        serialized = wait_certificate.serialize()
        signing_key = self._create_random_key()
        wait_certificate.signature = \
            signing.sign(serialized, signing_key)

        copy_wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_from_serialized(
                serialized,
                wait_certificate.signature)

        self.assertAlmostEqual(
            wait_certificate.request_time,
            copy_wait_certificate.request_time)
        self.assertAlmostEqual(
            wait_certificate.duration,
            copy_wait_certificate.duration)
        self.assertEqual(
            wait_certificate.previous_certificate_id,
            copy_wait_certificate.previous_certificate_id)
        self.assertAlmostEqual(
            wait_certificate.local_mean,
            copy_wait_certificate.local_mean)
        self.assertEqual(
            wait_certificate.validator_address,
            copy_wait_certificate.validator_address)
        self.assertEqual(
            wait_certificate.nonce,
            copy_wait_certificate.nonce)
        self.assertEqual(
            wait_certificate.block_hash,
            copy_wait_certificate.block_hash)
        self.assertEqual(
            wait_certificate.signature,
            copy_wait_certificate.signature)

        self.assertEqual(serialized, copy_wait_certificate.serialize())
コード例 #4
0
    def test_serialize_wait_certificate(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Smart, Maxwell Smart',
                local_mean=2.71828)

        wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                wait_timer=wait_timer,
                nonce='Eeny, meeny, miny, moe.',
                block_hash='Indigestion. Pepto Bismol.')

        self.assertIsNotNone(wait_certificate.serialize())
コード例 #5
0
    def test_serialize_wait_certificate(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Smart, Maxwell Smart',
                local_mean=2.71828)

        wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                wait_timer=wait_timer,
                nonce='Eeny, meeny, miny, moe.',
                block_hash='Indigestion. Pepto Bismol.')

        self.assertIsNotNone(wait_certificate.serialize())
コード例 #6
0
 def deserialize_wait_certificate(cls, serialized_certificate, signature):
     return \
         EnclaveWaitCertificate.wait_certificate_from_serialized(
             serialized_certificate=serialized_certificate,
             signature=signature)
コード例 #7
0
    def create_wait_certificate(cls,
                                sealed_signup_data,
                                wait_timer,
                                block_hash):
        with cls._lock:
            # Extract keys from the 'sealed' signup data
            if sealed_signup_data is None:
                raise ValueError('Sealed Signup Data is None')
            signup_data = \
                json2dict(
                    base64.b64decode(sealed_signup_data.encode()).decode())
            poet_private_key = signup_data['poet_private_key']
            poet_public_key = signup_data['poet_public_key']

            if poet_private_key is None or poet_public_key is None:
                raise \
                    ValueError(
                        'Invalid signup data. No poet key(s).')

            try:
                poet_public_key = Secp256k1PublicKey.from_hex(poet_public_key)
                poet_private_key = Secp256k1PrivateKey.from_hex(
                    poet_private_key)
            except ParseError:
                raise \
                    ValueError(
                        'Invalid signup data. Badly formatted poet key(s).')

            # Several criteria need to be met before we can create a wait
            # certificate:
            # 1. This signup data was used to sign this timer.
            #    i.e. the key sealed / unsealed by the TEE signed this
            #    wait timer.
            # 2. This timer has expired
            # 3. This timer has not timed out
            #
            # In a TEE implementation we would check HW counter agreement.
            # We can't usefully simulate a HW counter though.
            # i.e. wait_timer.counter_value == signup_data.counter.value

            #
            # Note - we make a concession for the genesis block (i.e., a wait
            # timer for which the previous certificate ID is the Null
            # identifier) in that we don't require the timer to have expired
            # and we don't worry about the timer having timed out.

            if wait_timer is None or \
                    not cls._context.verify(
                        wait_timer.signature,
                        wait_timer.serialize().encode(),
                        poet_public_key):
                raise \
                    ValueError(
                        'Validator is not using the current wait timer')

            is_not_genesis_block = \
                (wait_timer.previous_certificate_id != NULL_BLOCK_IDENTIFIER)

            now = time.time()
            expire_time = \
                wait_timer.request_time + \
                wait_timer.duration

            if is_not_genesis_block and now < expire_time:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer has '
                        'not expired')

            time_out_time = \
                wait_timer.request_time + \
                wait_timer.duration + \
                TIMER_TIMEOUT_PERIOD

            if is_not_genesis_block and time_out_time < now:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer '
                        'has timed out')

            # Create a random nonce for the certificate.  For our "random"
            # nonce we will take the timer signature, concat that with the
            # current time, JSON-ize it and create a SHA-256 hash over it.
            # Probably not considered random by security professional
            # standards, but it is good enough for the simulator.
            random_string = \
                dict2json({
                    'wait_timer_signature': wait_timer.signature,
                    'now': datetime.datetime.utcnow().isoformat()
                })
            nonce = hashlib.sha256(random_string.encode()).hexdigest()

            # First create a new enclave wait certificate using the data
            # provided and then sign the certificate with the PoET private key
            wait_certificate = \
                EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                    wait_timer=wait_timer,
                    nonce=nonce,
                    block_hash=block_hash)
            wait_certificate.signature = \
                cls._context.sign(
                    wait_certificate.serialize().encode(),
                    poet_private_key)

            # In a TEE implementation we would increment the HW counter here
            # to prevent replay.
            # We can't usefully simulate a HW counter though.

            return wait_certificate
コード例 #8
0
    def create_wait_certificate(cls, wait_timer, block_hash):
        with cls._lock:
            # If we don't have a PoET private key, then the enclave has not
            # been properly initialized (either by calling create_signup_info
            # or unseal_signup_data)
            if cls._poet_private_key is None:
                raise \
                    ValueError(
                        'Enclave must be initialized before attempting to '
                        'create a wait certificate')

            # Several criteria need to be met before we can create a wait
            # certificate:
            # 1. We have an active timer
            # 2. The caller's wait timer is the active wait timer.  We are not
            #    going to rely the objects, being the same, but will compute
            #    a signature over the object and verify that the signatures
            #    are the same.
            # 3. The active timer has expired
            # 4. The active timer has not timed out
            #
            # Note - we make a concession for the genesis block (i.e., a wait
            # timer for which the previous certificate ID is the Null
            # identifier) in that we don't require the timer to have expired
            # and we don't worry about the timer having timed out.
            if cls._active_wait_timer is None:
                raise \
                    ValueError(
                        'There is not a current enclave active wait timer')

            if wait_timer is None or \
                    cls._active_wait_timer.signature != \
                    signing.sign(
                        wait_timer.serialize(),
                        cls._poet_private_key):
                raise \
                    ValueError(
                        'Validator is not using the current wait timer')

            is_not_genesis_block = \
                (cls._active_wait_timer.previous_certificate_id !=
                 NULL_BLOCK_IDENTIFIER)

            now = time.time()
            expire_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration

            if is_not_genesis_block and now < expire_time:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer has '
                        'not expired')

            time_out_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration + \
                TIMER_TIMEOUT_PERIOD

            if is_not_genesis_block and time_out_time < now:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer '
                        'has timed out')

            # Create a random nonce for the certificate.  For our "random"
            # nonce we will take the timer signature, concat that with the
            # current time, JSON-ize it and create a SHA-256 hash over it.
            # Probably not considered random by security professional
            # standards, but it is good enough for the simulator.
            random_string = \
                dict2json({
                    'wait_timer_signature': cls._active_wait_timer.signature,
                    'now': datetime.datetime.utcnow().isoformat()
                })
            nonce = hashlib.sha256(random_string.encode()).hexdigest()

            # First create a new enclave wait certificate using the data
            # provided and then sign the certificate with the PoET private key
            wait_certificate = \
                EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                    wait_timer=cls._active_wait_timer,
                    nonce=nonce,
                    block_hash=block_hash)
            wait_certificate.signature = \
                signing.sign(
                    wait_certificate.serialize(),
                    cls._poet_private_key)

            # Now that we have created the certificate, we no longer have an
            # active timer
            cls._active_wait_timer = None

            return wait_certificate
コード例 #9
0
 def deserialize_wait_certificate(cls, serialized_certificate, signature):
     return \
         EnclaveWaitCertificate.wait_certificate_from_serialized(
             serialized_certificate=serialized_certificate,
             signature=signature)
コード例 #10
0
    def create_wait_certificate(cls,
                                sealed_signup_data,
                                wait_timer,
                                block_hash):
        with cls._lock:
            # Extract keys from the 'sealed' signup data
            if sealed_signup_data is None:
                raise ValueError('Sealed Signup Data is None')
            signup_data = \
                json2dict(
                    base64.b64decode(sealed_signup_data.encode()).decode())
            poet_private_key = signup_data['poet_private_key']
            poet_public_key = signup_data['poet_public_key']

            if poet_private_key is None or poet_public_key is None:
                raise \
                    ValueError(
                        'Invalid signup data. No poet key(s).')

            try:
                poet_public_key = Secp256k1PublicKey.from_hex(poet_public_key)
                poet_private_key = Secp256k1PrivateKey.from_hex(
                    poet_private_key)
            except ParseError:
                raise \
                    ValueError(
                        'Invalid signup data. Badly formatted poet key(s).')

            # Several criteria need to be met before we can create a wait
            # certificate:
            # 1. This signup data was used to sign this timer.
            #    i.e. the key sealed / unsealed by the TEE signed this
            #    wait timer.
            # 2. This timer has expired
            # 3. This timer has not timed out
            #
            # In a TEE implementation we would check HW counter agreement.
            # We can't usefully simulate a HW counter though.
            # i.e. wait_timer.counter_value == signup_data.counter.value

            #
            # Note - we make a concession for the genesis block (i.e., a wait
            # timer for which the previous certificate ID is the Null
            # identifier) in that we don't require the timer to have expired
            # and we don't worry about the timer having timed out.

            if wait_timer is None or \
                    not cls._context.verify(
                        wait_timer.signature,
                        wait_timer.serialize().encode(),
                        poet_public_key):
                raise \
                    ValueError(
                        'Validator is not using the current wait timer')

            is_not_genesis_block = \
                (wait_timer.previous_certificate_id !=
                 NULL_BLOCK_IDENTIFIER)

            now = time.time()
            expire_time = \
                wait_timer.request_time + \
                wait_timer.duration

            if is_not_genesis_block and now < expire_time:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer has '
                        'not expired')

            time_out_time = \
                wait_timer.request_time + \
                wait_timer.duration + \
                TIMER_TIMEOUT_PERIOD

            if is_not_genesis_block and time_out_time < now:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer '
                        'has timed out')

            # Create a random nonce for the certificate.  For our "random"
            # nonce we will take the timer signature, concat that with the
            # current time, JSON-ize it and create a SHA-256 hash over it.
            # Probably not considered random by security professional
            # standards, but it is good enough for the simulator.
            random_string = \
                dict2json({
                    'wait_timer_signature': wait_timer.signature,
                    'now': datetime.datetime.utcnow().isoformat()
                })
            nonce = hashlib.sha256(random_string.encode()).hexdigest()

            # First create a new enclave wait certificate using the data
            # provided and then sign the certificate with the PoET private key
            wait_certificate = \
                EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                    wait_timer=wait_timer,
                    nonce=nonce,
                    block_hash=block_hash)
            wait_certificate.signature = \
                cls._context.sign(
                    wait_certificate.serialize().encode(),
                    poet_private_key)

            # In a TEE implementation we would increment the HW counter here
            # to prevent replay.
            # We can't usefully simulate a HW counter though.

            return wait_certificate
コード例 #11
0
    def create_wait_certificate(cls,
                                wait_timer,
                                block_hash):
        with cls._lock:
            # If we don't have a PoET private key, then the enclave has not
            # been properly initialized (either by calling create_signup_info
            # or unseal_signup_data)
            if cls._poet_private_key is None:
                raise \
                    ValueError(
                        'Enclave must be initialized before attempting to '
                        'create a wait certificate')

            # Several criteria need to be met before we can create a wait
            # certificate:
            # 1. We have an active timer
            # 2. The caller's wait timer is the active wait timer.  We are not
            #    going to rely the objects, being the same, but will compute
            #    a signature over the object and verify that the signatures
            #    are the same.
            # 3. The active timer has expired
            # 4. The active timer has not timed out
            #
            # Note - we make a concession for the genesis block (i.e., a wait
            # timer for which the previous certificate ID is the Null
            # identifier) in that we don't require the timer to have expired
            # and we don't worry about the timer having timed out.
            if cls._active_wait_timer is None:
                raise \
                    ValueError(
                        'There is not a current enclave active wait timer')

            if wait_timer is None or \
                    cls._active_wait_timer.signature != \
                    signing.sign(
                        wait_timer.serialize(),
                        cls._poet_private_key):
                raise \
                    ValueError(
                        'Validator is not using the current wait timer')

            is_not_genesis_block = \
                (cls._active_wait_timer.previous_certificate_id !=
                 NULL_BLOCK_IDENTIFIER)

            now = time.time()
            expire_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration

            if is_not_genesis_block and now < expire_time:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer has '
                        'not expired')

            time_out_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration + \
                TIMER_TIMEOUT_PERIOD

            if is_not_genesis_block and time_out_time < now:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer '
                        'has timed out')

            # Create a random nonce for the certificate.  For our "random"
            # nonce we will take the timer signature, concat that with the
            # current time, JSON-ize it and create a SHA-256 hash over it.
            # Probably not considered random by security professional
            # standards, but it is good enough for the simulator.
            random_string = \
                dict2json({
                    'wait_timer_signature': cls._active_wait_timer.signature,
                    'now': datetime.datetime.utcnow().isoformat()
                })
            nonce = hashlib.sha256(random_string.encode()).hexdigest()

            # First create a new enclave wait certificate using the data
            # provided and then sign the certificate with the PoET private key
            wait_certificate = \
                EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                    wait_timer=cls._active_wait_timer,
                    nonce=nonce,
                    block_hash=block_hash)
            wait_certificate.signature = \
                signing.sign(
                    wait_certificate.serialize(),
                    cls._poet_private_key)

            # Now that we have created the certificate, we no longer have an
            # active timer
            cls._active_wait_timer = None

            return wait_certificate
コード例 #12
0
    def test_create_wait_certificate(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Smart, Maxwell Smart',
                local_mean=2.71828)

        wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                wait_timer=wait_timer,
                nonce='Eeny, meeny, miny, moe.',
                block_hash='Indigestion. Pepto Bismol.')

        self.assertAlmostEqual(
            wait_timer.request_time,
            wait_certificate.request_time)
        self.assertAlmostEqual(
            wait_timer.duration,
            wait_certificate.duration)
        self.assertEqual(
            wait_timer.previous_certificate_id,
            wait_certificate.previous_certificate_id)
        self.assertAlmostEqual(
            wait_timer.local_mean,
            wait_certificate.local_mean)
        self.assertEqual(
            wait_timer.validator_address,
            wait_certificate.validator_address)
        self.assertEqual(wait_certificate.nonce, 'Eeny, meeny, miny, moe.')
        self.assertEqual(
            wait_certificate.block_hash,
            'Indigestion. Pepto Bismol.')
        self.assertIsNone(wait_certificate.signature)

        # You probably wonder why I bother assigning
        # wait_certificate.previous_certificate_id  to a local variable -
        # this is to simply get around PEP8.
        # If I don't, it complains about the line being too long.
        # If I do a line continuation, it complains about a space around the =.
        previous_certificate_id = wait_certificate.previous_certificate_id
        other_wait_certificate = \
            EnclaveWaitCertificate(
                duration=wait_certificate.duration,
                previous_certificate_id=previous_certificate_id,
                local_mean=wait_certificate.local_mean,
                request_time=wait_certificate.request_time,
                validator_address='1600 Pennsylvania Avenue NW',
                nonce='Eeny, meeny, miny, moe.',
                block_hash=wait_certificate.block_hash)

        self.assertAlmostEqual(
            wait_certificate.duration,
            other_wait_certificate.duration)
        self.assertEqual(
            wait_certificate.previous_certificate_id,
            other_wait_certificate.previous_certificate_id)
        self.assertAlmostEqual(
            wait_certificate.local_mean,
            other_wait_certificate.local_mean)
        self.assertAlmostEqual(
            wait_certificate.request_time,
            other_wait_certificate.request_time)
        self.assertEqual(
            wait_certificate.validator_address,
            other_wait_certificate.validator_address)
        self.assertEqual(wait_certificate.nonce, other_wait_certificate.nonce)
        self.assertEqual(
            wait_certificate.block_hash,
            other_wait_certificate.block_hash)
        self.assertIsNone(other_wait_certificate.signature)