def discover_versions(self, protocol_versions=None): self.logger.debug( "discover_versions(protocol_versions={0}) called".format( protocol_versions)) msg = 'get protocol versions supported by server' result_versions = list() if protocol_versions: msg += " and client; client versions {0}".format(protocol_versions) for version in protocol_versions: if version in self.protocol_versions: result_versions.append(version) else: result_versions = self.protocol_versions self.logger.debug(msg) try: return DiscoverVersionsResult(ResultStatus(RS.SUCCESS), protocol_versions=result_versions) except Exception: msg = ResultMessage('DiscoverVersions Operation Failed') reason = ResultReason(ResultReasonEnum.GENERAL_FAILURE) return DiscoverVersionsResult(ResultStatus(RS.OPERATION_FAILED), result_reason=reason, result_message=msg)
def locate(self, maximum_items=None, storage_status_mask=None, object_group_member=None, attributes=None, credential=None): self.logger.debug('locate() called') msg = 'locating object(s) from repo' self.logger.debug(msg) try: uuids = self.repo.locate(maximum_items, storage_status_mask, object_group_member, attributes) return LocateResult(ResultStatus(RS.SUCCESS), uuids=uuids) except NotImplementedError: msg = ResultMessage('Locate Operation Not Supported') reason = ResultReason(ResultReasonEnum.OPERATION_NOT_SUPPORTED) return LocateResult(ResultStatus(RS.OPERATION_FAILED), result_reason=reason, result_message=msg)
def _get_duplicate_attribute_result(self, name): msg = '%s supplied multiple times' % name self.logger.debug(msg) status = ResultStatus(RS.OPERATION_FAILED) reason = ResultReason(ResultReasonEnum.INDEX_OUT_OF_BOUNDS) message = ResultMessage(msg) return OperationResult(status, reason, message)
def _get_missing_field_result(self, name): msg = '%s not supplied' % name self.logger.debug(msg) status = ResultStatus(RS.OPERATION_FAILED) reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage(msg) return OperationResult(status, reason, message)
def test_encrypt(self, send_mock, build_mock): """ Test that the client can encrypt data. """ payload = payloads.EncryptResponsePayload( unique_identifier='1', data=( b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B' ) ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.ENCRYPT), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.encrypt( ( b'\x37\x36\x35\x34\x33\x32\x31\x20' b'\x4E\x6F\x77\x20\x69\x73\x20\x74' b'\x68\x65\x20\x74\x69\x6D\x65\x20' b'\x66\x6F\x72\x20\x00' ), unique_identifier='1', cryptographic_parameters=CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS5, cryptographic_algorithm=enums.CryptographicAlgorithm.BLOWFISH ), iv_counter_nonce=b'\xFE\xDC\xBA\x98\x76\x54\x32\x10' ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( ( b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B' ), result.get('data') ) self.assertEqual(None, result.get('iv_counter_nonce')) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def destroy(self, uuid): self.logger.debug('destroy() called') ret_value = RS.OPERATION_FAILED if uuid is None or not hasattr(uuid, 'value'): self.logger.debug('no uuid provided') reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage('') return DestroyResult(ResultStatus(ret_value), reason, message) msg = 'deleting object from repo: {0}'.format(uuid) self.logger.debug(msg) if not self.repo.delete(uuid.value): self.logger.debug('repo did not find and delete managed object') reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage('') return DestroyResult(ResultStatus(ret_value), reason, message) ret_value = RS.SUCCESS return DestroyResult(ResultStatus(ret_value), uuid=uuid)
def test_derive_key(self, send_mock, build_mock): """ Test that the client can derive a key. """ payload = payloads.DeriveKeyResponsePayload( unique_identifier='1', ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.DERIVE_KEY), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.derive_key( object_type=enums.ObjectType.SYMMETRIC_KEY, unique_identifiers=['2', '3'], derivation_method=enums.DerivationMethod.ENCRYPT, derivation_parameters=DerivationParameters( cryptographic_parameters=CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.AES ), initialization_vector=b'\x01\x02\x03\x04', derivation_data=b'\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8' ), template_attribute=TemplateAttribute( attributes=[ self.attr_factory.create_attribute( 'Cryptographic Length', 128 ), self.attr_factory.create_attribute( 'Cryptographic Algorithm', enums.CryptographicAlgorithm.AES ) ] ), ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def test_signature_verify(self, send_mock, build_mock): """ Test that the client can verify a signature. """ payload = payloads.SignatureVerifyResponsePayload( unique_identifier='1', validity_indicator=enums.ValidityIndicator.INVALID ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.SIGNATURE_VERIFY), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.signature_verify( ( b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B' ), ( b'\x11\x11\x11\x11\x11\x11\x11\x11' ), unique_identifier='1', cryptographic_parameters=CryptographicParameters( padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.RSA, hashing_algorithm=enums.HashingAlgorithm.SHA_224 ) ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( enums.ValidityIndicator.INVALID, result.get('validity_indicator') ) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def register(self, object_type, template_attribute, secret, credential=None): self.logger.debug('register() called') self.logger.debug('object type = %s' % object_type) attributes = template_attribute.attributes ret_attributes = [] if object_type is None: self.logger.debug('invalid object type') return self._get_missing_field_result('object type') if object_type.value != OT.SYMMETRIC_KEY: self.logger.debug('invalid object type') return self._get_invalid_field_result('invalid object type') if secret is None or not isinstance(secret, SymmetricKey): msg = 'object type does not match that of secret' self.logger.debug(msg) return self._get_invalid_field_result(msg) self.logger.debug('Collecting all attributes') if attributes is None: attributes = [] attributes.extend(self._get_key_block_attributes(secret.key_block)) self.logger.debug('Verifying all attributes are valid and set') try: self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_ALGORITHM.value, (CA.AES,), 'unsupported algorithm') self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_LENGTH.value, (128, 256, 512), 'unsupported key length') self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_USAGE_MASK.value, (), '') except InvalidFieldException as e: self.logger.debug('InvalidFieldException raised') return RegisterResult(e.result.result_status, e.result.result_reason, e.result.result_message) s_uuid, uuid_attribute = self._save(secret, attributes) ret_attributes.append(uuid_attribute) template_attribute = TemplateAttribute(attributes=ret_attributes) return RegisterResult(ResultStatus(RS.SUCCESS), uuid=UniqueIdentifier(s_uuid), template_attribute=template_attribute)
def test_process_batch_item_with_error(self): result_status = ResultStatus(ResultStatusEnum.OPERATION_FAILED) result_reason = ResultReason(ResultReasonEnum.INVALID_MESSAGE) result_message = ResultMessage("message") batch_item = ResponseBatchItem(result_status=result_status, result_reason=result_reason, result_message=result_message) response = ResponseMessage(batch_items=[batch_item]) results = self.client._process_batch_items(response) base = "expected {0}, received {1}" msg = "number of results " + base.format(1, len(results)) self.assertEqual(1, len(results), msg) result = results[0] self.assertIsInstance(result, OperationResult) self.assertEqual(result.result_status, result_status) self.assertEqual(result.result_reason, result_reason) self.assertEqual(result.result_message.value, "message")
def create(self, object_type, template_attribute, credential=None): self.logger.debug('create() called') self.logger.debug('object type = %s' % object_type) bit_length = 256 attributes = template_attribute.attributes ret_attributes = [] if object_type.value != OT.SYMMETRIC_KEY: self.logger.debug('invalid object type') return self._get_invalid_field_result('invalid object type') try: alg_attr = self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_ALGORITHM.value, (CA.AES,), 'unsupported algorithm') len_attr = self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_LENGTH.value, (128, 256, 512), 'unsupported key length', False) self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_USAGE_MASK.value, (), '') except InvalidFieldException as e: self.logger.debug('InvalidFieldException raised') return e.result crypto_alg = CryptographicAlgorithm(CA(alg_attr.attribute_value.value)) if len_attr is None: self.logger.debug('cryptographic length not supplied') attribute_type = AT.CRYPTOGRAPHIC_LENGTH length_attribute = self.attribute_factory.\ create_attribute(attribute_type, bit_length) attributes.append(length_attribute) ret_attributes.append(length_attribute) else: bit_length = len_attr.attribute_value.value key = self._gen_symmetric_key(bit_length, crypto_alg) s_uuid, uuid_attribute = self._save(key, attributes) ret_attributes.append(uuid_attribute) template_attribute = TemplateAttribute(attributes=ret_attributes) return CreateResult(ResultStatus(RS.SUCCESS), object_type=object_type, uuid=UniqueIdentifier(s_uuid), template_attribute=template_attribute)
def get(self, uuid=None, key_format_type=None, key_compression_type=None, key_wrapping_specification=None, credential=None): self.logger.debug('get() called') ret_value = RS.OPERATION_FAILED if uuid is None or not hasattr(uuid, 'value'): self.logger.debug('no uuid provided') reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage('') return GetResult(ResultStatus(ret_value), reason, message) if key_format_type is None: self.logger.debug('key format type is None, setting to raw') key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) if key_format_type.value != KeyFormatTypeEnum.RAW: self.logger.debug('key format type is not raw') reason = ResultReason(ResultReasonEnum. KEY_FORMAT_TYPE_NOT_SUPPORTED) message = ResultMessage('') return GetResult(ResultStatus(ret_value), reason, message) if key_compression_type is not None: self.logger.debug('key compression type is not None') reason = ResultReason(ResultReasonEnum. KEY_COMPRESSION_TYPE_NOT_SUPPORTED) message = ResultMessage('') return GetResult(ResultStatus(ret_value), reason, message) if key_wrapping_specification is not None: self.logger.debug('key wrapping specification is not None') reason = ResultReason(ResultReasonEnum.FEATURE_NOT_SUPPORTED) message = ResultMessage('key wrapping is not currently supported') return GetResult(ResultStatus(ret_value), reason, message) self.logger.debug('retrieving object from repo') managed_object, _ = self.repo.get(uuid.value) if managed_object is None: self.logger.debug('object not found in repo') reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage('') return GetResult(ResultStatus(ret_value), reason, message) # currently only symmetric keys are supported, fix this in future object_type = ObjectType(OT.SYMMETRIC_KEY) ret_value = RS.SUCCESS return GetResult(ResultStatus(ret_value), object_type=object_type, uuid=uuid, secret=managed_object)
def test_sign(self, send_mock, build_mock): """ Test that the client can sign data """ payload = payloads.SignResponsePayload( unique_identifier='1', signature_data=b'aaaaaaaaaaaaaaaa' ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.SIGN), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.sign( b'\x11\x11\x11\x11\x11\x11\x11\x11', unique_identifier='1', cryptographic_parameters=CryptographicParameters( padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.RSA, hashing_algorithm=enums.HashingAlgorithm.SHA_224 ) ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( b'aaaaaaaaaaaaaaaa', result.get('signature') ) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def _get_invalid_field_result(self, msg): status = ResultStatus(RS.OPERATION_FAILED) reason = ResultReason(ResultReasonEnum.INVALID_FIELD) message = ResultMessage(msg) return OperationResult(status, reason, message)