diff --git a/docs/source/client.rst b/docs/source/client.rst index 5c47143..0788882 100644 --- a/docs/source/client.rst +++ b/docs/source/client.rst @@ -184,6 +184,73 @@ Class Documentation :raises Exception: This is raised if an error occurs while trying to close the connection. + .. py:method:: activate(uid=None) + + Activate a managed object stored by a KMIP appliance. + + :param string uid: The unique ID of the managed object to activate. + Optional, defaults to None. + + :return: None + + :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if + the client connection is unusable. + :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the + operation result is a failure. + :raises TypeError: This is raised if the input argument is invalid. + + Activating a symmetric key would look like this: + + .. code-block:: python + + >>> from kmip.pie import objects + >>> from kmip.pie import client + >>> from kmip import enums + >>> c = client.ProxyKmipClient() + >>> symmetric_key = objects.SymmetricKey( + ... enums.CryptographicAlgorithm.AES, + ... 128, + ... ( + ... b'\x00\x01\x02\x03\x04\x05\x06\x07' + ... b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ... ) + ... ) + >>> with c: + ... key_id = c.register(symmetric_key) + ... c.activate(key_id) + + .. py:method:: check(uid=None, usage_limits_count=None, cryptographic_usage_mask=None, lease_time=None) + + Check the constraints for a managed object. + + :param string uid: The unique ID of the managed object to check. + :param int usage_limits_count: The number of items that can be secured + with the specified managed object. + :param list cryptographic_usage_mask: A list of :class:`kmip.core.enums.CryptographicUsageMask` + enumerations specifying the operations allowed for the specified + managed object. + :param int least_time: The number of seconds that can be leased for the + specified managed object. + + :return: The string ID of the managed object that was checked. + + :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if + the client connection is unusable. + :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the + operation result is a failure. + :raises TypeError: This is raised if the input arguments are invalid. + + .. code-block:: python + + >>> from kmip.pie import client + >>> c = client.ProxyKmipClient() + >>> with c: + ... c.check( + ... uid="1", + ... usage_limits_count=50 + ... ) + '1' + .. py:method:: create(algorithm, length, operation_policy_name=None, name=None, cryptographic_usage_mask=None) Create a symmetric key on a KMIP appliance. @@ -286,14 +353,22 @@ Class Documentation ... ) ('450', '451') - .. py:method:: register(managed_object) + .. py:method:: decrypt(data, uid=None, cryptographic_parameters=None, iv_counter_nonce=None) - Register a managed object with a KMIP appliance. + Decrypt data using the specified decryption key and parameters. - :param managed_object: A :class:`kmip.pie.objects.ManagedObject` - instance to register with the server. + :param bytes data: The bytes to decrypt. Required. + :param string uid: The unique ID of the decryption key to use. + Optional, defaults to None. + :param dict cryptographic_parameters: A dictionary containing various + cryptographic settings to be used for the decryption. Optional, + defaults to None. See :term:`cryptographic_parameters` for more + information. + :param bytes iv_counter_nonce: The bytes to use for the IV/counter/ + nonce, if needed by the decryption algorithm and/or cipher mode. + Optional, defaults to None. - :return: The string uid of the newly registered managed object. + :return: The decrypted data bytes. :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if the client connection is unusable. @@ -301,7 +376,7 @@ Class Documentation operation result is a failure. :raises TypeError: This is raised if the input argument is invalid. - Registering an existing 128-bit AES symmetric key would look like this: + Decrypting cipher text with a symmetric key would look like this: .. code-block:: python @@ -309,18 +384,96 @@ Class Documentation >>> from kmip.pie import client >>> from kmip import enums >>> c = client.ProxyKmipClient() - >>> symmetric_key = objects.SymmetricKey( - ... enums.CryptographicAlgorithm.AES, - ... 128, - ... ( - ... b'\x00\x01\x02\x03\x04\x05\x06\x07' - ... b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' - ... ) - ... ) >>> with c: - ... c.register(symmetric_key) + ... key_id = c.create( + ... enums.CryptographicAlgorithm.AES, + ... 256, + ... cryptographic_usage_mask=[ + ... enums.CryptographicUsageMask.ENCRYPT, + ... enums.CryptographicUsageMask.DECRYPT + ... ] + ... ) + ... c.activate(key_id) + ... c.decrypt( + ... ( + ... b' \xb6:s0\x16\xea\t\x1b\x16\xed\xb2\x04-\xd6' + ... b'\xb6\\\xf3xJ\xfe\xa7[\x1eJ\x08I\xae\x14\xd2' + ... b\xdb\xe2' + ... ), + ... uid=key_id, + ... cryptographic_parameters={ + ... 'cryptographic_algorithm': + ... enums.CryptographicAlgorithm.AES, + ... 'block_cipher_mode': enums.BlockCipherMode.CBC, + ... 'padding_method': enums.PaddingMethod.PKCS5 + ... }, + ... iv_counter_nonce=( + ... b'\x85\x1e\x87\x64\x77\x6e\x67\x96' + ... b'\xaa\xb7\x22\xdb\xb6\x44\xac\xe8' + ... ) + ... ) ... - '452' + b'This is a secret message.' + + .. py:method:: delete_attribute(unique_identifier=None, **kwargs) + + Delete an attribute from a managed object. + + :param string unique_identifier: The unique ID of the managed object + from which to delete the specified attribute. + :param `**kwargs`: A placeholder for attribute values used to identify + the attribute to delete. See the examples below for more + information. + + :return: The string ID of the managed object from which the + attribute was deleted. + :return: A :class:`kmip.core.primitives.Struct` object + representing the deleted attribute. Only returned for KMIP + 1.0 - 1.4 messages. + + For KMIP 1.0 - 1.4, the supported `kwargs` values are: + + * `attribute_name` (string): The name of the attribute to delete. Required. + * `attribute_index` (int): The index of the attribute to delete. Defaults to zero. + + .. code-block:: python + + >>> from kmip.pie import client + >>> c = client.ProxyKmipClient() + >>> with c: + ... c.delete_attribute( + ... unique_identifier="1", + ... attribute_name="Name", + ... attribute_index=0 + ... ) + ('1', Attribute(...)) + + For KMIP 2.0+, the supported `kwargs` values are: + + * `current_attribute` (struct): A :class:`kmip.core.objects.CurrentAttribute` object containing the attribute to delete. Required if the attribute reference is not specified. + * `attribute_reference` (struct): A :class:`kmip.core.objects.AttributeReference` object containing the name of the attribute to delete. Required if the current attribute is not specified. + + .. code-block:: python + + >>> from kmip.pie import client + >>> from kmip import enums + >>> from kmip.core import objects, primitives + >>> c = client.ProxyKmipClient() + >>> with c: + ... c.delete_attribute( + ... unique_identifier="1", + ... current_attribute=objects.CurrentAttribute( + ... attribute=primitives.TextString( + ... value="Object Group 1", + ... tag=enums.Tags.OBJECT_GROUP + ... ), + ... ), + ... attribute_reference=objects.AttributeReference( + ... vendor_identification="Vendor 1", + ... attribute_name="Object Group" + ... ) + ... ) + '1' .. py:method:: derive_key(object_type, unique_identifiers, derivation_method, derivation_parameters, **kwargs) @@ -529,9 +682,99 @@ Class Documentation ... '460' - .. py:method:: locate(maximum_items=None, storage_status_mask=None, object_group_member=None, attributes=None) + .. py:method:: destroy(uid=None) - Documentation coming soon. + Destroy a managed object stored by a KMIP appliance. + + :param string uid: The unique ID of the managed object to destroy. + + :return: None + + :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if + the client connection is unusable. + :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the + operation result is a failure. + :raises TypeError: This is raised if the input argument is invalid. + + Destroying a symmetric key would look like this: + + .. code-block:: python + + >>> from kmip.pie import objects + >>> from kmip.pie import client + >>> from kmip import enums + >>> c = client.ProxyKmipClient() + >>> symmetric_key = objects.SymmetricKey( + ... enums.CryptographicAlgorithm.AES, + ... 128, + ... ( + ... b'\x00\x01\x02\x03\x04\x05\x06\x07' + ... b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ... ) + ... ) + >>> with c: + ... key_id = c.register(symmetric_key) + ... c.destroy(key_id) + + .. py:method:: encrypt(data, uid=None, cryptographic_parameters=None, iv_counter_nonce=None) + + Encrypt data using the specified encryption key and parameters. + + :param bytes data: The bytes to encrypt. Required. + :param string uid: The unique ID of the encryption key to use. + Optional, defaults to None. + :param dict cryptographic_parameters: A dictionary containing various + cryptographic settings to be used for the encryption. Optional, + defaults to None. See :term:`cryptographic_parameters` for more + information. + :param bytes iv_counter_nonce: The bytes to use for the IV/counter/ + nonce, if needed by the encryption algorithm and/or cipher mode. + Optional, defaults to None. + + :return: The encrypted data bytes. + :return: The IV/counter/nonce bytes used with the encryption algorithm, + only if it was autogenerated by the server. + + :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if + the client connection is unusable. + :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the + operation result is a failure. + :raises TypeError: This is raised if the input argument is invalid. + + Encrypting plain text with a symmetric key would look like this: + + .. code-block:: python + + >>> from kmip.pie import objects + >>> from kmip.pie import client + >>> from kmip import enums + >>> c = client.ProxyKmipClient() + >>> with c: + ... key_id = c.create( + ... enums.CryptographicAlgorithm.AES, + ... 256, + ... cryptographic_usage_mask=[ + ... enums.CryptographicUsageMask.ENCRYPT, + ... enums.CryptographicUsageMask.DECRYPT + ... ] + ... ) + ... c.activate(key_id) + ... c.encrypt( + ... b'This is a secret message.', + ... uid=key_id, + ... cryptographic_parameters={ + ... 'cryptographic_algorithm': + ... enums.CryptographicAlgorithm.AES, + ... 'block_cipher_mode': enums.BlockCipherMode.CBC, + ... 'padding_method': enums.PaddingMethod.PKCS5 + ... }, + ... iv_counter_nonce=( + ... b'\x85\x1e\x87\x64\x77\x6e\x67\x96' + ... b'\xaa\xb7\x22\xdb\xb6\x44\xac\xe8' + ... ) + ... ) + ... + (b'...', None) .. py:method:: get(uid=None, key_wrapping_specification=None) @@ -742,14 +985,24 @@ Class Documentation 'Unique Identifier' ] - .. py:method:: activate(uid=None) + .. py:method:: locate(maximum_items=None, storage_status_mask=None, object_group_member=None, offset_items=None, attributes=None) - Activate a managed object stored by a KMIP appliance. + Search for managed objects with specific matching attributes. - :param string uid: The unique ID of the managed object to activate. - Optional, defaults to None. + :param int maximum_items: The maximum number of results that should be + returned. + :param int storage_status_mask: A bit-mask indicating whether online or + archived objects should be included in the search. See + :term:`storage_status` for more information. + :param enum object_group_member: A :class:`kmip.core.enums.ObjectGroupMember` + enumeration indicating the object group member type. See + :term:`object_group_member` for more information. + :param int offset_items: The number of results that should be skipped + before results are returned. + :param list attributes: A list of :class:`kmip.core.objects.Attribute` + objects representing an attribute filter for the search. - :return: None + :return: A list of string IDs of all matching objects, per the operation parameters. :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if the client connection is unusable. @@ -757,7 +1010,141 @@ Class Documentation operation result is a failure. :raises TypeError: This is raised if the input argument is invalid. - Activating a symmetric key would look like this: + .. code-block:: python + + >>> from kmip.pie import client + >>> from kmip.core import enums + >>> from kmip.core.factories import attributes + >>> f = attributes.AttributeFactory() + >>> c = client.ProxyKmipClient() + >>> with c: + ... c.locate( + ... attributes=[ + ... f.create_attribute( + ... enums.AttributeType.OBJECT_TYPE, + ... enums.ObjectType.SYMMETRIC_KEY + ... ) + ... ] + ... ) + ['1', '2', '3'] + + .. py:method:: mac(data, uid=None, algorithm=None) + + Get the message authentication code for a piece of data. + + :param string data: The data to be MACed. + :param string uid: The unique ID of the managed object that is the key + to be used in the MAC operation. + :param enum algorithm: A :class:`kmip.core.enums.CryptographicAlgorithm` + enumeration specifying the algorithm to use in the MAC operation. + See :term:`cryptographic_algorithm` for more information. + + :return: The string ID of the managed object that is the key used in + the MAC operation. + :return: The bytestring representing the MAC of the data. + + :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if + the client connection is unusable. + :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the + operation result is a failure. + :raises TypeError: This is raised if the input argument is invalid. + + .. code-block:: python + + >>> from kmip.pie import client + >>> c = client.ProxyKmipClient() + >>> with c: + ... c.mac( + ... b'\x01\x02\x03\x04', + ... uid="5", + ... algorithm=enums.CryptographicAlgorithm.HMAC_SHA512 + ... ) + ('5', b'...') + + .. py:method:: modify_attribute(unique_identifier=None, **kwargs) + + Modify an attribute on a managed object. + + :param string unique_identifier: The unique ID of the managed object + on which to set the specified attribute. + :param `**kwargs`: A placeholder for attribute values used to identify + the attribute to set. See the example below for more + information. + + :return: The string ID of the managed object on which the attribute + was set. + :return: A :class:`kmip.core.primitives.Struct` object representing + the modified attribute. Only returned for KMIP 1.0 - 1.4 messages. + + For KMIP 1.0 - 1.4, the supported `kwargs` values are: + + * `attribute` (struct): A :class:`kmip.core.objects.Attribute` object + containing the details required to identify and modify an existing + attribute on the specified managed object. Required. + + .. code-block:: python + + >>> from kmip.pie import client + >>> from kmip.core import enums + >>> from kmip.core.factories import attributes + >>> f = attributes.AttributeFactory() + >>> c = client.ProxyKmipClient() + >>> with c: + ... c.modify_attribute( + ... unique_identifier="1", + ... attribute=f.create_attribute( + ... enums.AttributeType.NAME, + ... "New Name", + ... index=0 + ... ) + ... ) + ('1', Attribute(...)) + + For KMIP 2.0+, the supported `kwargs` values are: + + * `current_attribute` (struct): A :class:`kmip.core.objects.CurrentAttribute` object containing the existing attribute to modify. Required if the attribute is multivalued. + * `new_attribute` (struct): A :class:`kmip.core.objects.NewAttribute` object containing the new attribute. Required. + + .. code-block:: python + + >>> from kmip.pie import client + >>> from kmip import enums + >>> from kmip.core import objects, primitives + >>> c = client.ProxyKmipClient() + >>> with c: + ... c.modify_attribute( + ... unique_identifier="1", + ... current_attribute=objects.CurrentAttribute( + ... attribute=primitives.TextString( + ... value="Old Object Group", + ... tag=enums.Tags.OBJECT_GROUP + ... ), + ... ), + ... new_attribute=objects.NewAttribute( + ... attribute=primitives.TextString( + ... value="New Object Group", + ... tag=enums.Tags.OBJECT_GROUP + ... ) + ... ) + ... ) + '1' + + .. py:method:: register(managed_object) + + Register a managed object with a KMIP appliance. + + :param managed_object: A :class:`kmip.pie.objects.ManagedObject` + instance to register with the server. + + :return: The string uid of the newly registered managed object. + + :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if + the client connection is unusable. + :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the + operation result is a failure. + :raises TypeError: This is raised if the input argument is invalid. + + Registering an existing 128-bit AES symmetric key would look like this: .. code-block:: python @@ -774,8 +1161,46 @@ Class Documentation ... ) ... ) >>> with c: - ... key_id = c.register(symmetric_key) - ... c.activate(key_id) + ... c.register(symmetric_key) + ... + '452' + + .. py:method:: rekey(uid=None, offset=None, **kwargs) + + Rekey an existing key. + + :param string uid: The unique ID of the managed object that is the key + to rekey. + :param int offset: The time delta, in seconds, between the new key's + initialization date and activation date. + :param `**kwargs`: A placeholder for object attributes that + should be set on the newly rekeyed key. + + :return: The string ID of the newly rekeyed key. + + :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if + the client connection is unusable. + :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the + operation result is a failure. + :raises TypeError: This is raised if the input argument is invalid. + + The current set of supported `kwargs` values are: + + * `activation_date` (int): The new key's activation date, in seconds since the epoch. + * `process_start_date` (int): The new key's process start date, in seconds since the epoch. + * `protect_stop_date` (int): The new key's protect stop date, in seconds since the epoch. + * `deactivation_date` (int): The new key's deactivation date, in seconds since the epoch. + + .. code-block:: python + + >>> from kmip.pie import client + >>> c = client.ProxyKmipClient() + >>> with c: + ... c.rekey( + ... uid="1", + ... offset=60 + ... ) + "2" .. py:method:: revoke(revocation_reason, uid=None, revocation_message=None, compromise_occurrence_date=None) @@ -828,161 +1253,36 @@ Class Documentation ... key_id ... ) - .. py:method:: destroy(uid=None) + .. py:method:: set_attribute(unique_identifier=None, **kwargs) - Destroy a managed object stored by a KMIP appliance. + Set an attribute on a managed object. - :param string uid: The unique ID of the managed object to destroy. - - :return: None - - :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if - the client connection is unusable. - :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the - operation result is a failure. - :raises TypeError: This is raised if the input argument is invalid. - - Destroying a symmetric key would look like this: - - .. code-block:: python - - >>> from kmip.pie import objects - >>> from kmip.pie import client - >>> from kmip import enums - >>> c = client.ProxyKmipClient() - >>> symmetric_key = objects.SymmetricKey( - ... enums.CryptographicAlgorithm.AES, - ... 128, - ... ( - ... b'\x00\x01\x02\x03\x04\x05\x06\x07' - ... b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' - ... ) - ... ) - >>> with c: - ... key_id = c.register(symmetric_key) - ... c.destroy(key_id) - - .. py:method:: encrypt(data, uid=None, cryptographic_parameters=None, iv_counter_nonce=None) - - Encrypt data using the specified encryption key and parameters. - - :param bytes data: The bytes to encrypt. Required. - :param string uid: The unique ID of the encryption key to use. - Optional, defaults to None. - :param dict cryptographic_parameters: A dictionary containing various - cryptographic settings to be used for the encryption. Optional, - defaults to None. See :term:`cryptographic_parameters` for more + :param string unique_identifier: The unique ID of the managed object + on which to set the specified attribute. + :param `**kwargs`: A placeholder for attribute values used to identify + the attribute to set. See the example below for more information. - :param bytes iv_counter_nonce: The bytes to use for the IV/counter/ - nonce, if needed by the encryption algorithm and/or cipher mode. - Optional, defaults to None. - :return: The encrypted data bytes. - :return: The IV/counter/nonce bytes used with the encryption algorithm, - only if it was autogenerated by the server. + :return: The string ID of the managed object on which the attribute + was set. - :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if - the client connection is unusable. - :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the - operation result is a failure. - :raises TypeError: This is raised if the input argument is invalid. + This operation is supported by KMIP 2.0+ only. The supported `kwargs` + values are: - Encrypting plain text with a symmetric key would look like this: + * `attribute_name` (string): The name of the attribute to set. Required. + * `attribute_value` (various): The value of the attribute to set. Required. .. code-block:: python - >>> from kmip.pie import objects >>> from kmip.pie import client - >>> from kmip import enums >>> c = client.ProxyKmipClient() >>> with c: - ... key_id = c.create( - ... enums.CryptographicAlgorithm.AES, - ... 256, - ... cryptographic_usage_mask=[ - ... enums.CryptographicUsageMask.ENCRYPT, - ... enums.CryptographicUsageMask.DECRYPT - ... ] + ... c.set_attribute( + ... unique_identifier="1", + ... attribute_name="Sensitive", + ... attribute_value=True ... ) - ... c.activate(key_id) - ... c.encrypt( - ... b'This is a secret message.', - ... uid=key_id, - ... cryptographic_parameters={ - ... 'cryptographic_algorithm': - ... enums.CryptographicAlgorithm.AES, - ... 'block_cipher_mode': enums.BlockCipherMode.CBC, - ... 'padding_method': enums.PaddingMethod.PKCS5 - ... }, - ... iv_counter_nonce=( - ... b'\x85\x1e\x87\x64\x77\x6e\x67\x96' - ... b'\xaa\xb7\x22\xdb\xb6\x44\xac\xe8' - ... ) - ... ) - ... - (b'...', None) - - .. py:method:: decrypt(data, uid=None, cryptographic_parameters=None, iv_counter_nonce=None) - - Decrypt data using the specified decryption key and parameters. - - :param bytes data: The bytes to decrypt. Required. - :param string uid: The unique ID of the decryption key to use. - Optional, defaults to None. - :param dict cryptographic_parameters: A dictionary containing various - cryptographic settings to be used for the decryption. Optional, - defaults to None. See :term:`cryptographic_parameters` for more - information. - :param bytes iv_counter_nonce: The bytes to use for the IV/counter/ - nonce, if needed by the decryption algorithm and/or cipher mode. - Optional, defaults to None. - - :return: The decrypted data bytes. - - :raises kmip.pie.exceptions.ClientConnectionNotOpen: This is raised if - the client connection is unusable. - :raises kmip.pie.exceptions.KmipOperationFailure: This is raised if the - operation result is a failure. - :raises TypeError: This is raised if the input argument is invalid. - - Decrypting cipher text with a symmetric key would look like this: - - .. code-block:: python - - >>> from kmip.pie import objects - >>> from kmip.pie import client - >>> from kmip import enums - >>> c = client.ProxyKmipClient() - >>> with c: - ... key_id = c.create( - ... enums.CryptographicAlgorithm.AES, - ... 256, - ... cryptographic_usage_mask=[ - ... enums.CryptographicUsageMask.ENCRYPT, - ... enums.CryptographicUsageMask.DECRYPT - ... ] - ... ) - ... c.activate(key_id) - ... c.decrypt( - ... ( - ... b' \xb6:s0\x16\xea\t\x1b\x16\xed\xb2\x04-\xd6' - ... b'\xb6\\\xf3xJ\xfe\xa7[\x1eJ\x08I\xae\x14\xd2' - ... b\xdb\xe2' - ... ), - ... uid=key_id, - ... cryptographic_parameters={ - ... 'cryptographic_algorithm': - ... enums.CryptographicAlgorithm.AES, - ... 'block_cipher_mode': enums.BlockCipherMode.CBC, - ... 'padding_method': enums.PaddingMethod.PKCS5 - ... }, - ... iv_counter_nonce=( - ... b'\x85\x1e\x87\x64\x77\x6e\x67\x96' - ... b'\xaa\xb7\x22\xdb\xb6\x44\xac\xe8' - ... ) - ... ) - ... - b'This is a secret message.' + '1' .. py:method:: sign(data, uid=None, cryptographic_parameters=None) @@ -1098,9 +1398,4 @@ Class Documentation ... - .. py:method:: mac(data, uid=None, algorithm=None) - - Documentation coming soon. - - .. _`ssl`: https://docs.python.org/dev/library/ssl.html#socket-creation diff --git a/docs/source/community.rst b/docs/source/community.rst index 2c261c3..6f92e13 100644 --- a/docs/source/community.rst +++ b/docs/source/community.rst @@ -4,8 +4,6 @@ The PyKMIP community has various forums and resources you can use: * `Source code`_ * `Issue tracker`_ -* IRC: ``#pykmip`` on ``irc.freenode.net`` -* Twitter: ``@pykmip`` .. _`Source code`: https://github.com/openkmip/pykmip .. _`Issue tracker`: https://github.com/openkmip/pykmip/issues diff --git a/docs/source/index.rst b/docs/source/index.rst index 8774ea0..ae05bc3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -40,6 +40,7 @@ more information, check out the various articles below. changelog faq development + security client server community diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 3edc3a2..c963087 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -8,7 +8,7 @@ You can install PyKMIP via ``pip``: Supported platforms ------------------- -PyKMIP is tested on Python 2.7, 3.4, 3.5, and 3.6 on the following +PyKMIP is tested on Python 2.7, 3.4, 3.5, 3.6, and 3.7 on the following operating systems: * Ubuntu 12.04, 14.04, and 16.04 diff --git a/docs/source/security.rst b/docs/source/security.rst new file mode 100644 index 0000000..c15cec6 --- /dev/null +++ b/docs/source/security.rst @@ -0,0 +1,40 @@ +Security +======== +The PyKMIP development team takes security seriously and will respond promptly +to any reported security issue. Use the information provided here to inform +your security posture. + +Reporting a Security Issue +-------------------------- +If you discover a new PyKMIP security issue, please follow responsible +disclosure best practices and contact the project maintainers in private over +email to discuss the issue before filing a public GitHub issue. When reporting +a security issue, please include as much detail as possible. This includes: + +* a high-level description of the issue +* information on how to cause or reproduce the issue +* any details on specific portions of the project code base related to the issue + +Once you have provided this information, you should receive an acknowledgement. +Depending upon the severity of the issue, the project maintainers will respond +to collect additional information and work with you to address the security +issue. If applicable, a new library subrelease will be produced across all +actively supported releases to address and fix the issue. + +If the developerment team decides the issue does not warrant the sensitivity +of a security issue, you may file a public GitHub issue on the project +`issue tracker`_. + +Known Vulnerabilities +--------------------- + +The following are known vulnerabilities for older, unsupported versions of PyKMIP. + ++---------------------+--------------------------+-------------------+--------------------------+ +| CVE | Brief Description | PyKMIP Version(s) | Mitigation | ++=====================+==========================+===================+==========================+ +| `CVE-2018-1000872`_ | Server Denial-of-Service | <=0.7.0 | Upgrade to PyKMIP 0.8.0+ | ++---------------------+--------------------------+-------------------+--------------------------+ + +.. _`issue tracker`: https://github.com/OpenKMIP/PyKMIP/issues +.. _`CVE-2018-1000872`: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000872 \ No newline at end of file diff --git a/docs/source/server.rst b/docs/source/server.rst index d639d8f..df0126e 100644 --- a/docs/source/server.rst +++ b/docs/source/server.rst @@ -37,6 +37,7 @@ as found in the configuration file, is shown below: TLS_RSA_WITH_AES_256_CBC_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 logging_level=DEBUG + database_path=/tmp/pykmip.db The server can also be configured manually via Python. The following example shows how to create the ``KmipServer`` in Python code, directly specifying the @@ -61,7 +62,8 @@ different configuration values: ... 'TLS_RSA_WITH_AES_256_CBC_SHA256', ... 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384' ... ], - ... logging_level='DEBUG' + ... logging_level='DEBUG', + ... database_path='/tmp/pykmip.db' ... ) The different configuration options are defined below: @@ -178,9 +180,16 @@ to it: If PyKMIP is installed and you are able to ``import kmip`` in Python, you can copy the startup script and run it from any directory you choose. +PyKMIP also defines a system-wide entry point that can be used to run the +PyKMIP server once PyKMIP is installed. You can use the entry point like this: + +.. code-block:: console + + $ pykmip-server + Storage ------- -All data storage for the server is managed via `sqlalchemy`_. The current +All data storage for the server is managed via `SQLAlchemy`_. The current backend leverages `SQLite`_, storing managed objects in a flat file. The file location can be configured using the ``database_path`` configuration setting. By default this file will be located at ``/tmp/pykmip.database``. If this @@ -193,7 +202,7 @@ file is preserved across server restarts, object access will be maintained. is no upgrade path. Long term, the intent is to add support for more robust database and storage -backends available through ``sqlalchemy``. If you are interested in this work, +backends available through ``SQLAlchemy``. If you are interested in this work, please see :doc:`Development ` for more information. .. _authentication: @@ -761,6 +770,29 @@ Creating a private key object would look like this: ... "Example Private Key" ... ) +Split Keys +~~~~~~~~~~ +A split key is a secret value representing a key composed of multiple parts. +The parts of the key can be recombined cryptographically to reconstitute the +original key. + +Creating a split key object would look like this: + +.. code-block:: python + + >>> from kmip import enums + >>> from kmip.pie.objects import SplitKey + >>> key = SplitKey( + ... cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + ... cryptographic_length=128, + ... key_value=b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF', + ... name="Split Key", + ... split_key_parts=3, + ... key_part_identifier=1, + ... split_key_threshold=3, + ... split_key_method=enums.SplitKeyMethod.XOR + ... ) + Certificates ~~~~~~~~~~~~ A certificate is a cryptographic object that contains a public key along with @@ -839,6 +871,18 @@ operation, the PyKMIP server will not be able to support it either. If you are interested in adding a new cryptographic backend to the PyKMIP server, see :doc:`Development ` for more information. +Activate +~~~~~~~~ +The Activate operation updates the state of a managed object, allowing it to +be used for cryptographic operations. Specifically, the object transitions +from the pre-active state to the active state (see :term:`state`). + +Errors may be generated during the activation of a managed object. These +may occur in the following cases: + +* the managed object is not activatable (e.g., opaque data object) +* the managed object is not in the pre-active state + Create ~~~~~~ The Create operation is used to create symmetric keys for a variety of @@ -920,27 +964,26 @@ may occur in the following cases: * an invalid cryptographic length is provided for a specific cryptographic algorithm -Register -~~~~~~~~ -The Register operation is used to store an existing KMIP object with the -server. For examples of the objects that can be stored, see :ref:`objects`. +Decrypt +~~~~~~~ +The Decrypt operations allows the client to decrypt data with an existing +managed object stored by the server. Both symmetric and asymmetric decryption +are supported. See :ref:`encrypt` above for information on supported algorithms +and the types of errors to expect from the server. -All users are allowed to register objects. There are no quotas currently -enforced by the server. +DeleteAttribute +~~~~~~~~~~~~~~~ +The DeleteAttribute operation allows the client to delete an attribute from an +existing managed object. -Various KMIP-defined attributes may be set when an object is registered. -These may include: +Errors may be generated during the attribute deletion process. These may occur +in the following cases: -* :term:`cryptographic_algorithm` -* :term:`cryptographic_length` -* :term:`cryptographic_usage_mask` -* :term:`initial_date` -* :term:`key_format_type` -* :term:`name` -* :term:`object_type` -* :term:`operation_policy_name` -* :term:`state` -* :term:`unique_identifier` +* the specified managed object does not exist +* the specified attribute may not be applicable to the specified managed object +* the specified attribute is not supported by the server +* the specified attribute cannot be deleted by the client +* the specified attribute could not be located for deletion on the specified managed object DeriveKey ~~~~~~~~~ @@ -973,15 +1016,56 @@ in the following cases: * the cryptographic length is not provided with the request * the requested cryptographic length is longer than the generated key -Locate -~~~~~~ -The Locate operation is used to identify managed objects that the user has -access to, according to specific filtering criteria. Currently, the server -only support object filtering based on the object :term:`name` attribute. +Destroy +~~~~~~~ +The Destroy operation deletes a managed object from the server. Once destroyed, +the object can no longer be retrieved or used for cryptographic operations. +An object can only be destroyed if it is in the pre-active or deactivated +states. -If no filtering values are provided, the server will return a list of -:term:`unique_identifier` values corresponding to all of the managed objects -the user has access to. +Errors may be generated during the destruction of a managed object. These +may occur in the following cases: + +* the managed object is not destroyable (e.g., the object does not exist) +* the managed object is in the active state + +DiscoverVersions +~~~~~~~~~~~~~~~~ +The DiscoverVersions operation allows the client to determine which versions +of the KMIP specification are supported by the server. + +.. _encrypt: + +Encrypt +~~~~~~~ +The Encrypt operation allows the client to encrypt data with an existing +managed object stored by the server. Both symmetric and asymmetric encryption +are supported: + +Symmetric Key Algorithms +************************ +* `3DES`_ +* `AES`_ +* `Blowfish`_ +* `Camellia`_ +* `CAST5`_ +* `IDEA`_ +* `RC4`_ + +Asymmetric Key Algorithms +************************* +* `RSA`_ + +Errors may be generated during the encryption. These may occur in the +following cases: + +* the encryption key is not accessible to the user +* the encryption key is not in the active state and must be activated +* the encryption key does not have the Encrypt bit set in its usage mask +* the requested encryption algorithm is not supported +* the specified encryption key is not compatible with the requested algorithm +* the requested encryption algorithm requires a block cipher mode +* the requested block cipher mode is not supported .. _get: @@ -1035,49 +1119,64 @@ available for a specific managed object. Given the :term:`unique_identifier` of a managed object, the server will return a list of attribute names for attributes that can be accessed using the GetAttributes operation. -Activate -~~~~~~~~ -The Activate operation updates the state of a managed object, allowing it to -be used for cryptographic operations. Specifically, the object transitions -from the pre-active state to the active state (see :term:`state`). - -Errors may be generated during the activation of a managed object. These -may occur in the following cases: - -* the managed object is not activatable (e.g., opaque data object) -* the managed object is not in the pre-active state - -Revoke +Locate ~~~~~~ -The Revoke operation updates the state of a managed object, effectively -deactivating but not destroying it. The client provides a specific -:term:`revocation_reason_code` indicating why revocation is occurring. +The Locate operation is used to identify managed objects that the user has +access to, according to specific filtering criteria. Currently, the server +only support object filtering based on the object :term:`name` attribute. -If revocation is due to a key or CA compromise, the managed object is moved -to the compromised state if it is in the pre-active, active, or deactivated -states. If the object has already been destroyed, it will be moved to the -destroyed compromised state. Otherwise, if revocation is due to any other -reason, the managed object is moved to the deactivated state if it is in -the active state. +If no filtering values are provided, the server will return a list of +:term:`unique_identifier` values corresponding to all of the managed objects +the user has access to. -Errors may be generated during the revocation of a managed object. These +MAC +~~~ +The MAC operation allows the client to compute a message authentication code +on data using an existing managed object stored by the server. Both `HMAC`_ +and `CMAC`_ algorithms are supported: + +HMAC Hashing Algorithms +*********************** +* `MD5`_ +* `SHA1`_ +* `SHA224`_ +* `SHA256`_ +* `SHA384`_ +* `SHA512`_ + +CMAC Symmetric Algorithms +************************* +* `3DES`_ +* `AES`_ +* `Blowfish`_ +* `Camellia`_ +* `CAST5`_ +* `IDEA`_ +* `RC4`_ + +Errors may be generated during the authentication code creation process. These may occur in the following cases: -* the managed object is not revokable (e.g., opaque data object) -* the managed object is not active when revoked for a non-compromise +* the managed object to use is not accessible to the user +* the managed object to use is not in the active state and must be activated +* the managed object does not have the Generate bit set in its usage mask +* the requested algorithm is not supported for HMAC/CMAC generation -Destroy -~~~~~~~ -The Destroy operation deletes a managed object from the server. Once destroyed, -the object can no longer be retrieved or used for cryptographic operations. -An object can only be destroyed if it is in the pre-active or deactivated -states. +ModifyAttribute +~~~~~~~~~~~~~~~ +The ModifyAttribute operation allows the client to modify an existing attribute +on an existing managed object. -Errors may be generated during the destruction of a managed object. These -may occur in the following cases: +Errors may be generated during the attribute modification process. These may +occur in the following cases: -* the managed object is not destroyable (e.g., the object does not exist) -* the managed object is in the active state +* the specified managed object does not exist +* the specified attribute may not be applicable to the specified managed object +* the specified attribute is not supported by the server +* the specified attribute cannot be modified by the client +* the specified attribute is not set on the specified managed object +* the specified attribute is multivalued and the current attribute field must be specified +* the specified attribute index does not correspond to an existing attribute Query ~~~~~ @@ -1101,50 +1200,60 @@ types of information, depending upon which items the client requests: The PyKMIP server currently only includes the supported operations and the server information in Query responses. -DiscoverVersions -~~~~~~~~~~~~~~~~ -The DiscoverVersions operation allows the client to determine which versions -of the KMIP specification are supported by the server. +Register +~~~~~~~~ +The Register operation is used to store an existing KMIP object with the +server. For examples of the objects that can be stored, see :ref:`objects`. -.. _encrypt: +All users are allowed to register objects. There are no quotas currently +enforced by the server. -Encrypt -~~~~~~~ -The Encrypt operation allows the client to encrypt data with an existing -managed object stored by the server. Both symmetric and asymmetric encryption -are supported: +Various KMIP-defined attributes may be set when an object is registered. +These may include: -Symmetric Key Algorithms -************************ -* `3DES`_ -* `AES`_ -* `Blowfish`_ -* `Camellia`_ -* `CAST5`_ -* `IDEA`_ -* `RC4`_ +* :term:`cryptographic_algorithm` +* :term:`cryptographic_length` +* :term:`cryptographic_usage_mask` +* :term:`initial_date` +* :term:`key_format_type` +* :term:`name` +* :term:`object_type` +* :term:`operation_policy_name` +* :term:`state` +* :term:`unique_identifier` -Asymmetric Key Algorithms -************************* -* `RSA`_ +Revoke +~~~~~~ +The Revoke operation updates the state of a managed object, effectively +deactivating but not destroying it. The client provides a specific +:term:`revocation_reason_code` indicating why revocation is occurring. -Errors may be generated during the encryption. These may occur in the -following cases: +If revocation is due to a key or CA compromise, the managed object is moved +to the compromised state if it is in the pre-active, active, or deactivated +states. If the object has already been destroyed, it will be moved to the +destroyed compromised state. Otherwise, if revocation is due to any other +reason, the managed object is moved to the deactivated state if it is in +the active state. -* the encryption key is not accessible to the user -* the encryption key is not in the active state and must be activated -* the encryption key does not have the Encrypt bit set in its usage mask -* the requested encryption algorithm is not supported -* the specified encryption key is not compatible with the requested algorithm -* the requested encryption algorithm requires a block cipher mode -* the requested block cipher mode is not supported +Errors may be generated during the revocation of a managed object. These +may occur in the following cases: -Decrypt -~~~~~~~ -The Decrypt operations allows the client to decrypt data with an existing -managed object stored by the server. Both symmetric and asymmetric decryption -are supported. See :ref:`encrypt` above for information on supported algorithms -and the types of errors to expect from the server. +* the managed object is not revokable (e.g., opaque data object) +* the managed object is not active when revoked for a non-compromise + +SetAttribute +~~~~~~~~~~~~ +The SetAttribute operation allows the client to set the value of an attribute +on an existing managed object. + +Errors may be generated during the attribute setting process. These may occur +in the following cases: + +* the specified managed object does not exist +* the specified attribute may not be applicable to the specified managed object +* the specified attribute is not supported by the server +* the specified attribute cannot be set by the client +* the specified attribute is multivalued and cannot be set with this operation .. _sign: @@ -1181,41 +1290,8 @@ with an existing public key stored by the server. See :ref:`sign` above for information on supported algorithms and the types of errors to expect from the server. -MAC -~~~ -The MAC operation allows the client to compute a message authentication code -on data using an existing managed object stored by the server. Both `HMAC`_ -and `CMAC`_ algorithms are supported: - -HMAC Hashing Algorithms -*********************** -* `MD5`_ -* `SHA1`_ -* `SHA224`_ -* `SHA256`_ -* `SHA384`_ -* `SHA512`_ - -CMAC Symmetric Algorithms -************************* -* `3DES`_ -* `AES`_ -* `Blowfish`_ -* `Camellia`_ -* `CAST5`_ -* `IDEA`_ -* `RC4`_ - -Errors may be generated during the authentication code creation process. These -may occur in the following cases: - -* the managed object to use is not accessible to the user -* the managed object to use is not in the active state and must be activated -* the managed object does not have the Generate bit set in its usage mask -* the requested algorithm is not supported for HMAC/CMAC generation - .. _`ssl`: https://docs.python.org/dev/library/ssl.html#socket-creation -.. _`sqlalchemy`: https://www.sqlalchemy.org/ +.. _`SQLAlchemy`: https://www.sqlalchemy.org/ .. _`SQLite`: http://docs.sqlalchemy.org/en/latest/dialects/sqlite.html .. _`pyca/cryptography`: https://cryptography.io/en/latest/ .. _`OpenSSL`: https://www.openssl.org/