diff options
author | Jan Cholasta <jcholast@redhat.com> | 2014-06-13 14:49:29 +0200 |
---|---|---|
committer | Petr Viktorin <pviktori@redhat.com> | 2014-07-30 16:04:21 +0200 |
commit | 8bbdfff102849c0f573e56530a734643a568e0dd (patch) | |
tree | 3cb54cd77d1eb942a64fb612c525f9cd6f0b9477 | |
parent | 1b8a1e5564e634ab9358ac176f586d563220542c (diff) | |
download | freeipa-8bbdfff102849c0f573e56530a734643a568e0dd.tar.gz freeipa-8bbdfff102849c0f573e56530a734643a568e0dd.tar.xz freeipa-8bbdfff102849c0f573e56530a734643a568e0dd.zip |
Allow adding CA certificates to certificate store in ipa-cacert-manage.
Part of https://fedorahosted.org/freeipa/ticket/3737
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
-rw-r--r-- | install/tools/man/ipa-cacert-manage.1 | 23 | ||||
-rw-r--r-- | ipaserver/install/ipa_cacert_manage.py | 57 |
2 files changed, 78 insertions, 2 deletions
diff --git a/install/tools/man/ipa-cacert-manage.1 b/install/tools/man/ipa-cacert-manage.1 index cf42b2457..3006be7fc 100644 --- a/install/tools/man/ipa-cacert-manage.1 +++ b/install/tools/man/ipa-cacert-manage.1 @@ -37,6 +37,13 @@ When the IPA CA is subordinate of an external CA, the renewal process involves s .sp When the IPA CA is not configured, this command is not available. .RE +.TP +\fBinstall\fR +\- Install a CA certificate +.sp +.RS +This command can be used to install new CA certificate to IPA. +.RE .SH "OPTIONS" .TP \fB\-p\fR \fIDM_PASSWORD\fR, \fB\-\-password\fR=\fIDM_PASSWORD\fR @@ -54,6 +61,22 @@ PEM file containing a certificate signed by the external CA. Must be given with \fB\-\-external\-ca\-file\fR=\fIFILE\fR PEM file containing the external CA chain. .TP +\fB\-n\fR \fINICKNAME\fR, \fB\-\-nickname\fR=\fINICKNAME\fR +Nickname for the certificate. +.TP +\fB\-t\fR \fITRUST_FLAGS\fR, \fB\-\-trust\-flags\fR=\fITRUST_FLAGS\fR +Trust flags for the certificate in certutil format. Trust flags are of the form "X,Y,Z" where X is for SSL, Y is for S/MIME, and Z is for code signing. Use ",," for no explicit trust. +.sp +The supported trust flags are: +.RS +.IP +C \- CA trusted to issue server certificates +.IP +T \- CA trusted to issue client certificates +.IP +p \- not trusted +.RE +.TP \fB\-v\fR, \fB\-\-verbose\fR Print debugging information. .TP diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py index be92b8a1f..64602c835 100644 --- a/ipaserver/install/ipa_cacert_manage.py +++ b/ipaserver/install/ipa_cacert_manage.py @@ -36,7 +36,7 @@ from ipaserver.plugins.ldap2 import ldap2 class CACertManage(admintool.AdminTool): command_name = 'ipa-cacert-manage' - usage = "%prog renew [options]" + usage = "%prog {renew|install} [options]" description = "Manage CA certificates." @@ -67,6 +67,15 @@ class CACertManage(admintool.AdminTool): help="PEM file containing the external CA chain") parser.add_option_group(renew_group) + install_group = OptionGroup(parser, "Install options") + install_group.add_option( + "-n", "--nickname", dest='nickname', + help="Nickname for the certificate") + install_group.add_option( + "-t", "--trust-flags", dest='trust_flags', default='C,,', + help="Trust flags for the certificate in certutil format") + parser.add_option_group(install_group) + def validate_options(self): super(CACertManage, self).validate_options(needs_root=True) @@ -85,6 +94,9 @@ class CACertManage(admintool.AdminTool): parser.error("--external-ca-file not specified") elif not options.external_cert_file and options.external_ca_file: parser.error("--external-cert-file not specified") + elif command == 'install': + if len(self.args) < 2: + parser.error("certificate file name not provided") else: parser.error("unknown command \"%s\"" % command) @@ -95,7 +107,8 @@ class CACertManage(admintool.AdminTool): api.bootstrap(in_server=True) api.finalize() - if command == 'renew' and options.external_cert_file: + if ((command == 'renew' and options.external_cert_file) or + command == 'install'): self.conn = self.ldap_connect() else: self.conn = None @@ -103,6 +116,8 @@ class CACertManage(admintool.AdminTool): try: if command == 'renew': rc = self.renew() + elif command == 'install': + rc = self.install() finally: if self.conn is not None: self.conn.disconnect() @@ -298,3 +313,41 @@ class CACertManage(admintool.AdminTool): self.log.debug("modifying certmonger request '%s'", self.request_id) certmonger.modify(self.request_id, profile='ipaCACertRenewal') + + def install(self): + print "Installing CA certificate, please wait" + + options = self.options + cert_filename = self.args[1] + + nss_cert = None + try: + try: + nss_cert = x509.load_certificate_from_file(cert_filename) + except IOError, e: + raise admintool.ScriptError( + "Can't open \"%s\": %s" % (cert_filename, e)) + except (TypeError, NSPRError), e: + raise admintool.ScriptError("Not a valid certificate: %s" % e) + if not nss_cert.is_ca_cert(): + raise admintool.ScriptError("Not a CA certificate") + subject = nss_cert.subject + cert = nss_cert.der_data + finally: + del nss_cert + + nickname = options.nickname or str(subject) + + trust_flags = options.trust_flags + if ((set(trust_flags) - set(',CPTcgpuw')) or + len(trust_flags.split(',')) != 3): + raise admintool.ScriptError("Invalid trust flags") + + try: + certstore.put_ca_cert_nss( + self.conn, api.env.basedn, cert, nickname, trust_flags) + except ValueError, e: + raise admintool.ScriptError( + "Failed to install the certificate: %s" % e) + + print "CA certificate successfully installed" |