summaryrefslogtreecommitdiffstats
path: root/ipapython
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2016-04-11 12:42:35 +1000
committerJan Cholasta <jcholast@redhat.com>2016-06-09 09:04:27 +0200
commit0d37d230c066f9eb703c81e0e21b1b6738703b41 (patch)
treeaad0e681086001dc07ab86a3806f12c4a416c5d5 /ipapython
parentb584ffa4ac9c61bad9e4e05e5b39bd0503e39dcd (diff)
downloadfreeipa-0d37d230c066f9eb703c81e0e21b1b6738703b41.tar.gz
freeipa-0d37d230c066f9eb703c81e0e21b1b6738703b41.tar.xz
freeipa-0d37d230c066f9eb703c81e0e21b1b6738703b41.zip
Optionally add service name to Custodia key DNs
Lightweight CAs support introduces new service principals for Dogtag, with Custodia keys. The current Custodia key creation uses a DN that contains only they key type and the hostname, so keys for multiple services on the same host cannot be created. Add the 'generate_keys' method to generate keys for a host or an arbitrary service. When a service name is given, add the key entries in a nested container with RDN 'cn=<service name>'. (The container is assumed to exist). This change does not affect searching because subtree search is used, filtering on the ipaKeyUsage and memberPrincipal attributes. Part of: https://fedorahosted.org/freeipa/ticket/4559 Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Diffstat (limited to 'ipapython')
-rw-r--r--ipapython/secrets/kem.py27
1 files changed, 22 insertions, 5 deletions
diff --git a/ipapython/secrets/kem.py b/ipapython/secrets/kem.py
index 0abf28ae4..d45efe8cc 100644
--- a/ipapython/secrets/kem.py
+++ b/ipapython/secrets/kem.py
@@ -3,6 +3,7 @@
from __future__ import print_function
from ipaplatform.paths import paths
from six.moves.configparser import ConfigParser
+from ipapython.dn import DN
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa, ec
@@ -105,11 +106,24 @@ class KEMLdap(iSecLdap):
encoding=serialization.Encoding.DER,
format=serialization.PublicFormat.SubjectPublicKeyInfo)
- def set_key(self, usage, host, principal, key):
+ def set_key(self, usage, principal, key):
+ """
+ Write key for the host or service.
+
+ Service keys are nested one level beneath the 'cn=custodia'
+ container, in the 'cn=<servicename>' container; this allows
+ fine-grained control over key management permissions for
+ specific services.
+
+ The container is assumed to exist.
+
+ """
public_key = self._format_public_key(key)
conn = self.connect()
+ servicename, host = principal.split('@')[0].split('/')
name = '%s/%s' % (KEY_USAGE_MAP[usage], host)
- dn = 'cn=%s,%s' % (name, self.keysbase)
+ service_rdn = ('cn', servicename) if servicename != 'host' else DN()
+ dn = str(DN(('cn', name), service_rdn, self.keysbase))
try:
mods = [('objectClass', ['nsContainer',
'ipaKeyPolicy',
@@ -170,15 +184,18 @@ class IPAKEMKeys(KEMKeysStore):
return conn.get_key(usage, kid)
def generate_server_keys(self):
- principal = 'host/%s@%s' % (self.host, self.realm)
+ self.generate_keys('host')
+
+ def generate_keys(self, servicename):
+ principal = '%s/%s@%s' % (servicename, self.host, self.realm)
# Neutralize the key with read if any
self._server_keys = None
# Generate private key and store it
pubkeys = newServerKeys(self.config['server_keys'], principal)
# Store public key in LDAP
ldapconn = KEMLdap(self.ldap_uri)
- ldapconn.set_key(KEY_USAGE_SIG, self.host, principal, pubkeys[0])
- ldapconn.set_key(KEY_USAGE_ENC, self.host, principal, pubkeys[1])
+ ldapconn.set_key(KEY_USAGE_SIG, principal, pubkeys[0])
+ ldapconn.set_key(KEY_USAGE_ENC, principal, pubkeys[1])
@property
def server_keys(self):