Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions kmip/core/primitives.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(self, tag=enums.Tags.DEFAULT, type=enums.Types.DEFAULT):
self.tag = tag
self.type = type
self.length = None
self.logger = logging.getLogger('kmip.core.primitives')

# TODO (peter-hamilton) Convert this into a classmethod, class name can be
# obtained from cls parameter that replaces self
Expand All @@ -47,7 +48,11 @@ def is_oversized(self, stream):
def read_tag(self, istream):
# Read in the bytes for the tag
tts = istream.read(self.TAG_SIZE)
tag = unpack('!I', b'\x00' + tts[0:self.TAG_SIZE])[0]
try:
tag = unpack('!I', b'\x00' + tts[0:self.TAG_SIZE])[0]
except Exception:
self.logger.error("Error reading tag value from buffer")
return

enum_tag = enums.Tags(tag)

Expand Down Expand Up @@ -102,9 +107,12 @@ def read_value(self, istream):
raise NotImplementedError()

def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0):
self.read_tag(istream)
self.read_type(istream)
self.read_length(istream)
try:
self.read_tag(istream)
self.read_type(istream)
self.read_length(istream)
except Exception as e:
self.logger.warning(f"Skipping malformed field during read: {str(e)}")

def write_tag(self, ostream):
# Write the tag to the output stream
Expand Down
18 changes: 17 additions & 1 deletion kmip/services/server/barbican.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ def __init__(self, project_name, project_domain_name):
self.project_name = project_name
self.os_client = OpenstackHelper(self.region, self.user_domain_name, self.project_domain_name, self.project_name)
self.api = self.os_client.api.key_manager

self.logger = logging.getLogger('kmip.server.engine')

def create_secret(self, name, payload, algorithm=None, length=None):
keymgr = self.api
Expand All @@ -128,8 +130,22 @@ def create_secret(self, name, payload, algorithm=None, length=None):
attrs['algorithm'] = algorithm
if length:
attrs['bit_length'] = length
secret_ref = keymgr.create_secret(**attrs)
secret_ref = keymgr.create_secret(**attrs)

return secret_ref.secret_ref

#SECTION - Store metadata in barbican
def create_secret_metadata(self, secret_ref, metadata):
secret_id = secret_ref.rstrip('/').split('/')[-1]
barbican_endpoint = self.os_client.api.endpoint_for(service_type='key-manager')
url = f"{barbican_endpoint}/v1/secrets/{secret_id}/metadata"

metadata_payload = {"metadata": metadata}
_ = self.os_client.api.session.put(url, json=metadata_payload)

self.logger.debug(f'SAPCC: Metadata Created')

return

def retrive_secret(self, url):
try:
Expand Down
35 changes: 34 additions & 1 deletion kmip/services/server/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def __init__(self, policies=None, database_path=None):
self.os_project_name = os.environ.get("OS_PROJECT_NAME")
self.os_project_domain_name = os.environ.get("OS_PROJECT_DOMAIN_NAME")
self.barbican = barbican.Barbicanstore(self.os_project_name, self.os_project_domain_name)
self.netapp_metadata = {}

def _get_enum_string(self, e):
return ''.join([x.capitalize() for x in e.name.split('_')])
Expand Down Expand Up @@ -568,7 +569,17 @@ def _process_template_attribute(self, template_attribute):
for attribute in template_attribute.attributes:
name = attribute.attribute_name.value

if name.startswith('x-NETAPP'):
if name == 'x-NETAPP-ClusterId':
self.netapp_metadata[name] = attribute.attribute_value.value
else:
self._logger.info(f"SAPCC: ignored attribute {name}"
f"({attribute.attribute_value})")
continue


