Store HSM token and state

The HSM state is stored in fstore, so that CA and KRA installer use the
correct token names for internal certificates. The default token is
"internal", meaning the keys are stored in a NSSDB as usual.

Related: https://pagure.io/freeipa/issue/5608
Co-authored-by: Magnus K Karlsson <magnus-ka.karlsson@polisen.se>
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
This commit is contained in:
Christian Heimes 2019-08-16 14:34:16 +02:00
parent 828fdc0ed6
commit eb2313920e
3 changed files with 54 additions and 10 deletions

View File

@ -61,7 +61,7 @@ from ipaserver.install import installutils
from ipaserver.install import ldapupdate
from ipaserver.install import replication
from ipaserver.install import sysupgrade
from ipaserver.install.dogtaginstance import DogtagInstance
from ipaserver.install.dogtaginstance import DogtagInstance, INTERNAL_TOKEN
from ipaserver.plugins import ldap2
from ipaserver.masters import ENABLED_SERVICE
@ -280,7 +280,8 @@ class CAInstance(DogtagInstance):
server_cert_name: 'caServerCert',
}
token_names = {
server_cert_name: 'internal', # Server-Cert always on internal token
# Server-Cert always on internal token
server_cert_name: INTERNAL_TOKEN,
}
# The following must be aligned with the RewriteRule defined in
@ -581,6 +582,7 @@ class CAInstance(DogtagInstance):
nolog_list = [self.dm_password, self.admin_password, pki_pin]
config = self._create_spawn_config(cfg)
self.set_hsm_state(config)
pent = pwd.getpwnam(self.service_user)
with tempfile.NamedTemporaryFile('w') as f:
config.write(f)
@ -641,7 +643,7 @@ class CAInstance(DogtagInstance):
operations in 'certutil' calls.
"""
passwd = None
token = 'internal'
token = INTERNAL_TOKEN
with open(paths.PKI_TOMCAT_PASSWORD_CONF, 'r') as f:
for line in f:
(tok, pin) = line.split('=', 1)
@ -974,6 +976,7 @@ class CAInstance(DogtagInstance):
def uninstall(self):
# just eat state
self.restore_state("enabled")
self.restore_hsm_state()
DogtagInstance.uninstall(self)
@ -2051,7 +2054,7 @@ def add_lightweight_ca_tracking_requests(lwcas):
try:
certmonger.start_tracking(
certpath=paths.PKI_TOMCAT_ALIAS_DIR,
pin=certmonger.get_pin('internal'),
pin=certmonger.get_pin(INTERNAL_TOKEN),
nickname=nickname,
ca=ipalib.constants.RENEWAL_CA_NAME,
profile='caCACert',

View File

@ -52,10 +52,12 @@ from ipaserver.install import replication
from ipaserver.install.installutils import stopped_service
logger = logging.getLogger(__name__)
INTERNAL_TOKEN = "internal"
def get_security_domain():
"""
Get the security domain from the REST interface on the local Dogtag CA
@ -100,9 +102,8 @@ class DogtagInstance(service.Service):
# dict. The profile MUST be specified.
tracking_reqs = dict()
# token for CA and subsystem certificates. For now, only internal token
# is supported.
token_name = "internal"
# HSM state is shared between CA and KRA
hsm_sstore = 'pki_hsm'
# override token for specific nicknames
token_names = dict()
@ -218,7 +219,7 @@ class DogtagInstance(service.Service):
Enable client auth connection to the internal db.
"""
sub_system_nickname = "subsystemCert cert-pki-ca"
if self.token_name != "internal":
if self.token_name != INTERNAL_TOKEN:
# TODO: Dogtag 10.6.9 does not like "internal" prefix.
sub_system_nickname = '{}:{}'.format(
self.token_name, sub_system_nickname
@ -317,7 +318,7 @@ class DogtagInstance(service.Service):
# Give dogtag extra time to generate cert
timeout=CA_DBUS_TIMEOUT)
def __get_pin(self, token_name="internal"):
def __get_pin(self, token_name=INTERNAL_TOKEN):
try:
return certmonger.get_pin(token_name)
except IOError as e:
@ -587,6 +588,34 @@ class DogtagInstance(service.Service):
)
sysupgrade.set_upgrade_state('dogtag', state_name, True)
def set_hsm_state(self, config):
section_name = self.subsystem.upper()
assert section_name == 'CA'
if config.getboolean(section_name, 'pki_hsm_enable', fallback=False):
enable = True
token_name = config.get(section_name, 'pki_token_name')
else:
enable = False
token_name = INTERNAL_TOKEN
self.sstore.backup_state(self.hsm_sstore, "enabled", enable)
self.sstore.backup_state(self.hsm_sstore, "token_name", token_name)
def restore_hsm_state(self):
return (
self.sstore.restore_state(self.hsm_sstore, "enabled"),
self.sstore.restore_state(self.hsm_sstore, "token_name"),
)
@property
def hsm_enabled(self):
"""Is HSM support enabled?"""
return self.sstore.get_state(self.hsm_sstore, "enabled")
@property
def token_name(self):
"""HSM token name"""
return self.sstore.get_state(self.hsm_sstore, "token_name")
def _configure_clone(self, subsystem_config, security_domain_hostname,
clone_pkcs12_path):
subsystem_config.update(

View File

@ -473,6 +473,17 @@ def upgrade_ca_audit_cert_validity(ca):
return False
def ca_initialize_hsm_state(ca):
"""Initializse HSM state as False / internal token
"""
if not ca.sstore.has_state(ca.hsm_sstore):
section_name = ca.subsystem.upper()
config = SafeConfigParser()
config.add_section(section_name)
config.set(section_name, 'pki_hsm_enable', False)
ca.set_hsm_state(config)
def named_remove_deprecated_options():
"""
From IPA 3.3, persistent search is a default mechanism for new DNS zone
@ -2104,6 +2115,7 @@ def upgrade_configuration():
cainstance.repair_profile_caIPAserviceCert()
ca.setup_lightweight_ca_key_retrieval()
cainstance.ensure_ipa_authority_entry()
ca_initialize_hsm_state(ca)
migrate_to_authselect()
add_systemd_user_hbac()