Hi,

the attached patch fixes <https://fedorahosted.org/freeipa/ticket/4447>.

Honza

--
Jan Cholasta
>From e99142420af507f28a4e5885363b4f2153e2ab50 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 6 Aug 2014 09:43:19 +0200
Subject: [PATCH] Allow specifying key algorithm of the IPA CA cert in
 ipa-server-install.

This is especially useful for external CA install, as the algorithm is also
used for the CSR signature.

https://fedorahosted.org/freeipa/ticket/4447
---
 install/tools/ipa-server-install       | 24 +++++++++++++++++++++---
 install/tools/man/ipa-server-install.1 |  3 +++
 ipaserver/install/cainstance.py        | 12 ++++++++++--
 3 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index dc3655b..2667eaa 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -149,6 +149,13 @@ def validate_admin_password(password):
         raise ValueError('Password must not contain these characters: %s' %
             ', '.join('"%s"' % c for c in bad_characters))
 
+def validate_ca_key_algorithm(ca_key_algorithm):
+    supported = ('SHA1withRSA', 'SHA256withRSA', 'SHA512withRSA', 'MD5withRSA',
+                 'MD2withRSA')
+    if ca_key_algorithm not in supported:
+        raise ValueError(
+            "Key algorithm must be one of: %s" % ", ".join(supported))
+
 def parse_options():
     # Guaranteed to give a random 200k range below the 2G mark (uint32_t limit)
     namespace = random.randint(1, 10000) * 200000
@@ -226,6 +233,8 @@ def parse_options():
     cert_group.add_option("--subject", action="callback", callback=subject_callback,
                       type="string",
                       help="The certificate subject base (default O=<realm-name>)")
+    cert_group.add_option("--ca-key-algorithm", dest="ca_key_algorithm",
+                      help="Key algorithm of the IPA CA certificate (default SHA256withRSA)")
     parser.add_option_group(cert_group)
 
     dns_group = OptionGroup(parser, "DNS options")
@@ -340,6 +349,12 @@ def parse_options():
     if (options.external_cert_file and not os.path.isabs(options.external_cert_file)):
         parser.error("--external-cert-file must use an absolute path")
 
+    if options.ca_key_algorithm:
+        try:
+            validate_ca_key_algorithm(options.ca_key_algorithm)
+        except ValueError, e:
+            parser.error("invalid CA key algorithm: %s" % e)
+
     if options.idmax == 0:
         options.idmax = int(options.idstart) + 200000 - 1
 
@@ -1082,7 +1097,8 @@ def main():
             dogtag_constants=dogtag.install_constants)
         if external == 0:
             ca.configure_instance(host_name, domain_name, dm_password,
-                                  dm_password, subject_base=options.subject)
+                                  dm_password, subject_base=options.subject,
+                                  ca_key_algorithm=options.ca_key_algorithm)
         elif external == 1:
             # stage 1 of external CA installation
             options.realm_name = realm_name
@@ -1097,14 +1113,16 @@ def main():
             write_cache(vars(options))
             ca.configure_instance(host_name, domain_name, dm_password,
                                   dm_password, csr_file=paths.ROOT_IPA_CSR,
-                                  subject_base=options.subject)
+                                  subject_base=options.subject,
+                                  ca_key_algorithm=options.ca_key_algorithm)
         else:
             # stage 2 of external CA installation
             ca.configure_instance(host_name, domain_name, dm_password,
                                   dm_password,
                                   cert_file=options.external_cert_file,
                                   cert_chain_file=options.external_ca_file,
-                                  subject_base=options.subject)
+                                  subject_base=options.subject,
+                                  ca_key_algorithm=options.ca_key_algorithm)
 
         # Now put the CA cert where other instances exepct it
         ca.publish_ca_cert(CACERT)
diff --git a/install/tools/man/ipa-server-install.1 b/install/tools/man/ipa-server-install.1
index 4adf1d0..2665c9b 100644
--- a/install/tools/man/ipa-server-install.1
+++ b/install/tools/man/ipa-server-install.1
@@ -116,6 +116,9 @@ The password of the Kerberos KDC PKCS#12 file
 .TP
 \fB\-\-subject\fR=\fISUBJECT\fR
 The certificate subject base (default O=REALM.NAME)
+.TP
+\fB\-\-ca\-key\-algorithm\fR=\fIALGORITHM\fR
+Key algorithm of the IPA CA certificate (default SHA256withRSA)
 
 .SS "DNS OPTIONS"
 .TP
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index b64588c..efe4997 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -410,7 +410,7 @@ class CAInstance(service.Service):
                            pkcs12_info=None, master_host=None, csr_file=None,
                            cert_file=None, cert_chain_file=None,
                            master_replication_port=None,
-                           subject_base=None):
+                           subject_base=None, ca_key_algorithm=None):
         """Create a CA instance.
 
            For Dogtag 9, this may involve creating the pki-ca instance.
@@ -436,6 +436,10 @@ class CAInstance(service.Service):
             self.subject_base = DN(('O', self.realm))
         else:
             self.subject_base = subject_base
+        if ca_key_algorithm is None:
+            self.ca_key_algorithm = 'SHA256withRSA'
+        else:
+            self.ca_key_algorithm = ca_key_algorithm
 
         # Determine if we are installing as an externally-signed CA and
         # what stage we're in.
@@ -562,6 +566,9 @@ class CAInstance(service.Service):
         config.set("CA", "pki_audit_signing_nickname", "auditSigningCert cert-pki-ca")
         config.set("CA", "pki_ca_signing_nickname", "caSigningCert cert-pki-ca")
 
+        # CA key algorithm
+        config.set("CA", "pki_ca_signing_key_algorithm", self.ca_key_algorithm)
+
         if (self.clone):
             cafile = self.pkcs12_info[0]
             shutil.copy(cafile, paths.TMP_CA_P12)
@@ -709,7 +716,8 @@ class CAInstance(service.Service):
                     "-db_name", "ipaca",
                     "-key_size", "2048",
                     "-key_type", "rsa",
-                    "-key_algorithm", "SHA256withRSA",
+                    "-key_algorithm", self.ca_key_algorithm,
+                    "-signing_algorithm", "SHA256withRSA",
                     "-save_p12", "true",
                     "-backup_pwd", self.admin_password,
                     "-subsystem_name", self.service_name,
-- 
1.9.3

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to