Add ProxyKmipClient demos for the Encrypt / Decrypt operations

This change adds demos for the ProxyKmipClient, demonstrating how
to encrypt and decrypt messages. Demo utilities have been updated
to support the new demo scripts and the KMIPProxy client has been
updated to correctly return operation results.
This commit is contained in:
Peter Hamilton 2017-08-15 11:03:20 -04:00
parent 5758c6dd1e
commit b0d454da9a
5 changed files with 230 additions and 8 deletions

77
kmip/demos/pie/decrypt.py Normal file
View File

@ -0,0 +1,77 @@
# Copyright (c) 2017 The Johns Hopkins University/Applied Physics Laboratory
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import binascii
import logging
import sys
from kmip.core import enums
from kmip.demos import utils
from kmip.pie import client
# Real world example, assuming 'test' is a valid configuration:
#
# $ python kmip/demos/pie/encrypt.py -c test -m "My test message."
# INFO - Successfully created a new encryption key.
# INFO - Secret ID: 470
# INFO - Successfully activated the encryption key.
# INFO - Successfully encrypted the message.
# INFO - Cipher text: b'49cfacbb62659180c20dfbf9f7553488b3ea9ebeecd70ce2e5c4d4
# ece6def0d4'
# INFO - No autogenerated IV expected, since one was provided.
# INFO - Autogenerated IV: None
# $ python kmip/demos/pie/decrypt.py -c test -i 470 -m b'49cfacbb62659180c20df
# bf9f7553488b3ea9ebeecd70ce2e5c4d4ece6def0d4'
# INFO - Successfully decrypted the message.
# INFO - Plain text: 'My test message.'
if __name__ == '__main__':
logger = utils.build_console_logger(logging.INFO)
# Build and parse arguments
parser = utils.build_cli_parser(enums.Operation.DECRYPT)
opts, args = parser.parse_args(sys.argv[1:])
config = opts.config
uuid = opts.uuid
message = opts.message
if not message.startswith("b"):
raise ValueError("The message should be a byte string (e.g., b'...').")
else:
message = binascii.unhexlify(message[1:])
# Build the client and connect to the server
with client.ProxyKmipClient(config=config) as client:
# Decrypt the cipher text with the encryption key.
try:
plain_text = client.decrypt(
message,
uid=uuid,
cryptographic_parameters={
'cryptographic_algorithm':
enums.CryptographicAlgorithm.AES,
'block_cipher_mode': enums.BlockCipherMode.CBC,
'padding_method': enums.PaddingMethod.ANSI_X923
},
iv_counter_nonce=(
b'\x01\x7D\x45\xA0\x88\x08\x11\x11'
b'\xF0\x00\x12\xFF\x7A\x3A\x36\x90'
)
)
logger.info("Successfully decrypted the message.")
logger.info("Plain text: '{0}'".format(plain_text.decode('utf-8')))
except Exception as e:
logger.error(e)

103
kmip/demos/pie/encrypt.py Normal file
View File

