diff options
Diffstat (limited to 'ipapython/dnssec/abshsm.py')
-rw-r--r-- | ipapython/dnssec/abshsm.py | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/ipapython/dnssec/abshsm.py b/ipapython/dnssec/abshsm.py new file mode 100644 index 000000000..cc8119865 --- /dev/null +++ b/ipapython/dnssec/abshsm.py @@ -0,0 +1,187 @@ +#!/usr/bin/python +# +# Copyright (C) 2014 FreeIPA Contributors see COPYING for license +# + +import _ipap11helper + +attrs_id2name = { + #_ipap11helper.CKA_ALLOWED_MECHANISMS: 'ipk11allowedmechanisms', + _ipap11helper.CKA_ALWAYS_AUTHENTICATE: 'ipk11alwaysauthenticate', + _ipap11helper.CKA_ALWAYS_SENSITIVE: 'ipk11alwayssensitive', + #_ipap11helper.CKA_CHECK_VALUE: 'ipk11checkvalue', + _ipap11helper.CKA_COPYABLE: 'ipk11copyable', + _ipap11helper.CKA_DECRYPT: 'ipk11decrypt', + _ipap11helper.CKA_DERIVE: 'ipk11derive', + #_ipap11helper.CKA_DESTROYABLE: 'ipk11destroyable', + _ipap11helper.CKA_ENCRYPT: 'ipk11encrypt', + #_ipap11helper.CKA_END_DATE: 'ipk11enddate', + _ipap11helper.CKA_EXTRACTABLE: 'ipk11extractable', + _ipap11helper.CKA_ID: 'ipk11id', + #_ipap11helper.CKA_KEY_GEN_MECHANISM: 'ipk11keygenmechanism', + _ipap11helper.CKA_KEY_TYPE: 'ipk11keytype', + _ipap11helper.CKA_LABEL: 'ipk11label', + _ipap11helper.CKA_LOCAL: 'ipk11local', + _ipap11helper.CKA_MODIFIABLE: 'ipk11modifiable', + _ipap11helper.CKA_NEVER_EXTRACTABLE: 'ipk11neverextractable', + _ipap11helper.CKA_PRIVATE: 'ipk11private', + #_ipap11helper.CKA_PUBLIC_KEY_INFO: 'ipapublickey', + #_ipap11helper.CKA_PUBLIC_KEY_INFO: 'ipk11publickeyinfo', + _ipap11helper.CKA_SENSITIVE: 'ipk11sensitive', + _ipap11helper.CKA_SIGN: 'ipk11sign', + _ipap11helper.CKA_SIGN_RECOVER: 'ipk11signrecover', + #_ipap11helper.CKA_START_DATE: 'ipk11startdate', + #_ipap11helper.CKA_SUBJECT: 'ipk11subject', + _ipap11helper.CKA_TRUSTED: 'ipk11trusted', + _ipap11helper.CKA_UNWRAP: 'ipk11unwrap', + #_ipap11helper.CKA_UNWRAP_TEMPLATE: 'ipk11unwraptemplate', + _ipap11helper.CKA_VERIFY: 'ipk11verify', + _ipap11helper.CKA_VERIFY_RECOVER: 'ipk11verifyrecover', + _ipap11helper.CKA_WRAP: 'ipk11wrap', + #_ipap11helper.CKA_WRAP_TEMPLATE: 'ipk11wraptemplate', + _ipap11helper.CKA_WRAP_WITH_TRUSTED: 'ipk11wrapwithtrusted', +} + +attrs_name2id = dict(zip(attrs_id2name.values(), attrs_id2name.keys())) + +# attribute: +# http://www.freeipa.org/page/V4/PKCS11_in_LDAP/Schema#ipk11KeyType +# +# mapping table: +# http://www.freeipa.org/page/V4/PKCS11_in_LDAP/Schema#CK_MECHANISM_TYPE +keytype_name2id = { + "rsa": _ipap11helper.KEY_TYPE_RSA, + "aes": _ipap11helper.KEY_TYPE_AES, + } + +keytype_id2name = dict(zip(keytype_name2id.values(), keytype_name2id.keys())) + +wrappingmech_name2id = { + "rsaPkcs": _ipap11helper.MECH_RSA_PKCS, + "rsaPkcsOaep": _ipap11helper.MECH_RSA_PKCS_OAEP, + "aesKeyWrap": _ipap11helper.MECH_AES_KEY_WRAP, + "aesKeyWrapPad": _ipap11helper.MECH_AES_KEY_WRAP_PAD + } + +wrappingmech_id2name = dict(zip(wrappingmech_name2id.values(), + wrappingmech_name2id.keys())) + + +bool_attr_names = set([ + 'ipk11alwaysauthenticate', + 'ipk11alwayssensitive', + 'ipk11copyable', + 'ipk11decrypt', + 'ipk11derive', + 'ipk11encrypt', + 'ipk11extractable', + 'ipk11local', + 'ipk11modifiable', + 'ipk11neverextractable', + 'ipk11private', + 'ipk11sensitive', + 'ipk11sign', + 'ipk11signrecover', + 'ipk11trusted', + 'ipk11unwrap', + 'ipk11verify', + 'ipk11verifyrecover', + 'ipk11wrap', + 'ipk11wrapwithtrusted', +]) + +modifiable_attrs_id2name = { + _ipap11helper.CKA_DECRYPT: 'ipk11decrypt', + _ipap11helper.CKA_DERIVE: 'ipk11derive', + _ipap11helper.CKA_ENCRYPT: 'ipk11encrypt', + _ipap11helper.CKA_EXTRACTABLE: 'ipk11extractable', + _ipap11helper.CKA_ID: 'ipk11id', + _ipap11helper.CKA_LABEL: 'ipk11label', + _ipap11helper.CKA_SENSITIVE: 'ipk11sensitive', + _ipap11helper.CKA_SIGN: 'ipk11sign', + _ipap11helper.CKA_SIGN_RECOVER: 'ipk11signrecover', + _ipap11helper.CKA_UNWRAP: 'ipk11unwrap', + _ipap11helper.CKA_VERIFY: 'ipk11verify', + _ipap11helper.CKA_VERIFY_RECOVER: 'ipk11verifyrecover', + _ipap11helper.CKA_WRAP: 'ipk11wrap', +} + +modifiable_attrs_name2id = dict(zip(modifiable_attrs_id2name.values(), + modifiable_attrs_id2name.keys())) + +def sync_pkcs11_metadata(log, source, target): + """sync ipk11 metadata from source object to target object""" + + # iterate over list of modifiable PKCS#11 attributes - this prevents us + # from attempting to set read-only attributes like CKA_LOCAL + for attr in modifiable_attrs_name2id: + if attr in source: + if source[attr] != target[attr]: + log.debug('Updating attribute %s from "%s" to "%s"', attr, repr(source[attr]), repr(target[attr])) + target[attr] = source[attr] + +def populate_pkcs11_metadata(source, target): + """populate all ipk11 metadata attributes in target object from source object""" + for attr in attrs_name2id: + if attr in source: + target[attr] = source[attr] + +def ldap2p11helper_api_params(ldap_key): + """prepare dict with metadata parameters suitable for key unwrapping""" + unwrap_params = {} + + # some attributes are just renamed + direct_param_map = { + "ipk11label": "label", + "ipk11id": "id", + "ipk11copyable": "cka_copyable", + "ipk11decrypt": "cka_decrypt", + "ipk11derive": "cka_derive", + "ipk11encrypt": "cka_encrypt", + "ipk11extractable": "cka_extractable", + "ipk11modifiable": "cka_modifiable", + "ipk11private": "cka_private", + "ipk11sensitive": "cka_sensitive", + "ipk11sign": "cka_sign", + "ipk11unwrap": "cka_unwrap", + "ipk11verify": "cka_verify", + "ipk11wrap": "cka_wrap", + "ipk11wrapwithtrusted": "cka_wrap_with_trusted" + } + + for ldap_name, p11h_name in direct_param_map.iteritems(): + if ldap_name in ldap_key: + unwrap_params[p11h_name] = ldap_key[ldap_name] + + # and some others needs conversion + + indirect_param_map = { + "ipk11keytype": ("key_type", keytype_name2id), + "ipawrappingmech": ("wrapping_mech", wrappingmech_name2id), + } + + for ldap_name, rules in indirect_param_map.iteritems(): + p11h_name, mapping = rules + if ldap_name in ldap_key: + unwrap_params[p11h_name] = mapping[ldap_key[ldap_name]] + + return unwrap_params + + +class AbstractHSM(object): + def _filter_replica_keys(self, all_keys): + replica_keys = {} + for key_id, key in all_keys.iteritems(): + if not key['ipk11label'].startswith('dnssec-replica:'): + continue + replica_keys[key_id] = key + return replica_keys + + def _filter_zone_keys(self, all_keys): + zone_keys = {} + for key_id, key in all_keys.iteritems(): + if key['ipk11label'] == u'dnssec-master' \ + or key['ipk11label'].startswith('dnssec-replica:'): + continue + zone_keys[key_id] = key + return zone_keys |