httpinstance: handle supplied PKCS#12 files in installation

Part of the mod_nss -> mod_ssl move. This patch allows loading
necessary certificates for Apache to function from PKCS#12 files.
This should fix CA-less and domain level 0 installations.

Related: https://pagure.io/freeipa/issue/3757
Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
Stanislav Laznicka
2018-01-24 13:07:38 +01:00
parent 7dc923cc4c
commit 205675239a
3 changed files with 99 additions and 17 deletions

View File

@@ -86,6 +86,28 @@ def export_pem_p12(pkcs12_fname, pkcs12_pwd_fname, nickname, pem_fname):
"-passout", "file:" + pkcs12_pwd_fname])
def pkcs12_to_certkeys(p12_fname, p12_passwd=None):
"""
Deserializes pkcs12 file to python objects
:param p12_fname: A PKCS#12 filename
:param p12_passwd: Optional password for the pkcs12_fname file
"""
args = [paths.OPENSSL, "pkcs12", "-in", p12_fname, "-nodes"]
if p12_passwd:
pwd = ipautil.write_tmp_file(p12_passwd)
args.extend(["-passin", "file:{fname}".format(fname=pwd.name)])
else:
args.extend(["-passin", "pass:"])
pems = ipautil.run(args, capture_output=True).raw_output
certs = x509.load_certificate_list(pems)
priv_keys = x509.load_private_key_list(pems)
return (certs, priv_keys)
def is_ipa_issued_cert(api, cert):
"""
Return True if the certificate has been issued by IPA

View File

@@ -326,27 +326,34 @@ class HTTPInstance(service.Service):
certmonger.stop()
def __setup_ssl(self):
db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
subject_base=self.subject_base, user="root",
group=constants.HTTPD_GROUP,
create=True)
if self.pkcs12_info:
# db.init_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1],
# ca_file=self.ca_file,
# trust_flags=trust_flags)
server_certs = db.find_server_certs()
if len(server_certs) == 0:
p12_certs, p12_priv_keys = certs.pkcs12_to_certkeys(
*self.pkcs12_info)
keys_dict = {
k.public_key().public_numbers(): k
for k in p12_priv_keys
}
certs_keys = [
(c, keys_dict.get(c.public_key().public_numbers()))
for c in p12_certs
]
server_certs_keys = [
(c, k) for c, k in certs_keys if k is not None
]
if not server_certs_keys:
raise RuntimeError(
"Could not find a suitable server cert in import in %s"
% self.pkcs12_info[0]
)
# We only handle one server cert
nickname = server_certs[0][0]
if nickname == 'ipaCert':
nickname = server_certs[1][0]
self.cert = x509.load_der_x509_certificate(paths.HTTPD_CERT_FILE)
self.cert = server_certs_keys[0][0]
x509.write_certificate(self.cert, paths.HTTPD_CERT_FILE)
x509.write_pem_private_key(
server_certs_keys[0][1],
paths.HTTPD_KEY_FILE
)
if self.ca_is_configured:
self.start_tracking_certificates()