@ -0,0 +1,103 @@
# Copyright (c) 2017 The Johns Hopkins University/Applied Physics Laboratory
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import binascii
import logging
import sys
from kmip.core import enums
from kmip.demos import utils
from kmip.pie import client
# Real world example, assuming 'test' is a valid configuration:
#
# $ python kmip/demos/pie/encrypt.py -c test -m "My test message."
# INFO - Successfully created a new encryption key.
# INFO - Secret ID: 470
# INFO - Successfully activated the encryption key.
# INFO - Successfully encrypted the message.
# INFO - Cipher text: b'49cfacbb62659180c20dfbf9f7553488b3ea9ebeecd70ce2e5c4d4
# ece6def0d4'
# INFO - No autogenerated IV expected, since one was provided.
# INFO - Autogenerated IV: None
# $ python kmip/demos/pie/decrypt.py -c test -i 470 -m b'49cfacbb62659180c20df
# bf9f7553488b3ea9ebeecd70ce2e5c4d4ece6def0d4'
# INFO - Successfully decrypted the message.
# INFO - Plain text: 'My test message.'
if __name__ == '__main__':
logger = utils.build_console_logger(logging.INFO)
# Build and parse arguments
parser = utils.build_cli_parser(enums.Operation.ENCRYPT)
opts, args = parser.parse_args(sys.argv[1:])
config = opts.config
message = opts.message
message = bytes(message, 'utf-8')
# Build the client and connect to the server
with client.ProxyKmipClient(config=config) as client:
# Create an encryption key.
try:
key_id = client.create(
enums.CryptographicAlgorithm.AES,
128,
cryptographic_usage_mask=[
enums.CryptographicUsageMask.ENCRYPT,
enums.CryptographicUsageMask.DECRYPT
]
)
logger.info("Successfully created a new encryption key.")
logger.info("Secret ID: {0}".format(key_id))
except Exception as e:
logger.error(e)
sys.exit(-1)
# Activate the encryption key so that it can be used.
try:
client.activate(key_id)
logger.info("Successfully activated the encryption key.")
except Exception as e:
logger.error(e)
sys.exit(-1)
# Encrypt some data with the encryption key.
try:
cipher_text, autogenerated_iv = client.encrypt(
message,
uid=key_id,
cryptographic_parameters={
'cryptographic_algorithm':
enums.CryptographicAlgorithm.AES,
'block_cipher_mode': enums.BlockCipherMode.CBC,
'padding_method': enums.PaddingMethod.ANSI_X923
},
iv_counter_nonce=(
b'\x01\x7D\x45\xA0\x88\x08\x11\x11'
b'\xF0\x00\x12\xFF\x7A\x3A\x36\x90'
)
)
logger.info("Successfully encrypted the message.")
logger.info(
"Cipher text: {0}".format(binascii.hexlify(cipher_text))
)
logger.info(
"No autogenerated IV expected, since one was provided."
)
logger.info("Autogenerated IV: {0}".format(autogenerated_iv))
except Exception as e:
logger.error(e)

View File

@ -240,6 +240,36 @@ def build_cli_parser(operation=None):
default=None,
dest="algorithm",
help="Encryption algorithm for the secret (e.g., AES)")
elif operation is Operation.ENCRYPT:
parser.add_option(
"-m",
"--message",
action="store",
type="str",
default="This is a secret message.",
dest="message",
help="The message to encrypt."
)
elif operation is Operation.DECRYPT:
parser.add_option(
"-i",
"--uuid",
action="store",
type="str",
default=None,
dest="uuid",
help="The unique ID of the decryption key to use to decrypt the "
"cipher text."
)
parser.add_option(
"-m",
"--message",
action="store",
type="str",
default=None,
dest="message",
help="The cipher text to decrypt."
)
return parser

View File

@ -584,9 +584,15 @@ class KMIPProxy(KMIP):
result['data'] = payload.data
result['iv_counter_nonce'] = payload.iv_counter_nonce
result['result_status'] = batch_item.result_status
result['result_reason'] = batch_item.result_reason
result['result_message'] = batch_item.result_message
result['result_status'] = batch_item.result_status.value
try:
result['result_reason'] = batch_item.result_reason.value
except:
result['result_reason'] = batch_item.result_reason
try:
result['result_message'] = batch_item.result_message.value
except:
result['result_message'] = batch_item.result_message
return result
@ -653,9 +659,15 @@ class KMIPProxy(KMIP):
result['unique_identifier'] = payload.unique_identifier
result['data'] = payload.data
result['result_status'] = batch_item.result_status
result['result_reason'] = batch_item.result_reason
result['result_message'] = batch_item.result_message
result['result_status'] = batch_item.result_status.value
try:
result['result_reason'] = batch_item.result_reason.value
except:
result['result_reason'] = batch_item.result_reason
try:
result['result_message'] = batch_item.result_message.value
except:
result['result_message'] = batch_item.result_message
return result

View File

@ -839,7 +839,7 @@ class TestKMIPClient(TestCase):
self.assertEqual(None, result.get('iv_counter_nonce'))
self.assertEqual(
ResultStatusEnum.SUCCESS,
result.get('result_status').value
result.get('result_status')
)
self.assertEqual(None, result.get('result_reason'))
self.assertEqual(None, result.get('result_message'))
@ -901,7 +901,7 @@ class TestKMIPClient(TestCase):
)
self.assertEqual(
ResultStatusEnum.SUCCESS,
result.get('result_status').value
result.get('result_status')
)
self.assertEqual(None, result.get('result_reason'))
self.assertEqual(None, result.get('result_message'))