def install(self): print("Installing CA certificate, please wait") options = self.options cert_filename = self.args[1] try: cert = x509.load_certificate_from_file(cert_filename) except IOError as e: raise admintool.ScriptError("Can't open \"%s\": %s" % (cert_filename, e)) except (TypeError, ValueError) as e: raise admintool.ScriptError("Not a valid certificate: %s" % e) nickname = options.nickname or str(DN(cert.subject)) ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, api.env.realm, False) with certs.NSSDatabase() as tmpdb: tmpdb.create_db() tmpdb.add_cert(cert, nickname, EXTERNAL_CA_TRUST_FLAGS) for ca_cert, ca_nickname, ca_trust_flags in ca_certs: tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags) try: tmpdb.verify_ca_cert_validity(nickname) except ValueError as e: raise admintool.ScriptError( "Not a valid CA certificate: %s (visit " "http://www.freeipa.org/page/Troubleshooting for " "troubleshooting guide)" % e) trust_flags = options.trust_flags.split(',') if (set(options.trust_flags) - set(',CPTcgpuw') or len(trust_flags) not in [3, 4]): raise admintool.ScriptError("Invalid trust flags") extra_flags = trust_flags[3:] extra_usages = set() if extra_flags: if 'C' in extra_flags[0]: extra_usages.add(x509.EKU_PKINIT_KDC) if 'T' in extra_flags[0]: extra_usages.add(x509.EKU_PKINIT_CLIENT_AUTH) trust_flags = parse_trust_flags(','.join(trust_flags[:3])) trust_flags = TrustFlags(trust_flags.has_key, trust_flags.trusted, trust_flags.ca, trust_flags.usages | extra_usages) try: certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags) except ValueError as e: raise admintool.ScriptError( "Failed to install the certificate: %s" % e) print("CA certificate successfully installed")
def list(self): ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, api.env.realm, False) for _ca_cert, ca_nickname, _ca_trust_flags in ca_certs: print(ca_nickname)
def delete(self): options = self.options nickname = self.args[1] conn = api.Backend.ldap2 ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, api.env.realm, False) ipa_ca_nickname = get_ca_nickname(api.env.realm) found = False for _ca_cert, ca_nickname, _ca_trust_flags in ca_certs: if ca_nickname == nickname: if ca_nickname == ipa_ca_nickname: raise admintool.ScriptError( 'The IPA CA cannot be removed with this tool') else: found = True break if not found: raise admintool.ScriptError('Unknown CA \'{}\''.format(nickname)) with certs.NSSDatabase() as tmpdb: tmpdb.create_db() for ca_cert, ca_nickname, ca_trust_flags in ca_certs: tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags) loaded = tmpdb.list_certs() logger.debug("loaded raw certs '%s'", loaded) tmpdb.delete_cert(nickname) for ca_nickname, _trust_flags in loaded: if ca_nickname == nickname: continue elif ipa_ca_nickname == nickname: raise admintool.ScriptError("The IPA CA cannot be removed") logger.debug("Verifying %s", ca_nickname) try: tmpdb.verify_ca_cert_validity(ca_nickname) except ValueError as e: msg = "Verifying \'%s\' failed. Removing part of the " \ "chain? %s" % (nickname, e) if options.force: print(msg) continue raise admintool.ScriptError(msg) else: logger.debug("Verified %s", ca_nickname) for _ca_cert, ca_nickname, _ca_trust_flags in ca_certs: if ca_nickname == nickname: container_dn = DN(('cn', 'certificates'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) dn = DN(('cn', nickname), container_dn) logger.debug("Deleting %s", ca_nickname) conn.delete_entry(dn) return
def import_ca_certs(self, db, ca_is_configured, conn=None): if conn is None: conn = api.Backend.ldap2 try: ca_certs = certstore.get_ca_certs_nss(conn, self.suffix, self.realm, ca_is_configured) except errors.NotFound: pass else: for cert, nickname, trust_flags in ca_certs: db.add_cert(cert, nickname, trust_flags)
def import_ca_certs(self, db, ca_is_configured, conn=None): if conn is None: conn = api.Backend.ldap2 try: ca_certs = certstore.get_ca_certs_nss( conn, self.suffix, self.realm, ca_is_configured) except errors.NotFound: pass else: for cert, nickname, trust_flags in ca_certs: db.add_cert(cert, nickname, trust_flags)
def install(self): print("Installing CA certificate, please wait") options = self.options cert_filename = self.args[1] try: cert_obj = x509.load_certificate_from_file(cert_filename) except IOError as e: raise admintool.ScriptError( "Can't open \"%s\": %s" % (cert_filename, e)) except (TypeError, ValueError) as e: raise admintool.ScriptError("Not a valid certificate: %s" % e) cert = cert_obj.public_bytes(serialization.Encoding.DER) nickname = options.nickname or str(DN(cert_obj.subject)) ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, api.env.realm, False) with certs.NSSDatabase() as tmpdb: pw = ipautil.write_tmp_file(ipautil.ipa_generate_password()) tmpdb.create_db(pw.name) tmpdb.add_cert(cert, nickname, 'C,,') for ca_cert, ca_nickname, ca_trust_flags in ca_certs: tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags) try: tmpdb.verify_ca_cert_validity(nickname) except ValueError as e: raise admintool.ScriptError( "Not a valid CA certificate: %s (visit " "http://www.freeipa.org/page/Troubleshooting for " "troubleshooting guide)" % e) 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( api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags) except ValueError as e: raise admintool.ScriptError( "Failed to install the certificate: %s" % e) print("CA certificate successfully installed")
def install(self): print("Installing CA certificate, please wait") options = self.options cert_filename = self.args[1] try: cert_obj = x509.load_certificate_from_file(cert_filename) except IOError as e: raise admintool.ScriptError( "Can't open \"%s\": %s" % (cert_filename, e)) except (TypeError, ValueError) as e: raise admintool.ScriptError("Not a valid certificate: %s" % e) cert = cert_obj.public_bytes(serialization.Encoding.DER) nickname = options.nickname or str(DN(cert_obj.subject)) ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, api.env.realm, False) with certs.NSSDatabase() as tmpdb: tmpdb.create_db() tmpdb.add_cert(cert, nickname, 'C,,') for ca_cert, ca_nickname, ca_trust_flags in ca_certs: tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags) try: tmpdb.verify_ca_cert_validity(nickname) except ValueError as e: raise admintool.ScriptError( "Not a valid CA certificate: %s (visit " "http://www.freeipa.org/page/Troubleshooting for " "troubleshooting guide)" % e) 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( api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags) except ValueError as e: raise admintool.ScriptError( "Failed to install the certificate: %s" % e) print("CA certificate successfully installed")
def _get_keys(self, ca_host, cacerts_file, cacerts_pwd, data): # Fetch all needed certs one by one, then combine them in a single # PKCS12 file prefix = data['prefix'] certlist = data['list'] cli = self._get_custodia_client(server=ca_host) with NSSDatabase(None) as tmpdb: tmpdb.create_db() # Cert file password crtpwfile = os.path.join(tmpdb.secdir, 'crtpwfile') with open(crtpwfile, 'w+') as f: f.write(cacerts_pwd) for nickname in certlist: value = cli.fetch_key(os.path.join(prefix, nickname), False) v = json_decode(value) pk12pwfile = os.path.join(tmpdb.secdir, 'pk12pwfile') with open(pk12pwfile, 'w+') as f: f.write(v['export password']) pk12file = os.path.join(tmpdb.secdir, 'pk12file') with open(pk12file, 'wb') as f: f.write(b64decode(v['pkcs12 data'])) tmpdb.run_pk12util([ '-k', tmpdb.pwd_file, '-n', nickname, '-i', pk12file, '-w', pk12pwfile ]) # Add CA certificates, but don't import the main CA cert. It's # already present as 'caSigningCert cert-pki-ca'. With SQL db # format, a second import would rename the certificate. See # https://pagure.io/freeipa/issue/7498 for more details. conn = api.Backend.ldap2 suffix = ipautil.realm_to_suffix(self.realm) ca_certs = get_ca_certs_nss(conn, suffix, self.realm, True) for cert, nickname, trust_flags in ca_certs: if nickname == get_ca_nickname(self.realm): continue tmpdb.add_cert(cert, nickname, trust_flags) # Now that we gathered all certs, re-export ipautil.run([ paths.PKCS12EXPORT, '-d', tmpdb.secdir, '-p', tmpdb.pwd_file, '-w', crtpwfile, '-o', cacerts_file ])
def export_ca_certs_nssdb(self, db, ca_is_configured, conn=None): """ Export the CA certificates stored in LDAP into an NSS database :param db: the target NSS database :param ca_is_configured: whether IPA is CA-less or not :param conn: an optional LDAP connection to use """ if conn is None: conn = api.Backend.ldap2 try: ca_certs = certstore.get_ca_certs_nss(conn, self.suffix, self.realm, ca_is_configured) except errors.NotFound: pass else: for cert, nickname, trust_flags in ca_certs: db.add_cert(cert, nickname, trust_flags)
def export_ca_certs_nssdb(self, db, ca_is_configured, conn=None): """ Export the CA certificates stored in LDAP into an NSS database :param db: the target NSS database :param ca_is_configured: whether IPA is CA-less or not :param conn: an optional LDAP connection to use """ if conn is None: conn = api.Backend.ldap2 try: ca_certs = certstore.get_ca_certs_nss( conn, self.suffix, self.realm, ca_is_configured) except errors.NotFound: pass else: for cert, nickname, trust_flags in ca_certs: db.add_cert(cert, nickname, trust_flags)
def prune(self): expired_certs = [] ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, api.env.realm, False) now = datetime.datetime.utcnow() for ca_cert, ca_nickname, _ca_trust_flags in ca_certs: if ca_cert.not_valid_after < now: expired_certs.append(ca_nickname) self._delete_by_nickname(ca_nickname, self.options) if expired_certs: print("Expired certificates deleted:") for nickname in expired_certs: print(nickname) print("Run ipa-certupdate on enrolled machines to apply changes.") else: print("No certificates were deleted")
def install(self): print("Installing CA certificate, please wait") options = self.options cert_filename = self.args[1] try: cert_obj = x509.load_certificate_from_file(cert_filename) except IOError as e: raise admintool.ScriptError( "Can't open \"%s\": %s" % (cert_filename, e)) except (TypeError, ValueError) as e: raise admintool.ScriptError("Not a valid certificate: %s" % e) cert = cert_obj.public_bytes(serialization.Encoding.DER) nickname = options.nickname or str(DN(cert_obj.subject)) ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, api.env.realm, False) with certs.NSSDatabase() as tmpdb: tmpdb.create_db() tmpdb.add_cert(cert, nickname, EXTERNAL_CA_TRUST_FLAGS) for ca_cert, ca_nickname, ca_trust_flags in ca_certs: tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags) try: tmpdb.verify_ca_cert_validity(nickname) except ValueError as e: raise admintool.ScriptError( "Not a valid CA certificate: %s (visit " "http://www.freeipa.org/page/Troubleshooting for " "troubleshooting guide)" % e) trust_flags = options.trust_flags.split(',') if (set(options.trust_flags) - set(',CPTcgpuw') or len(trust_flags) not in [3, 4]): raise admintool.ScriptError("Invalid trust flags") extra_flags = trust_flags[3:] extra_usages = set() if extra_flags: if 'C' in extra_flags[0]: extra_usages.add(x509.EKU_PKINIT_KDC) if 'T' in extra_flags[0]: extra_usages.add(x509.EKU_PKINIT_CLIENT_AUTH) trust_flags = parse_trust_flags(','.join(trust_flags[:3])) trust_flags = TrustFlags(trust_flags.has_key, trust_flags.trusted, trust_flags.ca, trust_flags.usages | extra_usages) try: certstore.put_ca_cert_nss( api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags) except ValueError as e: raise admintool.ScriptError( "Failed to install the certificate: %s" % e) print("CA certificate successfully installed")
def install(self): print("Installing CA certificate, please wait") options = self.options ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, api.env.realm, False) with certs.NSSDatabase() as tmpdb: tmpdb.create_db() tmpdb.import_files(self.args[1:]) imported = tmpdb.list_certs() logger.debug("loaded raw certs '%s'", imported) if len(imported) > 1 and options.nickname: raise admintool.ScriptError( "Nickname can only be used if only a single " "certificate is loaded") # If a nickname was provided re-import the cert if options.nickname: (nickname, trust_flags) = imported[0] cert = tmpdb.get_cert(nickname) tmpdb.delete_cert(nickname) tmpdb.add_cert(cert, options.nickname, EXTERNAL_CA_TRUST_FLAGS) imported = tmpdb.list_certs() for ca_cert, ca_nickname, ca_trust_flags in ca_certs: tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags) for nickname, trust_flags in imported: if trust_flags.has_key: continue tmpdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS) for nickname, trust_flags in imported: try: tmpdb.verify_ca_cert_validity(nickname) except ValueError as e: raise admintool.ScriptError( "Not a valid CA certificate: %s (visit " "http://www.freeipa.org/page/Troubleshooting for " "troubleshooting guide)" % e) else: print("Verified %s" % nickname) trust_flags = options.trust_flags.split(',') if (set(options.trust_flags) - set(',CPTcgpuw') or len(trust_flags) not in [3, 4]): raise admintool.ScriptError("Invalid trust flags") extra_flags = trust_flags[3:] extra_usages = set() if extra_flags: if 'C' in extra_flags[0]: extra_usages.add(x509.EKU_PKINIT_KDC) if 'T' in extra_flags[0]: extra_usages.add(x509.EKU_PKINIT_CLIENT_AUTH) trust_flags = parse_trust_flags(','.join(trust_flags[:3])) trust_flags = TrustFlags(trust_flags.has_key, trust_flags.trusted, trust_flags.ca, trust_flags.usages | extra_usages) for nickname, _trust_flags in imported: try: cert = tmpdb.get_cert(nickname) certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags) except ValueError as e: raise admintool.ScriptError( "Failed to install the certificate: %s" % e) print("CA certificate successfully installed")
def install(self): print("Installing CA certificate, please wait") options = self.options ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, api.env.realm, False) with certs.NSSDatabase() as tmpdb: tmpdb.create_db() tmpdb.import_files(self.args[1:]) imported = tmpdb.list_certs() logger.debug("loaded raw certs '%s'", imported) if len(imported) > 1 and options.nickname: raise admintool.ScriptError( "Nickname can only be used if only a single " "certificate is loaded") # If a nickname was provided re-import the cert if options.nickname: (nickname, trust_flags) = imported[0] cert = tmpdb.get_cert(nickname) tmpdb.delete_cert(nickname) tmpdb.add_cert(cert, options.nickname, EXTERNAL_CA_TRUST_FLAGS) imported = tmpdb.list_certs() for ca_cert, ca_nickname, ca_trust_flags in ca_certs: tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags) for nickname, trust_flags in imported: if trust_flags.has_key: continue tmpdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS) for nickname, trust_flags in imported: try: tmpdb.verify_ca_cert_validity(nickname) except ValueError as e: raise admintool.ScriptError( "Not a valid CA certificate: %s (visit " "http://www.freeipa.org/page/Troubleshooting for " "troubleshooting guide)" % e) else: print("Verified %s" % nickname) trust_flags = options.trust_flags.split(',') if (set(options.trust_flags) - set(',CPTcgpuw') or len(trust_flags) not in [3, 4]): raise admintool.ScriptError("Invalid trust flags") extra_flags = trust_flags[3:] extra_usages = set() if extra_flags: if 'C' in extra_flags[0]: extra_usages.add(x509.EKU_PKINIT_KDC) if 'T' in extra_flags[0]: extra_usages.add(x509.EKU_PKINIT_CLIENT_AUTH) trust_flags = parse_trust_flags(','.join(trust_flags[:3])) trust_flags = TrustFlags(trust_flags.has_key, trust_flags.trusted, trust_flags.ca, trust_flags.usages | extra_usages) for nickname, _trust_flags in imported: try: cert = tmpdb.get_cert(nickname) certstore.put_ca_cert_nss( api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags) except ValueError as e: raise admintool.ScriptError( "Failed to install the certificate: %s" % e) print("CA certificate successfully installed")