Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add config about tpm #364

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
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
32 changes: 31 additions & 1 deletion kmip/services/server/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ def __init__(self):
'policy_path',
'enable_tls_client_auth',
'tls_cipher_suites',
'logging_level'
'logging_level',
'tpm_srk_pswd',
'enable_tpm'
]

def set_setting(self, setting, value):
Expand Down Expand Up @@ -92,6 +94,10 @@ def set_setting(self, setting, value):
self._set_enable_tls_client_auth(value)
elif setting == 'tls_cipher_suites':
self._set_tls_cipher_suites(value)
elif setting == 'enable_tpm':
self._set_enable_tpm(value)
elif setting == 'tpm_srk_pswd':
self._set_tpm_srk_pswd(value)
else:
self._set_logging_level(value)

Expand Down Expand Up @@ -164,6 +170,10 @@ def _parse_settings(self, parser):
self._set_enable_tls_client_auth(
parser.getboolean('server', 'enable_tls_client_auth')
)
if parser.has_option('server', 'enable_tpm'):
self._set_enable_tpm(parser.getboolean('server', 'enable_tpm'))
if parser.has_option('server', 'tpm_srk_pswd'):
self._set_tpm_srk_pswd(paser.get('server', 'tpm_srk_pswd'))
if parser.has_option('server', 'tls_cipher_suites'):
self._set_tls_cipher_suites(
parser.get('server', 'tls_cipher_suites')
Expand Down Expand Up @@ -278,6 +288,26 @@ def _set_enable_tls_client_auth(self, value):
"must be a boolean."
)

def _set_enable_tpm(self, value):
if value is None:
self.settings['enable_tpm'] = False
elif isinstance(value, bool):
self.settings['enable_tpm'] = value
else:
raise exceptions.ConfigurationError(
"The flag enabling the TPM must be a boolean"
)

def _set_tpm_srk_pswd(self, value):
if not value:
self.settings['tpm_srk_pswd'] = '0'*20
elif isinstance(value, six.string_types):
self.settings['tpm_srk_pswd'] = value
else:
raise exceptions.ConfigurationError(
"The tpm srk password, if specified, must be a valid string"
)

def _set_tls_cipher_suites(self, value):
if not value:
self.settings['tls_cipher_suites'] = []
Expand Down
24 changes: 23 additions & 1 deletion kmip/services/server/crypto/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
# 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 base64
import logging
import os

import subprocess
import tempfile

from cryptography import exceptions as errors
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization, hashes, hmac, cmac
Expand Down Expand Up @@ -1439,3 +1442,22 @@ def verify_signature(self,
"The signing algorithm '{0}' is not supported for "
"signature verification.".format(signing_algorithm)
)

def tpm_encrypt_key(self, plain_key):
p = subprocess.Popen(['tpm_sealdata', '--well-known'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
encrypted = p.communicate(plain_key)[0]
return base64.b64encode(encrypted)

def tpm_decrypt_key(self, encrypted_key):
encrypted_key = base64.b64decode(encrypted_key)
(encfile, encpath) = tempfile.mkstemp()
encfile = open(encpath, 'w')
encfile.write(encrypted_key)
encfile.close()
p = subprocess.Popen(['tpm_unsealdata', '--srk-well-known',
'-i', encpath],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
plain_key = p.communicate()[0]
os.remove(encpath)
return plain_key
14 changes: 10 additions & 4 deletions kmip/services/server/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class KmipEngine(object):
* Cryptographic usage mask enforcement per object type
"""

def __init__(self, policy_path=None):
def __init__(self, policy_path=None, enable_tpm=None):
"""
Create a KmipEngine.

Expand Down Expand Up @@ -126,7 +126,7 @@ def __init__(self, policy_path=None):
self._attribute_policy = policy.AttributePolicy(self._protocol_version)
self._operation_policies = copy.deepcopy(operation_policy.policies)
self._load_operation_policies(policy_path)

self._enable_tpm = enable_tpm
self._client_identity = None

def _load_operation_policies(self, policy_path):
Expand Down Expand Up @@ -1230,8 +1230,12 @@ def _process_create_key_pair(self, payload):
private_key._owner = self._client_identity
private_key.initial_date = public_key.initial_date

self._data_session.add(public_key)
self._data_session.add(private_key)
if self._enable_tpm:
self._data_session.add(self._cryptography_engine.tpm_encrypt_key(public_key))
self._data_session.add(self._cryptography_engine.tpm_encrypt_key(private_key))
else:
self._data_session.add(public_key)
self._data_session.add(private_key)

# NOTE (peterhamilton) SQLAlchemy will *not* assign an ID until
# commit is called. This makes future support for UNDO problematic.
Expand Down Expand Up @@ -1575,6 +1579,8 @@ def _process_get(self, payload):
unique_identifier,
enums.Operation.GET
)
if self._enable_tpm:
managed_object = self._cryptography_engine.tpm_decrypt_key(managed_object)

if key_format_type:
if not hasattr(managed_object, 'key_format_type'):
Expand Down
8 changes: 7 additions & 1 deletion kmip/services/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def __init__(
log_path='/var/log/pykmip/server.log',
policy_path=None,
enable_tls_client_auth=None,
enable_tpm=None,
tls_cipher_suites=None,
logging_level=None
):
Expand Down Expand Up @@ -128,6 +129,7 @@ def __init__(
auth_suite,
policy_path,
enable_tls_client_auth,
enable_tpm,
tls_cipher_suites,
logging_level
)
Expand All @@ -141,7 +143,8 @@ def __init__(
self.auth_suite = auth.BasicAuthenticationSuite(cipher_suites)

self._engine = engine.KmipEngine(
self.config.settings.get('policy_path')
self.config.settings.get('policy_path'),
self.config.settings.get('enable_tpm')
)
self._session_id = 1
self._is_serving = False
Expand Down Expand Up @@ -178,6 +181,7 @@ def _setup_configuration(
auth_suite=None,
policy_path=None,
enable_tls_client_auth=None,
enable_tpm=None,
tls_cipher_suites=None,
logging_level=None
):
Expand All @@ -203,6 +207,8 @@ def _setup_configuration(
'enable_tls_client_auth',
enable_tls_client_auth
)
if enable_tpm:
self.config.set_setting('enable_tpm', enable_tpm)
if tls_cipher_suites:
self.config.set_setting(
'tls_cipher_suites',
Expand Down