if not self._attribute_policy.is_attribute_supported(name):
self._logger.debug("SAPCC: 1")
raise exceptions.InvalidField(
"The {0} attribute is unsupported.".format(name)
)
Expand Down Expand Up @@ -889,6 +900,9 @@ def _set_attribute_on_managed_object(self, managed_object, attribute):
raise exceptions.InvalidField(
"Cannot set duplicate name values."
)
elif attribute_name == "x-NETAPP-ClusterId":
for value in attribute_value:
managed_object.x_netapp_cluster_id = value.value
elif attribute_name == "Application Specific Information":
for value in attribute_value:
managed_object.app_specific_info.append(
Expand All @@ -905,6 +919,7 @@ def _set_attribute_on_managed_object(self, managed_object, attribute):
objects.ObjectGroup(object_group=value.value)
)
else:
self._logger.debug("SAPCC: 2")
# TODO (peterhamilton) Remove when all attributes are supported
raise exceptions.InvalidField(
"The {0} attribute is unsupported.".format(attribute_name)
Expand Down Expand Up @@ -940,6 +955,7 @@ def _set_attribute_on_managed_object(self, managed_object, attribute):
else:
setattr(managed_object, field, value)
else:
self._logger.debug("SAPCC: 3")
# TODO (peterhamilton) Remove when all attributes are supported
raise exceptions.InvalidField(
"The {0} attribute is unsupported.".format(attribute_name)
Expand Down Expand Up @@ -2009,6 +2025,16 @@ def _process_register(self, payload):
managed_object._owner = self._client_identity[0]
managed_object.initial_date = int(time.time())

name = "KMIP_REGISTERED"
algorithm = managed_object.cryptographic_algorithm
length = managed_object.cryptographic_length
bburl = self.barbican.create_secret(str(name),
managed_object.value,
str(algorithm), length)
_ = self.barbican.create_secret_metadata(bburl, self.netapp_metadata)
managed_object.value = bburl.encode('utf-8')
managed_object.names = []

self._data_session.add(managed_object)

# NOTE (peterhamilton) SQLAlchemy will *not* assign an ID until
Expand All @@ -2026,8 +2052,12 @@ def _process_register(self, payload):
unique_identifier=str(managed_object.unique_identifier)
)

self._logger.debug(f'SAPCC: response_payload.unique_identifier - {response_payload.unique_identifier}')

self._id_placeholder = str(managed_object.unique_identifier)

self._logger.debug(f'SAPCC: _id_placeholder - {self._id_placeholder}')

return response_payload

@_kmip_version_supported('1.0')
Expand Down Expand Up @@ -2705,11 +2735,14 @@ def _process_get_attribute_list(self, payload):
def _process_activate(self, payload):
self._logger.info("Processing operation: Activate")

if payload.unique_identifier:
if payload.unique_identifier and payload.unique_identifier.value:
self._logger.debug(f'SAPCC: Inside if')
unique_identifier = payload.unique_identifier.value
else:
self._logger.debug(f'SAPCC: Inside else')
unique_identifier = self._id_placeholder

self._logger.debug(f'SAPCC: unique_identifier - {unique_identifier}')
managed_object = self._get_object_with_access_controls(
unique_identifier,
enums.Operation.ACTIVATE
Expand Down
18 changes: 18 additions & 0 deletions kmip/services/server/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,24 @@ def __init__(self, version):

# TODO (peterhamilton) Alphabetize these
self._attribute_rule_sets = {
'x-NETAPP-ClusterId': AttributeRuleSet(
False, # Required? False
('client',), # Who can supply it? client
True, # Readable
True, # Writable
True, # Can be used during Create
True, # Can be used during Register
(
enums.Operation.CREATE,
enums.Operation.REGISTER,
), # Allowed operations
(
enums.ObjectType.SECRET_DATA,
enums.ObjectType.OPAQUE_DATA,
enums.ObjectType.SYMMETRIC_KEY
), # Allowed object types
contents.ProtocolVersion(1, 4) # Minimum protocol version (1.4)
),
'Unique Identifier': AttributeRuleSet(
True,
('server', ),
Expand Down